こんにちは。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.he2 studioインストールフォルダ\internal\projectgen\rx\Generate\CCRXConversion\inc\CCRXmachine.c
こんにちは。NoMaYです。今朝、ちょっと頭に浮かんだ言葉があります。今回の件がどうなのかは分かりませんが、、、「GNURXへの愛ゆえに仕方が無いと現状のコードを擁護するか、GNURXへの愛ゆえにもっと良いコードが書けるのにと批判するか」それはそれとして、xchg()関数の他にmacl()関数を調べてみました。CC-RXでは、ループアンローリングまでして実行性能に気を使っているようですね。 [訂正]すみません、違っていました。でも、何だろう、、、 [再度訂正]再度すみません。素朴なループアンローリングではありませんでしたが、RXマイコンのMACLO命令とMACHI命令の動作をうまく利用してループ回数を半分にする技巧が使われていました。[ここまで] GNURX対応のCCRXmachine.cでは、呼び出しているビルトイン関数の事情で無駄なレジスタ操作が増えてしまっているのと、returnの部分の非効率さが、目に付きますね、、、([追記] CC-RXのmacl()関数のコードを理解した後で見るとCCRXmachine.cのmacl()関数のコードは変な気がします。)●CC-RXの記述machine.h
#ifndef _MACHINE#define _MACHINE#include <macro.h>#include <builtin.h>・・・#define macl(data1, data2, count) _builtin_macl(data1, data2, count)・・・#endif
builtin.h
#ifndef _BUILTIN#define _BUILTIN#include <macro.h>#ifdef __cplusplusextern "C" {#endif/* follow machine.h */・・・extern long _builtin_macl(short *, short *, unsigned long);・・・#ifdef __cplusplus}#endif /* #ifdef __cplusplus */#endif /* #ifndef _BUILTIN */
●GNURX対応のCCRXmachin.hとCCRXmachin.cの記述CCRXmachin.h
・・・long macl(short* data1, short* data2, unsigned long count);・・・
CCRXmachin.c
signed long long get_acc(void){ signed long long result = ((signed long long)__builtin_rx_mvfachi()) << 32; result |= (((signed long long)__builtin_rx_mvfacmi()) << 16) & 0xFFFF0000; return result;}・・・long macl(short* data1, short* data2, unsigned long count){ unsigned long index; __builtin_rx_mullo(0, 0); for(index = 0; index < count; index++) { __builtin_rx_maclo(data1[index], data2[index]); __builtin_rx_machi(data1[index], data2[index]); } return (long)(get_acc() >> 16);}
●CC-RXでの生成コード(当方特有の事情でCC-RX V2.03を使用)Cソース
long macl__(short* data1, short* data2, unsigned long count);long macl__(short *data1, short *data2, unsigned long count ){ return macl(data1, data2, count);}
リストファイル
; 31 long macl__(short *data1, short *data2, unsigned long count )00000001 6103 CMP #00H, R3 ; 32 { ; 33 return macl(data1, data2, count);00000003 660E MOV.L #00000000H, R1400000005 FD01EE MULLO R14, R1400000008 20rr BEQ L170000000A L12: ; entry0000000A 7C03 BTST #00H, R30000000C 22rr BGEU L140000000E L13: ; entry0000000E 6023 SUB #02H, R300000010 FD2A1E MOV.L [R1+], R1400000013 FD2A25 MOV.L [R2+], R500000016 FD05E5 MACLO R14, R500000019 FD04E5 MACHI R14, R50000001C 21rr BNE L130000001E 2Err B BRA L1700000020 L14: ; entry00000020 6013 SUB #01H, R300000022 20rr BEQ L1600000024 L15: ; entry00000024 6023 SUB #02H, R300000026 FD2A1E MOV.L [R1+], R1400000029 FD2A25 MOV.L [R2+], R50000002C FD05E5 MACLO R14, R50000002F FD04E5 MACHI R14, R500000032 21rr BNE L1500000034 L16: ; entry00000034 DC1E MOV.W [R1], R1400000036 DC25 MOV.W [R2], R500000038 FD05E5 MACLO R14, R50000003B L17: ; entry0000003B FD1F21 MVFACMI R1 ; 34 }0000003E 02 RTS
●GNURXでの生成コード(2018q1を使用)リストファイル
280:../src/CCRXmachine.c **** long macl(short* data1, short* data2, unsigned long count) 281:../src/CCRXmachine.c **** { 401 0105 7E A7 push.l r7 282:../src/CCRXmachine.c **** unsigned long index; 283:../src/CCRXmachine.c **** __builtin_rx_mullo(0, 0); 404 0107 66 05 mov.L #0, r5 405 0109 FD 01 55 mullo r5, r5 284:../src/CCRXmachine.c **** for(index = 0; index < count; index++) 408 010c 47 53 cmp r5, r3 409 010e 20 1C beq .L41 411 .balign 8,3,1 412 .L42: 413 0110 EF 14 mov.L r1, r4 414 0112 EF 2E mov.L r2, r14 285:../src/CCRXmachine.c **** { 286:../src/CCRXmachine.c **** __builtin_rx_maclo(data1[index], data2[index]); 416 0114 FD 29 1F mov.W [r1+], r15 417 0117 FD 29 27 mov.W [r2+], r7 418 011a FD 05 F7 maclo r15, r7 287:../src/CCRXmachine.c **** __builtin_rx_machi(data1[index], data2[index]); 420 011d DC 44 mov.W [r4], r4 421 011f DC EE mov.W [r14], r14 422 0121 FD 04 4E machi r4, r14 284:../src/CCRXmachine.c **** for(index = 0; index < count; index++) 424 0124 62 15 add #1, r5 426 0126 47 35 cmp r3, r5 427 0128 21 E8 bne .L42 429 .balign 8,3,2 430 .L41: 261:../src/CCRXmachine.c **** result |= (((signed long long)__builtin_rx_mvfacmi()) << 16) & 0xFFFF0000; 434 012a FD 1F 07 mvfachi r7 262:../src/CCRXmachine.c **** return result; 436 012d FD 1F 21 mvfacmi r1 288:../src/CCRXmachine.c **** } 289:../src/CCRXmachine.c **** return (long)(get_acc() >> 16); 440 0130 6D 07 shll #16, r7 441 0132 5F 11 movu.W r1, r1 442 0134 57 71 or r7, r1 290:../src/CCRXmachine.c **** } 444 0136 3F 77 01 rtsd #4, r7-r7
こんにちは。NoMaYです。前の投稿でmacl()関数を調べてみて、何か腑に落ちない、という感覚があったのですが、どうもGNURX対応のCCRXmachine.cのmacl()関数はバグっていると思われます。以下のデータで結果を求めてみると、CC-RXのmacl()関数とGNURX対応のCCRXmachine.cのmacl()関数では結果が異なってしまいました。データ:short data1[3] = {-1, -2, -3};short data2[3] = {-1, -2, -3};プログラム:long result;result = macl(data1, data2, 3);期待値:(-1)*(-1) + (-2)*(-2) + (-3)*(-3) = 14結果:CC-RXのmacl()関数 → 14GNURX対応のCCRXmachine.cのmacl()関数 → 17これは私の推測なのですが、CC-RXのmacl()関数で使われているループ回数を半減させる技法をきちんと理解せずにコードを真似たことにより、GNURX対応のCCRXmachine.cのmacl()関数のコードにバグが入ってしまったのではないかと思われます、、、