Top Page [◀◀]  2   3   4   5   6   7   8   9   ... [▶▶Last Page

GNURX用のCCRXmachine.hとCCRXmachine.cというソースがe2 studioフォルダにありました(内容は概ね名前から予想される通りのものでした)

こんにちは。NoMaYです。

e2 studio v6.3.0がリリースされていたので、インストールして幾つかプロジェクトを作成して、いつものようにe2 studioのインストールフォルダを眺めていたら、CCRXmachine.hとCCRXmachine.cというファイルがあることに気付きました。中を見てみると、概ねファイル名から予想される通りのソースファイルでした。(今までのe2 studioのインストールフォルダを見直してみたところ、以前からあったことが分かりましたが、今まで気付きませんでした。) ただ、一部コメントアウトされているものがあったり、以前に別スレッド『GUNRX用プロジェクトのスマートコンフィグレータのBSPを見ていて気付いた変な移植コード』で話題にしたことと同じ元のコードの意図を理解していない書き換えがあったり、ちょっと惜しいような気もしました。

e2 studioインストールフォルダ\internal\projectgen\rx\Generate\CCRXConversion\inc\CCRXmachine.h



e2 studioインストールフォルダ\internal\projectgen\rx\Generate\CCRXConversion\inc\CCRXmachine.c



  • こんにちは。NoMaYです。

    幾つか前の投稿で書いたCC-RXで積和演算を行うrmpab()関数(およびrmpaw()関数とrmpal()関数も)ですが、GNURXでの今回のCCRXmachine2.hの実装が何か汚くなって来たので、少し頭を冷やしてGoogle検索していたところ、GNURXのビルトイン関数に__builtin_rx_rmpa()という関数があることに気付きました。ところが、これがまた悩ましい仕様になっていました。

    void __builtin_rx_rmpa (void)

        Generates the rmpa machine instruction which initiates a repeated multiply and accumulate sequence.

    GNURX
    gcc-renesas.com/migration-guides/rx/index.html#Build_in

    GCC本家
    gcc.gnu.org/onlinedocs/gcc/RX-Built-in-Functions.html#index-_005f_005fbuiltin_005frx_005frmpa

    悩ましい点の1つ目は、積和演算関数は積和演算命令のデータのサイズ(B/W/L)に応じて3種類あるのですが、この__builtin_rx_rmpa()関数はバイトサイズ用のものであり、他のデータサイズ用のものが無い点です。

    2つ目は、積和演算関数には引数が4つあるのですが、この__builtin_rx_rmpa()関数には引数がありませんので、一体どうやって使えば良いのか分からない(ドキュメントに使い方の記述が無い)点です。加えて、恐らくこの様に使うに違いない、というのが分かっても試してみると、最適化無しでしか使えない点です。

    それで、まず使い方に関しては、RedHat社で組み込み向けGNUコンパイラを開発されているDJ Delorie氏が本家Rulzへ投稿したrmpa_gcc.zipのrmpa.cの以下のインラインアセンブラ部分をこの__builtin_rx_rmpa()関数で置き換える、ということになる筈だと思います。(ちなみに、今回のCCRXmachine2.hでも苦し紛れに同様な記述をしていたのですが、どうやらその記述で合っていそうだ、ということが分かって来ました。)

    Optimizing multiply-accumulate (RMPA) with GCC
    renesasrulz.com/rx/f/rx---forum/2509/optimizing-multiply-accumulate-rmpa-with-gcc


    rmpa.c (rmpa_gcc.zipに含まれているソース)

    #include "data.h"

    extern __inline__ __attribute__((always_inline))
    long long
    rmpaw (long long init, unsigned long count, short *a, short *b)
    {
      register long long rv __asm__("r4") = init;
      register unsigned long count_out __asm__("r3") = count;
      register short *a_out __asm__("r1") = a;
      register short *b_out __asm__("r2") = b;

      __asm__ volatile ("rmpa.w"
        : "=r" (rv), "=r" (count_out) , "=r" (a_out), "=r" (b_out)
        : "0" (rv), "1" (count_out), "2" (a_out), "3" (b_out)
        : "r6");
      return rv;
    }

    long long mac (short *a, short *b, int len)
    {
      return rmpaw (0, len, a, b);
    }

    これをそのままGNURX 2018q1でコンパイルした場合

    -O3
    ⇒ コードはソースの意図通り (もともと 引数 a --> r1, 引数 b --> r2, 引数 len --> r3 で呼ばれる)
    ⇒ ただし、そもそもソース上でr6を初期化しておらず、積和演算結果が意図通りにならない場合がある筈
    ⇒ また、アセンブラ記述部がa[0]~a[count-1]とb[0]~b[count-1]を参照しているという情報が無いので、
      上の例では意図通りのコードが生成されたものの、もっと複雑なソースにrmpaw()関数がインライン展開
      された場合に誤ったコードが生成される可能性がある(と思われます、、、詳細は後述します、、、)
       4                                    .global _mac
       6                                _mac:
      11 0000 7E A6                         push.l  r6
      17 0002 66 04                         mov.L   #0, r4
      18 0004 EF 45                         mov.L   r4, r5
      21 0006 7F 8D                         rmpa.w
      27 0008 EF 41                         mov.L   r4, r1
      28 000a EF 52                         mov.L   r5, r2
      29 000c 3F 66 01                      rtsd    #4, r6-r6
    -O0
    ⇒ コンパイルエラーになってしまう
    >make
    rx-elf-gcc -g -O0 -MMD -Wa,-adln=rmpa.lst   -c -o rmpa.o rmpa.c
    rmpa.c: In function 'mac':
    rmpa.c:22:1: error: r6 cannot be used in asm here
     }
     ^

    ところが、以下の通りインラインアセンブラ部分をこの__builtin_rx_rmpa()関数で置き換えてコンパイルしてみると、最適化有りでは正しくないコードが生成されてしまっている、ということに気付きます、、、

      register long long rv __asm__("r4") = init;
      register unsigned long count_out __asm__("r3") = count;
      register short *a_out __asm__("r1") = a;
      register short *b_out __asm__("r2") = b;

      __builtin_rx_rmpa();
      return rv;

    GNURX 2018q1でコンパイルした場合

    -O3 / -O2 / -O1
    ⇒ コードが滅茶苦茶 (r5:r4にinitの初期値0が設定されておらず、逆に戻り値はinitの初期値0のまま)
    ⇒ 補足すれば、最適化処理で__builtin_rx_rmpa();は入出力の全く無いNOP命令と同じ扱い!をされている
       4                                    .global _mac
       6                                _mac:
      11 0000 6E 67                         pushm   r6-r7
      13 0002 EF 06                         mov.L   r0, r6
      19 0004 7F 8E                         rmpa
      24 0006 66 01                         mov.L   #0, r1
      25 0008 EF 12                         mov.L   r1, r2
      26 000a 3F 67 02                      rtsd    #8, r6-r7
    -O0
    ⇒ コードはソースの意図通り
       4                                    .global _mac
       6                                _mac:
      10 0000 7E A6                         push.l  r6
      12 0002 71 06 E0                      add #-32, r0, r6
      14 0005 EF 60                         mov.L   r6, r0
      16 0007 A1 69                         mov.L   r1, 20[r6]      引数 a
      17 0009 A1 E2                         mov.L   r2, 24[r6]      引数 b
      18 000b A1 EB                         mov.L   r3, 28[r6]      引数 c
      20 000d A9 ED                         mov.L   28[r6], r5
      21 000f F8 66 00                      mov.L   #0, [r6]        0 --> init(下位32ビット)
      22 0012 3E 61 00                      mov.L   #0, 4[r6]       0 --> init(上位32ビット)
      23 0015 A0 E5                         mov.L   r5, 8[r6]       引数 c --> r5 --> count
      24 0017 A9 6D                         mov.L   20[r6], r5
      25 0019 A0 ED                         mov.L   r5, 12[r6]      引数 a --> r5 --> a_out
      26 001b A9 E5                         mov.L   24[r6], r5
      27 001d A1 65                         mov.L   r5, 16[r6]      引数 b --> r5 --> b_out
      31 001f EC 64                         mov.L   [r6], r4        init(下位32ビット) --> r4
      32 0021 A8 6D                         mov.L   4[r6], r5       init(上位32ビット) --> r5
      34 0023 A8 E3                         mov.L   8[r6], r3       count --> r3
      36 0025 A8 E9                         mov.L   12[r6], r1      a_out --> r1
      38 0027 A9 62                         mov.L   16[r6], r2      b_out --> r2
      40 0029 7F 8E                         rmpa
      42 002b EF 42                         mov.L   r4, r2
      43 002d EF 53                         mov.L   r5, r3
      44 002f EF 24                         mov.L   r2, r4
      45 0031 EF 35                         mov.L   r3, r5
      49 0033 EF 42                         mov.L   r4, r2
      50 0035 EF 53                         mov.L   r5, r3
      51 0037 EF 24                         mov.L   r2, r4
      52 0039 EF 35                         mov.L   r3, r5
      54 003b EF 41                         mov.L   r4, r1          r4 --> 戻り値(下位32ビット)
      55 003d EF 52                         mov.L   r5, r2          r5 --> 戻り値(上位32ビット)
      56 003f 3F 66 09                      rtsd    #36, r6-r6

    このような具合であり、以前に投稿した__builtin_rx_xchg()関数で「複雑難解な最適化処理との兼ね合いでどちらに転ぶか分からない不安があって悩ましい」と感じたのと同様に、この__builtin_rx_rmpa()関数でも最適化処理との絡みが悩ましい、と感じました。

    そして、最適化処理との絡みという点で、DJ Delorie氏のインラインアセンブラ部分も怪しい気がします。実は、今回のCCRXmachine2.hの為に色々調べていたので気付いたのですが、ストリング操作命令では以下のような記述が必要であり、それはRMPA命令でも同じだと思われます。ところが、DJ Delorie氏のインラインアセンブラ部分に、それに相当する記述(アセンブラ記述部がa[0]~a[count-1]とb[0]~b[count-1]を参照しているという記述)がありませんので、複雑なソースにrmpaw()関数がインライン展開された場合に最適化処理により誤ったコードが生成される可能性があると思われます、、、

    6.45.2 Extended Asm - Assembler Instructions with C Expression Operands
    gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Clobbers-and-Scratch-Registers


    IA-32インテル®アーキテクチャ ソフトウェア・デベロッパーズ・マニュアル 中巻B:命令セット・リファレンスN-Z
    www.intel.com/content/dam/www/public/ijkk/jp/ja/documents/developer/IA32_Arh_Dev_Man_Vol2B_i.pdf


    そもそも、DJ Delorie氏のソース上でr6が初期化されていませんので、積和演算結果が意図通りにならない場合がある筈だと思われます、、、

    RXファミリ ユーザーズマニュアル ソフトウェア編
    www.renesas.com/ja-jp/doc/products/mpumcu/doc/rx_family/r01us0032jj0120_rxsm.pdf


    ちなみに、今回のCCRXmachine2.hの手元の作業中のソースでは、rmpab()関数(およびrmpaw()関数とrmpal()関数も)は、ようやく以下の記述に至ったところです。

    #ifndef rmpab
    #define rmpab(init, count, addr1, addr2) ccrx_machine_h_rmpab(init, count, addr1, addr2)
    #endif
    static __inline__ long long ccrx_machine_h_rmpab(long long init, unsigned long count, signed char *addr1, signed char *addr2) __attribute__((always_inline));
    static __inline__ long long ccrx_machine_h_rmpab(long long init, unsigned long count, signed char *addr1, signed char *addr2)
    {
    /* CC-RX V2.03
            ARG init = R2:R1
            ARG count = R3
            ARG addr1 = R4
            ARG addr2 = 04H[R0](08H[R0] after push R6)
            RET R2:R1

            PUSH.L R6
            MOV.L R1, R14
            MOV.L R2, R5
            MOV.L 08H[R0], R2
            SHAR #1FH, R5, R6
            MOV.L R4, R1
            MOV.L R14, R4
            RMPA.B
            MOV.L R5, R2
            MOV.L R4, R1
            RTSD #04H, R6-R6
    */
        register long long _r5r4 __asm__("r4") = init;
        register signed char *_r1 __asm__("r1") = addr1;
        register signed char *_r2 __asm__("r2") = addr2;
        register unsigned long _r3 __asm__("r3") = count;
    #ifdef __OPTIMIZE__
        /* In case of other than -O0, we assign r6. */
        register signed long _rS __asm__("r6") = (signed long)(init >> 63);
    #else
        /* In case of -O0, we assign r8 because r6 and r7 are reserved for the frame pointer and something. */
        register signed long _rS __asm__("r8") = (signed long)(init >> 63);
    #endif
        __asm__ volatile
        (
            /* AssemblerTemplate */
    #ifdef __OPTIMIZE__
            "RMPA.B"        "\n\t"
    #else
            "XCHG R6, R8"   "\n\t"
            "RMPA.B"        "\n\t"
            "XCHG R6, R8"   "\n\t"
    #endif
            : /* OutputOperands */
                /**/ "+r" (_rS),
                /**/ "+r" (_r5r4),
                /**/ "+r" (_r3)
            : /* InputOperands */
                /**/ "r" (_r1),
                /**/ "r" (_r2),
                /**/ "m" (*(signed char (*)[count]) addr1),
                /**/ "m" (*(signed char (*)[count]) addr2)
            : /* Clobbers */
                /*"r1",*/ /* This causes a compile error: asm-specifier for variable '_r1' conflicts with asm clobber list */
                /*"r2" */ /* This causes a compile error: asm-specifier for variable '_r2' conflicts with asm clobber list */
        );
        __asm__ volatile
        (
            /* AssemblerTemplate */
            ""/*"NOP"*/     "\n\t"
            : /* OutputOperands */
                /* No outputs. */
            : /* InputOperands */
                /* No inputs. */
            : /* Clobbers */
                "r1",
                "r2"
            /* This asm statement can make the compiler to recognize that r1 and r2 are not equivalent to addr1 and addr2. */
            /* For example, after replacing 'return _r5r4;' --> 'return *addr1 * *addr2;' tentatively, code are different. */
    /* GNURX 2018q1 -O2
    In case of WITHOUT this asm statement, it is recognized that r1 and r2 are equivalent to addr1 and addr2 mistakenly.
         0019 7E A6                         push.l  r6
         001b 60 40                         sub     #4, r0
         001d EF 25                         mov.L   r2, r5
         001f A8 8A                         mov.L   12[r0], r2
         0021 FC 43 41                      xchg    r4, r1
         0024 FD BF 56                      shar    #31, r5, r6
         0027 7F 8C                         RMPA.B
     return *addr1 * *addr2;
         0029 CC 15                         mov.B   [r1], r5
         002b CC 21                         mov.B   [r2], r1
         002d 4F 51                         mul     r5, r1
         002f FD BF 12                      shar    #31, r1, r2
         0032 3F 66 02                      rtsd    #8, r6-r6
    In case of WITH this asm statement, it is recognized that r1 and r2 are not equivalent to addr1 and addr2 correctly.
         0019 7E A6                         push.l  r6
         001b 60 40                         sub     #4, r0
         001d EF 25                         mov.L   r2, r5
         001f ED 0E 03                      mov.L   12[r0], r14
         0022 EF 4F                         mov.L   r4, r15
         0024 EF 14                         mov.L   r1, r4
         0026 EF E2                         mov.L   r14, r2
         0028 EF F1                         mov.L   r15, r1
         002a FD BF 56                      shar    #31, r5, r6
         002d 7F 8C                         RMPA.B
     return *addr1 * *addr2;
         002f CC F1                         mov.B   [r15], r1
         0031 06 0C E1                      mul     [r14].B, r1
         0034 FD BF 12                      shar    #31, r1, r2
         0037 3F 66 02                      rtsd    #8, r6-r6
    */
        );
        return _r5r4;
    /* GNURX 2018q1 -O2
     108 0019 7E A6                         push.l  r6
     110 001b 60 40                         sub     #4, r0
     113 001d EF 25                         mov.L   r2, r5
     115 001f A8 8A                         mov.L   12[r0], r2
     120 0021 FC 43 41                      xchg    r4, r1
     122 0024 FD BF 56                      shar    #31, r5, r6
     125 0027 7F 8C                         RMPA.B
     134 0029 EF 41                         mov.L   r4, r1
     135 002b EF 52                         mov.L   r5, r2
     136 002d 3F 66 02                      rtsd    #8, r6-r6
    */
    /* GNURX 2018q1 -O0, (This caller is not good example, to be reconsidered...)
     185 00ab 6E 6C                         pushm   r6-r12
     187 00ad 71 06 D8                      add     #-40, r0, r6
     189 00b0 EF 60                         mov.L   r6, r0
     191 00b2 75 45 48                      mov.L   #0x48, r5
     192 00b5 4B 65                         add     r6, r5
     193 00b7 A1 69                         mov.L   r1, 20[r6]
     194 00b9 A1 E2                         mov.L   r2, 24[r6]
     195 00bb A1 EB                         mov.L   r3, 28[r6]
     196 00bd A2 64                         mov.L   r4, 32[r6]
     197 00bf A9 6C                         mov.L   20[r6], r4
     198 00c1 E3 64                         mov.L   r4, [r6]
     199 00c3 A9 E4                         mov.L   24[r6], r4
     200 00c5 A0 6C                         mov.L   r4, 4[r6]
     201 00c7 A9 EC                         mov.L   28[r6], r4
     202 00c9 A0 E4                         mov.L   r4, 8[r6]
     203 00cb AA 64                         mov.L   32[r6], r4
     204 00cd A0 EC                         mov.L   r4, 12[r6]
     205 00cf EC 55                         mov.L   [r5], r5
     206 00d1 A1 65                         mov.L   r5, 16[r6]
     210 00d3 EC 64                         mov.L   [r6], r4
     211 00d5 A8 6D                         mov.L   4[r6], r5
     213 00d7 A8 E9                         mov.L   12[r6], r1
     215 00d9 A9 62                         mov.L   16[r6], r2
     217 00db A8 E3                         mov.L   8[r6], r3
     219 00dd ED 6C 01                      mov.L   4[r6], r12
     220 00e0 FD BF CA                      shar    #31, r12, r10
     221 00e3 ED 6C 01                      mov.L   4[r6], r12
     222 00e6 FD BF CB                      shar    #31, r12, r11
     223 00e9 EF A8                         mov.L   r10, r8
     225 00eb ED 6A 03                      mov.L   12[r6], r10
     226 00ee ED 6B 04                      mov.L   16[r6], r11
     228 00f1 FC 43 68                      XCHG R6, R8
     229 00f4 7F 8C                         RMPA.B
     230 00f6 FC 43 68                      XCHG R6, R8
     239 00f9 EF 42                         mov.L   r4, r2
     240 00fb EF 53                         mov.L   r5, r3
     241 00fd EF 24                         mov.L   r2, r4
     242 00ff EF 35                         mov.L   r3, r5
     246 0101 EF 42                         mov.L   r4, r2
     247 0103 EF 53                         mov.L   r5, r3
     248 0105 EF 24                         mov.L   r2, r4
     249 0107 EF 35                         mov.L   r3, r5
     250 0109 EF 41                         mov.L   r4, r1
     251 010b EF 52                         mov.L   r5, r2
     252 010d 3F 6C 11                      rtsd    #68, r6-r12
    */
    }

     

  • こんにちは。NoMaYです。

    GNURX(というかGCC)のインラインアセンブラは難しいですね。(それでも、ようやく、きっとこれで合っているに違いない、という感覚が湧き上がってくることがあるレベルになって来ましたが、、、) 以前に投稿したGNURXでの今回のCCRXmachine2.hのxchg()関数のインラインアセンブラ記述の件で、何か腑に落ちない感覚があったのですが、しつこく調べていたところ、stackoverflowというサイトに投稿されていた以下のスレッドを見て、やっと直接の原因を理解出来ました(と思う)。そして、GCC本家のドキュメントを見直してみると、確かにそう書いてありました。つまり、GCCは、より良いコードを生成する為、アセンブラ記述部では変数への書き込みがあった時点で変数からの読み出しは全て完了しているものと仮定してコードを生成する、そういう実装になっている、ということでした。(でも、その仮定が正しくない場合もあるので、その動作を変更するアセンブラ記述も出来るようになっていました。)

    以前の投稿で腑に落ちなかった記述

    static __inline__ void xchg(signed long *data1, signed long *data2) __attribute__((always_inline));
    static __inline__ void xchg(signed long *data1, signed long *data2)
    {
    /* CC-RX V2.03
            MOV.L [R1], R14
            XCHG [R2].L, R14
            MOV.L R14, [R1]
            RTS
    */
        signed long temp; /* = *data1; */
        __asm__ volatile
        (
            /* AssemblerTemplate */
            "MOV.L [%[R1]], %[R14]\n\t"
            "XCHG [%[R2]].L, %[R14]\n\t"
            "MOV.L %[R14], [%[R1]]"
            : /* OutputOperands */
                [R14] "=r" (temp)
            : /* InputOperands */
                [R1] "r" (data1),
                [R2] "r" (data2)

        );
        /* *data1 = temp; */
        return;
    /* GNURX 2018q1
      92 0010 EC 12                         MOV.L [r1], r2 ← r2を壊してしまった
      93 0012 06 A0 10 22                   XCHG [r2].L, r2
      94 0016 E3 12                         MOV.L r2, [r1]
      97 0018 02                            rts
    */
    }

    そして以下のことが思い浮かんだが、、、

    ● インラインアセンブラ記述部のInputOperandとしてポインタの値だけというのは変だよね。少なくとも以下の何れか1つは一緒に指定されていないと変だよね。
    (1) OutputOperandにポインタの値を加工した値の出力
    (2) InputOperandにポインタの値(もしくは加工した値)によるメモリのリード
    (3) OutputOperandにポインタの値(もしくは加工した値)によるメモリのライト(もしくはリードモデファイライト)
    ●この何れも指定されていないのであれば、ポインタの値は実質使われていない、ということだから壊しても構わないよね。

    やっと直接の原因を理解出来た(と思う、、、)

    stackoverflow.com/questions/15819794/when-to-use-earlyclobber-constraint-in-extended-gcc-inline-assembly


    GCC本家のドキュメントをにも確かにそう書いてありました

    gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#index-asm-output-operands


    gcc.gnu.org/onlinedocs/gcc/Modifiers.html#index-earlyclobber-operand


    ですので、今回のCCRXmachine2.hの手元の作業中のソースでは、xchg()関数は以下の記述に至っています。(なお、以下のOutputOperandsとInputOperandsの制約はAssemblerTemplateの3行に渡っての制約ですので、xchg命令単体としての制約とは異なります。)

    #ifndef xchg
    #define xchg(data1, data2) ccrx_machine_h_xchg(data1, data2)
    #endif
    static __inline__ void ccrx_machine_h_xchg(signed long *data1, signed long *data2) __attribute__((always_inline));
    static __inline__ void ccrx_machine_h_xchg(signed long *data1, signed long *data2)
    {
    /* CC-RX V2.03
            MOV.L [R1], R14
            XCHG [R2].L, R14
            MOV.L R14, [R1]
            RTS
    */
        signed long temp;
        __asm__ volatile
        (
            /* AssemblerTemplate */
            "MOV.L [%[R1]], %[R14]"     "\n\t"
            "XCHG [%[R2]].L, %[R14]"    "\n\t"
            "MOV.L %[R14], [%[R1]]"     "\n\t"
            : /* OutputOperands */
                [R14] "=&r" (temp),
                /***/ "+m" (*data1),
                /***/ "+m" (*data2)
            : /* InputOperands */
                [R1] "r" (data1),
                [R2] "r" (data2)

        );
        return;
    /* GNURX 2018q1
      92 0010 EC 15                         MOV.L [r1], r5
      93 0012 06 A0 10 25                   XCHG [r2].L, r5
      94 0016 E3 15                         MOV.L r5, [r1]
      97 0018 02                            rts
    */
    }

    ちなみに、"+m" (*data1)や"+m" (*data2)の制約が無いと、私の前の投稿での__builtin_rx_rmpa()関数で滅茶苦茶なコードが生成された件と同様のトラブルが、複雑なソースにxchg()関数がインライン展開された場合に発生する可能性があると思われます。(同様のトラブルの別の例を挙げれば、変数(or 内蔵周辺)にvolatile宣言を付け忘れた時に、コンパイラの最適化レベルによっては、volatile宣言を忘れた変数(or 内蔵周辺)に対してのリードやライトが省略されていたり思わぬ位置に移動していたりする、ということが挙げられると思います。)

  • In reply to NoMaY:

    NoMaYさん、fujitaさん

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

    種々ご協力いただきありがとうございます。
    問題点の整理と対応状況をまとめました。

    ① GCC -O2指定時のxchg前後のmov命令順が不正
       →ルネサスから報告済。Workaroundがないかさらに問い合わせています。
        fujitaさんにも報告いただいたようで深謝いたします。
       何か見解がでてきたら、私からこのスレッドに報告します。
        また、ルネサスの本サイトに対する公式見解の出し方が不明瞭で申し訳なく思います。
        この点も可能な限り改善していきたいと私は考えております。

    ② 排他制御可能なコードが出力されない 
       →どのような対策が一番良いか検討を重ねる必要性を感じます。
        私が開発を進めているAmazon FreeRTOS関連予算の中でGCC対応を検討する項目がありますので
        そのなかでGCC用のBSPがどうあるべきか(GCCに対してフィードバックが要るのか)を
        検証します。当面はNoMaYさんにご提示いただいたコードを使わせていただき
        Amazon FreeRTOSのコードの一部とさせていただくつもりですが、
        引き続き相談させていただき、最適解を導いていきたいと思います。
         #私自身はアセンブラに弱く(というより管理ばかりでソフト全般弱くなってしまいました)
          専門家に助力を依頼しているところです。

    ③ e2 studioのCC-RX→GCCのソースコンバータ(command.h等)のラッパー関数xchg()は組込み関数を呼ぶように修正中です。

    以上です
  • こんにちは。NoMaYです。

    こういう書き方も行われているのですね。真似てみようと思います。あと、今回の私のやり方では変数がレジスタに割り付けられていることを前提にしているので、CISCのRXマイコンではregister宣言を付けるようにするのが良いのかも知れません。(ちなみに、以下の__get_PSP()関数や__TZ_get_PSP_NS()関数のresult変数にregister宣言が付いているのは、メモリの無い領域をスタックポインタが指している状況を想定してのことかも知れませんね。他方、__set_PSP()関数や__TZ_set_PSP_NS()関数の前後でauto変数を使わないようにするのは自己責任でしょうね。)

    github.com/ARMmbed/mbed-os/blob/master/cmsis/TARGET_CORTEX_M/cmsis_gcc.h

    #ifndef   __ASM
      #define __ASM                                  __asm
    #endif
    #ifndef   __INLINE
      #define __INLINE                               inline
    #endif
    #ifndef   __STATIC_INLINE
      #define __STATIC_INLINE                        static inline
    #endif
    #ifndef   __STATIC_FORCEINLINE                 
      #define __STATIC_FORCEINLINE                   __attribute__((always_inline)) static inline
    #endif
    /**
      \brief   Get Process Stack Pointer
      \details Returns the current value of the Process Stack Pointer (PSP).
      \return               PSP Register value
     */
    __STATIC_FORCEINLINE uint32_t __get_PSP(void)
    {
      register uint32_t result;

      __ASM volatile ("MRS %0, psp"  : "=r" (result) );
      return(result);
    }

    #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
    /**
      \brief   Get Process Stack Pointer (non-secure)
      \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state.
      \return               PSP Register value
     */
    __STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void)
    {
      register uint32_t result;

      __ASM volatile ("MRS %0, psp_ns"  : "=r" (result) );
      return(result);
    }
    #endif

    /**
      \brief   Set Process Stack Pointer
      \details Assigns the given value to the Process Stack Pointer (PSP).
      \param [in]    topOfProcStack  Process Stack Pointer value to set
     */
    __STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack)
    {
      __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : );
    }

    #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
    /**
      \brief   Set Process Stack Pointer (non-secure)
      \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state.
      \param [in]    topOfProcStack  Process Stack Pointer value to set
     */
    __STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack)
    {
      __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : );
    }
    #endif

    TOPPERS/ATK2でも似たようなことが行われていました。

    dev.toppers.jp/trac_user/contrib/browser/atk2-sc3_fl850f1l/arch/gcc/Compiler.h

    #define INLINE          __inline__
    #define LOCAL_INLINE    static __inline__

    #define Asm             __asm__ volatile    /* インラインアセンブラ(最適化抑止)*/

    dev.toppers.jp/trac_user/contrib/browser/atk2-sc3_fl850f1l/arch/ccrh/Compiler.h

    /*
     *      CXでは,インライン関数は「#pragma」を利用して、関数定義の前に
     *      インライン化するシンボルを予め指定しなければならない.
     *      インライン化するシンボルは,"xxx_inline_symbol.h"にて定義し,
     *      そのため,「Inline」シンボルは空マクロとして実装する.
     */
    #define INLINE
    #define LOCAL_INLINE    static

    /* インライン指定シンボルの登録       */
    #include "target_inline_symbols.h"

    //#define asm           __asm
    //#define Asm           __asm  /* インラインアセンブラ(最適化抑止)*/

     

  • こんにちは。NoMaYです。

    1つ前の投稿に書いたようにARM CMSISヘッダファイルを真似てみました。一応作り込み出来たかな、という感がしていますので、以前に投稿したCCRXmachine2.hとCCRXmachine2.cと確認用コードの新しいものを投稿します。少しずつテストして行こうと思いますが、たぶん最適化によるインライン展開先のソースの影響を受けてしまうだろうと思われますので、そこをどのようにテストすると良いか悩ましく思い始めました、、、

    CCRXmachine2.h

    7041.CCRXmachine2_h_20180703.txt
    /*
    License:
    The MIT License will be used.
    https://opensource.org/licenses/MIT
    */
    
    /*
    Docments:
    https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
    and
    https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html
    https://gcc.gnu.org/onlinedocs/gcc/Basic-Asm.html
    https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html
    (https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html)
    https://gcc.gnu.org/onlinedocs/gcc/Constraints.html
    https://gcc.gnu.org/onlinedocs/gcc/Simple-Constraints.html
    https://gcc.gnu.org/onlinedocs/gcc/Modifiers.html
    https://gcc.gnu.org/onlinedocs/gcc/Asm-Labels.html
    https://gcc.gnu.org/onlinedocs/gcc/Explicit-Register-Variables.html
    https://gcc.gnu.org/onlinedocs/gcc/Size-of-an-asm.html
    and
    https://gcc.gnu.org/onlinedocs/gcc/Alternate-Keywords.html
    https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html
    https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
    and
    https://stackoverflow.com/questions/15819794/when-to-use-earlyclobber-constraint-in-extended-gcc-inline-assembly
    https://stackoverflow.com/questions/31718637/determine-optimization-level-in-preprocessor
    https://github.com/ARMmbed/mbed-os/blob/master/cmsis/TARGET_CORTEX_M/
    and
    https://gcc-renesas.com/ja/rx/rx-latest-source-code/
    rx_gcc4.8.4_2018q1/gcc/gcc/config/rx/rx.c
       Handles the insertion of a single operand into the assembler output.
       The %<letter> directives supported are:
    
         %A  Print an operand without a leading # character.
         %B  Print an integer comparison name.
         %b  Print a bit number based on a single set or cleared bit.   
         %C  Print a control register name.
         %F  Print a condition code flag name.
         %G  Register used for small-data-area addressing
         %H  Print high part of a DImode register, integer or address.
         %L  Print low part of a DImode register, integer or address.
         %N  Print the negation of the immediate value.
         %P  Register used for PID addressing
         %Q  If the operand is a MEM, then correctly generate
             register indirect or register relative addressing.
         %R  Like %Q but for zero-extending loads. 
         %S  %Q with unsigned mode.
         %U  print QI unsigned constant
         %V  print HI unsigned constant
    */
    
    /*
    Use switch case function instead of RX INT instruction execution on stack.
    #define DONT_EXECUTE_RX_INT_INSTRUCTION_ON_STACK
    */
    
    #ifndef CCRXMACHINE2_H
    #define CCRXMACHINE2_H
    
    #ifndef   __ASM
      #define __ASM                 __asm__
    #endif
    #ifndef   __INLINE
      #define __INLINE              __inline__
    #endif
    #ifndef   __STATIC_INLINE
      #define __STATIC_INLINE       static __inline__
    #endif
    #ifndef   __STATIC_FORCEINLINE
      #define __STATIC_FORCEINLINE  __attribute__((always_inline)) static __inline__
    #endif
    #ifndef   __NO_RETURN
      #define __NO_RETURN           __attribute__((__noreturn__))
    #endif
    #ifndef   __USED
      #define __USED                __attribute__((used))
    #endif
    #ifndef   __WEAK
      #define __WEAK                __attribute__((weak))
    #endif
    #ifndef   __PACKED
      #define __PACKED              __attribute__((packed, aligned(1)))
    #endif
    #ifndef   __PACKED_STRUCT
      #define __PACKED_STRUCT       struct __attribute__((packed, aligned(1)))
    #endif
    #ifndef   __PACKED_UNION
      #define __PACKED_UNION        union __attribute__((packed, aligned(1)))
    #endif
    
    #ifndef max
    #define max(data1, data2) ccrx_machine_h_max(data1, data2)
    #endif
    __STATIC_FORCEINLINE signed long ccrx_machine_h_max(signed long data1, signed long data2)
    {
    /* CC-RX V2.03 -optimize=2
            MAX R2, R1
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MAX %[R2], %[R1]"
            : /* OutputOperands */
                [R1] "+r" (data1)
            : /* InputOperands */
                [R2] "r" (data2)
        );
        return data1;
    /* GNURX 2018q1 -O2
      16 0000 FC 13 21                      MAX r2, r1
      22 0003 02                            rts
    */
    }
    
    #ifndef min
    #define min(data1, data2) ccrx_machine_h_min(data1, data2)
    #endif
    __STATIC_FORCEINLINE signed long ccrx_machine_h_min(signed long data1, signed long data2)
    {
    /* CC-RX V2.03 -optimize=2
            MIN R2, R1
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MIN %[R2], %[R1]"
            : /* OutputOperands */
                [R1] "+r" (data1)
            : /* InputOperands */
                [R2] "r" (data2)
        );
        return data1;
    /* GNURX 2018q1 -O2
      35 0004 FC 17 21                      MIN r2, r1
      41 0007 02                            rts
    */
    }
    
    #ifndef revl
    #define revl(data) ccrx_machine_h_revl(data)
    #endif
    __STATIC_FORCEINLINE signed long revl(signed long data)
    {
    /* CC-RX V2.03 -optimize=2
            REVL R1, R1
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "REVL %[R1], %[R1]"
            : /* OutputOperands */
                [R1] "+r" (data)
        );
        return data;
    /* GNURX 2018q1 -O2
      54 0008 FD 67 11                      REVL r1, r1
      60 000b 02                            rts
    */
    }
    
    #ifndef revw
    #define revw(data) ccrx_machine_h_revw(data)
    #endif
    __STATIC_FORCEINLINE signed long revw(signed long data)
    {
    /* CC-RX V2.03 -optimize=2
            REVW R1, R1
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "REVW %[R1], %[R1]"
            : /* OutputOperands */
                [R1] "+r" (data)
        );
        return data;
    /* GNURX 2018q1 -O2
      73 000c FD 65 11                      REVW r1, r1
      79 000f 02                            rts
    */
    }
    
    #ifndef xchg
    #define xchg(data1, data2) ccrx_machine_h_xchg(data1, data2)
    #endif
    __STATIC_FORCEINLINE void ccrx_machine_h_xchg(signed long *data1, signed long *data2)
    {
    /* CC-RX V2.03 -optimize=2
            MOV.L [R1], R14
            XCHG [R2].L, R14
            MOV.L R14, [R1]
            RTS
    */
        register signed long temp;
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MOV.L [%[R1]], %[R14]"         "\n\t"
            "XCHG [%[R2]].L, %[R14]"        "\n\t"
            "MOV.L %[R14], [%[R1]]"         "\n\t"
            : /* OutputOperands */
                [R14] "=&r" (temp),
                /***/ "+m" (*data1),
                /***/ "+m" (*data2)
            : /* InputOperands */
                [R1] "r" (data1),
                [R2] "r" (data2)
    
        );
        return;
    /* GNURX 2018q1 -O2
      92 0010 EC 15                         MOV.L [r1], r5
      93 0012 06 A0 10 25                   XCHG [r2].L, r5
      94 0016 E3 15                         MOV.L r5, [r1]
      97 0018 02                            rts
    */
    }
    
    #ifndef rmpab
    #define rmpab(init, count, addr1, addr2) ccrx_machine_h_rmpab(init, count, addr1, addr2)
    #endif
    __STATIC_FORCEINLINE long long ccrx_machine_h_rmpab(long long init, unsigned long count, signed char *addr1, signed char *addr2)
    {
    /* CC-RX V2.03 -optimize=2
            ARG init = R2:R1
            ARG count = R3
            ARG addr1 = R4
            ARG addr2 = 04H[R0](08H[R0] after push R6)
            RET R2:R1
    
            PUSH.L R6
            MOV.L R1, R14
            MOV.L R2, R5
            MOV.L 08H[R0], R2
            SHAR #1FH, R5, R6
            MOV.L R4, R1
            MOV.L R14, R4
            RMPA.B
            MOV.L R5, R2
            MOV.L R4, R1
            RTSD #04H, R6-R6
    */
        register long long _r5r4 __ASM("r4") = init;
        register signed char *_r1 __ASM("r1") = addr1;
        register signed char *_r2 __ASM("r2") = addr2;
        register unsigned long _r3 __ASM("r3") = count;
    #ifdef __OPTIMIZE__
        /* In case of other than -O0, we assign r6. */
        register signed long _rS __ASM("r6") = (signed long)(init >> 63);
    #else
        /* In case of -O0, we assign r8 because r6 and r7 are reserved for the frame pointer and arg(?) pointer. */
        register signed long _rS __ASM("r8") = (signed long)(init >> 63);
    #endif
        __ASM volatile
        (
            /* AssemblerTemplate */
    #ifdef __OPTIMIZE__
            "RMPA.B"                        "\n\t"
    #else
            "XCHG R6, R8"                   "\n\t"
            "RMPA.B"                        "\n\t"
            "XCHG R6, R8"                   "\n\t"
    #endif
            : /* OutputOperands */
                /**/ "+r" (_rS),
                /**/ "+r" (_r5r4),
                /**/ "+r" (_r3)
            : /* InputOperands */
                /**/ "r" (_r1),
                /**/ "r" (_r2),
                /**/ "m" (*(signed char (*)[count]) addr1),
                /**/ "m" (*(signed char (*)[count]) addr2)
            : /* Clobbers */
                /*"r1",*/ /* This causes a compile error: asm-specifier for variable '_r1' conflicts with asm clobber list */
                /*"r2" */ /* This causes a compile error: asm-specifier for variable '_r2' conflicts with asm clobber list */
        );
        __ASM volatile
        (
            /* AssemblerTemplate */
            ""/*"NOP"*/                     "\n\t"
            : /* OutputOperands */
                /* No outputs. */
            : /* InputOperands */
                /* No inputs. */
            : /* Clobbers */
                "r1",
                "r2"
            /* This asm statement can make the compiler to recognize that r1 and r2 are not equivalent to addr1 and addr2. */
            /* For example, after replacing 'return _r5r4;' --> 'return *addr1 * *addr2;' tentatively, code are different. */
    /* GNURX 2018q1 -O2
    In case of WITHOUT this asm statement, it is recognized that r1 and r2 are equivalent to addr1 and addr2 mistakenly.
         0019 7E A6                         push.l  r6
         001b 60 40                         sub     #4, r0
         001d EF 25                         mov.L   r2, r5
         001f A8 8A                         mov.L   12[r0], r2
         0021 FC 43 41                      xchg    r4, r1
         0024 FD BF 56                      shar    #31, r5, r6
         0027 7F 8C                         RMPA.B
     return *addr1 * *addr2;
         0029 CC 15                         mov.B   [r1], r5
         002b CC 21                         mov.B   [r2], r1
         002d 4F 51                         mul     r5, r1
         002f FD BF 12                      shar    #31, r1, r2
         0032 3F 66 02                      rtsd    #8, r6-r6
    In case of WITH this asm statement, it is recognized that r1 and r2 are not equivalent to addr1 and addr2 correctly.
         0019 7E A6                         push.l  r6
         001b 60 40                         sub     #4, r0
         001d EF 25                         mov.L   r2, r5
         001f ED 0E 03                      mov.L   12[r0], r14
         0022 EF 4F                         mov.L   r4, r15
         0024 EF 14                         mov.L   r1, r4
         0026 EF E2                         mov.L   r14, r2
         0028 EF F1                         mov.L   r15, r1
         002a FD BF 56                      shar    #31, r5, r6
         002d 7F 8C                         RMPA.B
     return *addr1 * *addr2;
         002f CC F1                         mov.B   [r15], r1
         0031 06 0C E1                      mul     [r14].B, r1
         0034 FD BF 12                      shar    #31, r1, r2
         0037 3F 66 02                      rtsd    #8, r6-r6
    */
        );
        return _r5r4;
    /* GNURX 2018q1 -O2
     108 0019 7E A6                         push.l  r6
     110 001b 60 40                         sub     #4, r0
     113 001d EF 25                         mov.L   r2, r5
     115 001f A8 8A                         mov.L   12[r0], r2
     120 0021 FC 43 41                      xchg    r4, r1
     122 0024 FD BF 56                      shar    #31, r5, r6
     125 0027 7F 8C                         RMPA.B
     134 0029 EF 41                         mov.L   r4, r1
     135 002b EF 52                         mov.L   r5, r2
     136 002d 3F 66 02                      rtsd    #8, r6-r6
    */
    /* GNURX 2018q1 -O0, (This caller is not good example, to be reconsidered...)
     185 00ab 6E 6C                         pushm   r6-r12
     187 00ad 71 06 D8                      add     #-40, r0, r6
     189 00b0 EF 60                         mov.L   r6, r0
     191 00b2 75 45 48                      mov.L   #0x48, r5
     192 00b5 4B 65                         add     r6, r5
     193 00b7 A1 69                         mov.L   r1, 20[r6]
     194 00b9 A1 E2                         mov.L   r2, 24[r6]
     195 00bb A1 EB                         mov.L   r3, 28[r6]
     196 00bd A2 64                         mov.L   r4, 32[r6]
     197 00bf A9 6C                         mov.L   20[r6], r4
     198 00c1 E3 64                         mov.L   r4, [r6]
     199 00c3 A9 E4                         mov.L   24[r6], r4
     200 00c5 A0 6C                         mov.L   r4, 4[r6]
     201 00c7 A9 EC                         mov.L   28[r6], r4
     202 00c9 A0 E4                         mov.L   r4, 8[r6]
     203 00cb AA 64                         mov.L   32[r6], r4
     204 00cd A0 EC                         mov.L   r4, 12[r6]
     205 00cf EC 55                         mov.L   [r5], r5
     206 00d1 A1 65                         mov.L   r5, 16[r6]
     210 00d3 EC 64                         mov.L   [r6], r4
     211 00d5 A8 6D                         mov.L   4[r6], r5
     213 00d7 A8 E9                         mov.L   12[r6], r1
     215 00d9 A9 62                         mov.L   16[r6], r2
     217 00db A8 E3                         mov.L   8[r6], r3
     219 00dd ED 6C 01                      mov.L   4[r6], r12
     220 00e0 FD BF CA                      shar    #31, r12, r10
     221 00e3 ED 6C 01                      mov.L   4[r6], r12
     222 00e6 FD BF CB                      shar    #31, r12, r11
     223 00e9 EF A8                         mov.L   r10, r8
     225 00eb ED 6A 03                      mov.L   12[r6], r10
     226 00ee ED 6B 04                      mov.L   16[r6], r11
     228 00f1 FC 43 68                      XCHG R6, R8
     229 00f4 7F 8C                         RMPA.B
     230 00f6 FC 43 68                      XCHG R6, R8
     239 00f9 EF 42                         mov.L   r4, r2
     240 00fb EF 53                         mov.L   r5, r3
     241 00fd EF 24                         mov.L   r2, r4
     242 00ff EF 35                         mov.L   r3, r5
     246 0101 EF 42                         mov.L   r4, r2
     247 0103 EF 53                         mov.L   r5, r3
     248 0105 EF 24                         mov.L   r2, r4
     249 0107 EF 35                         mov.L   r3, r5
     250 0109 EF 41                         mov.L   r4, r1
     251 010b EF 52                         mov.L   r5, r2
     252 010d 3F 6C 11                      rtsd    #68, r6-r12
    */
    }
    
    #ifndef rmpaw
    #define rmpaw(init, count, addr1, addr2) ccrx_machine_h_rmpaw(init, count, addr1, addr2)
    #endif
    __STATIC_FORCEINLINE long long ccrx_machine_h_rmpaw(long long init, unsigned long count, short *addr1, short *addr2)
    {
    /* CC-RX V2.03 -optimize=2
            ARG init = R2:R1
            ARG count = R3
            ARG addr1 = R4
            ARG addr2 = 04H[R0](08H[R0] after PUSH R6)
            RET R2:R1
    
            PUSH.L R6
            MOV.L R1, R14
            MOV.L R2, R5
            MOV.L 08H[R0], R2
            SHAR #1FH, R5, R6
            MOV.L R4, R1
            MOV.L R14, R4
            RMPA.W
            MOV.L R5, R2
            MOV.L R4, R1
            RTSD #04H, R6-R6
    */
        register long long _r5r4 __ASM("r4") = init;
        register short *_r1 __ASM("r1") = addr1;
        register short *_r2 __ASM("r2") = addr2;
        register unsigned long _r3 __ASM("r3") = count;
    #ifdef __OPTIMIZE__
        /* In case of other than -O0, we assign r6. */
        register signed long _rS __ASM("r6") = (signed long)(init >> 63);
    #else
        /* In case of -O0, we assign r8 because r6 and r7 are reserved for the frame pointer and arg(?) pointer. */
        register signed long _rS __ASM("r8") = (signed long)(init >> 63);
    #endif
        __ASM volatile
        (
            /* AssemblerTemplate */
    #ifdef __OPTIMIZE__
            "RMPA.W"                        "\n\t"
    #else
            "XCHG R6, R8"                   "\n\t"
            "RMPA.W"                        "\n\t"
            "XCHG R6, R8"                   "\n\t"
    #endif
            : /* OutputOperands */
                /**/ "+r" (_rS),
                /**/ "+r" (_r5r4),
                /**/ "+r" (_r3)
            : /* InputOperands */
                /**/ "r" (_r1),
                /**/ "r" (_r2),
                /**/ "m" (*(signed short (*)[count]) addr1),
                /**/ "m" (*(signed short (*)[count]) addr2)
            : /* Clobbers */
                /*"r1",*/ /* This causes a compile error: asm-specifier for variable '_r1' conflicts with asm clobber list */
                /*"r2" */ /* This causes a compile error: asm-specifier for variable '_r2' conflicts with asm clobber list */
        );
        __ASM volatile
        (
            /* AssemblerTemplate */
            ""/*"NOP"*/                     "\n\t"
            : /* OutputOperands */
                /* No outputs. */
            : /* InputOperands */
                /* No inputs. */
            : /* Clobbers */
                "r1",
                "r2"
            /* This asm statement can make the compiler to recognize that r1 and r2 are not equivalent to addr1 and addr2. */
            /* Please see the comment in the rmpab() function. */
        );
        return _r5r4;
    /* GNURX 2018q1 -O2
    The difference from the rmpab() is the RMPA.B --> RMPA.W instruction.
    */
    }
    
    #ifndef rmpal
    #define rmpal(init, count, addr1, addr2) ccrx_machine_h_rmpal(init, count, addr1, addr2)
    #endif
    __STATIC_FORCEINLINE long long ccrx_machine_h_rmpal(long long init, unsigned long count, long *addr1, long *addr2)
    {
    /* CC-RX V2.03 -optimize=2
            ARG init = R2:R1
            ARG count = R3
            ARG addr1 = R4
            ARG addr2 = 04H[R0](08H[R0] after PUSH R6)
            RET R2:R1
    
            PUSH.L R6
            MOV.L R1, R14
            MOV.L R2, R5
            MOV.L 08H[R0], R2
            SHAR #1FH, R5, R6
            MOV.L R4, R1
            MOV.L R14, R4
            RMPA.L
            MOV.L R5, R2
            MOV.L R4, R1
            RTSD #04H, R6-R6
    */
        register long long _r5r4 __ASM("r4") = init;
        register long *_r1 __ASM("r1") = addr1;
        register long *_r2 __ASM("r2") = addr2;
        register unsigned long _r3 __ASM("r3") = count;
    #ifdef __OPTIMIZE__
        /* In case of other than -O0, we assign r6. */
        register signed long _rS __ASM("r6") = (signed long)(init >> 63);
    #else
        /* In case of -O0, we assign r8 because r6 and r7 are reserved for the frame pointer and arg(?) pointer. */
        register signed long _rS __ASM("r8") = (signed long)(init >> 63);
    #endif
        __ASM volatile
        (
            /* AssemblerTemplate */
    #ifdef __OPTIMIZE__
            "RMPA.L"                        "\n\t"
    #else
            "XCHG R6, R8"                   "\n\t"
            "RMPA.L"                        "\n\t"
            "XCHG R6, R8"                   "\n\t"
    #endif
            : /* OutputOperands */
                /**/ "+r" (_rS),
                /**/ "+r" (_r5r4),
                /**/ "+r" (_r3)
            : /* InputOperands */
                /**/ "r" (_r1),
                /**/ "r" (_r2),
                /**/ "m" (*(signed long (*)[count]) addr1),
                /**/ "m" (*(signed long (*)[count]) addr2)
            : /* Clobbers */
                /*"r1",*/ /* This causes a compile error: asm-specifier for variable '_r1' conflicts with asm clobber list */
                /*"r2" */ /* This causes a compile error: asm-specifier for variable '_r2' conflicts with asm clobber list */
        );
        __ASM volatile
        (
            /* AssemblerTemplate */
            ""/*"NOP"*/                     "\n\t"
            : /* OutputOperands */
                /* No outputs. */
            : /* InputOperands */
                /* No inputs. */
            : /* Clobbers */
                "r1",
                "r2"
            /* This asm statement can make the compiler to recognize that r1 and r2 are not equivalent to addr1 and addr2. */
            /* Please see the comment in the rmpab() function. */
        );
        return _r5r4;
    /* GNURX 2018q1 -O2
    The difference from the rmpab() is the RMPA.B --> RMPA.L instruction.
    */
    }
    
    #ifndef rolc
    #define rolc(data) ccrx_machine_h_rolc(data)
    #endif
    __STATIC_FORCEINLINE long ccrx_machine_h_rolc(unsigned long data)
    {
    /* CC-RX V2.03 -optimize=2
            ROLC R1
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "ROLC %[R1]"
            : /* OutputOperands */
                [R1] "+r" (data)
        );
        return data;
    /* GNURX 2018q1 -O2
     235 0067 7E 51                         ROLC r1
     241 0069 02                            rts
    */
    }
    
    #ifndef rorc
    #define rorc(data) ccrx_machine_h_rorc(data)
    #endif
    __STATIC_FORCEINLINE long ccrx_machine_h_rorc(unsigned long data)
    {
    /* CC-RX V2.03 -optimize=2
            RORC R1
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "RORC %[R1]"
            : /* OutputOperands */
                [R1] "+r" (data)
        );
        return data;
    /* GNURX 2018q1 -O2
     254 006a 7E 41                         RORC r1
     260 006c 02                            rts
    */
    }
    
    #ifndef rotl
    #define rotl(data, num) ccrx_machine_h_rotl(data, num)
    #endif
    __STATIC_FORCEINLINE long ccrx_machine_h_rotl(unsigned long data, unsigned long num)
    {
    /* CC-RX V2.03 -optimize=2
            ROTL R2, R1
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "ROTL %[R2], %[R1]"
            : /* OutputOperands */
                [R1] "+r" (data)
            : /* InputOperands */
                [R2] "r" (num)
        );
        return data;
    /* GNURX 2018q1 -O2
     292 0071 FD 64 21                      ROTR r2, r1
     298 0074 02                            rts
    */
    }
    
    #ifndef rotr
    #define rotr(data, num) ccrx_machine_h_rotr(data, num)
    #endif
    __STATIC_FORCEINLINE long ccrx_machine_h_rotr(unsigned long data, unsigned long num)
    {
    /* CC-RX V2.03 -optimize=2
            ROTR R2, R1
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "ROTR %[R2], %[R1]"
            : /* OutputOperands */
                [R1] "+r" (data)
            : /* InputOperands */
                [R2] "r" (num)
        );
        return data;
    /* GNURX 2018q1 -O2
     292 0071 FD 64 21                      ROTR r2, r1
     298 0074 02                            rts
    */
    }
    
    #ifndef brk
    #define brk() ccrx_machine_h_brk()
    #endif
    __STATIC_FORCEINLINE void ccrx_machine_h_brk(void)
    {
    /* CC-RX V2.03 -optimize=2
            BRK
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "BRK"
            : /* OutputOperands */
                /* No outputs. */
        );
        return;
    /* GNURX 2018q1 -O2
     310 0075 00                            BRK
     312 0076 02                            rts
    */
    }
    
    #ifndef int_exception
    #define int_exception(num) ccrx_machine_h_int_exception(num)
    #endif
    #ifdef DONT_EXECUTE_RX_INT_INSTRUCTION_ON_STACK
    
    void ccrx_machine_h_int_exception_switch_case_function(signed long num);
    
    #define ccrx_machine_h_int_exception(num) \
    do { \
        if (__builtin_constant_p(num)) { \
            __builtin_rx_int(num); \
        } else { \
            ccrx_machine_h_int_exception_switch_case_function(num); \
        } \
    } while (0)
    
    #else /* DONT_EXECUTE_RX_INT_INSTRUCTION_ON_STACK */
    
    #define ccrx_machine_h_int_exception(num) \
    do { \
        if (__builtin_constant_p(num)) { \
            __builtin_rx_int(num); \
        } else { \
            unsigned char int_rts[] = {0x75, 0x60, num, 0x02}; \
            ((void (*)(void*))int_rts)(int_rts); \
        } \
    } while (0)
    
    #endif /* DONT_EXECUTE_RX_INT_INSTRUCTION_ON_STACK */
    
    #ifndef wait
    #define wait() ccrx_machine_h_wait()
    #endif
    __STATIC_FORCEINLINE void ccrx_machine_h_wait(void)
    {
    /* CC-RX V2.03 -optimize=2
            WAIT
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "WAIT"
            : /* OutputOperands */
                /* No outputs. */
        );
        return;
    /* GNURX 2018q1 -O2
     372 0092 7F 96                         WAIT
     374 0094 02                            rts
    */
    }
    
    #ifndef nop
    #define nop() ccrx_machine_h_nop()
    #endif
    __STATIC_FORCEINLINE void ccrx_machine_h_nop(void)
    {
    /* CC-RX V2.03 -optimize=2
            NOP
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "NOP"
            : /* OutputOperands */
                /* No outputs. */
        );
        return;
    /* GNURX 2018q1 -O2
     388 0095 03                            NOP
     390 0096 02                            rts
    */
    }
    
    #ifndef set_ipl
    #define set_ipl(level) ccrx_machine_h_set_ipl(level)
    #endif
    __STATIC_FORCEINLINE void ccrx_machine_h_set_ipl(signed long level)
    {
    /* CC-RX V2.03 -optimize=2
            MVFC PSW, R14
            SHLL #1CH, R1
            SHLR #04H, R1
            AND #0F0FFFFFFH, R14
            OR R14, R1
            MVTC R1, PSW
            RTS
    */
        register unsigned long temp;
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVFC PSW, %[R14]"              "\n\t"
            "SHLL #0x1C, %[R1]"             "\n\t"
            "SHLR #0x04, %[R1]"             "\n\t"
            "AND #0xF0FFFFFF, %[R14]"       "\n\t"
            "OR %[R14], %[R1]"              "\n\t"
            "MVTC %[R1], PSW"               "\n\t"
            : /* OutputOperands */
                [R14] "=&r" (temp),
                [R1] "+r" (level)
        );
        return;
    /* GNURX 2018q1 -O2
     377 008e FD 6A 05                      MVFC PSW, r5
     378 0091 6D C1                         SHLL #0x1C, r1
     379 0093 68 41                         SHLR #0x04, r1
     380 0095 74 25 FF FF FF F0             AND #0xF0FFFFFF, r5
     381 009b 57 51                         OR r5, r1
     382 009d FD 68 10                      MVTC r1, PSW
     385 00a0 02                            rts
    */
    }
    
    #ifndef get_ipl
    #define get_ipl() ccrx_machine_h_get_ipl()
    #endif
    __STATIC_FORCEINLINE unsigned char ccrx_machine_h_get_ipl(void)
    {
    /* CC-RX V2.03 -optimize=2
            MVFC PSW, R14
            REVL R14, R1
            AND #0FH, R1
            RTS
    */
        register unsigned long temp;
        register unsigned char level;
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVFC PSW, %[R14]"              "\n\t"
            "REVL %[R14], %[R1]"            "\n\t"
            "AND #0x0F, %[R1]"              "\n\t"
            : /* OutputOperands */
                [R14] "=r" (temp),
                [R1] "=r" (level)
        );
        return level;
    /* GNURX 2018q1 -O2
     399 00a1 FD 6A 05                      MVFC PSW, r5
     400 00a4 FD 67 51                      REVL r5, r1
     401 00a7 64 F1                         AND #0x0F, r1
     407 00a9 5B 11                         movu.B  r1, r1      ★ TODO: check
     408 00ab 02                            rts
    */
    }
    
    #ifndef set_psw
    #define set_psw(data) ccrx_machine_h_set_psw(data)
    #endif
    __STATIC_FORCEINLINE void ccrx_machine_h_set_psw(unsigned long data)
    {
    /* CC-RX V2.03 -optimize=2
            MVTC R1, PSW
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVTC %[R1], PSW"
            : /* OutputOperands */
                /* No outputs. */
            : /* InputOperands */
                [R1] "r" (data)
        );
        return;
    /* GNURX 2018q1 -O2
     449 00b5 FD 68 10                      MVTC r1, PSW
     451 00b8 02                            rts
    */
    }
    
    #ifndef get_psw
    #define get_psw() ccrx_machine_h_get_psw()
    #endif
    __STATIC_FORCEINLINE unsigned long ccrx_machine_h_get_psw(void)
    {
    /* CC-RX V2.03 -optimize=2
            MVFC PSW, R1
            RTS
    */
        register unsigned long data;
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVFC PSW, %[R1]"
            : /* OutputOperands */
                [R1] "=r" (data)
        );
        return data;
    /* GNURX 2018q1 -O2
     465 00b9 FD 6A 01                      MVFC PSW, r1
     471 00bc 02                            rts
    */
    }
    
    #ifndef set_fpsw
    #define set_fpsw(data) ccrx_machine_h_set_fpsw(data)
    #endif
    __STATIC_FORCEINLINE void ccrx_machine_h_set_fpsw(unsigned long data)
    {
    /* CC-RX V2.03 -optimize=2
            MVTC R1, FPSW
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVTC %[R1], FPSW"
            : /* OutputOperands */
                /* No outputs. */
            : /* InputOperands */
                [R1] "r" (data)
        );
        return;
    /* GNURX 2018q1 -O2
     484 00bd FD 68 13                      MVTC r1, FPSW
     486 00c0 02                            rts
    */
    }
    
    #ifndef get_fpsw
    #define get_fpsw() ccrx_machine_h_get_fpsw()
    #endif
    __STATIC_FORCEINLINE unsigned long ccrx_machine_h_get_fpsw(void)
    {
    /* CC-RX V2.03 -optimize=2
            MVFC FPSW, R1
            RTS
    */
        register unsigned long data;
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVFC FPSW, %[R1]"
            : /* OutputOperands */
                [R1] "=r" (data)
        );
        return data;
    /* GNURX 2018q1 -O2
     500 00c1 FD 6A 31                      MVFC FPSW, r1
     506 00c4 02                            rts
    */
    }
    
    #ifndef set_usp
    #define set_usp(data) ccrx_machine_h_set_usp(data)
    #endif
    __STATIC_FORCEINLINE void ccrx_machine_h_set_usp(void *data)
    {
    /* CC-RX V2.03 -optimize=2
            MVTC R1, USP
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVTC %[R1], USP"
            : /* OutputOperands */
                /* No outputs. */
            : /* InputOperands */
                [R1] "r" (data)
        );
        return;
    /* GNURX 2018q1 -O2
     519 00c5 FD 68 12                      MVTC r1, USP
     521 00c8 02                            rts
    */
    }
    
    #ifndef get_usp
    #define get_usp() ccrx_machine_h_get_usp()
    #endif
    __STATIC_FORCEINLINE void *ccrx_machine_h_get_usp(void)
    {
    /* CC-RX V2.03 -optimize=2
            MVFC USP, R1
            RTS
    */
        register void *data;
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVFC USP, %[R1]"
            : /* OutputOperands */
                [R1] "=r" (data)
        );
        return data;
    /* GNURX 2018q1 -O2
     535 00c9 FD 6A 21                      MVFC USP, r1
     541 00cc 02                            rts
    */
    }
    
    #ifndef set_isp
    #define set_isp(data) ccrx_machine_h_set_isp(data)
    #endif
    __STATIC_FORCEINLINE void ccrx_machine_h_set_isp(void *data)
    {
    /* CC-RX V2.03 -optimize=2
            MVTC R1, ISP
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVTC %[R1], ISP"
            : /* OutputOperands */
                /* No outputs. */
            : /* InputOperands */
                [R1] "r" (data)
        );
        return;
    /* GNURX 2018q1 -O2
     554 00cd FD 68 1A                      MVTC r1, ISP
     556 00d0 02                            rts
    */
    }
    
    #ifndef get_isp
    #define get_isp() ccrx_machine_h_get_isp()
    #endif
    __STATIC_FORCEINLINE void *ccrx_machine_h_get_isp(void)
    {
    /* CC-RX V2.03 -optimize=2
            MVFC ISP, R1
            RTS
    */
        register void *data;
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVFC ISP, %[R1]"
            : /* OutputOperands */
                [R1] "=r" (data)
        );
        return data;
    /* GNURX 2018q1 -O2
     570 00d1 FD 6A A1                      MVFC ISP, r1
     576 00d4 02                            rts
    */
    }
    
    #ifndef set_intb
    #define set_intb(data) ccrx_machine_h_set_intb(data)
    #endif
    __STATIC_FORCEINLINE void ccrx_machine_h_set_intb(void *data)
    {
    /* CC-RX V2.03 -optimize=2
            MVTC R1, INTB
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVTC %[R1], INTB"
            : /* OutputOperands */
                /* No outputs. */
            : /* InputOperands */
                [R1] "r" (data)
        );
        return;
    /* GNURX 2018q1 -O2
     589 00d5 FD 68 1C                      MVTC r1, INTB
     591 00d8 02                            rts
    */
    }
    
    #ifndef get_intb
    #define get_intb() ccrx_machine_h_get_intb()
    #endif
    __STATIC_FORCEINLINE void *ccrx_machine_h_get_intb(void)
    {
    /* CC-RX V2.03 -optimize=2
            MVFC INTB, R1
            RTS
    */
        register void *data;
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVFC INTB, %[R1]"
            : /* OutputOperands */
                [R1] "=r" (data)
        );
        return data;
    /* GNURX 2018q1 -O2
     605 00d9 FD 6A C1                      MVFC INTB, r1
     611 00dc 02                            rts
    */
    }
    
    #ifndef set_bpsw
    #define set_bpsw(data) ccrx_machine_h_set_bpsw(data)
    #endif
    __STATIC_FORCEINLINE void ccrx_machine_h_set_bpsw(unsigned long data)
    {
    /* CC-RX V2.03 -optimize=2
            MVTC R1, BPSW
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVTC %[R1], BPSW"
            : /* OutputOperands */
                /* No outputs. */
            : /* InputOperands */
                [R1] "r" (data)
        );
        return;
    /* GNURX 2018q1 -O2
     624 00dd FD 68 18                      MVTC r1, BPSW
     626 00e0 02                            rts
    */
    }
    
    #ifndef get_bpsw
    #define get_bpsw() ccrx_machine_h_get_bpsw()
    #endif
    __STATIC_FORCEINLINE unsigned long ccrx_machine_h_get_bpsw(void)
    {
    /* CC-RX V2.03 -optimize=2
            MVFC BPSW, R1
            RTS
    */
        register unsigned long data;
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVFC BPSW, %[R1]"
            : /* OutputOperands */
                [R1] "=r" (data)
        );
        return data;
    /* GNURX 2018q1 -O2
     640 00e1 FD 6A 81                      MVFC BPSW, r1
     646 00e4 02                            rts
    */
    }
    
    #ifndef set_bpc
    #define set_bpc(data) ccrx_machine_h_set_bpc(data)
    #endif
    __STATIC_FORCEINLINE void ccrx_machine_h_set_bpc(void *data)
    {
    /* CC-RX V2.03 -optimize=2
            MVTC R1, BPC
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVTC %[R1], BPC"
            : /* OutputOperands */
                /* No outputs. */
            : /* InputOperands */
                [R1] "r" (data)
        );
        return;
    /* GNURX 2018q1 -O2
     659 00e5 FD 68 19                      MVTC r1, BPC
     661 00e8 02                            rts
    */
    }
    
    #ifndef get_bpc
    #define get_bpc() ccrx_machine_h_get_bpc()
    #endif
    __STATIC_FORCEINLINE void *ccrx_machine_h_get_bpc(void)
    {
    /* CC-RX V2.03 -optimize=2
            MVFC BPC, R1
            RTS
    */
        register void *data;
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVFC BPC, %[R1]"
            : /* OutputOperands */
                [R1] "=r" (data)
        );
        return data;
    /* GNURX 2018q1 -O2
     675 00e9 FD 6A 91                      MVFC BPC, r1
     681 00ec 02                            rts
    */
    }
    
    #ifndef set_fintv
    #define set_fintv(data) ccrx_machine_h_set_fintv(data)
    #endif
    __STATIC_FORCEINLINE void ccrx_machine_h_set_fintv(void *data)
    {
    /* CC-RX V2.03 -optimize=2
            MVTC R1, FINTV
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVTC %[R1], FINTV"
            : /* OutputOperands */
                /* No outputs. */
            : /* InputOperands */
                [R1] "r" (data)
        );
        return;
    /* GNURX 2018q1 -O2
     694 00ed FD 68 1B                      MVTC r1, FINTV
     696 00f0 02                            rts
    */
    }
    
    #ifndef get_fintv
    #define get_fintv() ccrx_machine_h_get_fintv()
    #endif
    __STATIC_FORCEINLINE void *ccrx_machine_h_get_fintv(void)
    {
    /* CC-RX V2.03 -optimize=2
            MVFC FINTV, R1
            RTS
    */
        register void *data;
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVFC FINTV, %[R1]"
            : /* OutputOperands */
                [R1] "=r" (data)
        );
        return data;
    /* GNURX 2018q1 -O2
     710 00f1 FD 6A B1                      MVFC FINTV, r1
     716 00f4 02                            rts
    */
    }
    
    #ifndef emul
    #define emul(data1, data2) ccrx_machine_h_emul(data1, data2)
    #endif
    __STATIC_FORCEINLINE signed long long ccrx_machine_h_emul(signed long data1, signed long data2)
    {
    /* CC-RX V2.03 -optimize=2
            MOV.L R1, R4
            EMUL R2, R4
            MOV.L R5, R2
            MOV.L R4, R1
            RTS
    */
        return (signed long long)data1 * data2;
    /* GNURX 2018q1 -O2
     728 00f5 FC 1B 12                      emul    r1, r2
     733 00f8 EF 21                         mov.L   r2, r1
     735 00fa EF 32                         mov.L   r3, r2
     736 00fc 02                            rts
    */
    }
    
    #ifndef emulu
    #define emulu(data1, data2) ccrx_machine_h_emulu(data1, data2)
    #endif
    __STATIC_FORCEINLINE unsigned long long ccrx_machine_h_emulu(unsigned long data1, unsigned long data2)
    {
    /* CC-RX V2.03 -optimize=2
            MOV.L R1, R4
            EMULU R2, R4
            MOV.L R5, R2
            MOV.L R4, R1
            RTS
    */
        return (unsigned long long)data1 * data2;
    /* GNURX 2018q1 -O2
     748 00fd FC 1F 12                      emulu   r1, r2
     753 0100 EF 21                         mov.L   r2, r1
     755 0102 EF 32                         mov.L   r3, r2
     756 0104 02                            rts
    */
    }
    
    #ifndef chg_pmusr
    #define chg_pmusr() ccrx_machine_h_chg_pmusr()
    #endif
    __STATIC_FORCEINLINE void ccrx_machine_h_chg_pmusr(void)
    {
    /* CC-RX V2.03 -optimize=2
            MVFC PSW, R14
            BTST #14H, R14
            BNE L48
    L47:    ; entry
            OR #00100000H, R14
            PUSH.L R14
    L49:
            MVFC PC, R14
            ADD #L48-L49, R14
            PUSH.L R14
            RTE
    L48:    ; entry
            RTS
    */
       register unsigned long temp;
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVFC PSW, %[R14]"              "\n\t"
            "BTST #0x14, %[R14]"            "\n\t"
            "BNE 3f"                        "\n"
    "1:"                                    "\n\t"
            "OR #0x00100000, %[R14]"        "\n\t"
            "PUSH.L %[R14]"                 "\n"
    "2:"                                    "\n\t"
            "MVFC PC, %[R14]"               "\n\t"
            "ADD #3f-2b, %[R14]"            "\n\t"
            "PUSH.L %[R14]"                 "\n\t"
            "RTE"                           "\n"
    "3:"                                    "\n\t"
            : /* OutputOperands */
                [R14] "=r" (temp)
        );
        return;
    /* GNURX 2018q1 -O2
     740 00fc FD 6A 05                      MVFC PSW, r5
     741 00ff 7D 45                         BTST #0x14, r5
     742 0101 21 13                         BNE 3f
     743                                1:
     744 0103 77 35 00 00 10                OR #0x00100000, r5
     745 0108 7E A5                         PUSH.L r5
     746                                2:
     747 010a FD 6A 15                      MVFC PC, r5
     748 010d 71 55 0A                      ADD #3f-2b, r5
     749 0110 7E A5                         PUSH.L r5
     750 0112 7F 95                         RTE
     751                                3:
     754 0114 02                            rts
    */
    }
    
    #ifndef set_acc
    #define set_acc(data) ccrx_machine_h_set_acc(data)
    #endif
    __STATIC_FORCEINLINE void ccrx_machine_h_set_acc(signed long long data)
    {
    /* CC-RX V2.03 -optimize=2
            MVTACLO R1
            MVTACHI R2
            RTS
    */
    #if 1
        register union llreg_u {
            unsigned long w32[2];
            signed long long w64;
        } temp;
        temp.w64 = data;
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVTACLO %[R1]"                 "\n\t"
            "MVTACHI %[R2]"                 "\n\t"
            : /* OutputOperands */
                /* No outputs. */
            : /* InputOperands */
                [R1] "r" (temp.w32[0]),
                [R2] "r" (temp.w32[1])
        );
        return;
    /* GNURX 2018q1 -O2 -mlittle-endian-data
     797 0115 FD 17 11                      MVTACLO r1
     798 0118 FD 17 02                      MVTACHI r2
     801 011b 02                            rts
    */
    /* GNURX 2018q1 -O2 -mbig-endian-data
     830 0134 FD 17 11                      MVTACLO r1
     831 0137 FD 17 02                      MVTACHI r2
     834 013a 02                            rts
    */
    /* GNURX 2018q1 -O0 -mlittle-endian-data
     1303 04d0 6E 6B                        pushm   r6-r11
     1305 04d2 71 06 F0                     add 	#-16, r0, r6
     1307 04d5 EF 60                        mov.L   r6, r0
     1309 04d7 A0 E1                        mov.L   r1, 8[r6]
     1310 04d9 A0 EA                        mov.L   r2, 12[r6]
     1311 04db A8 E5                        mov.L   8[r6], r5
     1312 04dd E3 65                        mov.L   r5, [r6]
     1313 04df A8 ED                        mov.L   12[r6], r5
     1314 04e1 A0 6D                        mov.L   r5, 4[r6]
     1318 04e3 EC 6A                        mov.L   [r6], r10
     1319 04e5 ED 6B 01                     mov.L   4[r6], r11
     1321 04e8 EF A5                        mov.L   r10, r5
     1323 04ea EF B4                        mov.L   r11, r4
     1326 04ec FD 17 15                     MVTACLO r5
     1327 04ef FD 17 04                     MVTACHI r4
     1333 04f2 3F 6B 0A                     rtsd    #40, r6-r11
    */
    /* GNURX 2018q1 -O0 -mbig-endian-data
     1313 04da 6E 6B                        pushm   r6-r11
     1315 04dc 71 06 F0                     add     #-16, r0, r6
     1317 04df EF 60                        mov.L   r6, r0
     1319 04e1 A0 E1                        mov.L   r1, 8[r6]
     1320 04e3 A0 EA                        mov.L   r2, 12[r6]
     1321 04e5 A8 E5                        mov.L   8[r6], r5
     1322 04e7 E3 65                        mov.L   r5, [r6]
     1323 04e9 A8 ED                        mov.L   12[r6], r5
     1324 04eb A0 6D                        mov.L   r5, 4[r6]
     1328 04ed EC 6A                        mov.L   [r6], r10
     1329 04ef ED 6B 01                     mov.L   4[r6], r11
     1331 04f2 EF A5                        mov.L   r10, r5
     1333 04f4 EF B4                        mov.L   r11, r4
     1336 04f6 FD 17 15                     MVTACLO r5
     1337 04f9 FD 17 04                     MVTACHI r4
     1343 04fc 3F 6B 0A                     rtsd    #40, r6-r11
    */
    #elif 0
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVTACLO %L[R99]"               "\n\t"
            "MVTACHI %H[R99]"               "\n\t"
            : /* OutputOperands */
                /* No outputs. */
            : /* InputOperands */
                [R99] "r" (data)
        );
        return;
    /* GNURX 2018q1 -O2
     791 0115 EF 14                         mov.L   r1, r4
     792 0117 EF 25                         mov.L   r2, r5
     798 0119 FD 17 14                      MVTACLO r4
     799 011c FD 17 05                      MVTACHI r5
     801 011f 02                            rts
    */
    #endif
    }
    
    #ifndef get_acc
    #define get_acc() ccrx_machine_h_get_acc()
    #endif
    __STATIC_FORCEINLINE signed long long ccrx_machine_h_get_acc(void)
    {
    /* CC-RX V2.03 -optimize=2
            MVFACMI R1
            SHLL #10H, R1
            MVFACHI R2
            RTS
    */
    #if 1
        register union llreg_u {
            unsigned long w32[2];
            signed long long w64;
        } result;
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVFACMI %[R1]"                 "\n\t"
            "SHLL #0x10, %[R1]"             "\n\t"
            "MVFACHI %[R2]"                 "\n\t"
            : /* OutputOperands */
                [R1] "=r" (result.w32[0]),
                [R2] "=r" (result.w32[1])
        );
        return result.w64;
    /* GNURX 2018q1 -O2 -mlittle-endian-data
     813 011c FD 1F 21                      MVFACMI r1
     814 011f 6D 01                         SHLL #0x10, r1
     815 0121 FD 1F 02                      MVFACHI r2
     818 0124 02                            rts
    */
    /* GNURX 2018q1 -O2 -mbig-endian-data
     846 013b FD 1F 21                      MVFACMI r1
     847 013e 6D 01                         SHLL #0x10, r1
     848 0140 FD 1F 02                      MVFACHI r2
     851 0143 02                            rts
    */
    /* GNURX 2018q1 -O0 -mlittle-endian-data
     1341 04f5 6E 6B                        pushm   r6-r11
     1343 04f7 EF 06                        mov.L   r0, r6
     1349 04f9 FD 1F 24                     MVFACMI r4
     1350 04fc 6D 04                        SHLL    #0x10, r4
     1351 04fe FD 1F 05                     MVFACHI r5
     1354 0501 EF 4A                        mov.L   r4, r10
     1355 0503 EF 5B                        mov.L   r5, r11
     1357 0505 EF A2                        mov.L   r10, r2
     1358 0507 EF B3                        mov.L   r11, r3
     1359 0509 EF 24                        mov.L   r2, r4
     1360 050b EF 35                        mov.L   r3, r5
     1364 050d EF 42                        mov.L   r4, r2
     1365 050f EF 53                        mov.L   r5, r3
     1366 0511 EF 24                        mov.L   r2, r4
     1367 0513 EF 35                        mov.L   r3, r5
     1368 0515 EF 41                        mov.L   r4, r1
     1369 0517 EF 52                        mov.L   r5, r2
     1370 0519 3F 6B 06                     rtsd    #24, r6-r11
    */
    /* GNURX 2018q1 -O2 -mbig-endian-data
     1351 04ff 6E 6B                        pushm   r6-r11
     1353 0501 EF 06                        mov.L   r0, r6
     1359 0503 FD 1F 24                     MVFACMI r4
     1360 0506 6D 04                        SHLL    #0x10, r4
     1361 0508 FD 1F 05                     MVFACHI r5
     1364 050b EF 4A                        mov.L   r4, r10
     1365 050d EF 5B                        mov.L   r5, r11
     1367 050f EF A2                        mov.L   r10, r2
     1368 0511 EF B3                        mov.L   r11, r3
     1369 0513 EF 24                        mov.L   r2, r4
     1370 0515 EF 35                        mov.L   r3, r5
     1374 0517 EF 42                        mov.L   r4, r2
     1375 0519 EF 53                        mov.L   r5, r3
     1376 051b EF 24                        mov.L   r2, r4
     1377 051d EF 35                        mov.L   r3, r5
     1378 051f EF 41                        mov.L   r4, r1
     1379 0521 EF 52                        mov.L   r5, r2
     1380 0523 3F 6B 06                     rtsd    #24, r6-r11
    */
    #elif 0
        register signed long long data;
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVFACMI %L[R99]"               "\n\t"
            "SHLL #0x10, %L[R99]"           "\n\t"
            "MVFACHI %H[R99]"               "\n\t"
            : /* OutputOperands */
                [R99] "=r" (data)
        );
        return data;
    /* GNURX 2018q1 -O2
     811 011c FD 1F 24                      MVFACMI r4
     812 011f 6D 04                         SHLL #0x10, r4
     813 0121 FD 1F 05                      MVFACHI r5
     819 0124 EF 41                         mov.L   r4, r1
     820 0126 EF 52                         mov.L   r5, r2
     821 0128 02                            rts
    */
    #endif
    }
    
    #ifndef setpsw_i
    #define setpsw_i() ccrx_machine_h_setpsw_i()
    #endif
    __STATIC_FORCEINLINE void ccrx_machine_h_setpsw_i(void)
    {
    /* CC-RX V2.03 -optimize=2
            SETPSW I
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "SETPSW I"
            : /* OutputOperands */
                /* No outputs. */
        );
        return;
    /* GNURX 2018q1 -O2
     829 012e 7F A8                         SETPSW I
     831 0130 02                            rts
    */
    }
    
    #ifndef clrpsw_i
    #define clrpsw_i() ccrx_machine_h_clrpsw_i()
    #endif
    __STATIC_FORCEINLINE void ccrx_machine_h_clrpsw_i(void)
    {
    /* CC-RX V2.03 -optimize=2
            CLRPSW I
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "CLRPSW I"
            : /* OutputOperands */
                /* No outputs. */
        );
        return;
    /* GNURX 2018q1 -O2
     845 0131 7F B8                         CLRPSW I
     847 0133 02                            rts
    */
    }
    
    #ifndef macl
    #define macl(data1, data2, count) ccrx_machine_h_macl(data1, data2, count)
    #endif
    __STATIC_FORCEINLINE long ccrx_machine_h_macl(short *data1, short *data2, unsigned long count)
    {
    /* CC-RX V2.03 -optimize=2
            CMP #00H, R3
            MOV.L #00000000H, R14
            MULLO R14, R14
            BEQ L60
    L55:    ; entry
            BTST #00H, R3
            BGEU L57
    L56:    ; entry
            SUB #02H, R3
            MOV.L [R1+], R14
            MOV.L [R2+], R5
            MACLO R14, R5
            MACHI R14, R5
            BNE L56
            BRA L60
    L57:    ; entry
            SUB #01H, R3
            BEQ L59
    L58:    ; entry
            SUB #02H, R3
            MOV.L [R1+], R14
            MOV.L [R2+], R5
            MACLO R14, R5
            MACHI R14, R5
            BNE L58
    L59:    ; entry
            MOV.W [R1], R14
            MOV.W [R2], R5
            MACLO R14, R5
    L60:    ; entry
            MVFACMI R1
            RTS
    */
        register long temp1;
        register long temp2;
        register long result;
        __ASM volatile
        (
            /* AssemblerTemplate */
            "CMP #0x00, %[R3]"              "\n\t"
            "MOV.L #0x00000000, %[R14]"     "\n\t"
            "MULLO %[R14], %[R14]"          "\n\t"
            "BEQ 6f"                        "\n"  
    "1:"                                    "\n\t"
            "BTST #0x00, %[R3]"             "\n\t"
            "BGEU 3f"                       "\n"  
    "2:"                                    "\n\t"
            "SUB #0x02, %[R3]"              "\n\t"
            "MOV.L [%[R1]+], %[R14]"        "\n\t"
            "MOV.L [%[R2]+], %[R5]"         "\n\t"
            "MACLO %[R14], %[R5]"           "\n\t"
            "MACHI %[R14], %[R5]"           "\n\t"
            "BNE 2b"                        "\n\t"
            "BRA 6f"                        "\n"  
    "3:"                                    "\n\t"
            "SUB #0x01, %[R3]"              "\n\t"
            "BEQ 5f"                        "\n"  
    "4:"                                    "\n\t"
            "SUB #0x02, %[R3]"              "\n\t"
            "MOV.L [%[R1]+], %[R14]"        "\n\t"
            "MOV.L [%[R2]+], %[R5]"         "\n\t"
            "MACLO %[R14], %[R5]"           "\n\t"
            "MACHI %[R14], %[R5]"           "\n\t"
            "BNE 4b"                        "\n"  
    "5:"                                    "\n\t"
            "MOV.W [%[R1]], %[R14]"         "\n\t"
            "MOV.W [%[R2]], %[R5]"          "\n\t"
            "MACLO %[R14], %[R5]"           "\n"  
    "6:"                                    "\n\t"
            : /* OutputOperands */
                [R1] "+r" (data1),
                [R2] "+r" (data2),
                [R3] "+r" (count),
                [R5] "=&r" (temp1),
                [R14] "=&r" (temp2)
            : /* InputOperands */
                /**/ "m" (*(short (*)[count]) data1),
                /**/ "m" (*(short (*)[count]) data2)
        );
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVFACMI %[R1]"                 "\n\t"
            : /* OutputOperands */
                [R1] "=r" (result)
        );
        return result;
    /* GNURX 2018q1 -O2
     834 012b 61 03                         CMP #0x00, r3
     835 012d 66 04                         MOV.L #0x00000000, r4
     836 012f FD 01 44                      MULLO r4, r4
     837 0132 20 33                         BEQ 6f
     838                                    1:
     839 0134 7C 03                         BTST #0x00, r3
     840 0136 22 14                         BGEU 3f
     841                                    2:
     842 0138 60 23                         SUB #0x02, r3
     843 013a FD 2A 14                      MOV.L [r1+], r4
     844 013d FD 2A 25                      MOV.L [r2+], r5
     845 0140 FD 05 45                      MACLO r4, r5
     846 0143 FD 04 45                      MACHI r4, r5
     847 0146 21 F2                         BNE 2b
     848 0148 2E 1D                         BRA 6f
     849                                    3:
     850 014a 60 13                         SUB #0x01, r3
     851 014c 20 12                         BEQ 5f
     852                                    4:
     853 014e 60 23                         SUB #0x02, r3
     854 0150 FD 2A 14                      MOV.L [r1+], r4
     855 0153 FD 2A 25                      MOV.L [r2+], r5
     856 0156 FD 05 45                      MACLO r4, r5
     857 0159 FD 04 45                      MACHI r4, r5
     858 015c 21 F2                         BNE 4b
     859                                    5:
     860 015e DC 14                         MOV.W [r1], r4
     861 0160 DC 25                         MOV.W [r2], r5
     862 0162 FD 05 45                      MACLO r4, r5
     868 0165 FD 1F 21                      MVFACMI r1
     874 0168 02                            rts
    */
    }
    
    #ifndef macw1
    #define macw1(data1, data2, count) ccrx_machine_h_macw1(data1, data2, count)
    #endif
    __STATIC_FORCEINLINE short ccrx_machine_h_macw1(short *data1, short *data2, unsigned long count)
    {
    /* CC-RX V2.03 -optimize=2
            CMP #00H, R3
            MOV.L #00000000H, R14
            MULLO R14, R14
            BEQ L67
    L62:    ; entry
            BTST #00H, R3
            BGEU L64
    L63:    ; entry
            SUB #02H, R3
            MOV.L [R1+], R14
            MOV.L [R2+], R5
            MACLO R14, R5
            MACHI R14, R5
            BNE L63
            BRA L67
    L64:    ; entry
            SUB #01H, R3
            BEQ L66
    L65:    ; entry
            SUB #02H, R3
            MOV.L [R1+], R14
            MOV.L [R2+], R5
            MACLO R14, R5
            MACHI R14, R5
            BNE L65
    L66:    ; entry
            MOV.W [R1], R14
            MOV.W [R2], R5
            MACLO R14, R5
    L67:    ; entry
            RACW #01H
            MVFACHI R1
            RTS
    */
        register long temp1;
        register long temp2;
        register short result;
        __ASM volatile
        (
            /* AssemblerTemplate */
            "CMP #0x00, %[R3]"              "\n\t"
            "MOV.L #0x00000000, %[R14]"     "\n\t"
            "MULLO %[R14], %[R14]"          "\n\t"
            "BEQ 6f"                        "\n"  
    "1:"                                    "\n\t"
            "BTST #0x00, %[R3]"             "\n\t"
            "BGEU 3f"                       "\n"  
    "2:"                                    "\n\t"
            "SUB #0x02, %[R3]"              "\n\t"
            "MOV.L [%[R1]+], %[R14]"        "\n\t"
            "MOV.L [%[R2]+], %[R5]"         "\n\t"
            "MACLO %[R14], %[R5]"           "\n\t"
            "MACHI %[R14], %[R5]"           "\n\t"
            "BNE 2b"                        "\n\t"
            "BRA 6f"                        "\n"  
    "3:"                                    "\n\t"
            "SUB #0x01, %[R3]"              "\n\t"
            "BEQ 5f"                        "\n"  
    "4:"                                    "\n\t"
            "SUB #0x02, %[R3]"              "\n\t"
            "MOV.L [%[R1]+], %[R14]"        "\n\t"
            "MOV.L [%[R2]+], %[R5]"         "\n\t"
            "MACLO %[R14], %[R5]"           "\n\t"
            "MACHI %[R14], %[R5]"           "\n\t"
            "BNE 4b"                        "\n"  
    "5:"                                    "\n\t"
            "MOV.W [%[R1]], %[R14]"         "\n\t"
            "MOV.W [%[R2]], %[R5]"          "\n\t"
            "MACLO %[R14], %[R5]"           "\n"  
    "6:"                                    "\n\t"
            : /* OutputOperands */
                [R1] "+r" (data1),
                [R2] "+r" (data2),
                [R3] "+r" (count),
                [R5] "=&r" (temp1),
                [R14] "=&r" (temp2)
            : /* InputOperands */
                /**/ "m" (*(short (*)[count]) data1),
                /**/ "m" (*(short (*)[count]) data2)
        );
        __ASM volatile
        (
            /* AssemblerTemplate */
            "RACW #0x01"                    "\n\t"
            "MVFACMI %[R1]"                 "\n\t"
            : /* OutputOperands */
                [R1] "=r" (result)
        );
        return result;
    /* GNURX 2018q1 -O2
     887 0169 61 03                         CMP #0x00, r3
     888 016b 66 04                         MOV.L #0x00000000, r4
     889 016d FD 01 44                      MULLO r4, r4
     890 0170 20 33                         BEQ 6f
     891                                    1:
     892 0172 7C 03                         BTST #0x00, r3
     893 0174 22 14                         BGEU 3f
     894                                    2:
     895 0176 60 23                         SUB #0x02, r3
     896 0178 FD 2A 14                      MOV.L [r1+], r4
     897 017b FD 2A 25                      MOV.L [r2+], r5
     898 017e FD 05 45                      MACLO r4, r5
     899 0181 FD 04 45                      MACHI r4, r5
     900 0184 21 F2                         BNE 2b
     901 0186 2E 1D                         BRA 6f
     902                                    3:
     903 0188 60 13                         SUB #0x01, r3
     904 018a 20 12                         BEQ 5f
     905                                    4:
     906 018c 60 23                         SUB #0x02, r3
     907 018e FD 2A 14                      MOV.L [r1+], r4
     908 0191 FD 2A 25                      MOV.L [r2+], r5
     909 0194 FD 05 45                      MACLO r4, r5
     910 0197 FD 04 45                      MACHI r4, r5
     911 019a 21 F2                         BNE 4b
     912                                    5:
     913 019c DC 14                         MOV.W [r1], r4
     914 019e DC 25                         MOV.W [r2], r5
     915 01a0 FD 05 45                      MACLO r4, r5
     916                                    6:
     921 01a3 FD 18 00                      RACW #0x01
     922 01a6 FD 1F 21                      MVFACMI r1
     928 01a9 DF 11                         mov.W   r1, r1      ★ TODO: check
     929 01ab 02                            rts
    */
    }
    
    #ifndef macw2
    #define macw2(data1, data2, count) ccrx_machine_h_macw2(data1, data2, count)
    #endif
    __STATIC_FORCEINLINE short ccrx_machine_h_macw2(short *data1, short *data2, unsigned long count)
    {
    /* CC-RX V2.03 -optimize=2
            CMP #00H, R3
            MOV.L #00000000H, R14
            MULLO R14, R14
            BEQ L74
    L69:    ; entry
            BTST #00H, R3
            BGEU L71
    L70:    ; entry
            SUB #02H, R3
            MOV.L [R1+], R14
            MOV.L [R2+], R5
            MACLO R14, R5
            MACHI R14, R5
            BNE L70
            BRA L74
    L71:    ; entry
            SUB #01H, R3
            BEQ L73
    L72:    ; entry
            SUB #02H, R3
            MOV.L [R1+], R14
            MOV.L [R2+], R5
            MACLO R14, R5
            MACHI R14, R5
            BNE L72
    L73:    ; entry
            MOV.W [R1], R14
            MOV.W [R2], R5
            MACLO R14, R5
    L74:    ; entry
            RACW #02H
            MVFACHI R1
            RTS
    */
        register long temp1;
        register long temp2;
        register short result;
        __ASM volatile
        (
            /* AssemblerTemplate */
            "CMP #0x00, %[R3]"              "\n\t"
            "MOV.L #0x00000000, %[R14]"     "\n\t"
            "MULLO %[R14], %[R14]"          "\n\t"
            "BEQ 6f"                        "\n"  
    "1:"                                    "\n\t"
            "BTST #0x00, %[R3]"             "\n\t"
            "BGEU 3f"                       "\n"  
    "2:"                                    "\n\t"
            "SUB #0x02, %[R3]"              "\n\t"
            "MOV.L [%[R1]+], %[R14]"        "\n\t"
            "MOV.L [%[R2]+], %[R5]"         "\n\t"
            "MACLO %[R14], %[R5]"           "\n\t"
            "MACHI %[R14], %[R5]"           "\n\t"
            "BNE 2b"                        "\n\t"
            "BRA 6f"                        "\n"  
    "3:"                                    "\n\t"
            "SUB #0x01, %[R3]"              "\n\t"
            "BEQ 5f"                        "\n"  
    "4:"                                    "\n\t"
            "SUB #0x02, %[R3]"              "\n\t"
            "MOV.L [%[R1]+], %[R14]"        "\n\t"
            "MOV.L [%[R2]+], %[R5]"         "\n\t"
            "MACLO %[R14], %[R5]"           "\n\t"
            "MACHI %[R14], %[R5]"           "\n\t"
            "BNE 4b"                        "\n"  
    "5:"                                    "\n\t"
            "MOV.W [%[R1]], %[R14]"         "\n\t"
            "MOV.W [%[R2]], %[R5]"          "\n\t"
            "MACLO %[R14], %[R5]"           "\n"  
    "6:"                                    "\n\t"
            : /* OutputOperands */
                [R1] "+r" (data1),
                [R2] "+r" (data2),
                [R3] "+r" (count),
                [R5] "=&r" (temp1),
                [R14] "=&r" (temp2)
            : /* InputOperands */
                /**/ "m" (*(short (*)[count]) data1),
                /**/ "m" (*(short (*)[count]) data2)
        );
        __ASM volatile
        (
            /* AssemblerTemplate */
            "RACW #02H"                     "\n\t"
            "MVFACMI %[R1]"                 "\n\t"
            : /* OutputOperands */
                [R1] "=r" (result)
        );
        return result;
    /* GNURX 2018q1 -O2
     942 01ac 61 03                         CMP #0x00, r3
     943 01ae 66 04                         MOV.L #0x00000000, r4
     944 01b0 FD 01 44                      MULLO r4, r4
     945 01b3 20 33                         BEQ 6f
     946                                    1:
     947 01b5 7C 03                         BTST #0x00, r3
     948 01b7 22 14                         BGEU 3f
     949                                    2:
     950 01b9 60 23                         SUB #0x02, r3
     951 01bb FD 2A 14                      MOV.L [r1+], r4
     952 01be FD 2A 25                      MOV.L [r2+], r5
     953 01c1 FD 05 45                      MACLO r4, r5
     954 01c4 FD 04 45                      MACHI r4, r5
     955 01c7 21 F2                         BNE 2b
     956 01c9 2E 1D                         BRA 6f
     957                                    3:
     958 01cb 60 13                         SUB #0x01, r3
     959 01cd 20 12                         BEQ 5f
     960                                    4:
     961 01cf 60 23                         SUB #0x02, r3
     962 01d1 FD 2A 14                      MOV.L [r1+], r4
     963 01d4 FD 2A 25                      MOV.L [r2+], r5
     964 01d7 FD 05 45                      MACLO r4, r5
     965 01da FD 04 45                      MACHI r4, r5
     966 01dd 21 F2                         BNE 4b
     967                                    5:
     968 01df DC 14                         MOV.W [r1], r4
     969 01e1 DC 25                         MOV.W [r2], r5
     970 01e3 FD 05 45                      MACLO r4, r5
     976 01e6 FD 18 10                      RACW #02H
     977 01e9 FD 1F 21                      MVFACMI r1
     983 01ec DF 11                         mov.W   r1, r1      ★ TODO: check
     984 01ee 02                            rts
    */
    }
    
    #ifndef set_extb
    #define set_extb(data) ccrx_machine_h_set_extb(data)
    #endif
    __STATIC_FORCEINLINE void ccrx_machine_h_set_extb(void *data)
    {
    /* CC-RX V2.03 -optimize=2
            MVTC R1, EXTB
            RTS
    */
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVTC %[R1], EXTB"
            : /* OutputOperands */
                /* No outputs. */
            : /* InputOperands */
                [R1] "r" (data)
        );
        return;
    /* GNURX 2018q1 -O2
     1014 0204 FD 68 1D                     MVTC r1, EXTB
     1016 0207 02                           rts
     */
    }
    
    #ifndef get_extb
    #define get_extb() ccrx_machine_h_get_extb()
    #endif
    __STATIC_FORCEINLINE void *ccrx_machine_h_get_extb(void)
    {
    /* CC-RX V2.03 -optimize=2
            MVFC EXTB, R1
            RTS
    */
        register void *data;
        __ASM volatile
        (
            /* AssemblerTemplate */
            "MVFC EXTB, %[R1]"
            : /* OutputOperands */
                [R1] "=r" (data)
        );
        return data;
    /* GNURX 2018q1 -O2
     1030 0208 FD 6A D1                     MVFC EXTB, r1
     1036 020b 02                           rts
    */
    }
    
    #endif /* CCRXMACHINE2_H */
    


    CCRXmachine2.c
    1651.CCRXmachine2_c_20180703.txt
    /*
    Use switch case function instead of RX INT instruction execution on stack.
    #define DONT_EXECUTE_RX_INT_INSTRUCTION_ON_STACK
    */
    
    #ifdef DONT_EXECUTE_RX_INT_INSTRUCTION_ON_STACK
    
    void ccrx_machine_h_int_exception_switch_case_function(signed long num);
    
    #define INTNUM(num)\
        __builtin_rx_int(num)
    
    #define INTN(N)\
        case N:\
        INTNUM(N);\
        break;
    
    #define INTN5(N)\
        INTN(N)\
        INTN(N+1)\
        INTN(N+2)\
        INTN(N+3)\
        INTN(N+4)
    
    #define INTN10(N)\
        INTN5(N)\
        INTN5(N+5)
    
    #define INTN50(N)\
        INTN10(N)\
        INTN10(N+10)\
        INTN10(N+20)\
        INTN10(N+30)\
        INTN10(N+40)
    
    void ccrx_machine_h_int_exception_switch_case_function(signed long num)
    {
        switch(num)
        {
        INTN50(0)
        INTN50(50)
        INTN50(100)
        INTN50(150)
        INTN50(200)
        INTN5(250)
        INTN(255)
        default:
        INTNUM(255);
        }
    }
    
    #endif /* DONT_EXECUTE_RX_INT_INSTRUCTION_ON_STACK */
    


    TestGNURX_CCRXmachine2_h.c
    1004.TestGNURX_CCRXmachine2_h_c_20180703.txt
    //#include "r_smc_entry.h"
    //#define DONT_EXECUTE_RX_INT_INSTRUCTION_ON_STACK
    #include "CCRXmachine2.h"
    
    signed long        _max(signed long data1, signed long data2)                                          ;
    signed long        _min(signed long data1, signed long data2)                                          ;
    unsigned long      _revl(unsigned long data)                                                           ;
    unsigned long      _revw(unsigned long data)                                                           ;
    void               _xchg(signed long *data1, signed long *data2)                                       ;
    long long          _rmpab(long long init, unsigned long count, signed char *addr1, signed char *addr2) ;
    long long          _rmpaw(long long init, unsigned long count, short *addr1, short *addr2)             ;
    long long          _rmpal(long long init, unsigned long count, long *addr1, long *addr2)               ;
    unsigned long      _rolc(unsigned long data)                                                           ;
    unsigned long      _rorc(unsigned long data)                                                           ;
    unsigned long      _rotl(unsigned long data, unsigned long num)                                        ;
    unsigned long      _rotr(unsigned long data, unsigned long num)                                        ;
    void               _brk(void)                                                                          ;
    void               _int_exception(signed long num)                                                     ;
    void               _my_int_exception_0(void)                                                           ;
    void               _my_int_exception_255(void)                                                         ;
    void               _wait(void)                                                                         ;
    void               _nop(void)                                                                          ;
    void               _set_ipl(signed long level)                                                         ;
    unsigned char      _get_ipl(void)                                                                      ;
    void               _set_psw(unsigned long data)                                                        ;
    unsigned long      _get_psw(void)                                                                      ;
    void               _set_fpsw(unsigned long data)                                                       ;
    unsigned long      _get_fpsw(void)                                                                     ;
    void               _set_usp(void *data)                                                                ;
    void *             _get_usp(void)                                                                      ;
    void               _set_isp(void *data)                                                                ;
    void *             _get_isp(void)                                                                      ;
    void               _set_intb(void *data)                                                               ;
    void *             _get_intb(void)                                                                     ;
    void               _set_bpsw(unsigned long data)                                                       ;
    unsigned long      _get_bpsw(void)                                                                     ;
    void               _set_bpc(void *data)                                                                ;
    void *             _get_bpc(void)                                                                      ;
    void               _set_fintv(void *data)                                                              ;
    void *             _get_fintv(void)                                                                    ;
    signed long long   _emul(signed long data1, signed long data2)                                         ;
    unsigned long long _emulu(unsigned long data1, unsigned long data2)                                    ;
    void               _chg_pmusr(void)                                                                    ;
    void               _set_acc(signed long long data)                                                     ;
    signed long long   _get_acc(void)                                                                      ;
    void               _setpsw_i(void)                                                                     ;
    void               _clrpsw_i(void)                                                                     ;
    long               _macl(short *data1, short *data2, unsigned long count)                              ;
    short              _macw1(short *data1, short *data2, unsigned long count)                             ;
    short              _macw2(short *data1, short *data2, unsigned long count)                             ;
    void               _set_extb(void *data)                                                               ;
    void *             _get_extb(void)                                                                     ;
    
    signed long        _max(signed long data1, signed long data2)                                          { return max(data1, data2);                }
    signed long        _min(signed long data1, signed long data2)                                          { return min(data1, data2);                }
    unsigned long      _revl(unsigned long data)                                                           { return revl(data);                       }
    unsigned long      _revw(unsigned long data)                                                           { return revw(data);                       }
    void               _xchg(signed long *data1, signed long *data2)                                       {        xchg(data1, data2);               }
    long long          _rmpab(long long init, unsigned long count, signed char *addr1, signed char *addr2) { return rmpab(init, count, addr1, addr2); }
    long long          _rmpaw(long long init, unsigned long count, short *addr1, short *addr2)             { return rmpaw(init, count, addr1, addr2); }
    long long          _rmpal(long long init, unsigned long count, long *addr1, long *addr2)               { return rmpal(init, count, addr1, addr2); }
    unsigned long      _rolc(unsigned long data)                                                           { return rolc(data);                       }
    unsigned long      _rorc(unsigned long data)                                                           { return rorc(data);                       }
    unsigned long      _rotl(unsigned long data, unsigned long num)                                        { return rotl(data, num);                  }
    unsigned long      _rotr(unsigned long data, unsigned long num)                                        { return rotr(data, num);                  }
    void               _brk(void)                                                                          {        brk();                            }
    void               _int_exception(signed long num)                                                     {        int_exception(num);               }
    void               _my_int_exception_0(void)                                                           {        int_exception(0);                 }
    void               _my_int_exception_255(void)                                                         {        int_exception(255);               }
    void               _wait(void)                                                                         {        wait();                           }
    void               _nop(void)                                                                          {        nop();                            }
    void               _set_ipl(signed long level)                                                         {        set_ipl(level);                   }
    unsigned char      _get_ipl(void)                                                                      { return get_ipl();                        }
    void               _set_psw(unsigned long data)                                                        {        set_psw(data);                    }
    unsigned long      _get_psw(void)                                                                      { return get_psw();                        }
    void               _set_fpsw(unsigned long data)                                                       {        set_fpsw(data);                   }
    unsigned long      _get_fpsw(void)                                                                     { return get_fpsw();                       }
    void               _set_usp(void *data)                                                                {        set_usp(data);                    }
    void *             _get_usp(void)                                                                      { return get_usp();                        }
    void               _set_isp(void *data)                                                                {        set_isp(data);                    }
    void *             _get_isp(void)                                                                      { return get_isp();                        }
    void               _set_intb(void *data)                                                               {        set_intb(data);                   }
    void *             _get_intb(void)                                                                     { return get_intb();                       }
    void               _set_bpsw(unsigned long data)                                                       {        set_bpsw(data);                   }
    unsigned long      _get_bpsw(void)                                                                     { return get_bpsw();                       }
    void               _set_bpc(void *data)                                                                {        set_bpc(data);                    }
    void *             _get_bpc(void)                                                                      { return get_bpc();                        }
    void               _set_fintv(void *data)                                                              {        set_fintv(data);                  }
    void *             _get_fintv(void)                                                                    { return get_fintv();                      }
    signed long long   _emul(signed long data1, signed long data2)                                         { return emul(data1, data2);               }
    unsigned long long _emulu(unsigned long data1, unsigned long data2)                                    { return emulu(data1, data2);              }
    void               _chg_pmusr(void)                                                                    {        chg_pmusr();                      }
    void               _set_acc(signed long long data)                                                     {        set_acc(data);                    }
    signed long long   _get_acc(void)                                                                      { return get_acc();                        }
    void               _setpsw_i(void)                                                                     {        setpsw_i();                       }
    void               _clrpsw_i(void)                                                                     {        clrpsw_i();                       }
    long               _macl(short *data1, short *data2, unsigned long count)                              { return macl(data1, data2, count);        }
    short              _macw1(short *data1, short *data2, unsigned long count)                             { return macw1(data1, data2, count);       }
    short              _macw2(short *data1, short *data2, unsigned long count)                             { return macw2(data1, data2, count);       }
    void               _set_extb(void *data)                                                               {        set_extb(data);                   }
    void *             _get_extb(void)                                                                     { return get_extb();                       }
    
    void main(void);
    void main(void)
    {
    	for (;;) ;
    }
    


    [追記]

    TestGNURX_CCRXmachine2_h.lst
    6038.TestGNURX_CCRXmachine2_h_lst_20180703.txt
       1                             		.file	"TestGNURX_CCRXmachine2_h.c"
       2                             		.section P,"ax"
       3                             	.Ltext0:
       4                             		.global	__max
       6                             	__max:
       7                             	.LFB45:
       8                             		.file 1 "../src/TestGNURX_CCRXmachine2_h.c"
       9                             		.loc 1 54 0
      10                             	.LVL0:
      11                             	.LBB92:
      12                             	.LBB93:
      13                             		.file 2 "../src/CCRXmachine2.h"
      14                             		.loc 2 101 0
      15                             	 ; 101 "../src/CCRXmachine2.h" 1
      16 0000 FC 13 21                		MAX r2, r1
      17                             	 ; 0 "" 2
      18                             	.LVL1:
      19                             	.LBE93:
      20                             	.LBE92:
      21                             		.loc 1 54 0
      22 0003 02                      		rts
      23                             	.LFE45:
      25                             		.global	__min
      27                             	__min:
      28                             	.LFB46:
      29                             		.loc 1 55 0
      30                             	.LVL2:
      31                             	.LBB94:
      32                             	.LBB95:
      33                             		.loc 2 126 0
      34                             	 ; 126 "../src/CCRXmachine2.h" 1
      35 0004 FC 17 21                		MIN r2, r1
      36                             	 ; 0 "" 2
      37                             	.LVL3:
      38                             	.LBE95:
      39                             	.LBE94:
      40                             		.loc 1 55 0
      41 0007 02                      		rts
      42                             	.LFE46:
      44                             		.global	__revl
      46                             	__revl:
      47                             	.LFB47:
      48                             		.loc 1 56 0
      49                             	.LVL4:
      50                             	.LBB96:
      51                             	.LBB97:
      52                             		.loc 2 151 0
      53                             	 ; 151 "../src/CCRXmachine2.h" 1
      54 0008 FD 67 11                		REVL r1, r1
      55                             	 ; 0 "" 2
      56                             	.LVL5:
      57                             	.LBE97:
      58                             	.LBE96:
      59                             		.loc 1 56 0
      60 000b 02                      		rts
      61                             	.LFE47:
      63                             		.global	__revw
      65                             	__revw:
      66                             	.LFB48:
      67                             		.loc 1 57 0
      68                             	.LVL6:
      69                             	.LBB98:
      70                             	.LBB99:
      71                             		.loc 2 174 0
      72                             	 ; 174 "../src/CCRXmachine2.h" 1
      73 000c FD 65 11                		REVW r1, r1
      74                             	 ; 0 "" 2
      75                             	.LVL7:
      76                             	.LBE99:
      77                             	.LBE98:
      78                             		.loc 1 57 0
      79 000f 02                      		rts
      80                             	.LFE48:
      82                             		.global	__xchg
      84                             	__xchg:
      85                             	.LFB49:
      86                             		.loc 1 58 0
      87                             	.LVL8:
      88                             	.LBB100:
      89                             	.LBB101:
      90                             		.loc 2 200 0
      91                             	 ; 200 "../src/CCRXmachine2.h" 1
      92 0010 EC 15                   		MOV.L [r1], r5
      93 0012 06 A0 10 25             		XCHG [r2].L, r5
      94 0016 E3 15                   		MOV.L r5, [r1]
      95                             		
      96                             	 ; 0 "" 2
      97                             	.LVL9:
      98 0018 02                      		rts
      99                             	.LBE101:
     100                             	.LBE100:
     101                             	.LFE49:
     103                             		.global	__rmpab
     105                             	__rmpab:
     106                             	.LFB50:
     107                             		.loc 1 59 0
     108                             	.LVL10:
     109 0019 7E A6                   		push.l	r6
     110                             	.LCFI0:
     111 001b 60 40                   		sub	#4, r0
     112                             	.LCFI1:
     113                             		.loc 1 59 0
     114 001d EF 25                   		mov.L	r2, r5
     115                             	.LVL11:
     116 001f A8 8A                   		mov.L	12[r0], r2
     117                             	.LVL12:
     118                             	.LBB102:
     119                             	.LBB103:
     120                             		.loc 2 249 0
     121 0021 FC 43 41                		xchg	r4, r1
     122                             		.loc 2 254 0
     123 0024 FD BF 56                		shar	#31, r5, r6
     124                             		.loc 2 259 0
     125                             	 ; 259 "../src/CCRXmachine2.h" 1
     126 0027 7F 8C                   		RMPA.B
     127                             		
     128                             	 ; 0 "" 2
     129                             	.LVL13:
     130                             		.loc 2 282 0
     131                             	 ; 282 "../src/CCRXmachine2.h" 1
     132                             		
     133                             		
     134                             	 ; 0 "" 2
     135                             	.LVL14:
     136                             	.LBE103:
     137                             	.LBE102:
     138                             		.loc 1 59 0
     139 0029 EF 41                   		mov.L	r4, r1
     140 002b EF 52                   		mov.L	r5, r2
     141 002d 3F 66 02                		rtsd	#8, r6-r6
     142                             	.LFE50:
     144                             		.global	__rmpaw
     146                             	__rmpaw:
     147                             	.LFB51:
     148                             		.loc 1 60 0
     149                             	.LVL15:
     150 0030 7E A6                   		push.l	r6
     151                             	.LCFI2:
     152 0032 60 40                   		sub	#4, r0
     153                             	.LCFI3:
     154                             		.loc 1 60 0
     155 0034 EF 25                   		mov.L	r2, r5
     156                             	.LVL16:
     157 0036 A8 8A                   		mov.L	12[r0], r2
     158                             	.LVL17:
     159                             	.LBB104:
     160                             	.LBB105:
     161                             		.loc 2 415 0
     162 0038 FC 43 41                		xchg	r4, r1
     163                             		.loc 2 420 0
     164 003b FD BF 56                		shar	#31, r5, r6
     165                             		.loc 2 425 0
     166                             	 ; 425 "../src/CCRXmachine2.h" 1
     167 003e 7F 8D                   		RMPA.W
     168                             		
     169                             	 ; 0 "" 2
     170                             	.LVL18:
     171                             		.loc 2 448 0
     172                             	 ; 448 "../src/CCRXmachine2.h" 1
     173                             		
     174                             		
     175                             	 ; 0 "" 2
     176                             	.LVL19:
     177                             	.LBE105:
     178                             	.LBE104:
     179                             		.loc 1 60 0
     180 0040 EF 41                   		mov.L	r4, r1
     181 0042 EF 52                   		mov.L	r5, r2
     182 0044 3F 66 02                		rtsd	#8, r6-r6
     183                             	.LFE51:
     185                             		.global	__rmpal
     187                             	__rmpal:
     188                             	.LFB52:
     189                             		.loc 1 61 0
     190                             	.LVL20:
     191 0047 7E A6                   		push.l	r6
     192                             	.LCFI4:
     193 0049 60 40                   		sub	#4, r0
     194                             	.LCFI5:
     195                             		.loc 1 61 0
     196 004b EF 25                   		mov.L	r2, r5
     197                             	.LVL21:
     198 004d A8 8A                   		mov.L	12[r0], r2
     199                             	.LVL22:
     200                             	.LBB106:
     201                             	.LBB107:
     202                             		.loc 2 493 0
     203 004f FC 43 41                		xchg	r4, r1
     204                             		.loc 2 498 0
     205 0052 FD BF 56                		shar	#31, r5, r6
     206                             		.loc 2 503 0
     207                             	 ; 503 "../src/CCRXmachine2.h" 1
     208 0055 7F 8E                   		RMPA.L
     209                             		
     210                             	 ; 0 "" 2
     211                             	.LVL23:
     212                             		.loc 2 526 0
     213                             	 ; 526 "../src/CCRXmachine2.h" 1
     214                             		
     215                             		
     216                             	 ; 0 "" 2
     217                             	.LVL24:
     218                             	.LBE107:
     219                             	.LBE106:
     220                             		.loc 1 61 0
     221 0057 EF 41                   		mov.L	r4, r1
     222 0059 EF 52                   		mov.L	r5, r2
     223 005b 3F 66 02                		rtsd	#8, r6-r6
     224                             	.LFE52:
     226                             		.global	__rolc
     228                             	__rolc:
     229                             	.LFB53:
     230                             		.loc 1 62 0
     231                             	.LVL25:
     232                             	.LBB108:
     233                             	.LBB109:
     234                             		.loc 2 555 0
     235                             	 ; 555 "../src/CCRXmachine2.h" 1
     236 005e 7E 51                   		ROLC r1
     237                             	 ; 0 "" 2
     238                             	.LVL26:
     239                             	.LBE109:
     240                             	.LBE108:
     241                             		.loc 1 62 0
     242 0060 02                      		rts
     243                             	.LFE53:
     245                             		.global	__rorc
     247                             	__rorc:
     248                             	.LFB54:
     249                             		.loc 1 63 0
     250                             	.LVL27:
     251                             	.LBB110:
     252                             	.LBB111:
     253                             		.loc 2 578 0
     254                             	 ; 578 "../src/CCRXmachine2.h" 1
     255 0061 7E 41                   		RORC r1
     256                             	 ; 0 "" 2
     257                             	.LVL28:
     258                             	.LBE111:
     259                             	.LBE110:
     260                             		.loc 1 63 0
     261 0063 02                      		rts
     262                             	.LFE54:
     264                             		.global	__rotl
     266                             	__rotl:
     267                             	.LFB55:
     268                             		.loc 1 64 0
     269                             	.LVL29:
     270                             	.LBB112:
     271                             	.LBB113:
     272                             		.loc 2 601 0
     273                             	 ; 601 "../src/CCRXmachine2.h" 1
     274 0064 FD 66 21                		ROTL r2, r1
     275                             	 ; 0 "" 2
     276                             	.LVL30:
     277                             	.LBE113:
     278                             	.LBE112:
     279                             		.loc 1 64 0
     280 0067 02                      		rts
     281                             	.LFE55:
     283                             		.global	__rotr
     285                             	__rotr:
     286                             	.LFB56:
     287                             		.loc 1 65 0
     288                             	.LVL31:
     289                             	.LBB114:
     290                             	.LBB115:
     291                             		.loc 2 626 0
     292                             	 ; 626 "../src/CCRXmachine2.h" 1
     293 0068 FD 64 21                		ROTR r2, r1
     294                             	 ; 0 "" 2
     295                             	.LVL32:
     296                             	.LBE115:
     297                             	.LBE114:
     298                             		.loc 1 65 0
     299 006b 02                      		rts
     300                             	.LFE56:
     302                             		.global	__brk
     304                             	__brk:
     305                             	.LFB57:
     306                             		.loc 1 66 0
     307                             	.LBB116:
     308                             	.LBB117:
     309                             		.loc 2 651 0
     310                             	 ; 651 "../src/CCRXmachine2.h" 1
     311 006c 00                      		BRK
     312                             	 ; 0 "" 2
     313 006d 02                      		rts
     314                             	.LBE117:
     315                             	.LBE116:
     316                             	.LFE57:
     318                             		.global	__int_exception
     320                             	__int_exception:
     321                             	.LFB58:
     322                             		.loc 1 67 0
     323                             	.LVL33:
     324 006e 60 40                   		sub	#4, r0
     325                             	.LCFI6:
     326                             	.LBB118:
     327                             		.loc 1 67 0
     328 0070 80 81                   		mov.B	r1, 2[r0]
     329 0072 F8 04 75                		mov.B	#0x75, [r0]
     330 0075 EF 01                   		mov.L	r0, r1
     331                             	.LVL34:
     332 0077 3C 01 60                		mov.B	#0x60, 1[r0]
     333 007a 3C 03 02                		mov.B	#2, 3[r0]
     334 007d 7F 10                   		jsr	r0
     335                             	.LVL35:
     336                             	.LBE118:
     337 007f 67 01                   		rtsd	#4
     338                             	.LFE58:
     340                             		.global	__my_int_exception_0
     342                             	__my_int_exception_0:
     343                             	.LFB59:
     344                             		.loc 1 68 0
     345                             		.loc 1 68 0
     346 0081 75 60 00                		int	#0
     347 0084 02                      		rts
     348                             	.LFE59:
     350                             		.global	__my_int_exception_255
     352                             	__my_int_exception_255:
     353                             	.LFB60:
     354                             		.loc 1 69 0
     355                             		.loc 1 69 0
     356 0085 75 60 FF                		int	#0xff
     357 0088 02                      		rts
     358                             	.LFE60:
     360                             		.global	__wait
     362                             	__wait:
     363                             	.LFB61:
     364                             		.loc 1 70 0
     365                             	.LBB119:
     366                             	.LBB120:
     367                             		.loc 2 704 0
     368                             	 ; 704 "../src/CCRXmachine2.h" 1
     369 0089 7F 96                   		WAIT
     370                             	 ; 0 "" 2
     371 008b 02                      		rts
     372                             	.LBE120:
     373                             	.LBE119:
     374                             	.LFE61:
     376                             		.global	__nop
     378                             	__nop:
     379                             	.LFB62:
     380                             		.loc 1 71 0
     381                             	.LBB121:
     382                             	.LBB122:
     383                             		.loc 2 727 0
     384                             	 ; 727 "../src/CCRXmachine2.h" 1
     385 008c 03                      		NOP
     386                             	 ; 0 "" 2
     387 008d 02                      		rts
     388                             	.LBE122:
     389                             	.LBE121:
     390                             	.LFE62:
     392                             		.global	__set_ipl
     394                             	__set_ipl:
     395                             	.LFB63:
     396                             		.loc 1 72 0
     397                             	.LVL36:
     398                             	.LBB123:
     399                             	.LBB124:
     400                             		.loc 2 756 0
     401                             	 ; 756 "../src/CCRXmachine2.h" 1
     402 008e FD 6A 05                		MVFC PSW, r5
     403 0091 6D C1                   		SHLL #0x1C, r1
     404 0093 68 41                   		SHLR #0x04, r1
     405 0095 74 25 FF FF FF F0       		AND #0xF0FFFFFF, r5
     406 009b 57 51                   		OR r5, r1
     407 009d FD 68 10                		MVTC r1, PSW
     408                             		
     409                             	 ; 0 "" 2
     410                             	.LVL37:
     411 00a0 02                      		rts
     412                             	.LBE124:
     413                             	.LBE123:
     414                             	.LFE63:
     416                             		.global	__get_ipl
     418                             	__get_ipl:
     419                             	.LFB64:
     420                             		.loc 1 73 0
     421                             	.LBB125:
     422                             	.LBB126:
     423                             		.loc 2 794 0
     424                             	 ; 794 "../src/CCRXmachine2.h" 1
     425 00a1 FD 6A 05                		MVFC PSW, r5
     426 00a4 FD 67 51                		REVL r5, r1
     427 00a7 64 F1                   		AND #0x0F, r1
     428                             		
     429                             	 ; 0 "" 2
     430                             	.LVL38:
     431                             	.LBE126:
     432                             	.LBE125:
     433                             		.loc 1 73 0
     434 00a9 5B 11                   		movu.B	r1, r1
     435 00ab 02                      		rts
     436                             	.LFE64:
     438                             		.global	__set_psw
     440                             	__set_psw:
     441                             	.LFB65:
     442                             		.loc 1 74 0
     443                             	.LVL39:
     444                             	.LBB127:
     445                             	.LBB128:
     446                             		.loc 2 823 0
     447                             	 ; 823 "../src/CCRXmachine2.h" 1
     448 00ac FD 68 10                		MVTC r1, PSW
     449                             	 ; 0 "" 2
     450 00af 02                      		rts
     451                             	.LBE128:
     452                             	.LBE127:
     453                             	.LFE65:
     455                             		.global	__get_psw
     457                             	__get_psw:
     458                             	.LFB66:
     459                             		.loc 1 75 0
     460                             	.LBB129:
     461                             	.LBB130:
     462                             		.loc 2 849 0
     463                             	 ; 849 "../src/CCRXmachine2.h" 1
     464 00b0 FD 6A 01                		MVFC PSW, r1
     465                             	 ; 0 "" 2
     466                             	.LVL40:
     467                             	.LBE130:
     468                             	.LBE129:
     469                             		.loc 1 75 0
     470 00b3 02                      		rts
     471                             	.LFE66:
     473                             		.global	__set_fpsw
     475                             	__set_fpsw:
     476                             	.LFB67:
     477                             		.loc 1 76 0
     478                             	.LVL41:
     479                             	.LBB131:
     480                             	.LBB132:
     481                             		.loc 2 872 0
     482                             	 ; 872 "../src/CCRXmachine2.h" 1
     483 00b4 FD 68 13                		MVTC r1, FPSW
     484                             	 ; 0 "" 2
     485 00b7 02                      		rts
     486                             	.LBE132:
     487                             	.LBE131:
     488                             	.LFE67:
     490                             		.global	__get_fpsw
     492                             	__get_fpsw:
     493                             	.LFB68:
     494                             		.loc 1 77 0
     495                             	.LBB133:
     496                             	.LBB134:
     497                             		.loc 2 898 0
     498                             	 ; 898 "../src/CCRXmachine2.h" 1
     499 00b8 FD 6A 31                		MVFC FPSW, r1
     500                             	 ; 0 "" 2
     501                             	.LVL42:
     502                             	.LBE134:
     503                             	.LBE133:
     504                             		.loc 1 77 0
     505 00bb 02                      		rts
     506                             	.LFE68:
     508                             		.global	__set_usp
     510                             	__set_usp:
     511                             	.LFB69:
     512                             		.loc 1 78 0
     513                             	.LVL43:
     514                             	.LBB135:
     515                             	.LBB136:
     516                             		.loc 2 921 0
     517                             	 ; 921 "../src/CCRXmachine2.h" 1
     518 00bc FD 68 12                		MVTC r1, USP
     519                             	 ; 0 "" 2
     520 00bf 02                      		rts
     521                             	.LBE136:
     522                             	.LBE135:
     523                             	.LFE69:
     525                             		.global	__get_usp
     527                             	__get_usp:
     528                             	.LFB70:
     529                             		.loc 1 79 0
     530                             	.LBB137:
     531                             	.LBB138:
     532                             		.loc 2 947 0
     533                             	 ; 947 "../src/CCRXmachine2.h" 1
     534 00c0 FD 6A 21                		MVFC USP, r1
     535                             	 ; 0 "" 2
     536                             	.LVL44:
     537                             	.LBE138:
     538                             	.LBE137:
     539                             		.loc 1 79 0
     540 00c3 02                      		rts
     541                             	.LFE70:
     543                             		.global	__set_isp
     545                             	__set_isp:
     546                             	.LFB71:
     547                             		.loc 1 80 0
     548                             	.LVL45:
     549                             	.LBB139:
     550                             	.LBB140:
     551                             		.loc 2 970 0
     552                             	 ; 970 "../src/CCRXmachine2.h" 1
     553 00c4 FD 68 1A                		MVTC r1, ISP
     554                             	 ; 0 "" 2
     555 00c7 02                      		rts
     556                             	.LBE140:
     557                             	.LBE139:
     558                             	.LFE71:
     560                             		.global	__get_isp
     562                             	__get_isp:
     563                             	.LFB72:
     564                             		.loc 1 81 0
     565                             	.LBB141:
     566                             	.LBB142:
     567                             		.loc 2 996 0
     568                             	 ; 996 "../src/CCRXmachine2.h" 1
     569 00c8 FD 6A A1                		MVFC ISP, r1
     570                             	 ; 0 "" 2
     571                             	.LVL46:
     572                             	.LBE142:
     573                             	.LBE141:
     574                             		.loc 1 81 0
     575 00cb 02                      		rts
     576                             	.LFE72:
     578                             		.global	__set_intb
     580                             	__set_intb:
     581                             	.LFB73:
     582                             		.loc 1 82 0
     583                             	.LVL47:
     584                             	.LBB143:
     585                             	.LBB144:
     586                             		.loc 2 1019 0
     587                             	 ; 1019 "../src/CCRXmachine2.h" 1
     588 00cc FD 68 1C                		MVTC r1, INTB
     589                             	 ; 0 "" 2
     590 00cf 02                      		rts
     591                             	.LBE144:
     592                             	.LBE143:
     593                             	.LFE73:
     595                             		.global	__get_intb
     597                             	__get_intb:
     598                             	.LFB74:
     599                             		.loc 1 83 0
     600                             	.LBB145:
     601                             	.LBB146:
     602                             		.loc 2 1045 0
     603                             	 ; 1045 "../src/CCRXmachine2.h" 1
     604 00d0 FD 6A C1                		MVFC INTB, r1
     605                             	 ; 0 "" 2
     606                             	.LVL48:
     607                             	.LBE146:
     608                             	.LBE145:
     609                             		.loc 1 83 0
     610 00d3 02                      		rts
     611                             	.LFE74:
     613                             		.global	__set_bpsw
     615                             	__set_bpsw:
     616                             	.LFB75:
     617                             		.loc 1 84 0
     618                             	.LVL49:
     619                             	.LBB147:
     620                             	.LBB148:
     621                             		.loc 2 1068 0
     622                             	 ; 1068 "../src/CCRXmachine2.h" 1
     623 00d4 FD 68 18                		MVTC r1, BPSW
     624                             	 ; 0 "" 2
     625 00d7 02                      		rts
     626                             	.LBE148:
     627                             	.LBE147:
     628                             	.LFE75:
     630                             		.global	__get_bpsw
     632                             	__get_bpsw:
     633                             	.LFB76:
     634                             		.loc 1 85 0
     635                             	.LBB149:
     636                             	.LBB150:
     637                             		.loc 2 1094 0
     638                             	 ; 1094 "../src/CCRXmachine2.h" 1
     639 00d8 FD 6A 81                		MVFC BPSW, r1
     640                             	 ; 0 "" 2
     641                             	.LVL50:
     642                             	.LBE150:
     643                             	.LBE149:
     644                             		.loc 1 85 0
     645 00db 02                      		rts
     646                             	.LFE76:
     648                             		.global	__set_bpc
     650                             	__set_bpc:
     651                             	.LFB77:
     652                             		.loc 1 86 0
     653                             	.LVL51:
     654                             	.LBB151:
     655                             	.LBB152:
     656                             		.loc 2 1117 0
     657                             	 ; 1117 "../src/CCRXmachine2.h" 1
     658 00dc FD 68 19                		MVTC r1, BPC
     659                             	 ; 0 "" 2
     660 00df 02                      		rts
     661                             	.LBE152:
     662                             	.LBE151:
     663                             	.LFE77:
     665                             		.global	__get_bpc
     667                             	__get_bpc:
     668                             	.LFB78:
     669                             		.loc 1 87 0
     670                             	.LBB153:
     671                             	.LBB154:
     672                             		.loc 2 1143 0
     673                             	 ; 1143 "../src/CCRXmachine2.h" 1
     674 00e0 FD 6A 91                		MVFC BPC, r1
     675                             	 ; 0 "" 2
     676                             	.LVL52:
     677                             	.LBE154:
     678                             	.LBE153:
     679                             		.loc 1 87 0
     680 00e3 02                      		rts
     681                             	.LFE78:
     683                             		.global	__set_fintv
     685                             	__set_fintv:
     686                             	.LFB79:
     687                             		.loc 1 88 0
     688                             	.LVL53:
     689                             	.LBB155:
     690                             	.LBB156:
     691                             		.loc 2 1166 0
     692                             	 ; 1166 "../src/CCRXmachine2.h" 1
     693 00e4 FD 68 1B                		MVTC r1, FINTV
     694                             	 ; 0 "" 2
     695 00e7 02                      		rts
     696                             	.LBE156:
     697                             	.LBE155:
     698                             	.LFE79:
     700                             		.global	__get_fintv
     702                             	__get_fintv:
     703                             	.LFB80:
     704                             		.loc 1 89 0
     705                             	.LBB157:
     706                             	.LBB158:
     707                             		.loc 2 1192 0
     708                             	 ; 1192 "../src/CCRXmachine2.h" 1
     709 00e8 FD 6A B1                		MVFC FINTV, r1
     710                             	 ; 0 "" 2
     711                             	.LVL54:
     712                             	.LBE158:
     713                             	.LBE157:
     714                             		.loc 1 89 0
     715 00eb 02                      		rts
     716                             	.LFE80:
     718                             		.global	__emul
     720                             	__emul:
     721                             	.LFB81:
     722                             		.loc 1 90 0
     723                             	.LVL55:
     724                             	.LBB159:
     725                             	.LBB160:
     726                             		.loc 2 1218 0
     727 00ec FC 1B 12                		emul	r1, r2
     728                             	.LVL56:
     729                             	.LBE160:
     730                             	.LBE159:
     731                             		.loc 1 90 0
     732 00ef EF 21                   		mov.L	r2, r1
     733                             	.LVL57:
     734 00f1 EF 32                   		mov.L	r3, r2
     735 00f3 02                      		rts
     736                             	.LFE81:
     738                             		.global	__emulu
     740                             	__emulu:
     741                             	.LFB82:
     742                             		.loc 1 91 0
     743                             	.LVL58:
     744                             	.LBB161:
     745                             	.LBB162:
     746                             		.loc 2 1239 0
     747 00f4 FC 1F 12                		emulu	r1, r2
     748                             	.LVL59:
     749                             	.LBE162:
     750                             	.LBE161:
     751                             		.loc 1 91 0
     752 00f7 EF 21                   		mov.L	r2, r1
     753                             	.LVL60:
     754 00f9 EF 32                   		mov.L	r3, r2
     755 00fb 02                      		rts
     756                             	.LFE82:
     758                             		.global	__chg_pmusr
     760                             	__chg_pmusr:
     761                             	.LFB83:
     762                             		.loc 1 92 0
     763                             	.LBB163:
     764                             	.LBB164:
     765                             		.loc 2 1269 0
     766                             	 ; 1269 "../src/CCRXmachine2.h" 1
     767 00fc FD 6A 05                		MVFC PSW, r5
     768 00ff 7D 45                   		BTST #0x14, r5
     769 0101 21 13                   		BNE 3f
     770                             	1:
     771 0103 77 35 00 00 10          		OR #0x00100000, r5
     772 0108 7E A5                   		PUSH.L r5
     773                             	2:
     774 010a FD 6A 15                		MVFC PC, r5
     775 010d 71 55 0A                		ADD #3f-2b, r5
     776 0110 7E A5                   		PUSH.L r5
     777 0112 7F 95                   		RTE
     778                             	3:
     779                             		
     780                             	 ; 0 "" 2
     781                             	.LVL61:
     782 0114 02                      		rts
     783                             	.LBE164:
     784                             	.LBE163:
     785                             	.LFE83:
     787                             		.global	__set_acc
     789                             	__set_acc:
     790                             	.LFB84:
     791                             		.loc 1 93 0
     792                             	.LVL62:
     793                             	.LBB165:
     794                             	.LBB166:
     795                             		.loc 2 1321 0
     796                             	 ; 1321 "../src/CCRXmachine2.h" 1
     797 0115 FD 17 11                		MVTACLO r1
     798 0118 FD 17 02                		MVTACHI r2
     799                             		
     800                             	 ; 0 "" 2
     801 011b 02                      		rts
     802                             	.LBE166:
     803                             	.LBE165:
     804                             	.LFE84:
     806                             		.global	__get_acc
     808                             	__get_acc:
     809                             	.LFB85:
     810                             		.loc 1 94 0
     811                             		.loc 1 94 0
     812                             	 ; 1417 "../src/CCRXmachine2.h" 1
     813 011c FD 1F 21                		MVFACMI r1
     814 011f 6D 01                   		SHLL #0x10, r1
     815 0121 FD 1F 02                		MVFACHI r2
     816                             		
     817                             	 ; 0 "" 2
     818 0124 02                      		rts
     819                             	.LFE85:
     821                             		.global	__setpsw_i
     823                             	__setpsw_i:
     824                             	.LFB86:
     825                             		.loc 1 95 0
     826                             	.LBB167:
     827                             	.LBB168:
     828                             		.loc 2 1512 0
     829                             	 ; 1512 "../src/CCRXmachine2.h" 1
     830 0125 7F A8                   		SETPSW I
     831                             	 ; 0 "" 2
     832 0127 02                      		rts
     833                             	.LBE168:
     834                             	.LBE167:
     835                             	.LFE86:
     837                             		.global	__clrpsw_i
     839                             	__clrpsw_i:
     840                             	.LFB87:
     841                             		.loc 1 96 0
     842                             	.LBB169:
     843                             	.LBB170:
     844                             		.loc 2 1535 0
     845                             	 ; 1535 "../src/CCRXmachine2.h" 1
     846 0128 7F B8                   		CLRPSW I
     847                             	 ; 0 "" 2
     848 012a 02                      		rts
     849                             	.LBE170:
     850                             	.LBE169:
     851                             	.LFE87:
     853                             		.global	__macl
     855                             	__macl:
     856                             	.LFB88:
     857                             		.loc 1 97 0
     858                             	.LVL63:
     859                             	.LBB171:
     860                             	.LBB172:
     861                             		.loc 2 1591 0
     862                             	 ; 1591 "../src/CCRXmachine2.h" 1
     863 012b 61 03                   		CMP #0x00, r3
     864 012d 66 04                   		MOV.L #0x00000000, r4
     865 012f FD 01 44                		MULLO r4, r4
     866 0132 20 33                   		BEQ 6f
     867                             	1:
     868 0134 7C 03                   		BTST #0x00, r3
     869 0136 22 14                   		BGEU 3f
     870                             	2:
     871 0138 60 23                   		SUB #0x02, r3
     872 013a FD 2A 14                		MOV.L [r1+], r4
     873 013d FD 2A 25                		MOV.L [r2+], r5
     874 0140 FD 05 45                		MACLO r4, r5
     875 0143 FD 04 45                		MACHI r4, r5
     876 0146 21 F2                   		BNE 2b
     877 0148 2E 1D                   		BRA 6f
     878                             	3:
     879 014a 60 13                   		SUB #0x01, r3
     880 014c 20 12                   		BEQ 5f
     881                             	4:
     882 014e 60 23                   		SUB #0x02, r3
     883 0150 FD 2A 14                		MOV.L [r1+], r4
     884 0153 FD 2A 25                		MOV.L [r2+], r5
     885 0156 FD 05 45                		MACLO r4, r5
     886 0159 FD 04 45                		MACHI r4, r5
     887 015c 21 F2                   		BNE 4b
     888                             	5:
     889 015e DC 14                   		MOV.W [r1], r4
     890 0160 DC 25                   		MOV.W [r2], r5
     891 0162 FD 05 45                		MACLO r4, r5
     892                             	6:
     893                             		
     894                             	 ; 0 "" 2
     895                             	.LVL64:
     896                             		.loc 2 1634 0
     897                             	 ; 1634 "../src/CCRXmachine2.h" 1
     898 0165 FD 1F 21                		MVFACMI r1
     899                             		
     900                             	 ; 0 "" 2
     901                             	.LVL65:
     902                             	.LBE172:
     903                             	.LBE171:
     904                             		.loc 1 97 0
     905 0168 02                      		rts
     906                             	.LFE88:
     908                             		.global	__macw1
     910                             	__macw1:
     911                             	.LFB89:
     912                             		.loc 1 98 0
     913                             	.LVL66:
     914                             	.LBB173:
     915                             	.LBB174:
     916                             		.loc 2 1720 0
     917                             	 ; 1720 "../src/CCRXmachine2.h" 1
     918 0169 61 03                   		CMP #0x00, r3
     919 016b 66 04                   		MOV.L #0x00000000, r4
     920 016d FD 01 44                		MULLO r4, r4
     921 0170 20 33                   		BEQ 6f
     922                             	1:
     923 0172 7C 03                   		BTST #0x00, r3
     924 0174 22 14                   		BGEU 3f
     925                             	2:
     926 0176 60 23                   		SUB #0x02, r3
     927 0178 FD 2A 14                		MOV.L [r1+], r4
     928 017b FD 2A 25                		MOV.L [r2+], r5
     929 017e FD 05 45                		MACLO r4, r5
     930 0181 FD 04 45                		MACHI r4, r5
     931 0184 21 F2                   		BNE 2b
     932 0186 2E 1D                   		BRA 6f
     933                             	3:
     934 0188 60 13                   		SUB #0x01, r3
     935 018a 20 12                   		BEQ 5f
     936                             	4:
     937 018c 60 23                   		SUB #0x02, r3
     938 018e FD 2A 14                		MOV.L [r1+], r4
     939 0191 FD 2A 25                		MOV.L [r2+], r5
     940 0194 FD 05 45                		MACLO r4, r5
     941 0197 FD 04 45                		MACHI r4, r5
     942 019a 21 F2                   		BNE 4b
     943                             	5:
     944 019c DC 14                   		MOV.W [r1], r4
     945 019e DC 25                   		MOV.W [r2], r5
     946 01a0 FD 05 45                		MACLO r4, r5
     947                             	6:
     948                             		
     949                             	 ; 0 "" 2
     950                             	.LVL67:
     951                             		.loc 2 1763 0
     952                             	 ; 1763 "../src/CCRXmachine2.h" 1
     953 01a3 FD 18 00                		RACW #0x01
     954 01a6 FD 1F 21                		MVFACMI r1
     955                             		
     956                             	 ; 0 "" 2
     957                             	.LVL68:
     958                             	.LBE174:
     959                             	.LBE173:
     960                             		.loc 1 98 0
     961 01a9 DF 11                   		mov.W	r1, r1
     962 01ab 02                      		rts
     963                             	.LFE89:
     965                             		.global	__macw2
     967                             	__macw2:
     968                             	.LFB90:
     969                             		.loc 1 99 0
     970                             	.LVL69:
     971                             	.LBB175:
     972                             	.LBB176:
     973                             		.loc 2 1853 0
     974                             	 ; 1853 "../src/CCRXmachine2.h" 1
     975 01ac 61 03                   		CMP #0x00, r3
     976 01ae 66 04                   		MOV.L #0x00000000, r4
     977 01b0 FD 01 44                		MULLO r4, r4
     978 01b3 20 33                   		BEQ 6f
     979                             	1:
     980 01b5 7C 03                   		BTST #0x00, r3
     981 01b7 22 14                   		BGEU 3f
     982                             	2:
     983 01b9 60 23                   		SUB #0x02, r3
     984 01bb FD 2A 14                		MOV.L [r1+], r4
     985 01be FD 2A 25                		MOV.L [r2+], r5
     986 01c1 FD 05 45                		MACLO r4, r5
     987 01c4 FD 04 45                		MACHI r4, r5
     988 01c7 21 F2                   		BNE 2b
     989 01c9 2E 1D                   		BRA 6f
     990                             	3:
     991 01cb 60 13                   		SUB #0x01, r3
     992 01cd 20 12                   		BEQ 5f
     993                             	4:
     994 01cf 60 23                   		SUB #0x02, r3
     995 01d1 FD 2A 14                		MOV.L [r1+], r4
     996 01d4 FD 2A 25                		MOV.L [r2+], r5
     997 01d7 FD 05 45                		MACLO r4, r5
     998 01da FD 04 45                		MACHI r4, r5
     999 01dd 21 F2                   		BNE 4b
     1000                             	5:
     1001 01df DC 14                   		MOV.W [r1], r4
     1002 01e1 DC 25                   		MOV.W [r2], r5
     1003 01e3 FD 05 45                		MACLO r4, r5
     1004                             	6:
     1005                             		
     1006                             	 ; 0 "" 2
     1007                             	.LVL70:
     1008                             		.loc 2 1896 0
     1009                             	 ; 1896 "../src/CCRXmachine2.h" 1
     1010 01e6 FD 18 10                		RACW #02H
     1011 01e9 FD 1F 21                		MVFACMI r1
     1012                             		
     1013                             	 ; 0 "" 2
     1014                             	.LVL71:
     1015                             	.LBE176:
     1016                             	.LBE175:
     1017                             		.loc 1 99 0
     1018 01ec DF 11                   		mov.W	r1, r1
     1019 01ee 02                      		rts
     1020                             	.LFE90:
     1022                             		.global	__set_extb
     1024                             	__set_extb:
     1025                             	.LFB91:
     1026                             		.loc 1 100 0
     1027                             	.LVL72:
     1028                             	.LBB177:
     1029                             	.LBB178:
     1030                             		.loc 2 1951 0
     1031                             	 ; 1951 "../src/CCRXmachine2.h" 1
     1032 01ef FD 68 1D                		MVTC r1, EXTB
     1033                             	 ; 0 "" 2
     1034 01f2 02                      		rts
     1035                             	.LBE178:
     1036                             	.LBE177:
     1037                             	.LFE91:
     1039                             		.global	__get_extb
     1041                             	__get_extb:
     1042                             	.LFB92:
     1043                             		.loc 1 101 0
     1044                             	.LBB179:
     1045                             	.LBB180:
     1046                             		.loc 2 1977 0
     1047                             	 ; 1977 "../src/CCRXmachine2.h" 1
     1048 01f3 FD 6A D1                		MVFC EXTB, r1
     1049                             	 ; 0 "" 2
     1050                             	.LVL73:
     1051                             	.LBE180:
     1052                             	.LBE179:
     1053                             		.loc 1 101 0
     1054 01f6 02                      		rts
     1055                             	.LFE92:
     1057                             		.section	.text.startup,"ax",@progbits
     1058                             		.global	_main
     1060                             	_main:
     1061                             	.LFB93:
     1062                             		.loc 1 105 0
     1063                             		.balign 8,3,3
     1064                             	.L54:
     1065 0000 2E 00                   		bra	.L54
     1066                             	.LFE93:
     1512                             	.Letext0:
    

     

  • In reply to fujita nozomu:

    自己レス

    > つーか、ただの交換も機能しない罠。

    https://gcc-renesas.com/ja/ で知らぬ間に GCC for Renesas 4.8.4.201803-GNURX Toolchain というのが公開されており(https://gcc-renesas.com/ja/rx-download-toolchains/)、これを早速ダウンロード、インストールしてみたところ、release_notes.pdf に変更点として

    > 3. [Bug-Fix]Fixed the xchgbuiltin function.

    というのがあり、期待して確認してみたところでは

    $ rx-elf-gcc -v
    Using built-in specs.
    COLLECT_GCC=C:\Renesas\e2studio\GCC_for_Renesas_RX_4.8.4.201803-GNURX-ELF\rx-elf\rx-elf\bin\rx-elf-gcc.exe
    COLLECT_LTO_WRAPPER=c:/renesas/e2studio/gcc_for_renesas_rx_4.8.4.201803-gnurx-elf/rx-elf/rx-elf/bin/../libexec/gcc/rx-elf/4.8.4.201803-GNURX/lto-wrapper.exe
    Target: rx-elf
    Configured with: /builder/AutomatedBuilds/rx/builds/2018q3_RX_RC4/rx/source/gcc/configure --target=rx-elf --host=i686-w64-mingw32 --enable-languages=c,c++ --disable-shared --with-newlib --enable-lto --enable-libssp --enable-plugins --enable-gold --disable-libstdcxx-pch --with-pkgversion=GCC_Build_20181126 --prefix=/builder/AutomatedBuilds/rx/builds/2018q3_RX_RC4/rx/rx_win
    Thread model: single
    gcc version 4.8.4.201803-GNURX (GCC_Build_20181126)
    
    $ cat -n xchgTest.c
         1  extern int a, b;
         2
         3  void hoge(void)
         4  {
         5      __builtin_rx_xchg(&a, &b);
         6  }
    
    $ rx-elf-gcc -O2 xchgTest.c -S -o -
            .file   "xchgTest.c"
            .section P,"ax"
            .global _hoge
            .type   _hoge, @function
    _hoge:
            mov.L   #_a, r3
            mov.L   #_b, r5
            mov.L   [r3], r2
            mov.L   [r5], r4
            xchg    r4, r2
            mov.L   r2, [r3]
            mov.L   r4, [r5]
            rts
            .size   _hoge, .-_hoge
            .ident  "GCC: (GCC_Build_20181126) 4.8.4.201803-GNURX"
    
    $ rx-elf-gcc -O0 xchgTest.c -S -o -
            .file   "xchgTest.c"
            .section P,"ax"
            .global _hoge
            .type   _hoge, @function
    _hoge:
            push.l  r6
            mov.L   r0, r6
            mov.L   #_a, r5
            mov.L   [r5], r4
            mov.L   #_b, r5
            mov.L   [r5], r5
            xchg    r5, r4
            mov.L   #_a, r3
            mov.L   r4, [r3]
            mov.L   #_b, r4
            mov.L   r5, [r4]
            rtsd    #4, r6-r6
            .size   _hoge, .-_hoge
            .ident  "GCC: (GCC_Build_20181126) 4.8.4.201803-GNURX"
    
    $
    

    なんと! 交換が機能するようになったようです(ヤッターオメデトーパチパチパチ

    ……ただ、排他制御には使えないし処理としても無駄に xchg 命令が使われてるだけなので価値はないですね。

    # ゲーまた GNU Tools に報告して今度は正しく直してくれたとしても半年後とかかよ。レスポンス悪すぎて気が遠くなるな。

  • In reply to fujita nozomu:

    fujitaさん
    ほやです。
    -O0 指定時のコードだけど、builtin関数を1個しか書かないとhoge関数由来のコードと、builtin関数由来のコードがどこからなのか区別が付きませんが、3つ4つ並べて書いたものを見た限りではbuiltin関数由来のコードが無用に大きいと言う訳でもなさそうです。「無駄に xchg 命令が使われてるだけ」って、どういう意味ですか?(喧嘩売ってるのでなくただ聞いているだけです念のため)

  • In reply to ほや:

    > 「無駄に xchg 命令が使われてるだけ」って、どういう意味ですか?

    `-O2' 版:

    _hoge:
            mov.L   #_a, r3
            mov.L   #_b, r5
            mov.L   [r3], r2
            mov.L   [r5], r4
            xchg    r4, r2
            mov.L   r2r4, [r3]
            mov.L   r4r2, [r5]
            rts
    

    `-O0' 版:

    _hoge:
            push.l  r6
            mov.L   r0, r6
            mov.L   #_a, r5
            mov.L   [r5], r4
            mov.L   #_b, r5
            mov.L   [r5], r5
            xchg    r5, r4
            mov.L   #_a, r3
            mov.L   r4r5, [r3]
            mov.L   #_b, r4r3
            mov.L   r5r4, [r4r3]
            rtsd    #4, r6-r6
    

    無駄に使われてる xchg 命令はない方が良いという意味です。

  • In reply to fujita nozomu:

    fujita nozomuさん
    ほや です。

    なるほど。意図は理解しましたが、そこまではやってくれないのではないかと思います。

    ここから先はGCCが何でできているかの話になってしまうのですが、
    GCCではビルトイン関数をRTLで記述されたinstruction patternとして実装されます。GNURXも同様のはずです。
    参考:https://gcc.gnu.org/onlinedocs/gccint/RTL-Template.html

    C言語部分からビルトイン関数へのパラメータ引き渡しをどうコードに展開するかはGCCに任されるので、そこはビルトイン関数の中身を工夫しても改善はされないでしょう。
    (RTLの書き方で工夫の余地があるかもしれませんが、余計な事やってバグが増えるのも心配…)
    上のコードで言えば、変数から持って来る所と変数に書き戻すコードはビルトイン関数の中身ではなくパラメータ引き渡し部に相当します(最適化で消えるのも中身ではなく引き渡しのコード)。

  • In reply to ほや:

    RTL で最小限のコードで XCHG 命令を記述できれば最適化でおかしくなることもないのでは?

    RTL ではありませんが下記のインラインアセンブラは引数がレジスタで渡されてインライン展開された場合、一つの XCHG 命令になります。

    $ cat -n xchg.c
         1  int xchg(int a, int* b)
         2  {
         3      __asm __volatile(
         4          "xchg    [%1], %0 \n"
         5          : "+r"(a)
         6          : "r"(b)
         7          : "memory"
         8      );
         9      return a;
        10  }
    
    $ rx-elf-gcc -O2 -c xchg.c ; rx-elf-objdump -d xchg.o
    
    xchg.o:     file format elf32-rx-le
    
    
    Disassembly of section P:
    
    00000000 <_xchg>:
       0:   06 a0 10 21                     xchg    [r2].l, r1
       4:   02                              rts
    
    $
    

    これ以上は最適化不能なので最適化の影響もないですね。RTL でも同じようなことは可能では?

    $ cat -n hogera.c
         1  static inline int xchg(int a, int* b) __attribute__((always_inline));
         2  static inline int xchg(int a, int* b)
         3  {
         4      __asm __volatile(
         5          "xchg    [%1], %0 \n"
         6          : "+r"(a)
         7          : "r"(b)
         8          : "memory"
         9      );
        10      return a;
        11  }
        12
        13  extern int a, b;
        14
        15  void inlineAsmXchgTest1(void)
        16  {
        17      a = xchg(a, &b);
        18  }
        19
        20  void builtinRxXchgTest1(void)
        21  {
        22      __builtin_rx_xchg(&a, &b);
        23  }
        24
        25  void inlineAsmXchgTest2(int* a, int* b)
        26  {
        27      *a = xchg(*a, b);
        28  }
        29
        30  void builtinRxXchgTest2(int* a, int* b)
        31  {
        32      __builtin_rx_xchg(a, b);
        33  }
    
    $ rx-elf-gcc -O2 -S hogera.c -o-
            .file   "hogera.c"
            .section P,"ax"
            .global _inlineAsmXchgTest1
            .type   _inlineAsmXchgTest1, @function
    _inlineAsmXchgTest1:
            mov.L   #_a, r4
            mov.L   [r4], r5
            mov.L   #_b, r3
     ; 4 "hogera.c" 1
            xchg    [r3], r5
    
     ; 0 "" 2
            mov.L   r5, [r4]
            rts
            .size   _inlineAsmXchgTest1, .-_inlineAsmXchgTest1
            .global _builtinRxXchgTest1
            .type   _builtinRxXchgTest1, @function
    _builtinRxXchgTest1:
            mov.L   #_a, r3
            mov.L   #_b, r5
            mov.L   [r3], r2
            mov.L   [r5], r4
            xchg    r4, r2
            mov.L   r2, [r3]
            mov.L   r4, [r5]
            rts
            .size   _builtinRxXchgTest1, .-_builtinRxXchgTest1
            .global _inlineAsmXchgTest2
            .type   _inlineAsmXchgTest2, @function
    _inlineAsmXchgTest2:
            mov.L   [r1], r5
     ; 4 "hogera.c" 1
            xchg    [r2], r5
    
     ; 0 "" 2
            mov.L   r5, [r1]
            rts
            .size   _inlineAsmXchgTest2, .-_inlineAsmXchgTest2
            .global _builtinRxXchgTest2
            .type   _builtinRxXchgTest2, @function
    _builtinRxXchgTest2:
            mov.L   [r1], r5
            xchg    [r2].L, r5
            mov.L   r5, [r1]
            rts
            .size   _builtinRxXchgTest2, .-_builtinRxXchgTest2
            .ident  "GCC: (GCC_Build_20181126) 4.8.4.201803-GNURX"
    
    $ rx-elf-gcc -O0 -S hogera.c -o-
            .file   "hogera.c"
            .section P,"ax"
            .global _inlineAsmXchgTest1
            .type   _inlineAsmXchgTest1, @function
    _inlineAsmXchgTest1:
            push.l  r6
            add     #-8, r0, r6
            mov.L   r6, r0
            mov.L   #_a, r5
            mov.L   [r5], r5
            mov.L   r5, [r6]
            mov.L   #_b, 4[r6]
            mov.L   4[r6], r4
            mov.L   [r6], r5
     ; 4 "hogera.c" 1
            xchg    [r4], r5
    
     ; 0 "" 2
            mov.L   r5, [r6]
            mov.L   [r6], r5
            mov.L   r5, r4
            mov.L   #_a, r5
            mov.L   r4, [r5]
            rtsd    #12, r6-r6
            .size   _inlineAsmXchgTest1, .-_inlineAsmXchgTest1
            .global _builtinRxXchgTest1
            .type   _builtinRxXchgTest1, @function
    _builtinRxXchgTest1:
            push.l  r6
            mov.L   r0, r6
            mov.L   #_a, r5
            mov.L   [r5], r4
            mov.L   #_b, r5
            mov.L   [r5], r5
            xchg    r5, r4
            mov.L   #_a, r3
            mov.L   r4, [r3]
            mov.L   #_b, r4
            mov.L   r5, [r4]
            rtsd    #4, r6-r6
            .size   _builtinRxXchgTest1, .-_builtinRxXchgTest1
            .global _inlineAsmXchgTest2
            .type   _inlineAsmXchgTest2, @function
    _inlineAsmXchgTest2:
            push.l  r6
            add     #-16, r0, r6
            mov.L   r6, r0
            mov.L   r1, 8[r6]
            mov.L   r2, 12[r6]
            mov.L   8[r6], r5
            mov.L   [r5], r5
            mov.L   r5, [r6]
            mov.L   12[r6], r5
            mov.L   r5, 4[r6]
            mov.L   4[r6], r4
            mov.L   [r6], r5
     ; 4 "hogera.c" 1
            xchg    [r4], r5
    
     ; 0 "" 2
            mov.L   r5, [r6]
            mov.L   [r6], r5
            mov.L   r5, r4
            mov.L   8[r6], r5
            mov.L   r4, [r5]
            rtsd    #20, r6-r6
            .size   _inlineAsmXchgTest2, .-_inlineAsmXchgTest2
            .global _builtinRxXchgTest2
            .type   _builtinRxXchgTest2, @function
    _builtinRxXchgTest2:
            push.l  r6
            add     #-8, r0, r6
            mov.L   r6, r0
            mov.L   r1, [r6]
            mov.L   r2, 4[r6]
            mov.L   [r6], r5
            mov.L   [r5], r4
            mov.L   4[r6], r5
            mov.L   [r5], r5
            xchg    r5, r4
            mov.L   [r6], r3
            mov.L   r4, [r3]
            mov.L   4[r6], r4
            mov.L   r5, [r4]
            rtsd    #12, r6-r6
            .size   _builtinRxXchgTest2, .-_builtinRxXchgTest2
            .ident  "GCC: (GCC_Build_20181126) 4.8.4.201803-GNURX"
    
    $
    
  • In reply to fujita nozomu:

    fujita nozomuさん
    ほや です。

    >RTL で最小限のコードで XCHG 命令を記述できれば最適化でおかしくなることもないのでは?
    RTL(instruction pattern)の中には最適化は及びません。
    修正前後のコードを比較した限りでの推測ですが、最適化で問題が出たのは渡されたパラメータに書き戻す手順をRTLの中で記述していなかったからだと思います。

    > RTL でも同じようなことは可能では?
    可能ではあるでしょう。
    RTLの記述で明示的にレジスタ渡しやアドレス渡しに限定するなど、渡されたパラメータの属性毎に書き分けをすれば出力コードはもっと短くなると思います。
    (書き分け方はこの辺にも書いてあります。難しそう→ https://gcc.gnu.org/onlinedocs/gccint/Expander-Definitions.html)
    しかしそういう事をやり始めると書き分けのケースから漏れたパターンは正しく処理されないし、他のinstruction patternも同じようにしなきゃならなくなったり、なんだか大変な事になりそうな気がします。
    「頑張ってみたけど、最適化に任せた方がマシだった」という結果になるかも。

Top Page [◀◀]  2   3   4   5   6   7   8   9   ... [▶▶Last Page