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

Reply via email to