こんにちは。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
> この実装は駄目ですね
一時変数を使用した単なる交換では排他制御に使えないのも勿論ですが、実行効率を上げる等の目的で特別な命令を吐かせたいところで用意されてる組み込み関数をただの関数として用意している時点で呼び出しコストも発生するし何考えてんのかという感じですね。
$ cat -n hoge.c 1 #include <CCRXmachine.h> 2 3 extern signed long var0, var1, var2; 4 5 void hoge(void) 6 { 7 xchg(&var0, &var1); 8 xchg(&var1, &var2); 9 xchg(&var2, &var0); 10 } $ rx-elf-gcc -O2 -c hoge.c ; rx-elf-objdump -d hoge.o CCRXmachine.o hoge.o: file format elf32-rx-le Disassembly of section P: 00000000 <_hoge>: 0: fb 12 00 00 00 00 mov.l #0, r1 6: fb 22 00 00 00 00 mov.l #0, r2 c: 05 00 00 00 bsr.a c <_hoge+0xc> 10: fb 12 00 00 00 00 mov.l #0, r1 16: fb 22 00 00 00 00 mov.l #0, r2 1c: 05 00 00 00 bsr.a 1c <_hoge+0x1c> 20: fb 12 00 00 00 00 mov.l #0, r1 26: fb 22 00 00 00 00 mov.l #0, r2 2c: 04 00 00 00 bra.a 2c <_hoge+0x2c> CCRXmachine.o: file format elf32-rx-le Disassembly of section P: 00000000 <_xchg>: 0: ec 15 mov.l [r1], r5 2: e0 21 mov.l [r2], [r1] 4: e3 25 mov.l r5, [r2] 6: 02 rts $
ヘッダファイルに
static inline void xchg(signed long *data1, signed long *data2) __attribute__((always_inline)); static inline void xchg(signed long *data1, signed long *data2) { signed long temp = *data1; __asm __volatile( " xchg [%1], %0\n" : "+r"(temp) : "r"(data2) ); *data1 = temp; }
とかあれば、
$ cat -n piyo.c 1 #include <CCRXmachine.h> 2 3 extern signed long var0, var1, var2; 4 5 void piyo(void) 6 { 7 xchg(&var0, &var1); 8 xchg(&var1, &var2); 9 xchg(&var2, &var0); 10 } $ rx-elf-gcc -O2 -c piyo.c ; rx-elf-objdump -d piyo.o piyo.o: file format elf32-rx-le Disassembly of section P: 00000000 <_piyo>: 0: fb 32 00 00 00 00 mov.l #0, r3 6: ec 32 mov.l [r3], r2 8: fb 42 00 00 00 00 mov.l #0, r4 e: 06 a0 10 42 xchg [r4].l, r2 12: fb 52 00 00 00 00 mov.l #0, r5 18: e3 32 mov.l r2, [r3] 1a: ec 42 mov.l [r4], r2 1c: 06 a0 10 52 xchg [r5].l, r2 20: e3 42 mov.l r2, [r4] 22: ec 54 mov.l [r5], r4 24: 06 a0 10 34 xchg [r3].l, r4 28: e3 54 mov.l r4, [r5] 2a: 02 rts $
低コストで xchg 命令も吐けて良いと思うのだけどなあ。
> 逆に-fltoがないとinline宣言してもインライン展開されないこともあったり、 関数宣言時に __attribute__((always_inline)) を指定しすると -flto に関係なくインライン展開が強制されると思いますが上手く行かないことがあるでしょうか? あるいは、インラインアセンブラを関数風のマクロで使用するというのも手だと思います。