I have a CPU which only operates on 32bit registers and as such define
WORD_REGISTER_OPERATIONS. This works well for arithmetic operations (everything
read to SI pseudo registers) but does not seem to apply to bitwise operators.
This generates marginally non-optimal code (additional sign extends on result)
and requires additional load instructions for QI and HI registers which zero
extend and are otherwise not required for anything else.
Is there any way to force the same SI pseudo register allocation for bitwise
operators as arithmetic? I have the usual PROMOTE_MODE to SImode defined, but
this doesn't appear to affect the pseudo register allocation.
For example, the difference between & and + for "(int) return ptr[0] op
ptr[1];" for char *ptr --
(insn 7 4 8 2 (set (reg:QI 31)
(mem:QI (reg/v/f:SI 28 [ ptr ]) [0 *ptr_5(D)+0 S1 A8])) "test.c":3:16 -1
(nil))
(insn 8 7 9 2 (set (reg:QI 32)
(mem:QI (plus:SI (reg/v/f:SI 28 [ ptr ])
(const_int 1 [0x1])) [0 MEM[(signed char *)ptr_5(D) + 1B]+0 S1
A8])) "test.c":3:16 -1
(nil))
(insn 9 8 10 2 (set (reg:SI 33)
(and:SI (subreg:SI (reg:QI 31) 0)
(subreg:SI (reg:QI 32) 0))) "test.c":3:16 -1
(nil))
(insn 10 9 11 2 (set (reg:SI 30 [ _6 ])
(sign_extend:SI (subreg:QI (reg:SI 33) 3))) "test.c":3:16 -1
(nil))
(insn 7 4 8 2 (set (reg:SI 32 [ _2 ])
(sign_extend:SI (mem:QI (reg/v/f:SI 29 [ ptr ]) [0 *ptr_6(D)+0 S1
A8]))) "test.c":3:12 -1
(nil))
(insn 8 7 9 2 (set (reg:SI 33 [ _4 ])
(sign_extend:SI (mem:QI (plus:SI (reg/v/f:SI 29 [ ptr ])
(const_int 1 [0x1])) [0 MEM[(signed char *)ptr_6(D) + 1B]+0
S1 A8]))) "test.c":3:21 -1
(nil))
(insn 9 8 10 2 (set (reg:SI 31 [ _7 ])
(plus:SI (reg:SI 32 [ _2 ])
(reg:SI 33 [ _4 ]))) "test.c":3:16 -1
(nil))
The arithmetic route allocates an SI register from the start and can correctly
sign extend the source compared to the bitwise route allocating QI (zero
extended) for the source, doing a full SI and anyway then sign extending the
result.
Thanks,
-- James