This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: porting GCC to a micro with a very limited addressing mode --- what to write in LEGITIMATE_ADDRESS, LEGITIMIZE_ADDRESS and micro.md ?!
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.ruocco@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
>>