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



Parents
  • こんにちは。NoMaYです。

    別スレッド『Amazon FreeRTOSだそうです。ルネサスさんのRXは参加しないのかな?』でCC-RX用プロジェクトをGNURX用プロジェクトへ移植する際に作ろうと考えていたCCRXmachine2.hの作業を始めようとして気付きましたが、前の投稿のchg_pmusr()関数の他にCC-RXの特殊なビルトイン関数としてint_exception()関数がありました。

    このint_exception()関数はCC-RXで以下のような記述をするとエラーになります。

    void my_int_exception(signed long num);

    void my_int_exception(signed long num)
    {
        int_exception(num);
    }
    F0544802:The value of the parameter for the in-line function is outside the defined range.

    これは、作ろうとしているCCRXmachine2.hでは、以下のようなマクロにするしかないかなと考えています。

    #define int_exception( num ) _int_exception_cpp_step2( num )
    #define _int_exception_cpp_step2( num ) do{ __asm __volatile ("INT #" #num); } while(0)

    理由は、以下の通り、INT命令のオペランドに割り込み番号をイミディエート値で指定する必要があるからです。

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


    ちなみに、コメントアウトされていますが、GNURX対応のCCRXmachine.cでも以下の記述が見られ、特殊である予感はしていました。

    /*略
    #define INTN(N)\
        case N:\
            __builtin_rx_int(N);

    #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 int_exception(signed long num)
    {
        switch(num)
        {
        INTN50(0)
        INTN50(50)
        INTN50(100)
        INTN50(150)
        INTN50(200)
        INTN5(250)
        INTN(255)
        default:
            __builtin_rx_int(255);
        }
    }
    略*/

     ところで、CCRXmachine2.hの作業の手始めとして、以下のCソースをCC-RX V2.03でコンパイルしてアセンブラソースを出力させてみました。

    CCRX_machine_h.c

    4666.CCRX_machine_h_c_20180608.txt
    #include <machine.h>
    
    /*
     * https://www.renesas.com/ja-jp/doc/products/tool/doc/011/r20ut3248jj0105-ccrx.pdf
     * 表4.26 (356頁 ~ 359頁 / 全970頁)
     */
    void _dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_(void) { ;                                                 }
    signed long        _max(signed long data1, signed long data2)                                          { return _builtin_max(data1, data2);                }
    signed long        _min(signed long data1, signed long data2)                                          { return _builtin_min(data1, data2);                }
    unsigned long      _revl(unsigned long data)                                                           { return _builtin_revl(data);                       }
    unsigned long      _revw(unsigned long data)                                                           { return _builtin_revw(data);                       }
    void               _xchg(signed long *data1, signed long *data2)                                       {        _builtin_xchg(data1, data2);               }
    long long          _rmpab(long long init, unsigned long count, signed char *addr1, signed char *addr2) { return _builtin_rmpab(init, count, addr1, addr2); }
    long long          _rmpaw(long long init, unsigned long count, short *addr1, short *addr2)             { return _builtin_rmpaw(init, count, addr1, addr2); }
    long long          _rmpal(long long init, unsigned long count, long *addr1, long *addr2)               { return _builtin_rmpal(init, count, addr1, addr2); }
    unsigned long      _rolc(unsigned long data)                                                           { return _builtin_rolc(data);                       }
    unsigned long      _rorc(unsigned long data)                                                           { return _builtin_rorc(data);                       }
    unsigned long      _rotl(unsigned long data, unsigned long num)                                        { return _builtin_rotl(data, num);                  }
    unsigned long      _rotr(unsigned long data, unsigned long num)                                        { return _builtin_rotr(data, num);                  }
    void               _brk(void)                                                                          {        _builtin_brk();                            }
    // void               _int_exception(signed long num)                                                     {        _builtin_int_exception(num);               }
    // F0544802:The value of the parameter for the in-line function is outside the defined range.
    void               _wait(void)                                                                         {        _builtin_wait();                           }
    void               _nop(void)                                                                          {        _builtin_nop();                            }
    void               _set_ipl(signed long level)                                                         {        _builtin_set_ipl(level);                   }
    unsigned char      _get_ipl(void)                                                                      { return _builtin_get_ipl();                        }
    void               _set_psw(unsigned long data)                                                        {        _builtin_set_psw(data);                    }
    unsigned long      _get_psw(void)                                                                      { return _builtin_get_psw();                        }
    void               _set_fpsw(unsigned long data)                                                       {        _builtin_set_fpsw(data);                   }
    unsigned long      _get_fpsw(void)                                                                     { return _builtin_get_fpsw();                       }
    void               _set_usp(void *data)                                                                {        _builtin_set_usp(data);                    }
    void *             _get_usp(void)                                                                      { return _builtin_get_usp();                        }
    void               _set_isp(void *data)                                                                {        _builtin_set_isp(data);                    }
    void *             _get_isp(void)                                                                      { return _builtin_get_isp();                        }
    void               _set_intb(void *data)                                                               {        _builtin_set_intb(data);                   }
    void *             _get_intb(void)                                                                     { return _builtin_get_intb();                       }
    void               _set_bpsw(unsigned long data)                                                       {        _builtin_set_bpsw(data);                   }
    unsigned long      _get_bpsw(void)                                                                     { return _builtin_get_bpsw();                       }
    void               _set_bpc(void *data)                                                                {        _builtin_set_bpc(data);                    }
    void *             _get_bpc(void)                                                                      { return _builtin_get_bpc();                        }
    void               _set_fintv(void *data)                                                              {        _builtin_set_fintv(data);                  }
    void *             _get_fintv(void)                                                                    { return _builtin_get_fintv();                      }
    signed long long   _emul(signed long data1, signed long data2)                                         { return _builtin_emul(data1, data2);               }
    unsigned long long _emulu(unsigned long data1, unsigned long data2)                                    { return _builtin_emulu(data1, data2);              }
    short              _macw1(short *data1, short *data2, unsigned long count)                             { return _builtin_macw1(data1, data2, count);       }
    short              _macw2(short *data1, short *data2, unsigned long count)                             { return _builtin_macw2(data1, data2, count);       }
    long               _macl(short *data1, short *data2, unsigned long count)                              { return _builtin_macl(data1, data2, count);        }
    void               _chg_pmusr(void)                                                                    {        _builtin_chg_pmusr();                      }
    void               _set_acc(signed long long data)                                                     {        _builtin_set_acc(data);                    }
    signed long long   _get_acc(void)                                                                      { return _builtin_get_acc();                        }
    void               _setpsw_i(void)                                                                     {        _builtin_setpsw_i();                       }
    void               _clrpsw_i(void)                                                                     {        _builtin_clrpsw_i();                       }
    void               _set_extb(void *data)                                                               {        _builtin_set_extb(data);                   }
    void *             _get_extb(void)                                                                     { return _builtin_get_extb();                       }
    
    /*
     * 表4.26の最後の3項目 (CC-RX V2.05 or later)
     */
    #if __RENESAS_VERSION__ >= 0x02050000
    void _dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy2(void) { ;                                                 }
    void               _bclr(unsigned char *data, unsigned long bit)                                       {        __bclr(data, bit);                         }
    void               _bnot(unsigned char *data, unsigned long bit)                                       {        __bnot(data, bit);                         }
    void               _bset(unsigned char *data, unsigned long bit)                                       {        __bset(data, bit);                         }
    #endif
    


    CCRX_machine_h.src
    4010.CCRX_machine_h_src_20180608.txt
    ;RX Family C/C++ Compiler (V2.03.00.03 [04 Dec 2014])  08-Jun-2018 18:56:32
    
    ;*** CPU TYPE ***
    
    ;-ISA=RXV2
    
    ;*** COMMAND PARAMETER ***
    
    ;-output=src=CCRX_machine_h.src
    ;-isa=rxv2
    ;-fpu
    ;-include=C:\Renesas\CS_~1\CC\CC-RX\V203~1.00\include,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\generate
    ;-lang=c
    ;-nomessage
    ;-obj_path=src
    ;-debug
    ;-listfile=src/CCRX_machine_h.lst
    ;-show=source,conditionals,definitions,expansions
    ;-asm_path=src
    ;-nologo
    ;CCRX_machine_h.c
    
    		.glb	__dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_
    		.glb	__max
    		.glb	__min
    		.glb	__revl
    		.glb	__revw
    		.glb	__xchg
    		.glb	__rmpab
    		.glb	__rmpaw
    		.glb	__rmpal
    		.glb	__rolc
    		.glb	__rorc
    		.glb	__rotl
    		.glb	__rotr
    		.glb	__brk
    		.glb	__wait
    		.glb	__nop
    		.glb	__set_ipl
    		.glb	__get_ipl
    		.glb	__set_psw
    		.glb	__get_psw
    		.glb	__set_fpsw
    		.glb	__get_fpsw
    		.glb	__set_usp
    		.glb	__get_usp
    		.glb	__set_isp
    		.glb	__get_isp
    		.glb	__set_intb
    		.glb	__get_intb
    		.glb	__set_bpsw
    		.glb	__get_bpsw
    		.glb	__set_bpc
    		.glb	__get_bpc
    		.glb	__set_fintv
    		.glb	__get_fintv
    		.glb	__emul
    		.glb	__emulu
    		.glb	__macw1
    		.glb	__macw2
    		.glb	__macl
    		.glb	__chg_pmusr
    		.glb	__set_acc
    		.glb	__get_acc
    		.glb	__setpsw_i
    		.glb	__clrpsw_i
    		.glb	__set_extb
    		.glb	__get_extb
    ;LineNo. C-SOURCE STATEMENT
    
    		.SECTION	P,CODE
    __dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_:
    		.STACK	__dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_=4
    ;       1 #include <machine.h>
    ;       2 
    ;       3 /*
    ;       4  * https://www.renesas.com/ja-jp/doc/products/tool/doc/011/r20ut3248jj0105-ccrx.pdf
    ;       5  * 表4.26 (356頁 ~ 359頁 / 全970頁)
    ;       6  */
    ;       7 void _dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_(void) { ;                                                 }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",7
    		RTS
    __max:
    		.STACK	__max=4
    ;       8 signed long        _max(signed long data1, signed long data2)                                          { return _builtin_max(data1, data2);                }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",8
    		MAX R2, R1
    		RTS
    __min:
    		.STACK	__min=4
    ;       9 signed long        _min(signed long data1, signed long data2)                                          { return _builtin_min(data1, data2);                }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",9
    		MIN R2, R1
    		RTS
    __revl:
    		.STACK	__revl=4
    ;      10 unsigned long      _revl(unsigned long data)                                                           { return _builtin_revl(data);                       }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",10
    		REVL R1, R1
    		RTS
    __revw:
    		.STACK	__revw=4
    ;      11 unsigned long      _revw(unsigned long data)                                                           { return _builtin_revw(data);                       }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",11
    		REVW R1, R1
    		RTS
    __xchg:
    		.STACK	__xchg=4
    ;      12 void               _xchg(signed long *data1, signed long *data2)                                       {        _builtin_xchg(data1, data2);               }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",12
    		MOV.L [R1], R14
    		XCHG [R2].L, R14
    		MOV.L R14, [R1]
    		RTS
    __rmpab:
    		.STACK	__rmpab=8
    ;      13 long long          _rmpab(long long init, unsigned long count, signed char *addr1, signed char *addr2) { return _builtin_rmpab(init, count, addr1, addr2); }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",13
    		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
    __rmpaw:
    		.STACK	__rmpaw=8
    ;      14 long long          _rmpaw(long long init, unsigned long count, short *addr1, short *addr2)             { return _builtin_rmpaw(init, count, addr1, addr2); }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",14
    		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
    __rmpal:
    		.STACK	__rmpal=8
    ;      15 long long          _rmpal(long long init, unsigned long count, long *addr1, long *addr2)               { return _builtin_rmpal(init, count, addr1, addr2); }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",15
    		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
    __rolc:
    		.STACK	__rolc=4
    ;      16 unsigned long      _rolc(unsigned long data)                                                           { return _builtin_rolc(data);                       }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",16
    		ROLC R1
    		RTS
    __rorc:
    		.STACK	__rorc=4
    ;      17 unsigned long      _rorc(unsigned long data)                                                           { return _builtin_rorc(data);                       }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",17
    		RORC R1
    		RTS
    __rotl:
    		.STACK	__rotl=4
    ;      18 unsigned long      _rotl(unsigned long data, unsigned long num)                                        { return _builtin_rotl(data, num);                  }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",18
    		ROTL R2, R1
    		RTS
    __rotr:
    		.STACK	__rotr=4
    ;      19 unsigned long      _rotr(unsigned long data, unsigned long num)                                        { return _builtin_rotr(data, num);                  }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",19
    		ROTR R2, R1
    		RTS
    __brk:
    		.STACK	__brk=4
    ;      20 void               _brk(void)                                                                          {        _builtin_brk();                            }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",20
    		BRK
    		RTS
    __wait:
    		.STACK	__wait=4
    ;      21 // void               _int_exception(signed long num)                                                     {        _builtin_int_exception(num);               }
    ;      22 // F0544802:The value of the parameter for the in-line function is outside the defined range.
    ;      23 void               _wait(void)                                                                         {        _builtin_wait();                           }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",23
    		WAIT
    		RTS
    __nop:
    		.STACK	__nop=4
    ;      24 void               _nop(void)                                                                          {        _builtin_nop();                            }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",24
    		NOP
    		RTS
    __set_ipl:
    		.STACK	__set_ipl=4
    ;      25 void               _set_ipl(signed long level)                                                         {        _builtin_set_ipl(level);                   }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",25
    		MVFC PSW, R14
    		SHLL #1CH, R1
    		SHLR #04H, R1
    		AND #0F0FFFFFFH, R14
    		OR R14, R1
    		MVTC R1, PSW
    		RTS
    __get_ipl:
    		.STACK	__get_ipl=4
    ;      26 unsigned char      _get_ipl(void)                                                                      { return _builtin_get_ipl();                        }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",26
    		MVFC PSW, R14
    		REVL R14, R1
    		AND #0FH, R1
    		RTS
    __set_psw:
    		.STACK	__set_psw=4
    ;      27 void               _set_psw(unsigned long data)                                                        {        _builtin_set_psw(data);                    }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",27
    		MVTC R1, PSW
    		RTS
    __get_psw:
    		.STACK	__get_psw=4
    ;      28 unsigned long      _get_psw(void)                                                                      { return _builtin_get_psw();                        }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",28
    		MVFC PSW, R1
    		RTS
    __set_fpsw:
    		.STACK	__set_fpsw=4
    ;      29 void               _set_fpsw(unsigned long data)                                                       {        _builtin_set_fpsw(data);                   }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",29
    		MVTC R1, FPSW
    		RTS
    __get_fpsw:
    		.STACK	__get_fpsw=4
    ;      30 unsigned long      _get_fpsw(void)                                                                     { return _builtin_get_fpsw();                       }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",30
    		MVFC FPSW, R1
    		RTS
    __set_usp:
    		.STACK	__set_usp=4
    ;      31 void               _set_usp(void *data)                                                                {        _builtin_set_usp(data);                    }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",31
    		MVTC R1, USP
    		RTS
    __get_usp:
    		.STACK	__get_usp=4
    ;      32 void *             _get_usp(void)                                                                      { return _builtin_get_usp();                        }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",32
    		MVFC USP, R1
    		RTS
    __set_isp:
    		.STACK	__set_isp=4
    ;      33 void               _set_isp(void *data)                                                                {        _builtin_set_isp(data);                    }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",33
    		MVTC R1, ISP
    		RTS
    __get_isp:
    		.STACK	__get_isp=4
    ;      34 void *             _get_isp(void)                                                                      { return _builtin_get_isp();                        }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",34
    		MVFC ISP, R1
    		RTS
    __set_intb:
    		.STACK	__set_intb=4
    ;      35 void               _set_intb(void *data)                                                               {        _builtin_set_intb(data);                   }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",35
    		MVTC R1, INTB
    		RTS
    __get_intb:
    		.STACK	__get_intb=4
    ;      36 void *             _get_intb(void)                                                                     { return _builtin_get_intb();                       }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",36
    		MVFC INTB, R1
    		RTS
    __set_bpsw:
    		.STACK	__set_bpsw=4
    ;      37 void               _set_bpsw(unsigned long data)                                                       {        _builtin_set_bpsw(data);                   }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",37
    		MVTC R1, BPSW
    		RTS
    __get_bpsw:
    		.STACK	__get_bpsw=4
    ;      38 unsigned long      _get_bpsw(void)                                                                     { return _builtin_get_bpsw();                       }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",38
    		MVFC BPSW, R1
    		RTS
    __set_bpc:
    		.STACK	__set_bpc=4
    ;      39 void               _set_bpc(void *data)                                                                {        _builtin_set_bpc(data);                    }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",39
    		MVTC R1, BPC
    		RTS
    __get_bpc:
    		.STACK	__get_bpc=4
    ;      40 void *             _get_bpc(void)                                                                      { return _builtin_get_bpc();                        }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",40
    		MVFC BPC, R1
    		RTS
    __set_fintv:
    		.STACK	__set_fintv=4
    ;      41 void               _set_fintv(void *data)                                                              {        _builtin_set_fintv(data);                  }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",41
    		MVTC R1, FINTV
    		RTS
    __get_fintv:
    		.STACK	__get_fintv=4
    ;      42 void *             _get_fintv(void)                                                                    { return _builtin_get_fintv();                      }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",42
    		MVFC FINTV, R1
    		RTS
    __emul:
    		.STACK	__emul=4
    ;      43 signed long long   _emul(signed long data1, signed long data2)                                         { return _builtin_emul(data1, data2);               }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",43
    		MOV.L R1, R4
    		EMUL R2, R4
    		MOV.L R5, R2
    		MOV.L R4, R1
    		RTS
    __emulu:
    		.STACK	__emulu=4
    ;      44 unsigned long long _emulu(unsigned long data1, unsigned long data2)                                    { return _builtin_emulu(data1, data2);              }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",44
    		MOV.L R1, R4
    		EMULU R2, R4
    		MOV.L R5, R2
    		MOV.L R4, R1
    		RTS
    __macw1:
    		.STACK	__macw1=4
    ;      45 short              _macw1(short *data1, short *data2, unsigned long count)                             { return _builtin_macw1(data1, data2, count);       }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",45
    		CMP #00H, R3
    		MOV.L #00000000H, R14
    		MULLO R14, R14
    		BEQ L52
    L47:	; entry
    		BTST #00H, R3
    		BGEU L49
    L48:	; entry
    		SUB #02H, R3
    		MOV.L [R1+], R14
    		MOV.L [R2+], R5
    		MACLO R14, R5
    		MACHI R14, R5
    		BNE L48
    		BRA L52
    L49:	; entry
    		SUB #01H, R3
    		BEQ L51
    L50:	; entry
    		SUB #02H, R3
    		MOV.L [R1+], R14
    		MOV.L [R2+], R5
    		MACLO R14, R5
    		MACHI R14, R5
    		BNE L50
    L51:	; entry
    		MOV.W [R1], R14
    		MOV.W [R2], R5
    		MACLO R14, R5
    L52:	; entry
    		RACW #01H
    		MVFACHI R1
    		RTS
    __macw2:
    		.STACK	__macw2=4
    ;      46 short              _macw2(short *data1, short *data2, unsigned long count)                             { return _builtin_macw2(data1, data2, count);       }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",46
    		CMP #00H, R3
    		MOV.L #00000000H, R14
    		MULLO R14, R14
    		BEQ L59
    L54:	; entry
    		BTST #00H, R3
    		BGEU L56
    L55:	; entry
    		SUB #02H, R3
    		MOV.L [R1+], R14
    		MOV.L [R2+], R5
    		MACLO R14, R5
    		MACHI R14, R5
    		BNE L55
    		BRA L59
    L56:	; entry
    		SUB #01H, R3
    		BEQ L58
    L57:	; entry
    		SUB #02H, R3
    		MOV.L [R1+], R14
    		MOV.L [R2+], R5
    		MACLO R14, R5
    		MACHI R14, R5
    		BNE L57
    L58:	; entry
    		MOV.W [R1], R14
    		MOV.W [R2], R5
    		MACLO R14, R5
    L59:	; entry
    		RACW #02H
    		MVFACHI R1
    		RTS
    __macl:
    		.STACK	__macl=4
    ;      47 long               _macl(short *data1, short *data2, unsigned long count)                              { return _builtin_macl(data1, data2, count);        }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",47
    		CMP #00H, R3
    		MOV.L #00000000H, R14
    		MULLO R14, R14
    		BEQ L66
    L61:	; entry
    		BTST #00H, R3
    		BGEU L63
    L62:	; entry
    		SUB #02H, R3
    		MOV.L [R1+], R14
    		MOV.L [R2+], R5
    		MACLO R14, R5
    		MACHI R14, R5
    		BNE L62
    		BRA L66
    L63:	; entry
    		SUB #01H, R3
    		BEQ L65
    L64:	; entry
    		SUB #02H, R3
    		MOV.L [R1+], R14
    		MOV.L [R2+], R5
    		MACLO R14, R5
    		MACHI R14, R5
    		BNE L64
    L65:	; entry
    		MOV.W [R1], R14
    		MOV.W [R2], R5
    		MACLO R14, R5
    L66:	; entry
    		MVFACMI R1
    		RTS
    __chg_pmusr:
    		.STACK	__chg_pmusr=12
    ;      48 void               _chg_pmusr(void)                                                                    {        _builtin_chg_pmusr();                      }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",48
    		MVFC PSW, R14
    		BTST #14H, R14
    		BNE L69
    L68:	; entry
    		OR #00100000H, R14
    		PUSH.L R14
    L70:
    		MVFC PC, R14
    		ADD #L69-L70, R14
    		PUSH.L R14
    		RTE
    L69:	; entry
    		RTS
    __set_acc:
    		.STACK	__set_acc=4
    ;      49 void               _set_acc(signed long long data)                                                     {        _builtin_set_acc(data);                    }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",49
    		MVTACLO R1
    		MVTACHI R2
    		RTS
    __get_acc:
    		.STACK	__get_acc=4
    ;      50 signed long long   _get_acc(void)                                                                      { return _builtin_get_acc();                        }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",50
    		MVFACMI R1
    		SHLL #10H, R1
    		MVFACHI R2
    		RTS
    __setpsw_i:
    		.STACK	__setpsw_i=4
    ;      51 void               _setpsw_i(void)                                                                     {        _builtin_setpsw_i();                       }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",51
    		SETPSW I
    		RTS
    __clrpsw_i:
    		.STACK	__clrpsw_i=4
    ;      52 void               _clrpsw_i(void)                                                                     {        _builtin_clrpsw_i();                       }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",52
    		CLRPSW I
    		RTS
    __set_extb:
    		.STACK	__set_extb=4
    ;      53 void               _set_extb(void *data)                                                               {        _builtin_set_extb(data);                   }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",53
    		MVTC R1, EXTB
    		RTS
    __get_extb:
    		.STACK	__get_extb=4
    ;      54 void *             _get_extb(void)                                                                     { return _builtin_get_extb();                       }
    		.LINE  "C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRX_machine_h\src\CCRX_machine_h.c",54
    		MVFC EXTB, R1
    		RTS
    ;      55 
    ;      56 /*
    ;      57  * 表4.26の最後の3項目 (CC-RX V2.05 or later)
    ;      58  */
    ;      59 #if __RENESAS_VERSION__ >= 0x02050000
    ;      60 void _dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy_dummy2(void) { ;                                                 }
    ;      61 void               _bclr(unsigned char *data, unsigned long bit)                                       {        __bclr(data, bit);                         }
    ;      62 void               _bnot(unsigned char *data, unsigned long bit)                                       {        __bnot(data, bit);                         }
    ;      63 void               _bset(unsigned char *data, unsigned long bit)                                       {        __bset(data, bit);                         }
    ;      64 #endif
    		.END
    


    思うに、無用なバグ混入を防止する為、そもそもこういう仕事は以下のような作業をすると良かったのかな、という気がしないこともないような気がしました、、、

    ・CC-RXの開発チームにビルトイン関数のアセンブラソースを貰えないか相談する
    (貰えなかったら上のようにCC-RXでアセンブラソースを出力させる)
    ・引数と戻り値の規約をGNURXに合わせる
    ・インライン展開の記法に合わせる
    [追記]
    ・コード生成機能のr_cg_macrodriver.h(ここでnop(), brk(), wait()が#defineされている)との整合を図る

  • ちなみに、コメントアウトされていますが、

    成る程、こういう書き方もできるのか。勉強になるな。

    #define INTN(N)\
        case N:\
            __asm __volatile("INT #" #N "\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)
    
    #define int_exception( num ) _int_exception_cpp_step2( num )
    #define _int_exception_cpp_step2( num ) \
    do { \
        if (__builtin_constant_p(num)) { \
            __asm __volatile("INT %0 \n"::"i"(num)); \
        } else { \
            switch (num) { \
            INTN50(0) \
            INTN50(50) \
            INTN50(100) \
            INTN50(150) \
            INTN50(200) \
            INTN5(250) \
            INTN(255) \
            default: \
                __asm __volatile("INT #255\n"); break; \
            } \
        } \
    } while (0);
    
  • 自己書き換えコードで行けるのかな?

    $ cat -n intexception.c
         1  #include 
         2
         3  #define int_exception( num ) _int_exception_cpp_step2( num )
         4  #define _int_exception_cpp_step2( num ) \
         5  do { \
         6      if (__builtin_constant_p(num)) { \
         7          __asm __volatile("INT %0 \n"::"i"(num)); \
         8      } else { \
         9          volatile uint8_t int_rts[] = {0x75, 0x60, num, 0x02}; \
        10          ((void (*)(void))int_rts)(); \
        11      } \
        12  } while (0);
        13
        14  void hoge(void)
        15  {
        16      int_exception(0);
        17      int_exception(1);
        18      int_exception(2);
        19      int_exception(255);
        20      int num = 123;
        21      int_exception(num);
        22      extern int ext;
        23      int_exception(ext);
        24  }
    
    $ rx-elf-gcc -Wall -Wextra -O2 intexception.c -S -o -
            .file   "intexception.c"
            .section P,"ax"
            .global _hoge
            .type   _hoge, @function
    _hoge:
            sub     #4, r0
     ; 16 "intexception.c" 1
            INT #0
    
     ; 0 "" 2
     ; 17 "intexception.c" 1
            INT #1
    
     ; 0 "" 2
     ; 18 "intexception.c" 1
            INT #2
    
     ; 0 "" 2
     ; 19 "intexception.c" 1
            INT #0xff
    
     ; 0 "" 2
     ; 21 "intexception.c" 1
            INT #0x7b
    
     ; 0 "" 2
            mov.L   #_ext, r5
            movu.B  [r5], r5
            shll    #16, r5
            or      #0x2006075, r5
            mov.L   r5, [r0]
            jsr     r0
            rtsd    #4
            .size   _hoge, .-_hoge
            .ident  "GCC: (GCC_Build_20180316) 4.8.4.201801-GNURX"
    
    $
  • fujitaさん、こんにちは。NoMaYです。

    アドバイス、どうも有難う御座います。デフォルトで変数時に自己書き換えコード、オプションで変数時に関数呼び出しコード、いずれも定数時は__builtin_rx_int()関数、としてみようと思います。オプションを用意する理由は、自己書き換えコードをスタック上で実行する方式はリエントラント性の点から良いと思ったのですが、以前にメモリプロテクションユニットに関して色々と投稿した身としては、このことでスタック領域全域に実行許可属性を付けないといけなくなってしまうのが気になってしまったからです。あと、コードを書いて気付いたのですが、そういえば__builtin_rx_int()関数があるのだから素朴に使えば良いよな、と我ながら思いました。今、こんな感じに書いています。

    #ifdef DONT_EXECUTE_RX_INT_INSTRUCTION_ON_STACK

    void int_exception_switch_case_function(signed long num);

    #define int_exception(num) \
    do { \
        if (__builtin_constant_p(num)) { \
            __builtin_rx_int(num); \
        } else { \
            int_exception_switch_case_function(num); \
        } \
    } while (0)

    #else /* DONT_EXECUTE_RX_INT_INSTRUCTION_ON_STACK */

    #define 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 */

     

Reply
  • fujitaさん、こんにちは。NoMaYです。

    アドバイス、どうも有難う御座います。デフォルトで変数時に自己書き換えコード、オプションで変数時に関数呼び出しコード、いずれも定数時は__builtin_rx_int()関数、としてみようと思います。オプションを用意する理由は、自己書き換えコードをスタック上で実行する方式はリエントラント性の点から良いと思ったのですが、以前にメモリプロテクションユニットに関して色々と投稿した身としては、このことでスタック領域全域に実行許可属性を付けないといけなくなってしまうのが気になってしまったからです。あと、コードを書いて気付いたのですが、そういえば__builtin_rx_int()関数があるのだから素朴に使えば良いよな、と我ながら思いました。今、こんな感じに書いています。

    #ifdef DONT_EXECUTE_RX_INT_INSTRUCTION_ON_STACK

    void int_exception_switch_case_function(signed long num);

    #define int_exception(num) \
    do { \
        if (__builtin_constant_p(num)) { \
            __builtin_rx_int(num); \
        } else { \
            int_exception_switch_case_function(num); \
        } \
    } while (0)

    #else /* DONT_EXECUTE_RX_INT_INSTRUCTION_ON_STACK */

    #define 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 */

     

Children
No Data