試したのはこれです。shortでbit1です。
/*volatile*/
unsigned
short bar1;
/*volatile*/
unsigned
short bar;
void
tst_bar_bit1(void)
{
if(bar1&2)
bar &= ~2;
else
bar |= 2;
}
rx-elf-gccで-O2 -fomitframe-pointerでコンパイルすると
0000 FB E2 00 00 00 00 mov.L #_bar1, r14
0006 DC EE mov.W [r14], r14
0008 64 2E and #2, r14
000a 5F EE movu.W r14, r14
000c 61 0E cmp #0, r14
000e FB E2 00 00 00 00 mov.L #_bar, r14
0014 DC E4 mov.W [r14], r4
0016 1E bne .L5
0017 65 24 or #2, r4
0019 D3 E4 mov.W r4, [r14]
001b 02 rts
.L5:
001c 75 24 FD and #-3, r4
001f D3 E4 mov.W r4, [r14]
0021 02 rts
色の付いたところをbtst命令を使うようにしてみます。
Failed to match this instruction:
(set (pc)
(if_then_else (eq (if_then_else:SI (zero_extract:SI (subreg:SI (reg:HI 31 [ bar1 ]) 0)
(const_int 1 [0x1])
(const_int 1 [0x1]))
(const_int 2 [0x2])
(const_int 0 [0]))
(const_int 0 [0]))
(label_ref 20)
(pc)))
このコンバインパターンを成功するように
(define_insn_and_split "*cbranchhi4_tst_ext"
[(set (pc)
(if_then_else
(match_operator 4 "rx_z_comparison_operator"
[ (if_then_else:SI
(zero_extract:SI
(subreg:SI
(match_operand:HI 0 "register_operand" "r")
0)
(match_operand 1 "rx_constshift_operand" "")
(match_operand 2 "rx_constshift_operand" ""))
(match_operand 5 "const_int_operand" "")
(const_int 0))
(const_int 0)])
(match_operand 3 "label_ref_operand" "")
(pc)))]
"INTVAL (operands[1]) == 1"
"#"
"reload_completed"
[(const_int 0)]
{
HOST_WIDE_INT mask;
rtx x;
mask = 1;
mask <<= INTVAL (operands[1]);
mask -= 1;
mask <<= INTVAL (operands[2]);
operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
x = gen_rtx_AND (SImode, operands[0], gen_int_mode (mask, SImode));
rx_split_cbranch (CC_ZSmode, GET_CODE (operands[4]),
x, const0_rtx, operands[3]);
DONE;
})
これをrx.mdのその2の前あたりに追加します。
この変更を使ったgccでコンパイルすると
0000 FB E2 00 00 00 00 mov.L #_bar1, r14
0006 DC EE mov.W [r14], r14
0008 7C 1E btst #1, r14
000a FB E2 00 00 00 00 mov.L #_bar, r14
0010 DC E4 mov.W [r14], r4
0012 1E bne .L5
0013 65 24 or #2, r4
0015 D3 E4 mov.W r4, [r14]
0017 02 rts
.L5:
0018 75 24 FD and #-3, r4
001b D3 E4 mov.W r4, [r14]
001d 02 rts
こうなります。
[0回]
PR