LLVMにRenesas RL78をPortingしようとしているのかな?

こんにちは。NoMaYです。

ウェブで調べ物をしていて気付いたのですが、RenesasさんはLLVM(今はGCCと並ぶ著名なフリーコンパイラ)にRL78をPortingしようとしているのかも、、、

[llvm-dev] New LLVM backend for Renesas RL78 MCU
Sebastian Perta via llvm-dev llvm-dev at lists.llvm.org
Wed Apr 1 10:26:05 PDT 2020
lists.llvm.org/pipermail/llvm-dev/2020-April/140546.html
 

  • NoMaYさん

    シェルティですこんにちは。

    色々と実験ありがとうございます。permission deniedが特に気になります。ツールチームと相談開始しました。

    ①再現環境もらえませんか?

    ②再現頻度はどのくらいでしょう?

    ③再現環境が置いてあるファイルパスを教えてください。

    ④ほやさんが書き込んでいる視点(操作手順や設定など)での情報もあれば教えてください。

    再現したりしなかったり、とのことなので情報まとまった段階で情報いただければと思います。

    種々お手数おかけしてすみません。新しい開発環境の精度をもっと上げていきたいと考えてます。

    本スレッド含め掲示板の内容は全般継続的に確認させていただいております。

    以上です

  • こんにちは。NoMaYです。

    LLVM-RL78+e2 studioでメモリを見ようとしたらgdbが落ちた、、、

    以下、画面コピーです。


     

  • こんにちは。NoMaYです。

    別スレッドのFreeRTOSのRTOSDemoプログラムをデバッグしていて気付いたのですけど、FreeRTOSのスタックオーバーフローチェックでスタックに書いたシグニチャ(0xA5)が壊れていないかどうかをチェックしている箇所で以下のコードが生成されていました。このコードは、レジスタバンク0以外が使われていた場合には、設計者の意図通りには動作しないです。LLVM-RL78の開発者は、昨日のビット操作命令の必要性が分かっていないことに加え、レジスタバンクがどういうものかということも分かっていないと思われるのです、、、

    生成されていたコード:

    00005938 _OUTLINED_FUNCTION_15:
        5938: 12                            movw bc, ax
        5939: 7a fa a5                      xor 0xffefa, #165
        593c: 7a fb a5                      xor 0xffefb, #165
        593f: d7                            ret

     
    意図としていたものと思われるコード(なお命令セットとして2つめと3つめの命令は存在しません):

    movw bc, ax
    xor  c, 0xA5
    xor  b, 0xA5
    ret

     

  • 「xx は動作を停止しました」は、「一定時間以内にWindowsのイベントに応答しなかった」という意味ですが、これだけで異常かどうかは判断できません。
    GDBコマンド打っても何も反応がないなら本当に止まっているのでしょうが...

  • > レジスタバンク0以外が使われていた場合には、設計者の意図通りには動作しないです。

    RL78版の gcc の出力するコードではバンク 1 と 2 のレジスタはメモリにマップされてる汎用レジスタという扱いで、レジスタバンクは 0 固定で動作するという前提でしたが似たような感じで RL78 の特徴が活きない想定なのでは?

  • こんにちは。NoMaYです。

    以前に投稿したBlinkyサンプルプログラムのzipファイルにリストファイル(GNURL78)と逆アセンブルダンプファイル(LLVM-RL78とGNURL78)も入れておいたのですが、内蔵周辺レジスタアクセスのコードがLLVM-RL78はGNURL78より随分悪い件をちょっと調べていて気付いたことがありました。

    (1) LLVM向けiodefine.hではPIF0ビットは16ビットレジスタのビットの扱いになっていました
    (2) volatileが付いているので8ビットアクセスとなるビット操作命令を使うのはC言語規格とは整合しないですね
    (3) PIF0ビットが16ビットレジスタのビットの扱いなのはRL78/G14のGNURL78向けiodefine.hでも同じでした

    src/smc_gen/r_bsp/mcu/rl78_g23/register_access/llvm/iodefine.h

    #define PIF0 IF0_bit.no2

    #define IF0_bit (*(volatile union un_if0 *)0xFFFE0).BIT

    union un_if0 {
        unsigned short if0;
        __BITS16 BIT;
    };

    typedef struct {
        unsigned short no0 :1;
        unsigned short no1 :1;
        unsigned short no2 :1;
        unsigned short no3 :1;
        unsigned short no4 :1;
        unsigned short no5 :1;
        unsigned short no6 :1;
        unsigned short no7 :1;
        unsigned short no8 :1;
        unsigned short no9 :1;
        unsigned short no10 :1;
        unsigned short no11 :1;
        unsigned short no12 :1;
        unsigned short no13 :1;
        unsigned short no14 :1;
        unsigned short no15 :1;
    } __BITS16;

     
    [追記]

    試しにiodefine.hを書き換えてみましたが、あまり変わらなかったですね。残念。

    現状の定義

    #define PIF0 IF0_bit.no2
    #define PMK0 MK0_bit.no2

     
    試しの定義

    #define PIF0 IF0L_bit.no2
    #define PMK0 MK0L_bit.no2

     
    現状での生成コード

    0000332a _R_Config_INTC_INTP0_Start:
    ;     PIF0 = 0U;    /* clear INTP0 interrupt flag */
        332a: 36 e0 ff                         movw hl, #65504
        332d: ab                               movw ax, [hl]
        332e: 5a f8 fb                         and 0xffef8, #251
        3331: 36 e0 ff                         movw hl, #65504
        3334: bb                               movw [hl], ax
    ;     PMK0 = 0U;    /* enable INTP0 interrupt */
        3335: 36 e4 ff                         movw hl, #65508
        3338: ab                               movw ax, [hl]
        3339: 5a f8 fb                         and 0xffef8, #251
        333c: 36 e4 ff                         movw hl, #65508
        333f: bb                               movw [hl], ax
    ; }
        3340: d7                               ret

     
    試しでの生成コード

    0000332a _R_Config_INTC_INTP0_Start:
    ;     PIF0 = 0U;    /* clear INTP0 interrupt flag */
        332a: 36 e0 ff                         movw hl, #65504
        332d: 8b                               mov a, [hl]
        332e: 71 ab                            clr1 a.2
        3330: 36 e0 ff                         movw hl, #65504
        3333: 9b                               mov [hl], a
    ;     PMK0 = 0U;    /* enable INTP0 interrupt */
        3334: 36 e4 ff                         movw hl, #65508
        3337: 8b                               mov a, [hl]
        3338: 71 ab                            clr1 a.2
        333a: 36 e4 ff                         movw hl, #65508
        333d: 9b                               mov [hl], a
    ; }
        333e: d7                               ret

     

  • こんにちは。NoMaYです。

    > LLVM-RL78+e2 studioですが、デバッグ中にバグの箇所が分かったのでソースを修正して(デバッグ中のまま)ビルドするとpermission deniedでリンクエラーになることがあります。(エラーにならない時もあり、何の手順が影響しているのかは分からないです。また、どっちのケースの頻度が多いかまでは数えていません。)

    COM PortデバッガだけでなくRenesas RL78 Simulatorでも起きました。(すみません、画面コピーをとり忘れました。) でも、未だに、何をしていると(何をした後だと)駄目になるのか、分からないです。

    > 実は、ICCRL78+e2 studio+IARビルドプラグインの組み合わせでも同様ですが(しかも、こちらは、ほぼ100%そうだったと記憶していますが)、GNURL78+e2 studio(やCC-RL+e2 studio)の組み合わせでは発生していませんでしたので、LLVM-RL78+e2 studioでも発生しないようにしてもらいたいですね、、、

    そういえば、実は、今は以前に投稿した別問題の対応でリンク時(というか正確にはリンク後)に、生成されたプログラムの特定領域を特定値でFILLするリンクオプション(というかリンク後オプションみたいな?)を指定しているのですけれども、それ以降は全く起きていませんでした。(どうやらリンカは一旦仮の名前でロードモジュールを生成して、リンカとは別ツールでパッチを当てた後、最終的に本来の名前のロードモジュールにコピーし直すようです。それが、どうも、問題を起きなくさせているような印象です。)

    もう来月にはe2 studio 2021-07?が出る筈ですけれども、再現方法不明では、もう間に合いませんね、、、

  • > もう来月にはe2 studio 2021-07?が出る筈ですけれども、

    7/14の日付で新しいのが出てますね。

  • こんにちは。NoMaYです。

    > 7/14の日付で新しいのが出てますね。

    情報どうもありがとうございます。LLVM for Renesas RL78 が 10.0.0.202104 --> 10.0.0.202107 とアップデートされていましたね。newlib nano が使えるようになったとのことで、使ってみると確かにビルドしたプログラムのサイズが大幅に小さくなりました。(GNURL78と同等(少しLLVM-RL78の方が小さい)になった。)

    手持ちのプログラムその1

    LLVM-RL78   49,958 バイト@10.0.0.202104 --> 23,646 バイト@10.0.0.202107
    GNURL78     24,386 バイト@4.9.2.202002
    CC-RL       16,426 バイト@V1.10.00
    ICCRL78     15,850 バイト@V4.21.1

     
    手持ちのプログラムその2

    LLVM-RL78   73,396 バイト@10.0.0.202104 --> 46,198 バイト@10.0.0.202107
    GNURL78     50,418 バイト@4.9.2.202002
    CC-RL       34,766 バイト@V1.10.00
    ICCRL78     対象外(評価版のサイズ制限(16Kバイト)を超えるので同一プログラムをビルド出来ない)

     
    注:
    (1) 各ツールのサイズ表示機能を使用しているので計測対象が微妙に異なるかも知れません
    (2) ICCRL78は評価版のサイズ制限(16Kバイト)の事情で関数ポインタの先の関数が64Kバイト内に制限されるコードです。
    (2') 他のコンパイラでは関数ポインタの先の関数が64Kバイト内に制限されないコードです。

  • こんにちは。NoMaYです。

    ルネサスさんのCC-XXコンパイラもLLVMテクノロジを採用していますが、これ程の差は何でしょうかね、、、もちろん、ルネサスさんのCC-XXコンパイラの開発者の方々が大変優秀な証拠ですね、と言ってしまえば終わりなのですが、これ程の差というのは技術的側面においてちょっと気になります。(計測対象が違っているかも知れないという可能性も含めて、、、)

    手持ちのプログラムその1

    LLVM-RL78   23,646 バイト@10.0.0.202107
    CC-RL       16,426 バイト@V1.10.00

     
    手持ちのプログラムその2

    LLVM-RL78   46,198 バイト@10.0.0.202107
    CC-RL       34,766 バイト@V1.10.00