こんにちは。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です。> PUSHM命令(レジスタ数が多い場合(最大15レジスタ)) : 最大 15 クロック> POPM命令(レジスタ数が多い場合(最大15レジスタ)) : 最大 15 or 15+1 クロック> RTSD命令(レジスタ数が多い場合(最大15レジスタ)) : 最大 15+1 or 15+2 クロックもしコンパイラが生成コード内で以下のような命令を使用していた場合、DIV命令やDIVU命令と同等レベルとはちょっと言い難いとしても、FDIV命令(命令実行に 16 or 18 クロック掛かる(命令実行が終わるまで割り込みルーチンへ飛ぶのが遅れる))と同等レベルとは言えるだろうと思います。(DIV命令やDIVU命令は実行クロック数の幅が広いです。3~20 or 5~22とか、2~18 or 4~20とか、だったりします。)
PUSHM R1-R15POP R1-R15RTSD #IMM, R1-R15
CC-RXの -nouse_div_inst というコンパイルオプションでDIV命令やDIVU命令やFDIV命令(やDDIV命令)を使用しないよう抑止出来るのですけれども、それなら上記のような命令の使用も抑止出来て欲しいところです。考慮する点は、CC-RXの関数呼び出し時のレジスタの使用規則では、通常関数の先頭と末尾で上記のような命令が使用されることは無い、という点です。そして、上記のような命令が使用されることがあり得る割り込み関数では、以下の画面コピーの通り、#pragma interrupt構文で抑止出来るようになっています。(1) 通常関数の場合使用されるのは、せいぜい、以下のような命令まで。
PUSHM R6-R13POP R6-R13RTSD #IMM, R6-R13
(2) 割り込み関数の場合以下の構文で抑止可能です。
#pragma interrupt <関数名>(save[,enable,<他の割り込み仕様>])
続く。(あとは、DPUSHM命令とDPOPM命令です。)以下、CC-RXのヘルプの画面コピーです。
こんにちは。NoMaYです。> DPUSHM命令(レジスタ数が多い場合(最大16レジスタ)) : 最大 16 クロック> DPOPM命令(レジスタ数が多い場合(最大16レジスタ)) : 最大 16 or 16+1 クロックコンパイラは生成コード内で以下のような命令を素朴に使用していますね。CC-RXでも特殊な対応(例えば複数命令に分割するような機能とか)は無いようでした。1つ前の投稿で書いたことの繰り返しですけれども、CC-RXの -nouse_div_inst というコンパイルオプションで抑止される命令のうち、DIV命令やDIVU命令と同等レベルとはちょっと言い難いとしても、FDIV命令と同等レベルの命令実行時間とは言えるだろうと思います。(他の多くの命令と比べて、有意に実行時間が長く、長くなっている分だけ割り込みルーチンへ飛ぶのが遅れる。)
DPUSHM.D DR0-DR15DPOPM.D DR0-DR15
試したソース
double d1, d2;double dA, dB, dC, dD;static void Check_DPUSHM_DPOPM(void);static void Check_DPUSHM_DPOPM(void){ double d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16; d3 = d1 + d2 + 3.0; d4 = d1 - d2 + 4.0; d5 = d1 + d2 + 5.0; d6 = d1 - d2 + 6.0; d7 = d1 + d2 + 7.0; d8 = d1 - d2 + 8.0; d9 = d1 + d2 + 9.0; d10 = d1 - d2 + 10.0; d11 = d1 + d2 + 11.0; d12 = d1 - d2 + 12.0; d13 = d1 + d2 + 13.0; d14 = d1 - d2 + 14.0; d15 = d1 + d2 + 15.0; d16 = d1 - d2 + 16.0; dA = d3 + d4 + d5 + d6 + d7 + d8 + d9 + d10 + d11 + d12 + d13 + d14 + d15 + d16; dB = d3 * d4 * d5 * d6 * d7 * d8 * d9 * d10 * d11 * d12 * d13 * d14 * d15 * d16; dC = d3 - d4 - d5 - d6 - d7 - d8 - d9 - d10 - d11 - d12 - d13 - d14 - d15 - d16; dD = d3 / d4 / d5 / d6 / d7 / d8 / d9 / d10 / d11 / d12 / d13 / d14 / d15 / d16;}
CC-RXでのリストファイル
.SECTION P,CODE00000000 __$Check_DPUSHM_DPOPM: .STACK __$Check_DPUSHM_DPOPM=13200000000 75B00F DPUSHM.D DR0-DR1500000003 FBE2rrrrrrrr MOV.L #_d1, R1400000009 FCC8E830 DMOV.D [R14], DR30000000D FBE2rrrrrrrr MOV.L #_d2, R1400000013 FCC8E810 DMOV.D [R14], DR100000017 76903021 DADD DR1, DR3, DR20000001B 769031F1 DSUB DR1, DR3, DR150000001F F9030300000840 DMOV.D #40080000H, DRH000000026 F9031300001040 DMOV.D #40100000H, DRH10000002D 76902000 DADD DR0, DR2, DR000000031 7690F0E1 DADD DR1, DR15, DR1400000035 F9031300001440 DMOV.D #40140000H, DRH10000003C 769020D1 DADD DR1, DR2, DR1300000040 F9031300001840 DMOV.D #40180000H, DRH100000047 7690003E DADD DR14, DR0, DR30000004B 7690F0C1 DADD DR1, DR15, DR120000004F F9031300001C40 DMOV.D #401C0000H, DRH100000056 769020B1 DADD DR1, DR2, DR110000005A FBF2rrrrrrrr MOV.L #_dA, R1500000060 7690303D DADD DR13, DR3, DR300000064 F9031300002040 DMOV.D #40200000H, DRH10000006B 7690F0A1 DADD DR1, DR15, DR100000006F F9031300002240 DMOV.D #40220000H, DRH100000076 7690303C DADD DR12, DR3, DR30000007A 76902091 DADD DR1, DR2, DR90000007E F9031300002440 DMOV.D #40240000H, DRH100000085 7690F081 DADD DR1, DR15, DR800000089 7690303B DADD DR11, DR3, DR30000008D F9031300002640 DMOV.D #40260000H, DRH100000094 76902071 DADD DR1, DR2, DR700000098 F9031300002840 DMOV.D #40280000H, DRH10000009F 7690303A DADD DR10, DR3, DR3000000A3 7690F061 DADD DR1, DR15, DR6000000A7 FBE2rrrrrrrr MOV.L #_dB, R14000000AD F9031300002A40 DMOV.D #402A0000H, DRH1000000B4 76902051 DADD DR1, DR2, DR5000000B8 76903039 DADD DR9, DR3, DR3000000BC F9031300002C40 DMOV.D #402C0000H, DRH1000000C3 7690F041 DADD DR1, DR15, DR4000000C7 76903038 DADD DR8, DR3, DR3000000CB 76903037 DADD DR7, DR3, DR3000000CF 76903036 DADD DR6, DR3, DR3000000D3 76903035 DADD DR5, DR3, DR3000000D7 76903014 DADD DR4, DR3, DR1000000DB F9033300002E40 DMOV.D #402E0000H, DRH3000000E2 76902033 DADD DR3, DR2, DR3000000E6 76901023 DADD DR3, DR1, DR2000000EA F9031300003040 DMOV.D #40300000H, DRH1000000F1 7690F011 DADD DR1, DR15, DR1000000F5 76902021 DADD DR1, DR2, DR2000000F9 FC78F820 DMOV.D DR2, [R15]…略… …略…000001B1 75B80F DPOPM.D DR0-DR15000001B4 02 RTS
;*** COMMAND PARAMETER *** ;-isa=rxv3 ;-fpu ;-dpfpu ;-save_acc …略(-MAKEUDと-include)… ;-asmopt=-bank ;-lang=c99 ;-utf8 ;-message ;-output=obj ;-obj_path=src ;-debug ;-outcode=utf8 ;-show=source ;-optimize=max ;-goptimize ;-speed ;-type_size_access_to_volatile ;-nologo ;-listfile=src/RXv3_Check_FSQRT_DSQRT_etc.lst ;../src/RXv3_Check_FSQRT_DSQRT_etc.c
ICCRXでのリストファイル
\ In section .text, align 1, keep-with-next \ _Check_DPUSHM_DPOPM: \ 000000 FB 1E MOV.L #_f1:24,R1 \ ..'.... \ 000005 75 B0 0F DPUSHM.D DR0,DR15 \ 000008 FC C9 18 04 DMOV.D 0x10[R1],DR2 \ 20 \ 00000D FC C9 18 02 DMOV.D 0x8[R1],DR0 \ 00 \ 000012 F9 03 43 00 DMOV.D #0x40080000,DRH4 \ 00 08 40 \ 000019 F9 03 53 00 DMOV.D #0x40100000,DRH5 \ 00 10 40 \ 000020 76 90 20 30 DADD DR0,DR2,DR3 \ 000024 76 90 01 22 DSUB DR2,DR0,DR2 \ 000028 76 90 40 43 DADD DR3,DR4,DR4 \ 00002C 76 90 50 52 DADD DR2,DR5,DR5 \ 000030 F9 03 63 00 DMOV.D #0x40140000,DRH6 \ 00 14 40 \ 000037 F9 03 73 00 DMOV.D #0x40180000,DRH7 \ 00 18 40 \ 00003E F9 03 93 00 DMOV.D #0x40200000,DRH9 \ 00 20 40 \ 000045 F9 03 B3 00 DMOV.D #0x40240000,DRH11 \ 00 24 40 \ 00004C F9 03 D3 00 DMOV.D #0x40280000,DRH13 \ 00 28 40 \ 000053 F9 03 F3 00 DMOV.D #0x402c0000,DRH15 \ 00 2C 40 \ 00005A F9 03 03 00 DMOV.D #0x40300000,DRH0 \ 00 30 40 \ 000061 76 90 60 63 DADD DR3,DR6,DR6 \ 000065 76 90 70 72 DADD DR2,DR7,DR7 \ 000069 76 90 90 92 DADD DR2,DR9,DR9 \ 00006D 76 90 B0 B2 DADD DR2,DR11,DR11 \ 000071 76 90 D0 D2 DADD DR2,DR13,DR13 \ 000075 76 90 F0 F2 DADD DR2,DR15,DR15 \ 000079 76 90 00 22 DADD DR2,DR0,DR2 \ 00007D 76 90 50 04 DADD DR4,DR5,DR0 \ 000081 F9 03 83 00 DMOV.D #0x401c0000,DRH8 \ 00 1C 40 \ 000088 76 90 60 00 DADD DR0,DR6,DR0 \ 00008C 76 90 80 83 DADD DR3,DR8,DR8 \ 000090 76 90 70 00 DADD DR0,DR7,DR0 \ 000094 F9 03 A3 00 DMOV.D #0x40220000,DRH10 \ 00 22 40 \ 00009B 76 90 80 00 DADD DR0,DR8,DR0 \ 00009F 76 90 A0 A3 DADD DR3,DR10,DR10 \ 0000A3 76 90 90 00 DADD DR0,DR9,DR0 \ 0000A7 F9 03 C3 00 DMOV.D #0x40260000,DRH12 \ 00 26 40 \ 0000AE 76 90 A0 00 DADD DR0,DR10,DR0 \ 0000B2 76 90 C0 C3 DADD DR3,DR12,DR12 \ 0000B6 76 90 B0 00 DADD DR0,DR11,DR0 \ 0000BA F9 03 E3 00 DMOV.D #0x402a0000,DRH14 \ 00 2A 40 \ 0000C1 76 90 C0 00 DADD DR0,DR12,DR0 \ 0000C5 76 90 E0 E3 DADD DR3,DR14,DR14 \ 0000C9 76 90 D0 00 DADD DR0,DR13,DR0 \ 0000CD F9 03 13 00 DMOV.D #0x402e0000,DRH1 \ 00 2E 40 \ 0000D4 76 90 E0 00 DADD DR0,DR14,DR0 \ 0000D8 76 90 10 33 DADD DR3,DR1,DR3 \ 0000DC 76 90 F0 00 DADD DR0,DR15,DR0 \ 0000E0 76 90 30 00 DADD DR0,DR3,DR0 \ 0000E4 76 90 20 00 DADD DR0,DR2,DR0 \ 0000E8 FC 79 18 06 DMOV.D DR0,0x18[R1] \ 00 …略… \ 000198 75 B8 0F DPOPM.D DR0,DR15 \ 00019B 02 RTS
# Command line =# ..\src\RXv3_Check_FSQRT_DSQRT_etc.c -o# src\RXv3_Check_FSQRT_DSQRT_etc.o --no_wrap_diagnostics# --require_prototypes -e --align_func=1 --tfu=none -Ohs# --no_size_constraints --no_cross_call --debug -lC ./ …略(-I)…# --remarks --source_encoding utf8 --utf8_text_in --text_out utf8# --save_acc --endian l --core rxv3 --fpu=*** --data_model=f --double=***# --int=32 --dlib_config C:/Renesas/EWB/8.4/rx/LIB/dlrxdlln.h
GNURXでのリストファイル
4 .section .text.Check_DPUSHM_DPOPM,"ax",@progbits 6 _Check_DPUSHM_DPOPM: 10 0000 75 B0 0F dpushm.d dr0-dr15 15 0003 FB 52 00 00 00 00 mov.L #_d1, r5 16 0009 FC C8 58 50 dmov.D [r5], dr5 17 000d FB 52 00 00 00 00 mov.L #_d2, r5 18 0013 FC C8 58 00 dmov.D [r5], dr0 20 0017 76 90 51 30 dsub dr0, dr5, dr3 22 001b 76 90 00 55 dadd dr5, dr0, dr5 24 001f F9 03 13 00 00 08 40 dmov.D #0x40080000, drh1 25 0026 76 90 10 15 dadd dr5, dr1, dr1 29 002a F9 03 63 00 00 10 40 dmov.D #0x40100000, drh6 30 0031 76 90 60 63 dadd dr3, dr6, dr6 34 0035 F9 03 F3 00 00 14 40 dmov.D #0x40140000, drh15 35 003c 76 90 F0 F5 dadd dr5, dr15, dr15 39 0040 76 90 62 41 dmul dr1, dr6, dr4 41 0044 76 90 11 06 dsub dr6, dr1, dr0 43 0048 F9 03 E3 00 00 18 40 dmov.D #0x40180000, drh14 44 004f 76 90 E0 E3 dadd dr3, dr14, dr14 48 0053 76 90 F2 44 dmul dr4, dr15, dr4 50 0057 76 90 01 0F dsub dr15, dr0, dr0 …略… 135 0103 F9 03 F3 00 00 2E 40 dmov.D #0x402e0000, drh15 138 010a 76 90 F0 55 dadd dr5, dr15, dr5 142 010e 76 90 62 44 dmul dr4, dr6, dr4 144 0112 76 90 01 06 dsub dr6, dr0, dr0 146 0116 76 90 25 2E ddiv dr14, dr2, dr2 148 011a 76 90 E0 11 dadd dr1, dr14, dr1 150 011e F9 03 E3 00 00 30 40 dmov.D #0x40300000, drh14 153 0125 76 90 E0 33 dadd dr3, dr14, dr3 157 0129 76 90 52 44 dmul dr4, dr5, dr4 159 012d 76 90 01 05 dsub dr5, dr0, dr0 161 0131 76 90 25 2D ddiv dr13, dr2, dr2 163 0135 76 90 D0 11 dadd dr1, dr13, dr1 165 0139 76 90 32 44 dmul dr4, dr3, dr4 167 013d 76 90 01 03 dsub dr3, dr0, dr0 169 0141 76 90 C0 11 dadd dr1, dr12, dr1 171 0145 76 90 25 2C ddiv dr12, dr2, dr2 173 0149 76 90 25 2B ddiv dr11, dr2, dr2 175 014d 76 90 B0 11 dadd dr1, dr11, dr1 177 0151 76 90 A0 11 dadd dr1, dr10, dr1 179 0155 76 90 25 2A ddiv dr10, dr2, dr2 181 0159 76 90 90 11 dadd dr1, dr9, dr1 183 015d 76 90 25 29 ddiv dr9, dr2, dr2 185 0161 76 90 80 11 dadd dr1, dr8, dr1 187 0165 76 90 25 28 ddiv dr8, dr2, dr2 189 0169 76 90 70 11 dadd dr1, dr7, dr1 191 016d 76 90 25 27 ddiv dr7, dr2, dr2 193 0171 76 90 60 11 dadd dr1, dr6, dr1 195 0175 76 90 25 26 ddiv dr6, dr2, dr2 197 0179 76 90 50 11 dadd dr1, dr5, dr1 199 017d 76 90 25 25 ddiv dr5, dr2, dr2 201 0181 76 90 30 11 dadd dr1, dr3, dr1 203 0185 76 90 25 23 ddiv dr3, dr2, dr2 205 0189 FB 52 00 00 00 00 mov.L #_dA, r5 208 018f FC 78 58 10 dmov.D dr1, [r5] 211 0193 FB 52 00 00 00 00 mov.L #_dB, r5 212 0199 FC 78 58 40 dmov.D dr4, [r5] 215 019d FB 52 00 00 00 00 mov.L #_dC, r5 216 01a3 FC 78 58 00 dmov.D dr0, [r5] 219 01a7 FB 52 00 00 00 00 mov.L #_dD, r5 220 01ad FC 78 58 20 dmov.D dr2, [r5] 222 01b1 75 B8 0F dpopm.d dr0-dr15 225 01b4 02 rts
こんにちは。NoMaYです。すみません、うっかり三角関数演算器の存在を忘れていました。実は私は仕組みが良く分かっていないのですが、コプロセッサとしてCPU本体と協調動作するという仕組みでは無いのですけれども、CPU本体は、演算終了までの期間、どういう状況になっているのか私は良く分かっていません。ということで少し調べてみようと思います。ちなみに、以下のハードウェアマニュアルの画面コピーの通り、演算時間は14クロックほどなので、CC-RXの -nouse_div_inst というコンパイルオプションで抑止される命令のうちのFDIV命令の実行時間と同等レベルのようです。以下、ハードウェアマニュアルの画面コピーです。RX660グループ ユーザーズマニュアル ハードウェア編R01UH0937JJ0100 Rev.1.00 Pages 2302 2022.03.18www.renesas.com/jp/ja/document/mah/rx660-group-users-manual-hardware#page=1928
こんにちは。NoMaYです。三角関数演算器を使用する場合の各コンパイラのコンパイルオプションは以下の通りです。(現状では、コンパイラによって、サポートされている数学関数に多寡があります。)
CC-RX : -tfu=intrinsic[,mathlib]ICCRX : --tfu {none|intrinsic|intrinsic_mathlib}GNURX : -mtfu=intrinsic[,mathlib]
以下、ドキュメントの画面コピーです。CC-RXICCRXGNURXRenesas - GNURX Migration Guide (コンパイラオプションの項目に説明が無くて、組み込み関数の項目に説明がある)llvm-gcc-renesas.com/migration-guides/rx/index.html#Built_in
こんにちは。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
こんにちは。NoMaYです。RXスマートコンフィグレータの(というかFITの)BSPモジュールにも三角関数演算器を使用するソースがありますね。r_bsp/mcu/all/r_rx_intrinsic_functions.c
#ifdef BSP_MCU_TRIGONOMETRIC#ifdef __TFU/******************************************************************************** Function Name: R_BSP_InitTFU* Description : Initialize arithmetic unit for trigonometric functions.* Arguments : none* Return Value : none*******************************************************************************/R_BSP_PRAGMA_INLINE_ASM(R_BSP_InitTFU)void R_BSP_InitTFU(void){ R_BSP_ASM_BEGIN R_BSP_ASM( PUSH.L R1 ) R_BSP_ASM( MOV.L #81400H, R1 ) R_BSP_ASM( MOV.B #7, [R1] ) R_BSP_ASM( MOV.B #7, 1[R1] ) R_BSP_ASM( POP R1 ) R_BSP_ASM_END} /* End of function R_BSP_InitTFU() */#ifdef __FPU/******************************************************************************** Function Name: R_BSP_CalcSine_Cosine* Description : Uses the trigonometric function unit to calculate the sine and cosine of an angle at the same time* (single precision).* Arguments : f - Value in radians from which to calculate the sine and cosine* : sin - Address for storing the result of the sine operation* : cos - Address for storing the result of the cosine operation* Return Value : none*******************************************************************************/R_BSP_PRAGMA_INLINE_ASM(R_BSP_CalcSine_Cosine)void R_BSP_CalcSine_Cosine(float f, float *sin, float *cos){ R_BSP_ASM_BEGIN R_BSP_ASM( PUSH.L R4 ) R_BSP_ASM( MOV.L #81410H, R4 ) R_BSP_ASM( MOV.L R1, 4[R4] ) R_BSP_ASM( MOV.L 4[R4], [R2] ) R_BSP_ASM( MOV.L [R4], [R3] ) R_BSP_ASM( POP R4 ) R_BSP_ASM_END} /* End of function R_BSP_CalcSine_Cosine() *//******************************************************************************** Function Name: R_BSP_CalcAtan_SquareRoot* Description : Uses the trigonometric function unit to calculate the arc tangent of x and y and the square root of * the sum of squares of these values at the same time (single precision).* Arguments : y - Coordinate y (the numerator of the tangent)* x - Coordinate x (the denominator of the tangent)* atan2 - Address for storing the result of the arc tangent operation for y/x* hypot - Address for storing the result of the square root of the sum of squares of x and y* Return Value : none*******************************************************************************/R_BSP_PRAGMA_INLINE_ASM(R_BSP_CalcAtan_SquareRoot)void R_BSP_CalcAtan_SquareRoot(float y, float x, float *atan2, float *hypot){ R_BSP_ASM_BEGIN R_BSP_ASM( PUSHM R5-R6 ) R_BSP_ASM( MOV.L #81418H, R5 ) R_BSP_ASM( MOV.L R2, [R5] ) R_BSP_ASM( MOV.L R1, 4[R5] ) R_BSP_ASM( MOV.L 4[R5], [R3] ) R_BSP_ASM( MOV.L [R5], R6 ) R_BSP_ASM( FMUL #3F1B74EEH, R6 ) R_BSP_ASM( MOV.L R6, [R4] ) R_BSP_ASM( POPM R5-R6 ) R_BSP_ASM_END} /* End of function R_BSP_CalcAtan_SquareRoot() */#endif /* __FPU */#endif /* __TFU */#endif /* BSP_MCU_TRIGONOMETRIC */
こんにちは。NoMaYです。ちょっと脱線しますけれども、RAマイコン向けに三角関数演算器に関するアプリケーションノートが出ていますね。RA6T2 Accelerators (IIRFA/TFU) performance in motor applicationwww.renesas.com/jp/ja/document/apn/ra6t2-accelerators-iirfatfu-performance-motor-applicationあと、RXマイコン向けにはベーシックなテーマでアプリケーションノートが出ていますね。RXv3 CPU搭載RXファミリ 数値計算用ライブラリ関数ベンチマークデータwww.renesas.com/us/ja/document/apn/rx-family-rxv3-cpu-mathematics-library-function-benchmark-data-rev100なお、どちらにも割り込み応答時間に関するデータは載っていないですね。(コンパイラの生成コード内で実行時間の長い命令が使用されると、その分だけ割り込みルーチンへ飛ぶのが遅れる可能性が生じる。)以下、ドキュメントの画面コピーです。RAマイコン向けのものRXマイコン向けのもの
こんにちは。NoMaYです。またちょっと脱線しますけれども、CC-RXは以下の関数で三角関数演算器を1回使用しただけでしたね。賢いなぁ、と思いました。(他方、ICCRXとGNURXは三角関数演算器を4回使用しました。ソース通りとも言えますが、普通かなぁ。)試したソースです。
struct vec { float X; float Y; };void rot(float t, struct vec *v1, struct vec *v2);void rot(float t, struct vec *v1, struct vec *v2){ v2->X = - sinf(t) * v1->Y + cosf(t) * v1->X; v2->Y = sinf(t) * v1->X + cosf(t) * v1->Y;}
CC-RXでのリストファイル (赤文字箇所で三角関数演算器の演算を開始させています)
00000000 _rot:00000000 FB4E101408 MOV.L #00081410H, R400000005 A049 MOV.L R1, 04H[R4]00000007 EC2F MOV.L [R2], R1500000009 A849 MOV.L 04H[R4], R10000000B EC4E MOV.L [R4], R140000000D A82C MOV.L 04H[R2], R40000000F FC8FEF FMUL R14, R1500000012 FC8F14 FMUL R1, R400000015 FC834F FSUB R4, R1500000018 E33F MOV.L R15, [R3]0000001A EC2F MOV.L [R2], R150000001C A82A MOV.L 04H[R2], R20000001E FC8FF1 FMUL R15, R100000021 FC8F2E FMUL R2, R1400000024 FC8BE1 FADD R14, R100000027 A039 MOV.L R1, 04H[R3]00000029 02 RTS
ICCRXでのリストファイル (赤文字箇所で三角関数演算器の演算を開始させています)
\ _rot: \ 000000 FB 5E 10 14 MOV.L #0x81410,R5 \ 08 \ 000005 A0 59 MOV.L R1,0x4[R5] \ 000007 A8 5C MOV.L 0x4[R5],R4 \ 000009 A0 59 MOV.L R1,0x4[R5] \ 00000B EC 5E MOV.L [R5],R14 \ 00000D EC 25 MOV.L [R2],R5 \ 00000F FC 8F E5 FMUL R14,R5 \ 000012 ED 2E 01 MOV.L 0x4[R2],R14 \ 000015 FC 8F E4 FMUL R14,R4 \ 000018 FF 84 45 FSUB R4,R5,R4 \ 00001B FB 5E 10 14 MOV.L #0x81410,R5 \ 08 \ 000020 E3 34 MOV.L R4,[R3] \ 000022 A0 59 MOV.L R1,0x4[R5] \ 000024 A8 5C MOV.L 0x4[R5],R4 \ 000026 EC 2F MOV.L [R2],R15 \ 000028 FC 8F 4F FMUL R4,R15 \ 00002B A0 59 MOV.L R1,0x4[R5] \ 00002D EC 51 MOV.L [R5],R1 \ 00002F A8 2D MOV.L 0x4[R2],R5 \ 000031 FC 8F 51 FMUL R5,R1 \ 000034 FC 8B F1 FADD R15,R1 \ 000037 A0 39 MOV.L R1,0x4[R3] \ 000039 02 RTS
GNURXでのリストファイル (赤文字箇所で三角関数演算器の演算を開始させています)(RXv3のDPFPUを有効にしているとDPFPUのレジスタを使う変なクセがありますね)
456 _rot: 461 0000 7E A7 push.l r7 463 0002 75 B0 01 dpushm.d dr0-dr1 467 0005 FB EE 14 14 08 mov.L #0x81414, r14 468 000a E3 E1 mov.L r1, [r14] 469 000c EC E4 mov.L [r14], r4 471 000e FB FE 10 14 08 mov.L #0x81410, r15 473 0013 A8 2F mov.L 4[r2], r7 475 0015 E7 F1 01 mov.L r1, 4[r15] 477 0018 FD 77 84 0A ftod r4, dr0 479 001c EC F4 mov.L [r15], r4 481 001e 76 90 0C 02 dneg dr0, dr0 482 0022 76 90 0D 1C dtof dr0, dr1 483 0026 FD 75 85 10 dmov.L drl1, r5 485 002a FC 8F 75 fmul r7, r5 487 002d EC 27 mov.L [r2], r7 488 002f FC 8F 74 fmul r7, r4 490 0032 FC 8B 45 fadd r4, r5 492 0035 E3 35 mov.L r5, [r3] 495 0037 E3 E1 mov.L r1, [r14] 496 0039 EC E4 mov.L [r14], r4 498 003b EC 2E mov.L [r2], r14 500 003d E7 F1 01 mov.L r1, 4[r15] 501 0040 EC F5 mov.L [r15], r5 503 0042 A8 2A mov.L 4[r2], r2 506 0044 FC 8F E4 fmul r14, r4 508 0047 FC 8F 25 fmul r2, r5 510 004a FC 8B 45 fadd r4, r5 512 004d A0 3D mov.L r5, 4[r3] 514 004f 75 B8 01 dpopm.d dr0-dr1 515 0052 7E B7 pop r7 516 0054 02 rts
こんにちは。NoMaYです。またちょっと脱線しますけれども、RA6T2の先日のアプリケーションノートのサンプルプログラムをダウンロードしてe2 studio v2022-10+fsp v4.1.0とGNU Arm Embedded Toolchain v10.3-2021.10もダウンロードして、先日の以下の関数のリストファイルをGNUARMで出力させてみました。(サンプルプログラムを使用したのはコンパイルオプションやFSP設定をどうすれば良いか分かりませんでしたので、きっと最適なものになっているに違いないと考えたからです。なお、ちょっと意外なことに最適化オプションが-O0になっていましたので-O3に変更するということは行いました。)RA6T2の先日のアプリケーションノートのサンプルプログラム(zipファイル)RA6T2 Accelerators (IIRFA/TFU) performance in motor applicationwww.renesas.com/jp/ja/document/scd/ra6t2-accelerators-iirfatfu-performance-motor-application試したソースです。
GNUARMでのコンパイルオプション
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16 -O3 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -Wuninitialized -Wall -Wextra -Wmissing-declarations -Wconversion -Wpointer-arith -Wshadow -Wlogical-op -Waggregate-return -Wfloat-equal -g -D_RENESAS_RA_ -D_RA_CORE=CM33 -I"C:/Renesas/GitHubDesktop/workspaces/workspace_e2v202210_fspv410/r01an6468xx0100-ra6t2/workspace/RA6T2_IIR_TFU_Sample_V100/src" -I"C:/Renesas/GitHubDesktop/workspaces/workspace_e2v202210_fspv410/r01an6468xx0100-ra6t2/workspace/RA6T2_IIR_TFU_Sample_V100/src/user_interface" -I"C:/Renesas/GitHubDesktop/workspaces/workspace_e2v202210_fspv410/r01an6468xx0100-ra6t2/workspace/RA6T2_IIR_TFU_Sample_V100/src" -I"C:/Renesas/GitHubDesktop/workspaces/workspace_e2v202210_fspv410/r01an6468xx0100-ra6t2/workspace/RA6T2_IIR_TFU_Sample_V100/ra/fsp/inc" -I"C:/Renesas/GitHubDesktop/workspaces/workspace_e2v202210_fspv410/r01an6468xx0100-ra6t2/workspace/RA6T2_IIR_TFU_Sample_V100/ra/fsp/inc/api" -I"C:/Renesas/GitHubDesktop/workspaces/workspace_e2v202210_fspv410/r01an6468xx0100-ra6t2/workspace/RA6T2_IIR_TFU_Sample_V100/ra/fsp/inc/instances" -I"C:/Renesas/GitHubDesktop/workspaces/workspace_e2v202210_fspv410/r01an6468xx0100-ra6t2/workspace/RA6T2_IIR_TFU_Sample_V100/ra/arm/CMSIS_5/CMSIS/Core/Include" -I"C:/Renesas/GitHubDesktop/workspaces/workspace_e2v202210_fspv410/r01an6468xx0100-ra6t2/workspace/RA6T2_IIR_TFU_Sample_V100/ra_gen" -I"C:/Renesas/GitHubDesktop/workspaces/workspace_e2v202210_fspv410/r01an6468xx0100-ra6t2/workspace/RA6T2_IIR_TFU_Sample_V100/ra_cfg/fsp_cfg/bsp" -I"C:/Renesas/GitHubDesktop/workspaces/workspace_e2v202210_fspv410/r01an6468xx0100-ra6t2/workspace/RA6T2_IIR_TFU_Sample_V100/ra_cfg/fsp_cfg" -std=c99 -Wa,-adhlns="src/iir_tfu_main.o.lst" -MMD -MP -MF"src/iir_tfu_main.d" -MT"src/iir_tfu_main.o" -c -o "src/iir_tfu_main.o" -x c "../src/iir_tfu_main.c"
GNUARMでのリストファイル (赤文字箇所で三角関数演算器の演算を開始させています)
3302 000a 00BF .section .text.rot,"ax",%progbits 3303 .align 1 3304 .p2align 2,,3 3305 .global rot 3306 .syntax unified 3307 .thumb 3308 .thumb_func 3310 rot: 3315 @ args = 0, pretend = 0, frame = 0 3316 @ frame_needed = 0, uses_anonymous_args = 0 3317 @ link register save eliminated. 3322 0000 134B ldr r3, .L42 3331 0002 83ED050A vstr.32 s0, [r3, #20] 3334 0006 93ED057A vldr.32 s14, [r3, #20] 3340 000a D0ED017A vldr.32 s15, [r0, #4] 3348 000e 83ED050A vstr.32 s0, [r3, #20] 3351 0012 D3ED046A vldr.32 s13, [r3, #16] 3357 0016 90ED006A vldr.32 s12, [r0] 3359 001a 27EE677A vnmul.f32 s14, s14, s15 3361 001e 66EE866A vmul.f32 s13, s13, s12 3363 0022 37EE267A vadd.f32 s14, s14, s13 3365 0026 81ED007A vstr.32 s14, [r1] 3374 002a 83ED050A vstr.32 s0, [r3, #20] 3377 002e 93ED057A vldr.32 s14, [r3, #20] 3383 0032 D0ED006A vldr.32 s13, [r0] 3387 0036 83ED050A vstr.32 s0, [r3, #20] 3391 003a 27EE267A vmul.f32 s14, s14, s13 3400 003e D3ED046A vldr.32 s13, [r3, #16] 3406 0042 67EEA67A vmul.f32 s15, s15, s13 3408 0046 77EE877A vadd.f32 s15, s15, s14 3410 004a C1ED017A vstr.32 s15, [r1, #4] 3412 004e 7047 bx lr 3413 .L43: 3414 .align 2 3415 .L42: 3416 0050 00100240 .word 1073876992 ⇒ 0x40021000
[関連リンク]命令セット - APS Academy Cortex-A編 (すみません、Cortex-M編より詳しかったのでCortex-A編を最初にしました)投稿日 2014年5月20日www.aps-web.jp/academy/ca/219/命令セット - APS Academy Cortex-M編投稿日 2012年11月30日www.aps-web.jp/academy/cm/253/[追記]以下、FSPのソースです。ra/fsp/src/bsp/mcu/all/bsp_tfu.h
#if BSP_CFG_USE_TFU_MATHLIB #define sinf(x) __sinf(x) #define cosf(x) __cosf(x) #define atan2f(y, x) __atan2f(y, x) #define hypotf(x, y) __hypotf(x, y) #define atan2hypotf(y, x, a, h) __atan2hypotf(y, x, a, h) #define sincosf(a, s, c) __sincosf(a, s, c)#endif
/***************************************************************************//** * Calculates sine of the given angle. * @param[in] angle The value of an angle in radian. * * @retval Sine value of an angle. ******************************************************************************/#if __ICCARM__ #pragma inline = forced#endifBSP_TFU_INLINE float __sinf (float angle){ /* Set the angle to R_TFU->SCDT1 */ R_TFU->SCDT1 = angle; /* Read sin from R_TFU->SCDT1 */ return R_TFU->SCDT1;}/***************************************************************************//** * Calculates cosine of the given angle. * @param[in] angle The value of an angle in radian. * * @retval Cosine value of an angle. ******************************************************************************/#if __ICCARM__ #pragma inline = forced#endifBSP_TFU_INLINE float __cosf (float angle){ /* Set the angle to R_TFU->SCDT1 */ R_TFU->SCDT1 = angle; /* Read cos from R_TFU->SCDT1 */ return R_TFU->SCDT0;}
/***************************************************************************//** * Calculates sine and cosine of the given angle. * @param[in] angle The value of an angle in radian. * @param[out] sin Sine value of an angle. * @param[out] cos Cosine value of an angle. ******************************************************************************/#if __ICCARM__ #pragma inline = forced#endifBSP_TFU_INLINE void __sincosf (float angle, float * sin, float * cos){ /* Set the angle to R_TFU->SCDT1 */ R_TFU->SCDT1 = angle; /* Read sin from R_TFU->SCDT1 */ *sin = R_TFU->SCDT1; /* Read sin from R_TFU->SCDT1 */ *cos = R_TFU->SCDT0;}
[追記]同じくra/fsp/src/bsp/mcu/all/bsp_tfu.hからです。
/***************************************************************************//** * Calculates the arc tangent based on given X-cordinate and Y-cordinate values. * @param[in] y_cord Y-Axis cordinate value. * @param[in] x_cord X-Axis cordinate value. * * @retval Arc tangent for given values. ******************************************************************************/#if __ICCARM__ #pragma inline = forced#endifBSP_TFU_INLINE float __atan2f (float y_cord, float x_cord){ /* Set X-cordinate to R_TFU->ATDT0 */ R_TFU->ATDT0 = x_cord; /* set Y-cordinate to R_TFU->ATDT1 */ R_TFU->ATDT1 = y_cord; /* Read arctan(y/x) from R_TFU->ATDT1 */ return R_TFU->ATDT1;}/***************************************************************************//** * Calculates the hypotenuse based on given X-cordinate and Y-cordinate values. * @param[in] y_cord Y-cordinate value. * @param[in] x_cord X-cordinate value. * * @retval Hypotenuse for given values. ******************************************************************************/#if __ICCARM__ #pragma inline = forced#endifBSP_TFU_INLINE float __hypotf (float x_cord, float y_cord){ /* Set X-coordinate to R_TFU->ATDT0 */ R_TFU->ATDT0 = x_cord; /* set Y-coordinate to R_TFU->ATDT1 */ R_TFU->ATDT1 = y_cord; /* Read sqrt (x_cord2 + y_cord2) from R_TFU->ATDT0 */ return R_TFU->ATDT0 * R_TFU_HYPOT_SCALING_FACTOR;}
/***************************************************************************//** * Calculates the arc tangent and hypotenuse based on given X-cordinate and Y-cordinate values. * @param[in] y_cord Y-cordinate value. * @param[in] x_cord X-cordinate value. * @param[out] atan2 Arc tangent for given values. * @param[out] hypot Hypotenuse for given values. ******************************************************************************/#if __ICCARM__ #pragma inline = forced#endifBSP_TFU_INLINE void __atan2hypotf (float y_cord, float x_cord, float * atan2, float * hypot){ /* Set X-coordinate to R_TFU->ATDT0 */ R_TFU->ATDT0 = x_cord; /* set Y-coordinate to R_TFU->ATDT1 */ R_TFU->ATDT1 = y_cord; /* Read arctan(y/x) from R_TFU->ATDT1 */ *atan2 = R_TFU->ATDT1; /* Read sqrt (x_cord2 + y_cord2) from R_TFU->ATDT0 */ *hypot = R_TFU->ATDT0 * R_TFU_HYPOT_SCALING_FACTOR;}
[追記]RA6T2の三角関数演算器の仕様はハードウェアマニュアルに記載されていますね。RA6T2 グループ ユーザーズマニュアル ハードウェア編www.renesas.com/jp/ja/document/mah/ra6t2-group-users-manual-hardware#page=1381
こんにちは。NoMaYです。またちょっと脱線しますけれども、CC-RX/ICCRX/GNURX/GNUARMで以下の関数のリストファイルを出力させてみました。各コンパイラでの関数のサイズです。
試したソースです。
#include <math.h>#if defined(__ICCRX__)#include <intrinsics.h>#elif defined(__GNUC__) && defined(_RENESAS_RA_)#include "bsp_api.h"#endifstruct vec { float X; float Y; };void rot_2(float t, struct vec *v1, struct vec *v2);void rot_2(float t, struct vec *v1, struct vec *v2){ float sinf_t, cosf_t;#if defined(__CCRX__) __sincosf(t, &sinf_t, &cosf_t);#elif defined(__ICCRX__) __sincosf(t, &sinf_t, &cosf_t);#elif defined(__GNUC__) && defined(__RX__) __builtin_rx_sincosf(t, &sinf_t, &cosf_t);#elif defined(__GNUC__) && defined(_RENESAS_RA_) __sincosf(t, &sinf_t, &cosf_t);#endif v2->X = - sinf_t * v1->Y + cosf_t * v1->X; v2->Y = sinf_t * v1->X + cosf_t * v1->Y;}
00000000 _rot_2:00000000 FB4E101408 MOV.L #00081410H, R400000005 A049 MOV.L R1, 04H[R4]00000007 EC2E MOV.L [R2], R1400000009 A849 MOV.L 04H[R4], R10000000B EC4F MOV.L [R4], R150000000D A82C MOV.L 04H[R2], R40000000F FC8FFE FMUL R15, R1400000012 FFB514 FMUL R1, R4, R500000015 FC8F4F FMUL R4, R1500000018 FC835E FSUB R5, R140000001B E33E MOV.L R14, [R3]0000001D FC8C21 FMUL [R2].L, R100000020 FC8BF1 FADD R15, R100000023 A039 MOV.L R1, 04H[R3]00000025 02 RTS00000026
ICCRXでのリストファイル (スタック上のsinf_tとcosf_tへの代入と参照が発生していますね)
\ _rot_2: \ 000000 60 80 SUB #0x8,SP \ 000002 FB 4E 10 14 MOV.L #0x81410,R4 \ 08 \ 000007 A0 49 MOV.L R1,0x4[R4] \ 000009 A8 49 MOV.L 0x4[R4],R1 \ 00000B A0 09 MOV.L R1,0x4[SP] \ 00000D EC 44 MOV.L [R4],R4 \ 00000F E3 04 MOV.L R4,[SP] \ 000011 EC 01 MOV.L [SP],R1 \ 000013 EC 24 MOV.L [R2],R4 \ 000015 ED 2E 01 MOV.L 0x4[R2],R14 \ 000018 A8 0D MOV.L 0x4[SP],R5 \ 00001A FC 8F 14 FMUL R1,R4 \ 00001D FC 8F 5E FMUL R5,R14 \ 000020 FF 8E E4 FSUB R14,R4,R14 \ 000023 E3 3E MOV.L R14,[R3] \ 000025 A8 09 MOV.L 0x4[SP],R1 \ 000027 EC 24 MOV.L [R2],R4 \ 000029 EC 05 MOV.L [SP],R5 \ 00002B ED 2E 01 MOV.L 0x4[R2],R14 \ 00002E FC 8F 14 FMUL R1,R4 \ 000031 FF B2 E5 FMUL R14,R5,R2 \ 000034 FC 8B 42 FADD R4,R2 \ 000037 A0 3A MOV.L R2,0x4[R3] \ 000039 67 02 RTSD #0x8 00003B
GNURXでのリストファイル (スタック上のsinf_tとcosf_tへの代入と参照が発生していますね) (RXv3のDPFPUを有効にしているとDPFPUのレジスタを使う変なクセがありますね)
427 _rot_2: 432 0000 75 B0 01 dpushm.d dr0-dr1 434 0003 60 80 sub #8, r0 438 0005 FB 5E 10 14 08 mov.L #0x81410, r5 439 000a A0 59 mov.L r1, 4[r5] 440 000c A8 5C mov.L 4[r5], r4 442 000e A8 29 mov.L 4[r2], r1 445 0010 EC 2E mov.L [r2], r14 447 0012 A0 0C mov.L r4, 4[r0] 450 0014 EC 5F mov.L [r5], r15 452 0016 A8 0C mov.L 4[r0], r4 453 0018 FD 77 84 0A ftod r4, dr0 454 001c 76 90 0C 02 dneg dr0, dr0 455 0020 76 90 0D 1C dtof dr0, dr1 456 0024 FD 75 85 10 dmov.L drl1, r5 458 0028 E3 0F mov.L r15, [r0] 461 002a EC 0F mov.L [r0], r15 463 002c FC 8F 15 fmul r1, r5 465 002f FC 8F FE fmul r15, r14 467 0032 FC 8B E5 fadd r14, r5 469 0035 E3 35 mov.L r5, [r3] 472 0037 EC 25 mov.L [r2], r5 474 0039 FC 8F F1 fmul r15, r1 476 003c FC 8F 54 fmul r5, r4 478 003f FC 8B 14 fadd r1, r4 480 0042 A0 3C mov.L r4, 4[r3] 482 0044 62 80 add #8, r0 483 0046 75 B8 01 dpopm.d dr0-dr1 484 0049 02 rts 004a
GNUARMでのリストファイル
3428 rot_2: 3441 0000 0E4B ldr r3, .L45 3450 0002 83ED050A vstr.32 s0, [r3, #20] 3453 0006 D3ED057A vldr.32 s15, [r3, #20] 3459 000a 90ED017A vldr.32 s14, [r0, #4] 3463 000e D3ED046A vldr.32 s13, [r3, #16] 3470 0012 D0ED005A vldr.32 s11, [r0] 3472 0016 27EEC76A vnmul.f32 s12, s15, s14 3474 001a 27EE267A vmul.f32 s14, s14, s13 3476 001e 66EEA56A vmul.f32 s13, s13, s11 3479 0022 76EE266A vadd.f32 s13, s12, s13 3481 0026 C1ED006A vstr.32 s13, [r1] 3484 002a D0ED006A vldr.32 s13, [r0] 3485 002e 67EEA67A vmul.f32 s15, s15, s13 3488 0032 77EE877A vadd.f32 s15, s15, s14 3490 0036 C1ED017A vstr.32 s15, [r1, #4] 3492 003a 7047 bx lr 3493 .L46: 3494 .align 2 3495 .L45: 3496 003c 00100240 .word 1073876992 ⇒ 0x40021000 0040