>Peter Barada wrote: >> I'd like to make the reload look like: >> (set (reg:SI y) (plus:SI (reg_SI 16) (const_int 32832))) >> (set (reg:DF x) (mem:DF (reg:SI y))) > >Reload already knows how to make this transformation, so it should not >be necessary to resort to LEGITIMIZE_RELOAD_ADDRESS. This is only >needed for target specific tricks that reload can not and does not know >about. >
I figured out how to make it work using LEGITIMIZE_RELOAD_ADDRESS(at least for gcc-3.4.3) via: /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to replace the input X, or NULL_RTX if no replacement is called for. If a new X is returned, then goto WIN in the invoking macro. Reload will try to handle large displacements off a base register by pushing the displacement into a register and using mode6, but this doesn't work for the ColdFire FPU, so in that case, if the address is not valid for the mode, and is either mode 5 or mode 6, then push the *entire* address into a register and use mode 2 to access the value. */ rtx m68k_legitimize_reload_address (rtx *x, enum machine_mode mode, int opnum, int type, int ind_levels ATTRIBUTE_UNUSED) { /* If the address is valid for 'mode', accept it. */ if (strict_memory_address_p(mode, *x)) { return NULL_RTX; } /* The ColdFire v4e can't handle FP mode 6 addresses. Unfortunately reload tries to remap a mode 5 address with the offset out of range into a mode 6. Push an FP mode 5 with displacement out of range or mode 6 address into a register and use mode 2 addressing instead. */ if (TARGET_CFV4E && GET_MODE_CLASS (mode) == MODE_FLOAT && GET_CODE (*x) == PLUS && !(GET_CODE (XEXP (*x, 0)) == REG && ((GET_CODE (XEXP (*x, 1)) == CONST_INT && (INTVAL (XEXP (*x, 1)) >= -32768 && INTVAL (XEXP (*x, 1)) <= 32767))))) { push_reload (*x, NULL_RTX, x, NULL, BASE_REG_CLASS, GET_MODE (*x), VOIDmode, 0, 0, opnum, type); return *x; } return NULL_RTX; } Hopefully I got it right. If not, yell. :) >See the code in find_reloads_address with the comment > /* If we have address of a stack slot but it's not valid because the > displacement is too large, compute the sum in a register. > >The problem here seems to be that double_reg_address_ok is true, but you >don't want it to be true. It can only be true if >GO_IF_LEGITIMATE_ADDRESS accept REG+REG+4. Perhaps the problem here is >that a double address reg is OK for integer loads, but not for FP loads, >in which case the double_address_reg_ok logic in reloads needs to be >generalized a bit. Maybe an array based on mode instead of a single >variable? Or maybe just int and fp versions are good enough for now. For ColdFire v4e, FP loads and stores can not use REG+REG addressing. I think you are correct that this current hack can be improved by making an array of mode to determine if double_reg_address_ok should be true, but I think in the end that a more flexible scheme be thought about since this isn't the *only* peculiarity of the ColdFire. One is that pc-relative addressing is only available on the *source*, not the destination, and currently GO_IF_LEGITIMATE_ADDRESS nor LEGITIMIZE_ADDRESS have no way of know if its a source or destination. Unfortunately I don't have any spare time to try that approach this week. If I can find the time next week, I'll put together a patch against mainline that addresses this, but first I'd have to reproduce the problem there(which will give a testcase). -- Peter Barada [EMAIL PROTECTED]