こんにちは。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
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:つーか、ただの交換も機能しない罠。
static rtxrx_expand_builtin_xchg (tree exp){ rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0)); rtx arg2 = expand_normal (CALL_EXPR_ARG (exp, 1)); /* if arg2 is a reg than we can safely use the form xchg [Rs].memex, Rd, othewise only xchg Rs, Rd */ if(REG_P(arg2)) { rtx mem1 = gen_rtx_MEM (SImode, arg1); rtx mem2 = gen_rtx_MEM (SImode, arg2); rtx mem1toreg = copy_to_reg(mem1); MEM_VOLATILE_P (mem1) = 1; MEM_VOLATILE_P (mem2) = 1; emit_insn (gen_exchangesi (mem1toreg, mem2)); emit_move_insn(mem1, mem1toreg); } else { rtx mem1 = gen_rtx_MEM (SImode, arg1); rtx mem2 = gen_rtx_MEM (SImode, arg2); rtx mem1toreg = copy_to_reg(mem1); rtx mem2toreg = copy_to_reg(mem2); MEM_VOLATILE_P (mem1) = 1; MEM_VOLATILE_P (mem2) = 1; emit_insn (gen_exchangesi (mem1toreg, mem2toreg)); emit_move_insn(mem1, mem1toreg); emit_move_insn(mem2, mem2toreg); } return NULL_RTX;}
> ひょっとして、後続の最適化処理で命令の順番が入れ替わってしまったのでは?
最適化レベル 0 や 1 でコンパイルすると効率は悪いものゝ交換自体には問題がないっぽいコードを吐くのでそれっぽい感じですね。
$ rx-elf-gcc -O0 xchgTest.c -S -o - .file "xchgTest.c" .section P,"ax" .global _hoge .type _hoge, @function _hoge: push.l r6 mov.L r0, r6 mov.L #_a, r5 mov.L [r5], r4 mov.L #_b, r5 mov.L [r5], r5 xchg r5, r4 mov.L #_a, r3 mov.L r4, [r3] mov.L #_b, r4 mov.L r5, [r4] rtsd #4, r6-r6 .size _hoge, .-_hoge .ident "GCC: (GCC_Build_20180316) 4.8.4.201801-GNURX" $ rx-elf-gcc -O1 xchgTest.c -S -o - .file "xchgTest.c" .section P,"ax" .global _hoge .type _hoge, @function _hoge: mov.L #_a, r3 mov.L [r3], r2 mov.L #_b, r5 mov.L [r5], r4 xchg r4, r2 mov.L r2, [r3] mov.L r4, [r5] rts .size _hoge, .-_hoge .ident "GCC: (GCC_Build_20180316) 4.8.4.201801-GNURX" $