Skip to content

Commit

Permalink
Merge pull request #888 from braddr/fix-glue
Browse files Browse the repository at this point in the history
hide exact registers from the glue layer
  • Loading branch information
WalterBright committed Apr 20, 2012
2 parents 466760e + 6e79151 commit d41f621
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 46 deletions.
57 changes: 51 additions & 6 deletions src/backend/cod1.c
Expand Up @@ -2239,6 +2239,48 @@ void fillParameters(elem *e, Parameter *parameters, int *pi)
}
}

/*******************************
* Return the set of registers to use for parameter passing.
*/

const unsigned char* getintegerparamsreglist(tym_t tyf, size_t* num)
{
if (I64)
{
static const unsigned char reglist[] = { DI,SI,DX,CX,R8,R9 };
*num = 6;
return reglist;
}
else
{
*num = 1;
if (tyf == TYjfunc)
{
static const unsigned char reglist[] = { AX };
return reglist;
}
else
{
static const unsigned char reglist[] = { CX };
return reglist;
}
}
}

const unsigned char* getfloatparamsreglist(tym_t tyf, size_t* num)
{
if (I64)
{
*num = 8;
static const unsigned char reglist[] = { XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7 };
return reglist;
}
else
{
*num = 0;
return NULL;
}
}

/*******************************
* Generate code sequence for function call.
Expand Down Expand Up @@ -2392,6 +2434,7 @@ code *cdfunc(elem *e,regm_t *pretregs)
}
else
{ assert(I64);
tym_t tyf = tybasic(e->E1->Ety);

// Easier to deal with parameters as an array: parameters[0..np]
int np = el_nparams(e->E2);
Expand All @@ -2416,14 +2459,16 @@ code *cdfunc(elem *e,regm_t *pretregs)

// Figure out which parameters go in registers
// Compute numpara, the total bytes pushed on the stack
size_t numintegerregs = 0, numfloatregs = 0;
const unsigned char* argregs = getintegerparamsreglist(tyf, &numintegerregs);
const unsigned char* floatregs = getfloatparamsreglist(tyf, &numfloatregs);
int r = 0;
int xmmcnt = XMM0;
int xmmcnt = 0;
for (int i = np; --i >= 0;)
{
static const unsigned char argregs[6] = { DI,SI,DX,CX,R8,R9 };
elem *ep = parameters[i].e;
tym_t ty = ep->Ety;
if (r < sizeof(argregs)/sizeof(argregs[0])) // if more arg regs
if (r < numintegerregs) // if more arg regs
{ unsigned sz;
if (
// This must match type_jparam()
Expand All @@ -2437,11 +2482,11 @@ code *cdfunc(elem *e,regm_t *pretregs)
continue; // goes in register, not stack
}
}
if (xmmcnt <= XMM7)
if (xmmcnt < numfloatregs)
{
if (tyxmmreg(ty))
{
parameters[i].reg = xmmcnt;
parameters[i].reg = floatregs[xmmcnt];
xmmcnt++;
continue; // goes in register, not stack
}
Expand Down Expand Up @@ -2560,7 +2605,7 @@ code *cdfunc(elem *e,regm_t *pretregs)
// Variadic functions store the number of XMM registers used in AL
if (e->Eflags & EFLAGS_variadic)
{ code *c1 = getregs(mAX);
c1 = movregconst(c1,AX,xmmcnt - XMM0,1);
c1 = movregconst(c1,AX,xmmcnt,1);
c = cat(c, c1);
keepmsk |= mAX;
}
Expand Down
2 changes: 2 additions & 0 deletions src/backend/code.h
Expand Up @@ -725,6 +725,8 @@ code *fixresult (elem *e , regm_t retregs , regm_t *pretregs );
code *callclib (elem *e , unsigned clib , regm_t *pretregs , regm_t keepmask );
cd_t cdfunc;
cd_t cdstrthis;
const unsigned char* getintegerparamsreglist(tym_t tyf, size_t* num);
const unsigned char* getfloatparamsreglist(tym_t tyf, size_t* num);
code *params(elem *, unsigned);
code *offsetinreg (elem *e , regm_t *pretregs );
code *loaddata (elem *e , regm_t *pretregs );
Expand Down
69 changes: 29 additions & 40 deletions src/glue.c
Expand Up @@ -466,7 +466,8 @@ void Module::genobjfile(int multiobj)
sp->Stype = type_fake(TYint);
sp->Stype->Tcount++;
sp->Sclass = SCfastpar;
sp->Spreg = I64 ? DI : AX;
size_t num;
sp->Spreg = getintegerparamsreglist(TYjfunc, &num)[0];
sp->Sflags &= ~SFLspill;
sp->Sfl = FLpara; // FLauto?
cstate.CSpsymtab = &ma->Sfunc->Flocsym;
Expand Down Expand Up @@ -779,51 +780,39 @@ void FuncDeclaration::toObjFile(int multiobj)
// Determine register assignments
if (pi)
{
if (global.params.is64bit)
{
// Order of assignment of pointer or integer parameters
static const unsigned char argregs[6] = { DI,SI,DX,CX,R8,R9 };
int r = 0;
int xmmcnt = XMM0;

for (size_t i = 0; i < pi; i++)
{ Symbol *sp = params[i];
tym_t ty = tybasic(sp->Stype->Tty);
// BUG: doesn't work for structs
if (r < sizeof(argregs)/sizeof(argregs[0]))
size_t numintegerregs = 0, numfloatregs = 0;
const unsigned char* argregs = getintegerparamsreglist(tyf, &numintegerregs);
const unsigned char* floatregs = getfloatparamsreglist(tyf, &numfloatregs);

// Order of assignment of pointer or integer parameters
int r = 0;
int xmmcnt = 0;

for (size_t i = 0; i < pi; i++)
{ Symbol *sp = params[i];
tym_t ty = tybasic(sp->Stype->Tty);
// BUG: doesn't work for structs
if (r < numintegerregs)
{
if ((I64 || (i == 0 && (tyf == TYjfunc || tyf == TYmfunc))) && type_jparam(sp->Stype))
{
if (type_jparam(sp->Stype))
{
sp->Sclass = SCfastpar;
sp->Spreg = argregs[r];
sp->Sfl = FLauto;
++r;
}
sp->Sclass = SCfastpar;
sp->Spreg = argregs[r];
sp->Sfl = FLauto;
++r;
}
if (xmmcnt <= XMM7)
}
if (xmmcnt < numfloatregs)
{
if (tyxmmreg(ty))
{
if (tyxmmreg(ty))
{
sp->Sclass = SCfastpar;
sp->Spreg = xmmcnt;
sp->Sfl = FLauto;
++xmmcnt;
}
sp->Sclass = SCfastpar;
sp->Spreg = floatregs[xmmcnt];
sp->Sfl = FLauto;
++xmmcnt;
}
}
}
else
{
// First parameter goes in register
Symbol *sp = params[0];
if ((tyf == TYjfunc || tyf == TYmfunc) &&
type_jparam(sp->Stype))
{ sp->Sclass = SCfastpar;
sp->Spreg = (tyf == TYjfunc) ? AX : CX;
sp->Sfl = FLauto;
//printf("'%s' is SCfastpar\n",sp->Sident);
}
}
}

if (func->fbody)
Expand Down

0 comments on commit d41f621

Please sign in to comment.