This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: About EXTRA_ADDRESS_CONSTRAINT
- From: Alexandre Courbot <Alexandre dot Courbot at lifl dot fr>
- To: "Ulrich Weigand" <Ulrich dot Weigand at de dot ibm dot com>
- Cc: gcc at gcc dot gnu dot org
- Date: Thu, 22 May 2003 15:33:01 +0200
- Subject: Re: About EXTRA_ADDRESS_CONSTRAINT
- References: <OFAB524AB5.06E43D6E-ONC1256D2C.005F81EB@de.ibm.com>
> >I've defined a special constraint for my port describing members of
> > structures because I need to access structure members via a special
> > method of the target language (i.e. there are get/set instructions to
> > access members). Therefore I needed such access to structure members to
> > be reloaded when needed. As I can't work with addresses on my target, I
> > wanted the *content* of the member to be reloaded, not the address
> > (otherwise it would place the address into a register and generate a set
> > to the address contained in that register, which I can't handle). So
> > everything suggests me to mark my constraint with
> > EXTRA_ADDRESS_CONSTRAINT.
>
> I'm not sure I understand the specific requirements your port has, could
> you elaborate a bit? In particular, I don't understand the bit about
> 'can't work with addresses' -- how can you implement pointers then?
You're right, I've not been clear enough. Let me explain with an example then.
I'm porting GCC to generate code for an abstract language. That's why there
are no explicit pointers. I don't intend to get all GCC to work in these
conditions - I just need support for some things.
In my port, the C structures are changed into "objects" that have the same
members. Thus you can request a member with the "get" and "set" methods. For
instance:
obj.member = 2;
Will be compiled to (simplified version, normally indexes are used, not
strings):
obj set "member" 2
and
var = obj.member;
to
var <- obj get "member"
This means that if I do an addition for which the result should be placed in
the member of a structure, I'll need an extra placeholder (what we call a
"temporary", and is mapped to registers in my port):
obj.member = var + 2;
will be turned into:
.temp t0
t0 <- var + 2
obj set "member" t0
The insn that is generated by the + operator is of the form:
(set (mem (const (plus (symbol_ref "obj") (const_int x))))
(plus (mem (symbol_ref "var")) (const_int 2)))
During reloading, I designed my EXTRA_ADDRESS_CONSTRAINT marked constraint to
detect the destination was a member of a struct, and thus it changed this
insn into:
(set (reg REG) (plus (mem (symbol_ref "var")) (const_int 2)))
(set (mem (const (plus (symbol_ref "obj") (const_int x))))
(reg REG))
Which was fine! But unfortunately it seems to be risky :( Using
EXTRA_MEMORY_CONSTRAINT doesn't do what I need (it stores the address of the
location to store the result into into the register and do a mem on it -
which I can't reflect in the generated code)
The pattern that matches this is:
(set (match_operand 0 "nonimmediate_operand" "=Q")
(plus (match_operand 1 "general_operand" "Q")
(match_operand 2 "general_operand" "Q")))
(Q is my "doesn't belong to a structure" constraint)
> In any case, it doesn't appear to be what EXTRA_ADDRESS_CONSTRAINT
> was intended for. Maybe you need to consider SECONDARY_RELOAD_CLASS
> and/or SECONDARY_MEMORY_NEEDED?
AFAIK these macros are only useful to control the reloading of registers.
Therefore I don't think they are useful in cases like mine (mem to mem
moves).
> >I'd like to know: is it safe to use a constraint marked with
> >EXTRA_ADDRESS_CONSTRAINT with another predicate than address_operand?
>
> No.
I'm really open to any suggestion that would allow me to do it a safe way
then! :)
Thanks for the reply,
Alex.