Hi, I am doing a port in GCC 4.5.1. For the port
1. there is only (reg + offset) addressing mode only when reg is SP. Other base registers are not allowed 2. FP cannot be used as a base register. (FP based addressing is done by copying it into a base register) In order to take advantage of FP elimination (this will create SP + offset addressing), what i did the following 1. Created a new register class (address registers + FP) and used this new class as the BASE_REG_CLASS 2. Defined HARD_REGNO_OK_FOR_BASE_P like the following : #define HARD_REGNO_OK_FOR_BASE_P(NUM) \ ((NUM) < FIRST_PSEUDO_REGISTER \ && (((reload_completed || reload_in_progress)? 0 : (NUM) == FP_REG) \ || REGNO_REG_CLASS(NUM) == ADD_REGS)) 3. In legitimate_address_p i have the followoing: if (REGNO (x) == FP_REG) { if (strict) return false; else return true; } else if (strict) return STRICT_REG_OK_FOR_BASE_P (REGNO (x)); else return NONSTRICT_REG_OK_FOR_BASE_P (REGNO (x)); But when FP doesn't get eliminated i will get address of the form (plus:QI (reg/f:QI 27 as15) (const_int 2)) which gets reloaded by replacing FP with address register, other than SP. I am guessing this happens because of modified BASE_REG_CLASS. I haven't confirmed this. So in order to over come this what i have done is, in legitimize_reload_address i have the following : if (GET_CODE (*x) == PLUS && REG_P (XEXP (*x, 0)) && REGNO (XEXP (*x, 0)) < FIRST_PSEUDO_REGISTER && GET_CODE (XEXP (*x, 1)) == CONST_INT && XEXP (*x, 0) == frame_pointer_rtx) { /* GCC will by default reload the FP into a BASE_CLASS_REG, which results in an invalid address. For us, the best thing to do is move the whole expression to a REG. */ push_reload (*x, NULL_RTX, x, NULL, SPAA_REGS, mode, VOIDmode,0, 0, opnum, (enum reload_type)type); return 1; } Does my logic makes sense? Is there any better way to implement this? With this implementation for the following sequence : (insn 9 6 10 2 fun_calls.c:12 (set (reg/f:QI 42) (mem/f/c/i:QI (plus:QI (reg/f:QI 33 AP) (const_int -2 [0xfffffffffffffffe])) [0 f+0 S1 A32])) 9 {movqi_op} (nil)) (insn 10 9 11 2 fun_calls.c:12 (set (reg:QI 43) (const_int 60 [0x3c])) 7 {movqi_op} (nil)) I am getting the following output: (insn 45 6 47 2 fun_calls.c:12 (set (reg:QI 28 a0) (const_int 2 [0x2])) 9 {movqi_op} (nil)) (insn 47 45 48 2 fun_calls.c:12 (set (reg:QI 28 a0) (reg/f:QI 27 as15)) 9 {movqi_op} (nil)) (insn 48 47 49 2 fun_calls.c:12 (set (reg:QI 28 a0) (plus:QI (reg:QI 28 a0) (const_int 2 [0x2]))) 14 {addqi3} (expr_list:REG_EQUIV (plus:QI (reg/f:QI 27 as15) (const_int 2 [0x2])) (nil))) (insn 49 48 10 2 fun_calls.c:12 (set (reg/f:QI 0 g0 [42]) (mem/f/c/i:QI (reg:QI 28 a0) [0 f+0 S1 A32])) 9 {movqi_op} (nil)) insn 45 is redundant. Is this generated because the legitimize_reload_address is wrong? Any hints as to why the redundant instruction gets generated? Regards, Shafi