Thanks Jim and Ian. I've added a secondary_reload which does this: ... if (code == MEM) { if (fp_plus_const_operand(XEXP(x, 0), mode)) { sri->icode = in_p ? CODE_FOR_reload_insi : CODE_FOR_reload_outsi; return NO_REGS; }
where fp_plus_const_operand is taken from the bfin port - it checks that this is RTL of the form ((plus (reg const)). The .md file contains: --- (define_expand "reload_insi" [(parallel [(set (match_operand:SI 0 "register_operand" "=r") (match_operand:SI 1 "memory_operand" "m")) (clobber (match_operand:SI 2 "register_operand" "=a"))])] "" { fprintf(stderr, "reload_insi\n"); rtx plus_op = XEXP(operands[1], 0); rtx fp_op = XEXP (plus_op, 0); rtx const_op = XEXP (plus_op, 1); rtx primary = operands[0]; rtx scratch = operands[2]; emit_move_insn (scratch, fp_op); emit_insn (gen_addsi3 (scratch, scratch, const_op)); emit_move_insn (primary, gen_rtx_MEM(Pmode, scratch)); DONE; } ) (define_expand "reload_outsi" [(parallel [(match_operand 0 "memory_operand" "=m") (match_operand 1 "register_operand" "r") (match_operand:SI 2 "register_operand" "=&a")])] "" { fprintf(stderr, "reload_outsi\n"); rtx plus_op = XEXP(operands[0], 0); rtx fp_op = XEXP (plus_op, 0); rtx const_op = XEXP (plus_op, 1); rtx primary = operands[1]; rtx scratch = operands[2]; emit_move_insn (scratch, fp_op); emit_insn (gen_addsi3 (scratch, scratch, const_op)); emit_move_insn (gen_rtx_MEM(Pmode, scratch), primary); DONE; } ) --- The reload_insi is being called and is expanding into the correct code but for some reason the reload_outsi never gets called. sri->icode is being set correctly and propagates a few levels up but I couldn't track it any further. The s390 port does the reload in the same way as me. The bfin is similar. I haven't looked further into GO_IF_LEGITIMATE_ADDRESS but it's the next part to look at. It's a stripped down version of the mmix one so it should be roughly OK. I'm a bit confused with the documentation versus the ports. For example, REGNO_MODE_CODE_OK_FOR_BASE_P doesn't appear to need a strict form according to the documentation but the bfin port has a strict and non-strict version. Most of the ports have a REG_OK_FOR_BASE_P macro with strict and non-strict versions macro but it's not documented, isn't used, and might have been removed around gcc 4.0. Any ideas on why the reload_outsi above is being eaten? Thanks, -- Michael 2009/4/30 Jim Wilson <wil...@codesourcery.com>: > Michael Hope wrote: >> >> HI there. I'm working on porting gcc to a new architecture which only >> does indirect addressing - there is no indirect with displacement. > > The IA-64 target also has only indirect addressing. Well, it has some > auto-increment addressing modes too, but that isn't relevant here. You > could try looking at the IA-64 port to see why it works and yours doesn't. > >> The problem is with spill locations in GCC 4.4.0. The elimination >> code correctly elimates the frame and args pointer and replaces it >> with register X. The problem is that it then generates indirect with >> offset loads to load spilt values. > > Since this is happening inside reload, first thing I would check is to make > sure you handle REG_OK_STRICT correctly. Before reload, a pseudo-reg is a > valid memory address. Inside reload, an unallocated pseudo-reg is actually > a memory location, and hence can not be a valid memory address. This is > controlled by REG_OK_STRICT. > > Jim >