試したのはこれです。今回はbit1です。
/*volatile*/
unsigned
char bar1;
/*volatile*/
unsigned
char 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 CC EE mov.B [r14], r14
0008 64 2E and #2, r14
000a 5B EE movu.B r14, r14
000c 61 0E cmp #0, r14
000e FB E2 00 00 00 00 mov.L #_bar, r14
0014 1C bne .L5
0015 F0 E1 bset #1, [r14].B
0017 02 rts
.L5:
0018 F0 E9 bclr #1, [r14].B
001a 02 rts
こうなります。(注:改造したrx-elf-gccを使っているので出力コードが違うことがあります)
色の付いたところをbtst命令を使うようにしてみます。
Failed to match this instruction:
(set (pc)
(if_then_else (eq (if_then_else:SI (zero_extract:SI (subreg:SI (reg:QI 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 21)
(pc)))
コンバインパターンを成功するように
(define_insn_and_split "*cbranchqi4_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:QI 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のその1の前あたりに追加します。
この変更を使ったgccでコンパイルすると
0000 FB E2 00 00 00 00 mov.L #_bar1, r14
0006 CC EE mov.B [r14], r14
0008 7C 1E btst #1, r14
000a FB E2 00 00 00 00 mov.L #_bar, r14
0010 1C bne .L5
0011 F0 E1 bset #1, [r14].B
0013 02 rts
.L5:
0014 F0 E9 bclr #1, [r14].B
0016 02 rts
btstを使うようになります。
[0回]
PR