こんにちは。NoMaYです。RXv3コア搭載の120MH動作のRXマイコンも、RX66T以降、RX671、RX66N、RX660と品種が増えてきましたが、RXv3コアのセールスポイントの1つであるレジスタ一括退避機能の使い方が今ひとつピンと来ません。そこで、いつものように、ちょっと好奇心からスレッドを立ててみました。(注: RX66Tは、160MHz動作、レジスタ一括退避機能未搭載、です。) いつものように、ぼちぼちと続きます。ホワイトペーパー卓越したMCU性能と電力効率を実現するRXv3コア2019年10月www.renesas.com/jp/ja/document/whp/introducing-rxv3-core-superior-performance-excellent-power-efficiency#page=6「割り込み応答時間の改善モータ制御システムなどは、高速な割り込み処理によるリアルタイム性能が必要となってきます。RXv3コアには、割り込み処理時にレジスタを高速退避/復帰するために、オプション機能として、レジスタ退避バンクと呼ばれる専用メモリを実装しています。図6に示すように、レジスタ退避バンクを使用することで割り込み応答時間を短縮でき、割り込み処理全体の時間を短縮することができます。 割り込み処理ルーチンの中で、SAVE命令を使用すると汎用レジスタとアキュムレータを1クロックで専用メモリに保存できます。RSTR命令は、保存されたレジスタを3~6cycleで復元します。レジスタ退避バンクは専用メモリを複数面持っており、多重割り込みにも対応することが可能です。図6.割り込み応答時間の改善レジスタ退避バンクは、割り込みハンドラだけでなく、RTOSコンテキスト切り替えにも使用できます。 RTOSコンテキスト切り替え時間は、レジスタバンク保存機能により最大20%高速化します。」
こんにちは。NoMaYです。コンパイラ(CC-RX/ICCRX/GNURX)が三角関数演算器をどのように使用するのかリストファイルからコードを抜き出してみました。併せて、FPUのFSQRT命令とDPFPUのDSQRT命令を使用するコードもリストファイルから抜き出してみました。ちなみに、三角関数演算器は、内蔵周辺レジスタのICLK同期のバスに接続されていて、たぶん、演算終了までの期間、バスにウェイトを掛けることでCPU本体を待たせるようになっているのではないかな、という気がします。もっとも、バスにウェイトを掛けることでCPU本体を待たせるといっても、CPU本体は本当に待たなければいけないタイミングまでどんどん先へと進んで行ってすぐには止まらないのではないかな、という気がしますけれども。以下、試したソースです。
static float Check_TFU_sinf(float x){ return sinf(x);}
static float Check_TFU_cosf(float x){ return cosf(x);}
static float Check_TFU_atan2f(float y, float x){ return atan2f(y, x);}
static float Check_TFU_hypotf(float x, float y){ return hypotf(x, y);}
static float Check_TFU_asinf(float x){ return asinf(x);}
static float Check_TFU_acosf(float x){ return acosf(x);}
static float Check_TFU_atanf(float x){ return atanf(x);}
static float Check_TFU_tanf(float x){ return tanf(x);}
static float Check_Using_FSQRT(float x){ return sqrtf(x);}
static double Check_Using_DSQRT(double x){ return sqrt(x);}
以下、リストファイルです。float sinf(float x)の場合
CC-RX0000022E __$Check_TFU_sinf:0000022E FBEE141408 MOV.L #00081414H, R1400000233 E3E1 MOV.L R1, [R14]00000235 ECE1 MOV.L [R14], R100000237 02 RTSICCRX \ _Check_TFU_sinf: \ 000000 FB 2E 10 14 MOV.L #0x81410,R2 \ 08 \ 000005 A0 29 MOV.L R1,0x4[R2] \ 000007 A8 29 MOV.L 0x4[R2],R1 \ 000009 02 RTSGNURX 304 _Check_TFU_sinf: 310 0000 FB 5E 14 14 08 mov.L #0x81414, r5 311 0005 E3 51 mov.L r1, [r5] 312 0007 EC 51 mov.L [r5], r1 315 0009 02 rts
float TFU_cosf(float x)の場合
CC-RX00000238 __$Check_TFU_cosf:00000238 FB2E101408 MOV.L #00081410H, R20000023D A029 MOV.L R1, 04H[R2]0000023F EC21 MOV.L [R2], R100000241 02 RTSICCRX \ _Check_TFU_cosf: \ 000000 FB 2E 10 14 MOV.L #0x81410,R2 \ 08 \ 000005 A0 29 MOV.L R1,0x4[R2] \ 000007 EC 21 MOV.L [R2],R1 \ 000009 02 RTSGNURX 320 _Check_TFU_cosf: 326 0000 FB 5E 10 14 08 mov.L #0x81410, r5 327 0005 A0 59 mov.L r1, 4[r5] 328 0007 EC 51 mov.L [r5], r1 331 0009 02 rts
float atan2f(float y, float x)の場合
CC-RX00000242 __$Check_TFU_atan2f:00000242 FBEE181408 MOV.L #00081418H, R1400000247 FD22E2 MOV.L R2, [R14+]0000024A E3E1 MOV.L R1, [R14]0000024C ECE1 MOV.L [R14], R10000024E 02 RTSICCRX \ _Check_TFU_atan2f: \ 000000 FB 3E 10 14 MOV.L #0x81410,R3 \ 08 \ 000005 A0 B2 MOV.L R2,0x8[R3] \ 000007 A0 B9 MOV.L R1,0xc[R3] \ 000009 A8 B9 MOV.L 0xc[R3],R1 \ 00000B 02 RTSGNURX 342 0000 FB 5E 18 14 08 mov.L #0x81418, r5 343 0005 E3 52 mov.L r2, [r5] 344 0007 A0 59 mov.L r1, 4[r5] 345 0009 A8 59 mov.L 4[r5], r1 348 000b 02 rts
float hypotf(float x, float y)の場合 (GNURXの生成コードはちょっとマズイですね(0番地に定数をライトしてリードしている))
CC-RX0000024F __$Check_TFU_hypotf:0000024F FB3E181408 MOV.L #00081418H, R300000254 E331 MOV.L R1, [R3]00000256 A03A MOV.L R2, 04H[R3]00000258 EC31 MOV.L [R3], R10000025A FD7231EE741B3F FMUL #3F1B74EEH, R100000261 02 RTSICCRX \ _Check_TFU_hypotf: \ 000000 FB 3E 10 14 MOV.L #0x81410,R3 \ 08 \ 000005 A0 B2 MOV.L R2,0x8[R3] \ 000007 A0 B9 MOV.L R1,0xc[R3] \ 000009 A8 B1 MOV.L 0x8[R3],R1 \ 00000B FD 72 31 EE FMUL #0x3f1b74ee,R1 \ 74 1B 3F \ 000012 02 RTSGNURX 359 0000 FB 5E 18 14 08 mov.L #0x81418, r5 360 0005 E3 51 mov.L r1, [r5] 361 0007 66 04 mov.L #0, r4 362 0009 F8 42 EE 74 1B 3F mov.L #0x3f1b74ee, [r4] 363 000f EC 44 mov.L [r4], r4 364 0011 A0 5A mov.L r2, 4[r5] 365 0013 EC 51 mov.L [r5], r1 368 0015 FC 8F 41 fmul r4, r1 369 0018 02 rts
float asinf(float x)の場合
CC-RX00000262 __$Check_TFU_asinf:00000262 FFBF11 FMUL R1, R1, R1500000265 FBE20000803F MOV.L #3F800000H, R140000026B FC83FE FSUB R15, R140000026E FCA3EF FSQRT R14, R1500000271 FBEE181408 MOV.L #00081418H, R1400000276 FD22EF MOV.L R15, [R14+]00000279 E3E1 MOV.L R1, [R14]0000027B ECE1 MOV.L [R14], R10000027D 02 RTSICCRX \ _Check_TFU_asinf: \ 000000 04 ..'.... BRA.A _asinfGNURX 374 _Check_TFU_asinf: 380 0000 04 00 00 00 bra _asinf
float acosf(float x)の場合
CC-RX0000027E __$Check_TFU_acosf:0000027E FBFE181408 MOV.L #00081418H, R1500000283 FD22F1 MOV.L R1, [R15+]00000286 FC8F11 FMUL R1, R100000289 FBE20000803F MOV.L #3F800000H, R140000028F FC831E FSUB R1, R1400000292 FCA3EE FSQRT R14, R1400000295 E3FE MOV.L R14, [R15]00000297 ECF1 MOV.L [R15], R100000299 02 RTSICCRX \ _Check_TFU_acosf: \ 000000 04 ..'.... BRA.A _acosfGNURX 387 _Check_TFU_acosf: 393 0000 04 00 00 00 bra _acosf
float atanf(float x)の場合
CC-RX0000029A __$Check_TFU_atanf:0000029A FBEE181408 MOV.L #00081418H, R140000029F FBF20000803F MOV.L #3F800000H, R15000002A5 FD22EF MOV.L R15, [R14+]000002A8 E3E1 MOV.L R1, [R14]000002AA ECE1 MOV.L [R14], R1000002AC 02 RTSICCRX \ _Check_TFU_atanf: \ 000000 04 ..'.... BRA.A _atanfGNURX 400 _Check_TFU_atanf: 406 0000 04 00 00 00 bra _atanf
float tanf(float x)の場合
CC-RX000002AD __$Check_TFU_tanf:000002AD FB2E101408 MOV.L #00081410H, R2000002B2 A029 MOV.L R1, 04H[R2]000002B4 A829 MOV.L 04H[R2], R1000002B6 EC2E MOV.L [R2], R14000002B8 FD721E00000000 FCMP #00000000H, R14000002BF 18 S BNE L25000002C0 L24: ; _$__inline_tanf.exit000002C0 FB120000807F MOV.L #7F800000H, R1000002C6 02 RTS000002C7 L25: ; if_break_bb.i000002C7 FC93E1 FDIV R14, R1000002CA 02 RTSICCRX \ _Check_TFU_tanf: \ 000000 04 ..'.... BRA.A _tanfGNURX 413 _Check_TFU_tanf: 419 0000 04 00 00 00 bra _tanf
float sqrtf(float x)の場合 (GNURXの生成コードはちょっと煩雑ですね(すみません、読み解いていません))
CC-RX0000001B __$Check_Using_FSQRT:0000001B FCA311 FSQRT R1, R10000001E 02 RTSICCRX \ _Check_Using_FSQRT: \ 000000 FC A3 11 FSQRT R1,R1 \ 000003 02 RTSGNURX 268 _Check_Using_FSQRT: 273 0000 75 B0 01 dpushm.d dr0-dr1 275 0003 60 40 sub #4, r0 278 0005 F9 03 03 00 00 00 00 dmov.D #0, drh0 279 000c FD 77 81 1A ftod r1, dr1 281 0010 FC A3 15 fsqrt r1, r5 282 0013 76 90 18 10 dcmpun dr0, dr1 283 0017 75 90 1B mvfdr 284 001a 21 12 bnz .L7 285 001c 76 90 08 61 dcmple dr1, dr0 286 0020 75 90 1B mvfdr 287 0023 11 bz .L7 288 0024 E3 05 mov.L r5, [r0] 289 0026 05 00 00 00 bsr _sqrtf 292 002a EC 05 mov.L [r0], r5 293 .balign 8,3,1 294 .L7: 296 002c EF 51 mov.L r5, r1 297 002e 62 40 add #4, r0 298 0030 75 B8 01 dpopm.d dr0-dr1 299 0033 02 rts
double sqrt(double x)の場合 (GNURXの生成コードはちょっと煩雑ですね(すみません、読み解いていません))
CC-RX00000000 __$Check_Using_DSQRT:00000000 75B000 DPUSHM.D DR0-DR000000003 FD778100 DMOV.L R1, DRL000000007 FD778202 DMOV.L R2, DRH00000000B 76900D00 DSQRT DR0, DR00000000F FD758100 DMOV.L DRL0, R100000013 FD758202 DMOV.L DRH0, R200000017 75B800 DPOPM.D DR0-DR00000001A 02 RTSICCRX \ _Check_Using_DSQRT: \ 000000 75 B0 00 DPUSHM.D DR0,DR0 \ 000003 FD 77 81 00 DMOV.L R1,DRL0 \ 000007 FD 77 82 02 DMOV.L R2,DRH0 \ 00000B 76 90 0D 00 DSQRT DR0,DR0 \ 00000F FD 75 81 00 DMOV.L DRL0,R1 \ 000013 FD 75 82 02 DMOV.L DRH0,R2 \ 000017 75 B8 00 DPOPM.D DR0,DR0 \ 00001A 02 RTSGNURX 230 _Check_Using_DSQRT: 235 0000 6E AB pushm r10-r11 237 0002 75 B0 02 dpushm.d dr0-dr2 241 0005 FD 77 81 00 dmov.L r1, drl0 242 0009 FD 77 82 02 dmov.L r2, drh0 243 000d F9 03 13 00 00 00 00 dmov.D #0, drh1 245 0014 76 90 0D 20 dsqrt dr0, dr2 246 0018 FD 75 8A 20 dmov.L drl2, r10 247 001c FD 75 8B 22 dmov.L drh2, r11 248 0020 76 90 08 11 dcmpun dr1, dr0 249 0024 75 90 1B mvfdr 250 0027 21 11 bnz .L4 251 0029 76 90 18 60 dcmple dr0, dr1 252 002d 75 90 1B mvfdr 253 0030 10 bz .L4 254 0031 05 00 00 00 bsr _sqrt 256 0035 FC 13 00 .balign 8,3,3 257 .L4: 259 0038 EF A1 mov.L r10, r1 260 003a EF B2 mov.L r11, r2 261 003c 75 B8 02 dpopm.d dr0-dr2 262 003f 6F AB popm r10-r11 263 0041 02 rts