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
  • GNURX の __builtin_rx_xchg() を確認してみましたが

     $ 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 -v
    Using built-in specs.
    COLLECT_GCC=C:\Renesas\e2studio\GCC for Renesas RX 4.8.4.201801-GNURX-ELF\rx-elf\rx-elf\bin\rx-elf-gcc.exe
    COLLECT_LTO_WRAPPER=c:/renesas/e2studio/gcc\ for\ renesas\ rx\ 4.8.4.201801-gnurx-elf/rx-elf/rx-elf/bin/../libexec/gcc/rx-elf/4.8.4.201801-GNURX/lto-wrapper.exe
    Target: rx-elf
    Configured with: /builder/AutomatedBuilds/rx/builds/2018q1_RX_RC3/rx/source/gcc/configure --target=rx-elf --host=i586-mingw32msvc --enable-languages=c,c++ --disable-shared --with-newlib --enable-lto --enable-libssp --enable-plugins --enable-gold --disable-libstdcxx-pch --with-pkgversion=GCC_Build_20180316 --prefix=/builder/AutomatedBuilds/rx/builds/2018q1_RX_RC3/rx/rx_win
    Thread model: single
    gcc version 4.8.4.201801-GNURX (GCC_Build_20180316)
    
    $ rx-elf-gcc -O2 xchgTest.c -S -o -
            .file   "xchgTest.c"
            .section P,"ax"
            .global _hoge
            .type   _hoge, @function
    _hoge:
            mov.L   #_a, r2
            mov.L   [r2], r3
            mov.L   #_b, r5
            mov.L   [r5], r4
            mov.L   r3, [r2]
            xchg    r4, r3
            mov.L   r4, [r5]
            rts
            .size   _hoge, .-_hoge
            .ident  "GCC: (GCC_Build_20180316) 4.8.4.201801-GNURX"
    
    $   
    

    ちょっと排他制御には使えない感じですね。

  • こんにちは。NoMaYです。

    fujita nozomu said:
    ちょっと排他制御には使えない感じですね。

    幾つか前の私の投稿で引用したGNURXのGCCの__builtin_rx_xchg()関数のソースですが、if節の方が気になりましたので、CC-RXの場合のRTOS対応版FITのBSPモジュールとCMT_RXモジュールから以下のようにコードを抜き出してコンパイル(-O2)してみると、__builtin_rx_xchg()関数でセマフォのロックに使用出来る命令列が生成されていました。(とはいえ、複雑難解な最適化処理との兼ね合いでどちらに転ぶか分からない不安があって悩ましいですが。)

    以下のソースの赤字箇所で__builtin_rx_xchg()関数を使用してみた

    #define bool _Bool
    #define false 0
    #define true 1

    typedef signed char int8_t;
    typedef unsigned char uint8_t;
    typedef signed short int16_t;
    typedef unsigned short uint16_t;
    typedef signed long int32_t;
    typedef unsigned long uint32_t;
    typedef signed long long int64_t;
    typedef unsigned long long uint64_t;
    typedef unsigned long size_t;

    /* By default modules will use global locks found in mcu_locks.c. If the user is using a RTOS and would rather use its
       locking mechanisms then they can change this macro.
       NOTE: If '1' is chosen for this macro then the user must also change the next macro 'BSP_CFG_USER_LOCKING_TYPE'.
       0 = Use default locking (non-RTOS)
       1 = Use user defined locking mechanism.
    */
    #define BSP_CFG_USER_LOCKING_ENABLED    (0)

    /* If the user decides to use their own locking mechanism with FIT modules then they will need to redefine the typedef
       that is used for the locks. If the user is using a RTOS then they would likely redefine the typedef to be
       a semaphore/mutex type of their RTOS. Use the macro below to set the type that will be used for the locks.
       NOTE: If BSP_CFG_USER_LOCKING_ENABLED == 0 then this typedef is ignored.
       NOTE: Do not surround the type with parentheses '(' ')'.
    */
    #define BSP_CFG_USER_LOCKING_TYPE       bsp_lock_t

    typedef enum
    {
        BSP_LOCK_BSC = 0,
        BSP_LOCK_CAC,
        BSP_LOCK_CAN0,
        BSP_LOCK_CAN1,
        BSP_LOCK_CMT,
        BSP_LOCK_CMT0,
        BSP_LOCK_CMT1,
        BSP_LOCK_CMT2,
        BSP_LOCK_CMT3,
        /* 略 */
        BSP_LOCK_GLCDC,
        BSP_LOCK_DRW2D,
        BSP_NUM_LOCKS //This entry is not a valid lock. It is used for sizing g_bsp_Locks[] array below. Do not touch!
    } mcu_lock_t;

    typedef struct
    {
        /* The actual lock. int32_t is used because this is what the xchg() instruction takes as parameters. */
        int32_t     lock;
        /* Could add a ID for locking and unlocking. In this could protect against any function being able to unlock. */
    } bsp_lock_t;

    BSP_CFG_USER_LOCKING_TYPE g_bsp_Locks[BSP_NUM_LOCKS];    

    bool R_BSP_SoftwareLock (BSP_CFG_USER_LOCKING_TYPE * const plock)
    {
    #if BSP_CFG_USER_LOCKING_ENABLED == 0
        bool ret = false;

        /* Variable used in trying to acquire lock. Using the xchg instruction makes this atomic */
        int32_t is_locked = true;
        
        /* This example uses the RX MCU's atomic xchg() instruction. plock->lock is the lock we are trying to reserve.
           The way this works is that 'is_locked' gets the value of the plock->lock and plock->lock gets the value of
           'is_locked' which we just set to 'true'. Basically this is an atomic 'swap' command. If the lock had not yet been
           reserved then its value would be 'false' and after the xchg() instruction finished 'is_locked' would have
           'false'. If it had already been reserved then 'is_locked' would have 'true' after the xchg() instruction. Since
           plock->lock was already 'true' and we just set it back to 'true' everything is ok. To see if we reserved the lock
           we just need to check the value of 'is_locked' after this instruction finishes. */

        /* Try to acquire semaphore to obtain lock */
        __builtin_rx_xchg((int *)&is_locked, (int *)&plock->lock); /* xchg(&is_locked, &plock->lock); */
        
        /* Check to see if semaphore was successfully taken */
        if (is_locked == false)
        {        
            /* Lock obtained, return success. */
            ret = true;
        }
        else
        {
            /* Lock was not obtained, another task already has it. */
        }

        return ret;   
    #else
        /* User is going to handle the locking themselves. */
        return BSP_CFG_USER_LOCKING_SW_LOCK_FUNCTION(plock);
    #endif
    } /* End of function R_BSP_SoftwareLock() */

    bool R_BSP_HardwareLock (mcu_lock_t const hw_index)
    {
    #if BSP_CFG_USER_LOCKING_ENABLED == 0
        /* Pass actual lock to software lock function. */
        return R_BSP_SoftwareLock(&g_bsp_Locks[hw_index]);
    #else
        /* User is going to handle the locking themselves. */
        return BSP_CFG_USER_LOCKING_HW_LOCK_FUNCTION(hw_index);
    #endif
    } /* End of function R_BSP_HardwareLock() */

    #define CMT_RX_NUM_CHANNELS 4

    /*static*/ bool cmt_find_channel (uint32_t * channel)
    {
        bool     channel_found = false;
        uint32_t i;

        /* Look for an available channel. */
        for (i = 0; i < CMT_RX_NUM_CHANNELS; i++)
        {
    #if BSP_CFG_RTOS_USED == 0      // Non-OS
    #elif BSP_CFG_RTOS_USED == 1    // FreeRTOS
            if (i == BSP_CFG_RTOS_SYSTEM_TIMER)
            {
                /* Found CMT channel is being used for RTOS. */
                continue;
            }
    #elif BSP_CFG_RTOS_USED == 2    // SEGGER embOS
    #elif BSP_CFG_RTOS_USED == 3    // Micrium MicroC/OS
    #elif BSP_CFG_RTOS_USED == 4    // Renesas RI600V4 & RI600PX
    #endif
            if (true == R_BSP_HardwareLock((mcu_lock_t)(BSP_LOCK_CMT0 + i)))
            {
                /* Channel found. */
                *channel = i;
                channel_found = true;
                
                break;            
            }
        }        

        return channel_found;
    }

    以下のリストの赤字箇所でセマフォのロックに使用出来る命令列が生成されていた

     1035                                   .global _R_BSP_SoftwareLock
     1037                               _R_BSP_SoftwareLock:
     1041 020c 60 40                        sub #4, r0
     1045 020e F8 06 01                     mov.L   #1, [r0]
     1047 0211 EC 05                        mov.L   [r0], r5
     1048 0213 06 A0 10 15                  xchg    [r1].L, r5
     1049 0217 E3 05                        mov.L   r5, [r0]
     1051 0219 EC 01                        mov.L   [r0], r1
     1054 021b 61 01                        cmp #0, r1
     1055 021d FC DB 10                     sceq.L  r1
     1057 0220 67 01                        rtsd    #4

     1060                                   .global _R_BSP_HardwareLock
     1062                               _R_BSP_HardwareLock:
     1066 0222 60 40                        sub #4, r0
     1072 0224 F8 06 01                     mov.L   #1, [r0]
     1076 0227 6C 21                        shll    #2, r1
     1081 0229 EC 05                        mov.L   [r0], r5
     1085 022b 70 11 00 00 00 00            add #_g_bsp_Locks, r1
     1090 0231 06 A0 10 15                  xchg    [r1].L, r5
     1091 0235 E3 05                        mov.L   r5, [r0]
     1093 0237 EC 01                        mov.L   [r0], r1
     1098 0239 61 01                        cmp #0, r1
     1099 023b FC DB 10                     sceq.L  r1
     1101 023e 67 01                        rtsd    #4

     1104                                   .global _cmt_find_channel
     1106                               _cmt_find_channel:
     1110 0240 60 40                        sub #4, r0
     1113 0242 FB 32 00 00 00 00            mov.L   #_g_bsp_Locks+20, r3
     1115 0248 66 04                        mov.L   #0, r4
     1117                                   .balign 8,3,4
     1123 024a F8 06 01                     mov.L   #1, [r0]
     1125 024d EC 05                        mov.L   [r0], r5
     1126 024f 06 A0 10 35                  xchg    [r3].L, r5
     1127 0253 E3 05                        mov.L   r5, [r0]
     1129 0255 EC 05                        mov.L   [r0], r5
     1130 0257 61 05                        cmp #0, r5
     1131 0259 19                           bne .L67
     1137 025a E3 14                        mov.L   r4, [r1]
     1140 025c 66 11                        mov #1, r1
     1143 025e 5B 11                        movu.B  r1, r1
     1146 0260 67 01                        rtsd    #4
     1150 0262 62 14                        add #1, r4
     1152 0264 62 43                        add #4, r3
     1154 0266 61 44                        cmp #4, r4
     1155 0268 21 E2                        bne .L61
     1157 026a 66 01                        mov #0, r1
     1160 026c 5B 11                        movu.B  r1, r1
     1163 026e 67 01                        rtsd    #4

     

  • こんにちは。NoMaYです。

    すみません。__builtin_rx_xchg()関数の引数を入れ替えたところ、セマフォのロックには使用出来ませんが、メモリオペランドを伴う命令列が生成されていましたので、GNURXのGCCの__builtin_rx_xchg()関数のソースのif節かelse節かは関係無いようですね。すみません。

    __builtin_rx_xchg()関数の引数を入れ替えてみた

    //    __builtin_rx_xchg((int *)&is_locked, (int *)&plock->lock); /* xchg(&is_locked, &plock->lock); */
        __builtin_rx_xchg((int *)&plock->lock, (int *)&is_locked); /* xchg(&is_locked, &plock->lock); */

    セマフォのロックには使用出来ないがメモリオペランドを伴う命令列が生成されていた

       4                                    .global _R_BSP_SoftwareLock
      11 0000 60 40                         sub #4, r0
      15 0002 EF 15                         mov.L   r1, r5
      17 0004 EC 14                         mov.L   [r1], r4
      19 0006 F8 06 01                      mov.L   #1, [r0]
      21 0009 06 A0 10 04                   xchg    [r0].L, r4
      23 000d 66 01                         mov.L   #0, r1
      26 000f E3 54                         mov.L   r4, [r5]
      28 0011 67 01                         rtsd    #4

      31                                    .global _R_BSP_HardwareLock
      33                                _R_BSP_HardwareLock:
      37 0013 60 40                         sub #4, r0
      41 0015 6C 21                         shll    #2, r1
      43 0017 70 15 00 00 00 00             add #_g_bsp_Locks, r1, r5
      48 001d EC 54                         mov.L   [r5], r4
      50 001f F8 06 01                      mov.L   #1, [r0]
      52 0022 06 A0 10 04                   xchg    [r0].L, r4
      56 0026 66 01                         mov.L   #0, r1
      60 0028 E3 54                         mov.L   r4, [r5]
      64 002a 67 01                         rtsd    #4

      67                                    .global _cmt_find_channel
      69                                _cmt_find_channel:
      73 002c 60 40                         sub #4, r0
      76 002e FB 42 00 00 00 00             mov.L   #_g_bsp_Locks+20, r4
      78 0034 66 05                         mov.L   #0, r5
      80                                    .balign 8,3,1
      86 0036 EC 43                         mov.L   [r4], r3
      88 0038 F8 06 01                      mov.L   #1, [r0]
      90 003b 06 A0 10 03                   xchg    [r0].L, r3
      95 003f 62 15                         add #1, r5
     101 0041 FD 22 43                      mov.L   r3, [r4+]
     107 0044 61 45                         cmp #4, r5
     108 0046 21 F0                         bne .L9
     110 0048 66 01                         mov.L   #0, r1
     112 004a 67 01                         rtsd    #4

     

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

    すみません。__builtin_rx_xchg()関数の引数を入れ替えたところ、セマフォのロックには使用出来ませんが、メモリオペランドを伴う命令列が生成されていましたので、GNURXのGCCの__builtin_rx_xchg()関数のソースのif節かelse節かは関係無いようですね。すみません。

    __builtin_rx_xchg()関数の引数を入れ替えてみた

    //    __builtin_rx_xchg((int *)&is_locked, (int *)&plock->lock); /* xchg(&is_locked, &plock->lock); */
        __builtin_rx_xchg((int *)&plock->lock, (int *)&is_locked); /* xchg(&is_locked, &plock->lock); */

    セマフォのロックには使用出来ないがメモリオペランドを伴う命令列が生成されていた

       4                                    .global _R_BSP_SoftwareLock
      11 0000 60 40                         sub #4, r0
      15 0002 EF 15                         mov.L   r1, r5
      17 0004 EC 14                         mov.L   [r1], r4
      19 0006 F8 06 01                      mov.L   #1, [r0]
      21 0009 06 A0 10 04                   xchg    [r0].L, r4
      23 000d 66 01                         mov.L   #0, r1
      26 000f E3 54                         mov.L   r4, [r5]
      28 0011 67 01                         rtsd    #4

      31                                    .global _R_BSP_HardwareLock
      33                                _R_BSP_HardwareLock:
      37 0013 60 40                         sub #4, r0
      41 0015 6C 21                         shll    #2, r1
      43 0017 70 15 00 00 00 00             add #_g_bsp_Locks, r1, r5
      48 001d EC 54                         mov.L   [r5], r4
      50 001f F8 06 01                      mov.L   #1, [r0]
      52 0022 06 A0 10 04                   xchg    [r0].L, r4
      56 0026 66 01                         mov.L   #0, r1
      60 0028 E3 54                         mov.L   r4, [r5]
      64 002a 67 01                         rtsd    #4

      67                                    .global _cmt_find_channel
      69                                _cmt_find_channel:
      73 002c 60 40                         sub #4, r0
      76 002e FB 42 00 00 00 00             mov.L   #_g_bsp_Locks+20, r4
      78 0034 66 05                         mov.L   #0, r5
      80                                    .balign 8,3,1
      86 0036 EC 43                         mov.L   [r4], r3
      88 0038 F8 06 01                      mov.L   #1, [r0]
      90 003b 06 A0 10 03                   xchg    [r0].L, r3
      95 003f 62 15                         add #1, r5
     101 0041 FD 22 43                      mov.L   r3, [r4+]
     107 0044 61 45                         cmp #4, r5
     108 0046 21 F0                         bne .L9
     110 0048 66 01                         mov.L   #0, r1
     112 004a 67 01                         rtsd    #4

     

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

    度々すみません。私が前々回と前回に試したケースは何れもGNURXのGCCの__builtin_rx_xchg()関数のソースのif節に該当していたようです。スタック上の変数のアドレスを&で取得した場合にもif文のREG_P(arg2)は真になるようです。よくよく考えてみれば、R0レジスタ相対になるのですから、そうなって然るべきものでした。今回、以下の4つの場合を試してみて、そのことを理解しました。

    (1) リエントラント性は脇において試しにis_locked変数をstatic宣言してみたもの

    bool R_BSP_SoftwareLock (BSP_CFG_USER_LOCKING_TYPE * const plock)
    {

        static int32_t is_locked = true;

        __builtin_rx_xchg((int *)&is_locked, (int *)&plock->lock);

    (2) 上記(1)で__builtin_rx_xchg()関数の引数を入れ替えたもの

    bool R_BSP_SoftwareLock (BSP_CFG_USER_LOCKING_TYPE * const plock)
    {

        static int32_t is_locked = true;

        __builtin_rx_xchg((int *)&plock->lock, (int *)&is_locked);

    (3) 上位関数から渡されたplock変数は脇において試しに&g_bsp_Locks[BSP_LOCK_CMT0 + 0]を書いたもの

    bool R_BSP_SoftwareLock (BSP_CFG_USER_LOCKING_TYPE * const plock)
    {

        int32_t is_locked = true;

        __builtin_rx_xchg((int *)&g_bsp_Locks[BSP_LOCK_CMT0 + 0], (int *)&is_locked);

    (4) 上記(3)で__builtin_rx_xchg()関数の引数を入れ替えたもの

    bool R_BSP_SoftwareLock (BSP_CFG_USER_LOCKING_TYPE * const plock)
    {

        int32_t is_locked = true;

        __builtin_rx_xchg((int *)&is_locked, (int *)&g_bsp_Locks[BSP_LOCK_CMT0 + 0]);

    結果は以下の通りでした。

    (1) リエントラント性は脇において試しにis_locked変数をstatic宣言してみたもの

    bool R_BSP_SoftwareLock (BSP_CFG_USER_LOCKING_TYPE * const plock)
    {

        static int32_t is_locked = true;

        __builtin_rx_xchg((int *)&is_locked, (int *)&plock->lock);


       4                                    .global _R_BSP_SoftwareLock
       6                                _R_BSP_SoftwareLock:
      12 0000 FB 52 00 00 00 00             mov.L   #_is_locked.1408, r5
      13 0006 EC 54                         mov.L   [r5], r4
      14 0008 06 A0 10 14                   xchg    [r1].L, r4
      15 000c E3 54                         mov.L   r4, [r5]
      18 000e EC 51                         mov.L   [r5], r1
      21 0010 61 01                         cmp #0, r1
      22 0012 FC DB 10                      sceq.L  r1
      23 0015 02                            rts

    (2) 上記(1)で__builtin_rx_xchg()関数の引数を入れ替えたもの

    bool R_BSP_SoftwareLock (BSP_CFG_USER_LOCKING_TYPE * const plock)
    {

        static int32_t is_locked = true;

        __builtin_rx_xchg((int *)&plock->lock, (int *)&is_locked);


       4                                    .global _R_BSP_SoftwareLock
       6                                _R_BSP_SoftwareLock:
      12 0000 EC 14                         mov.L   [r1], r4
      13 0002 FB 52 00 00 00 00             mov.L   #_is_locked.1408, r5
      14 0008 EC 53                         mov.L   [r5], r3
      15 000a E3 14                         mov.L   r4, [r1]
      16 000c E3 53                         mov.L   r3, [r5]
      19 000e EC 51                         mov.L   [r5], r1
      22 0010 FC 43 34                      xchg    r3, r4
      24 0013 61 01                         cmp #0, r1
      25 0015 FC DB 10                      sceq.L  r1
      26 0018 02                            rts

    (3) 上位関数から渡されたplock変数は脇において試しに&g_bsp_Locks[BSP_LOCK_CMT0 + 0]を書いたもの

    bool R_BSP_SoftwareLock (BSP_CFG_USER_LOCKING_TYPE * const plock)
    {

        int32_t is_locked = true;

        __builtin_rx_xchg((int *)&g_bsp_Locks[BSP_LOCK_CMT0 + 0], (int *)&is_locked);


       6                                _R_BSP_SoftwareLock:
      11 0000 60 40                         sub #4, r0
      15 0002 FB 52 00 00 00 00             mov.L   #_g_bsp_Locks+20, r5
      16 0008 EC 54                         mov.L   [r5], r4
      18 000a F8 06 01                      mov.L   #1, [r0]
      20 000d 06 A0 10 04                   xchg    [r0].L, r4
      22 0011 66 01                         mov.L   #0, r1
      25 0013 E3 54                         mov.L   r4, [r5]
      27 0015 67 01                         rtsd    #4

    (4) 上記(3)で__builtin_rx_xchg()関数の引数を入れ替えたもの

    bool R_BSP_SoftwareLock (BSP_CFG_USER_LOCKING_TYPE * const plock)
    {

        int32_t is_locked = true;

        __builtin_rx_xchg((int *)&is_locked, (int *)&g_bsp_Locks[BSP_LOCK_CMT0 + 0]);


       4                                    .global _R_BSP_SoftwareLock
       6                                _R_BSP_SoftwareLock:
      11 0000 60 40                         sub #4, r0
      15 0002 F8 06 01                      mov.L   #1, [r0]
      17 0005 EC 03                         mov.L   [r0], r3
      18 0007 FB 52 00 00 00 00             mov.L   #_g_bsp_Locks+20, r5
      19 000d E3 03                         mov.L   r3, [r0]
      20 000f EC 54                         mov.L   [r5], r4
      22 0011 FC 43 43                      xchg    r4, r3
      23 0014 E3 54                         mov.L   r4, [r5]
      26 0016 EC 01                         mov.L   [r0], r1
      28 0018 61 01                         cmp #0, r1
      29 001a FC DB 10                      sceq.L  r1
      31 001d 67 01                         rtsd    #4

     

  • こんにちは。NoMaYです。

    幾つか前の私の投稿でGNURXのGCCの__builtin_rx_xchg()関数のソースについて「複雑難解な最適化処理との兼ね合いでどちらに転ぶか分からない不安があって悩ましい」と書きましたが、1つ例が思い浮かびました。

    今まで上位側で以下のようにしていたら期待したセマフォのロックに使用出来る命令列が生成されていた

    /*static*/ bool cmt_find_channel (uint32_t * channel)
    {
        bool     channel_found = false;
        uint32_t i;
        bool     cmt_locked;

        /* Look for an available channel. */
        for (i = 0; i < CMT_RX_NUM_CHANNELS; i++)
        {
    #if BSP_CFG_RTOS_USED == 0      // Non-OS
    #elif BSP_CFG_RTOS_USED == 1    // FreeRTOS
            if (i == BSP_CFG_RTOS_SYSTEM_TIMER)
            {
                /* Found CMT channel is being used for RTOS. */
                continue;
            }
    #elif BSP_CFG_RTOS_USED == 2    // SEGGER embOS
    #elif BSP_CFG_RTOS_USED == 3    // Micrium MicroC/OS
    #elif BSP_CFG_RTOS_USED == 4    // Renesas RI600V4 & RI600PX
    #endif
            if (true == R_BSP_HardwareLock((mcu_lock_t)(BSP_LOCK_CMT0 + i)))
            {
                /* Channel found. */
                *channel = i;
                channel_found = true;
                
                break;            
            }
        }        

        return channel_found;
    }
     1104                                   .global _cmt_find_channel
     1106                               _cmt_find_channel:
     1110 0240 60 40                        sub #4, r0
     1113 0242 FB 32 00 00 00 00            mov.L   #_g_bsp_Locks+20, r3
     1115 0248 66 04                        mov.L   #0, r4
     1117                                   .balign 8,3,4
     1123 024a F8 06 01                     mov.L   #1, [r0]
     1125 024d EC 05                        mov.L   [r0], r5
     1126 024f 06 A0 10 35                  xchg    [r3].L, r5
     1127 0253 E3 05                        mov.L   r5, [r0]
     1129 0255 EC 05                        mov.L   [r0], r5
     1130 0257 61 05                        cmp #0, r5
     1131 0259 19                           bne .L67
     1137 025a E3 14                        mov.L   r4, [r1]
     1140 025c 66 11                        mov #1, r1
     1143 025e 5B 11                        movu.B  r1, r1
     1146 0260 67 01                        rtsd    #4
     1150 0262 62 14                        add #1, r4
     1152 0264 62 43                        add #4, r3
     1154 0266 61 44                        cmp #4, r4
     1155 0268 21 E2                        bne .L61
     1157 026a 66 01                        mov #0, r1
     1160 026c 5B 11                        movu.B  r1, r1
     1163 026e 67 01                        rtsd    #4

    ところが以下のように書き換えたらそのような命令列が生成されなくなってしまった(ただの交換も機能しない)

    /*static*/ bool cmt_find_channel (uint32_t * channel)
    {
        bool     channel_found = false;
        uint32_t i;
        bool     cmt_locked;

        /* Look for an available channel. */
        for (i = 0; i < CMT_RX_NUM_CHANNELS; i++)
        {
    #if BSP_CFG_RTOS_USED == 0      // Non-OS
    #elif BSP_CFG_RTOS_USED == 1    // FreeRTOS
            if (i == BSP_CFG_RTOS_SYSTEM_TIMER)
            {
                /* Found CMT channel is being used for RTOS. */
                continue;
            }
    #elif BSP_CFG_RTOS_USED == 2    // SEGGER embOS
    #elif BSP_CFG_RTOS_USED == 3    // Micrium MicroC/OS
    #elif BSP_CFG_RTOS_USED == 4    // Renesas RI600V4 & RI600PX
    #endif
            //if (true == R_BSP_HardwareLock((mcu_lock_t)(BSP_LOCK_CMT0 + i)))
            switch (i)
            {
            case 0:
                cmt_locked = R_BSP_HardwareLock((mcu_lock_t)BSP_LOCK_CMT0);
                break;
            case 1:
                cmt_locked = R_BSP_HardwareLock((mcu_lock_t)BSP_LOCK_CMT1);
                break;
            case 2:
                cmt_locked = R_BSP_HardwareLock((mcu_lock_t)BSP_LOCK_CMT2);
                break;
            case 3:
                cmt_locked = R_BSP_HardwareLock((mcu_lock_t)BSP_LOCK_CMT3);
                break;
            default:
                /* never */
                cmt_locked = false;
            }
            if (true == cmt_locked)
            {
                /* Channel found. */
                *channel = i;
                channel_found = true;
                
                break;            
            }
        }        

        return channel_found;
    }
      74                                    .global _cmt_find_channel
      76                                _cmt_find_channel:
      80 0034 6E 67                         pushm   r6-r7
      82 0036 60 40                         sub #4, r0
      86 0038 66 05                         mov.L   #0, r5
      91 003a FB 72 00 00 00 00             mov.L   #_g_bsp_Locks+28, r7
      98 0040 FB F2 00 00 00 00             mov.L   #_g_bsp_Locks+32, r15
     105 0046 FB E2 00 00 00 00             mov.L   #_g_bsp_Locks+24, r14
     112 004c FB 22 00 00 00 00             mov.L   #_g_bsp_Locks+20, r2
     114                                    .balign 8,3,1
     115                                .L13:
     120 0052 61 25                         cmp #2, r5
     121 0054 20 6C                         beq .L7
     123 0056 61 35                         cmp #3, r5
     124 0058 20 51                         beq .L8
     125 005a 61 15                         cmp #1, r5
     126 005c 20 2A                         beq .L9
     131 005e F8 06 01                      mov.L   #1, [r0]
     133 0061 EC 04                         mov.L   [r0], r4
     134 0063 EC 23                         mov.L   [r2], r3
     135 0065 E3 04                         mov.L   r4, [r0]
     136 0067 FC 43 34                      xchg    r3, r4
     138 006a EC 04                         mov.L   [r0], r4
     139 006c 61 04                         cmp #0, r4
     140 006e FC DB 40                      sceq.L  r4
     142 0071 E3 23                         mov.L   r3, [r2]
     144                                    .balign 8,3,1
     145                                .L10:
     150 0073 5B 44                         movu.B  r4, r4
     151 0075 61 04                         cmp #0, r4
     152 0077 21 29                         bne .L17
     154                                    .balign 8,3,1
     155                                .L11:
     157 0079 62 15                         add #1, r5
     159 007b 61 45                         cmp #4, r5
     160 007d 21 D5                         bne .L13
     162 007f CF 41                         mov.B   r4, r1
     165 0081 5B 11                         movu.B  r1, r1
     167 0083 3F 67 03                      rtsd    #12, r6-r7
     169                                .L9:
     174 0086 E3 05                         mov.L   r5, [r0]
     176 0088 EC 04                         mov.L   [r0], r4
     177 008a EC E6                         mov.L   [r14], r6
     178 008c E3 04                         mov.L   r4, [r0]
     179 008e FC 43 64                      xchg    r6, r4
     181 0091 EC 04                         mov.L   [r0], r4
     182 0093 61 04                         cmp #0, r4
     183 0095 FC DB 40                      sceq.L  r4
     185 0098 E3 E6                         mov.L   r6, [r14]
     191 009a 5B 44                         movu.B  r4, r4
     193 009c 61 04                         cmp #0, r4
     195 009e 20 DB                         beq .L11
     197                                    .balign 8,3,1
     198                                .L17:
     200 00a0 E3 15                         mov.L   r5, [r1]
     203 00a2 66 11                         mov #1, r1
     206 00a4 5B 11                         movu.B  r1, r1
     208 00a6 3F 67 03                      rtsd    #12, r6-r7
     210                                .L8:
     215 00a9 F8 06 01                      mov.L   #1, [r0]
     217 00ac EC 03                         mov.L   [r0], r3
     218 00ae EC F6                         mov.L   [r15], r6
     219 00b0 E3 03                         mov.L   r3, [r0]
     220 00b2 E3 F6                         mov.L   r6, [r15]
     222 00b4 EC 04                         mov.L   [r0], r4
     223 00b6 61 04                         cmp #0, r4
     224 00b8 FC DB 40                      sceq.L  r4
     227 00bb FC 43 63                      xchg    r6, r3
     232 00be 2E B5                         bra .L10
     234                                .L7:
     239 00c0 F8 06 01                      mov.L   #1, [r0]
     241 00c3 EC 04                         mov.L   [r0], r4
     242 00c5 EC 76                         mov.L   [r7], r6
     243 00c7 E3 04                         mov.L   r4, [r0]
     244 00c9 FC 43 64                      xchg    r6, r4
     246 00cc EC 04                         mov.L   [r0], r4
     247 00ce 61 04                         cmp #0, r4
     248 00d0 FC DB 40                      sceq.L  r4
     250 00d3 E3 76                         mov.L   r6, [r7]
     256 00d5 2E 9E                         bra .L10