Avoiding REG+OFF memory accesses

2009-05-06 Thread Iceman

Sorry for such trivial question, but is there any macro that can be used to 
avoig GCC to generate
REG+OFF memory accesses?
So basically to force GCC to break:

(mem (plus (reg const_int)))

into

(set regtmp (plus (reg const_int)))
(set (mem regtmp) reg)

This w/out writing custom RTL.
Can you please Cc me, since I am not subscribed. Thank you.

   James


  


Re: Avoiding REG+OFF memory accesses

2009-05-08 Thread Iceman

Ian suggestion worked perfectly, thanks. Can you tell me the macro/function 
name to look up
to work out the secondary reload you're mentioning?




- Original Message 
From: Michael Meissner 
To: Ian Lance Taylor 
Cc: Iceman ; g...@gnu.org
Sent: Friday, May 8, 2009 11:47:43 AM
Subject: Re: Avoiding REG+OFF memory accesses

On Wed, May 06, 2009 at 05:01:33PM -0700, Ian Lance Taylor wrote:
> Iceman  writes:
> 
> > Sorry for such trivial question, but is there any macro that can be used to 
> > avoig GCC to generate
> > REG+OFF memory accesses?
> > So basically to force GCC to break:
> >
> > (mem (plus (reg const_int)))
> >
> > into
> >
> > (set regtmp (plus (reg const_int)))
> > (set (mem regtmp) reg)
> >
> > This w/out writing custom RTL.
> 
> Assuming this is a private port, this should happen more or less
> automatically if GO_IF_LEGITIMATE_ADDRESS rejects register plus offset
> addressing.
> 
> If that is not what you are looking for, I think you need to provide
> some more context.

And you may also need to provide secondary reload support as well to convert
spill addresses into just REG addresses.

-- 
Michael Meissner, IBM
4 Technology Place Drive, MS 2203A, Westford, MA, 01886, USA
meiss...@linux.vnet.ibm.com



  


Re: Avoiding REG+OFF memory accesses

2009-05-08 Thread Iceman

Perfect, thank you!




- Original Message 
From: Michael Meissner 
To: Iceman 
Cc: Michael Meissner ; Ian Lance Taylor 
; g...@gnu.org
Sent: Friday, May 8, 2009 3:45:20 PM
Subject: Re: Avoiding REG+OFF memory accesses

On Fri, May 08, 2009 at 02:05:18PM -0700, Iceman wrote:
> 
> Ian suggestion worked perfectly, thanks. Can you tell me the macro/function 
> name to look up
> to work out the secondary reload you're mentioning?

Look up TARGET_SECONDARY_RELOAD in the documentation.  Basically it is a hook
that is called and the backend can say it needs extra scratch registers for a
move, or whether it needs to load a value into another register class.

-- 
Michael Meissner, IBM
4 Technology Place Drive, MS 2203A, Westford, MA, 01886, USA
meiss...@linux.vnet.ibm.com



  


varargs target handling

2009-05-08 Thread Iceman

Hi!
I'm porting GCC to a software VM with 32 32bit registers, and 32 64bit 
registers.
The 64bit registers are used for DI, SF and DF mode. Pointers and QI, HI and SI
modes are handled with 32bit registers.
The first 8 32bit parameters of functions are passed into the first 8 32bit 
registers (g0..7)
and the first 8 64bit function parameters are passed in the first 8 64bit 
registers (d0..7).
Everything works fine, but now I've to figure out how to handle varargs 
functions.
Before adding the 64bit registers, I simply had a bit set in the cumulative 
args, to signal
a vararg function, and I was dumping g0..7 in the prologue, that looked like:

  str.l g0, SP[4]
  str.l g1, SP[8]
  str.l g2, SP[12]
  str.l g3, SP[16]
  str.l g4, SP[20]
  str.l g5, SP[24]
  str.l g6, SP[28]
  str.l g7, SP[32]
  push SP
  mov SP, FP

This was working fine, and the code generated by GCC for the _builtin_* va_arg 
macros
were OK.
Now having the 64bit registers passed in registers (before they were pushed) 
confuses
me a little WRT the implementation.
My idea was to increase REG_PARM_STACK_SPACE to add the space for 8 64bit 
registers,
and dump d0..7 into this area.
So instead of (8 * 4) it'd become (8 * 4 + 8 * 8).
Then I was thinking in creating a va_list (via xxx_build_builtin_va_list()) 
like:

struct va_list {
void *gptr;   // Pointer to the first byte after the register dump area
void *rptr;// Pointer to the first byte of the 32bit dump area
int rcount;   // Byte count left for 32bit pulls
void *xptr;   // Pointer to the first byte of the 64bit dump area
 int xcount;  // Byte count left for 64bit pulls
};

In xxx_va_start() I'd initialize va_list like:

first_arg = SP + 4; // Skip IP
v->gptr = first_arg + 8 * 4 + 8 * 8;
v->rptr = first_arg;
v->rcount = 8 * 4;
v->xptr = v->rptr + 8 * 4;
v->xcount = 8 * 8;

The in the arg function I'd implement a logic like:

if (TYPE_SIZE <= 4) {
if (v->rcount > 0) {
arg = *(int *) v->rptr;
v->rptr += 4;
v->rcount -= 4;
} else {
arg = *(int *) v->gptr;
v->gptr += 4;
}
return arg;
}
if (v->xcount > 0) {
arg = *(long long *) v->xptr;
v->xptr += 8;
v->xcount -= 8;
} else {
arg = *(long long *) v->gptr;
v->gptr += 8;
}
return arg;


Question. Am I doing it wrong? If yes, what are my best options to tackle this 
problem?
If not, how can I implement the logic above in practical terms?
Thank you,