On Thu, Jun 08, 2006 at 11:02:12PM +0200, Wolfgang Mües wrote:
> Rask,
>
> > arm-elf-gcc -g -mswp-byte-writes -Wall -O2 -fomit-frame-pointer
> > -ffast-math -mthumb-interwork -isystem
> > /usr/lib/devkitpro/libnds/include -mcpu=arm9tdmi -mtune=arm9tdmi
> > -DARM9 -S arm9_main.c -o arm9_main.S arm9_main.c: In function 'test':
> > arm9_main.c:20: error: unable to generate reloads for:
> > (insn:HI 20 21 22 1 arm9_main.c:16 (set (mem/v:QI (post_inc:SI
> > (reg/v/f:SI 3 r3 [orig:102 p ] [102])) [0 S1 A8]) (subreg/s/u:QI
> > (reg:SI 2 r2 [orig:103 c.36 ] [103]) 0)) 157 {*arm_movqi_insn_swp}
> > (nil) (expr_list:REG_INC (reg/v/f:SI 3 r3 [orig:102 p ] [102])
> > (nil)))
> > arm9_main.c:20: internal compiler error: in find_reloads, at
> > reload.c:3720
>
> void test(void)
[...]
>
> Without the change in arm_legitimate_address_p, we get post increment
> pointer into swpb. The non-working 'Q' constraint....
The constraint works, but reload doesn't figure out how to fix up the
operand. It does compile for me because reload fixes it:
Reloads for insn # 17
Reload 0: reload_in (SI) = (post_inc:SI (reg/v/f:SI 2 r2 [orig:102 p ] [102]))
reload_out (VOID) = (post_inc:SI (reg/v/f:SI 2 r2 [orig:102 p ] [102]))
GENERAL_REGS, RELOAD_FOR_INPUT (opnum = 0), inc by 1
reload_in_reg: (post_inc:SI (reg/v/f:SI 2 r2 [orig:102 p ] [102]))
reload_reg_rtx: (reg:SI 3 r3)
test:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
ldr r0, .L8
@ lr needed for prologue
ldrb r1, [r0, #0] @ zero_extendqisi2
mov r2, #134217728
.L2:
mov r3, r2
swpb ip, r1, [r3, #0]
ldr r3, .L8+4
add r2, r2, #1
cmp r2, r3
bne .L2
mov r3, #40
swpb r2, r3, [r0, #0]
bx lr
Reload probably got smarter since the version you use. The post_inc address
first appears during the life1 pass. It should be possible to prevent it
from appearing with an appropriate predicate. Try adding this:
; Match (mem (reg ...)), just like the Q constraint.
(define_predicate "Q_memory_operand"
(and (match_code "mem")
(match_code "reg" "0"))
)
Then change the *swp* patterns to use Q_memory_operand instead of
memory_operand. I then get
test:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
ldr r0, .L8
@ lr needed for prologue
ldrb r1, [r0, #0] @ zero_extendqisi2
mov r2, #134217728
.L2:
ldr r3, .L8+4
swpb ip, r1, [r2, #0]
add r2, r2, #1
cmp r2, r3
bne .L2
mov r3, #40
swpb r2, r3, [r0, #0]
bx lr
which is an improvement.
--
Rask Ingemann Lambertsen