Now my GO_IF_LEGITIMATE_ADDRESS refuses anything that is not a REG or a CONSTANT_ADDRESS:
int legitimate_address1(enum machine_mode MODE,rtx X) { if(CONSTANT_ADDRESS_P(X)) return 1; if(GET_CODE(X)==REG && is_base_reg(REGNO(X))) return 1; return 0; /* fails everything else */ } /* this is the strict version, the non strict version is similar */ but GCC (4.0.2, just in case the version is relevant) still aborts the compilation. Then I found this wiki note about forcing complex addresses into registers: http://gcc.gnu.org/wiki/WritingANewBackEnd ... rtx copy_addr_to_reg (rtx x) Equivalent to copy_to_mode_reg (Pmode, x). For example, this function can be used to compute a complex address X in a register for an instruction which supports only register indirect addressing. See also replace_equiv_address() below. ... Thus I changed in the .md file the movXX RTL expand macro to force any MEM expression into a register: (define_expand "movhi" /* my micro is 16 bit... */ [(set (match_operand:HI 0 "nonimmediate_operand" "") (match_operand:HI 1 "general_operand" "") )] "" { if(!no_new_pseudos && GET_CODE(operands[0])==MEM) { if( /* addr in operands[0] == base reg + offset */ ) operands[0] = copy_addr_to_reg ( operands[0] ); } ) The GCC still fails to generate the assembly code to do the arithmetic computation of the baseReg+offset-->tempReg, and then use (tempReg) as address. Note that with the current MD GCC is able to generate simple sums like R1 = R2 + R3 and R1 = R2 + IMM, thus the basic math to compute an address is there. Any suggestion on what I am doing wrong ? Sergio Michael Hope wrote: > Hi Sergio. My port has similar addressing modes - all memory must be > accessed by one of two registers and can only be accessed indirectly, > indirect with pre increment, and indirect with post increment. The > key is GO_IF_LEGITIMATE_ADDRESS and the legitimate address helper > function. Mine looks like this: > > /* Return 1 if the address is OK, otherwise 0. > Used by GO_IF_LEGITIMATE_ADDRESS. */ > > bool > tomi_legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED, > rtx x, > bool strict_checking) > { > /* (mem reg) */ > if (REG_P (x) > && tomi_reg_ok (x, strict_checking) > ) > { > return 1; > } > > if (GET_CODE(x) == PRE_DEC) > { > ... > } > > if (GET_CODE(x) == POST_INC) > { > ... > } > > return 0; > } > > tomi_reg_ok returns true if x is any register when strict checking is > clear and true if x is one of my addressing registers when strict > checking is set. > > GCC will feed any memory accesses through this function to see if they > are directly supported, and if not it will break them up into > something smaller and try again. > > Hope that helps, > > -- Michael > > > 2010/1/26 Sergio Ruocco <sergio.ruo...@gmail.com>: >> Gabriel Paubert wrote: >>> On Mon, Jan 25, 2010 at 01:34:09PM +0100, Sergio Ruocco wrote: >>>> Hi everyone, >>>> >>>> I am porting GCC to a custom 16-bit microcontroller with very limited >>>> addressing modes. Basically, it can only load/store using a (general >>>> purpose) register as the address, without any offset: >>>> >>>> LOAD (R2) R1 ; load R1 from memory at address (R2) >>>> STORE R1 (R2) ; store R1 to memory at address (R2) >>>> >>>> As far as I can understand, this is more limited than the current >>>> architectures supported by GCC that I found in the current gcc/config/*. >>> The Itanium (ia64) has the same limited choice of addressing modes. >>> >>> Gabriel >> Thanks Gabriel. >> >> I dived into the ia64 md, but it is still unclear to me how the various >> parts (macros, define_expand and define_insn in MD etc.) work together >> to force the computation of a source/dest address plus offset into a >> register... can anyone help me with this ? >> >> Thanks, >> >> Sergio >>