Skip to content

Commit

Permalink
more 2 register parameter support
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Jun 2, 2012
1 parent 56e101c commit 852708e
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 50 deletions.
12 changes: 9 additions & 3 deletions src/backend/cc.h
Expand Up @@ -144,7 +144,6 @@ enum LANG
# define debug_assert(e)
#endif


/***************************
* Print out debugging information.
*/
Expand Down Expand Up @@ -1164,10 +1163,17 @@ struct Symbol
#define Simport _SU.Simport_
// Symbol it was imported from
#endif
unsigned char Spreg_; // SCfastpar: register parameter is passed in
#define Spreg _SU.Spreg_
struct // SCfastpar
{
reg_t Spreg_; // register parameter is passed in
reg_t Spreg2_; // if 2 registers, this is the most significant, else NOREG
}_SR;
#define Spreg _SU._SR.Spreg_
#define Spreg2 _SU._SR.Spreg2_
}_SU;

regm_t Spregm(); // return mask of Spreg and Spreg2

#if SCPP || MARS
Symbol *Sscope; // enclosing scope (could be struct tag,
// enclosing inline function for statics,
Expand Down
1 change: 1 addition & 0 deletions src/backend/cdef.h
Expand Up @@ -881,6 +881,7 @@ struct Symbol;
struct LIST;
struct elem;

typedef unsigned char reg_t; // register number
typedef unsigned regm_t; // Register mask type
struct immed_t
{ targ_size_t value[REGMAX]; // immediate values in registers
Expand Down
6 changes: 3 additions & 3 deletions src/backend/cgcod.c
Expand Up @@ -200,7 +200,7 @@ void codgen()
s->Sflags &= ~SFLread;
switch (s->Sclass)
{ case SCfastpar:
regcon.params |= mask[s->Spreg];
regcon.params |= s->Spregm();
case SCparameter:
if (s->Sfl == FLreg)
noparams |= s->Sregm;
Expand Down Expand Up @@ -831,10 +831,10 @@ STATIC void blcodgen(block *bl)

sflsave[i] = s->Sfl;
if (s->Sclass & SCfastpar &&
regcon.params & mask[s->Spreg] &&
regcon.params & s->Spregm() &&
vec_testbit(dfoidx,s->Srange))
{
regcon.used |= mask[s->Spreg];
regcon.used |= s->Spregm();
}

if (s->Sfl == FLreg)
Expand Down
21 changes: 15 additions & 6 deletions src/backend/cod1.c
Expand Up @@ -1269,7 +1269,12 @@ code *getlvalue(code *pcs,elem *e,regm_t keepmsk)
goto L2;

case FLauto:
if (s->Sclass == SCfastpar && regcon.params & mask[s->Spreg])
if (s->Sclass == SCfastpar)
{ regm_t pregm = s->Spregm();
/* See if the parameter is still hanging about in a register,
* and so can we load from that register instead.
*/
if (regcon.params & pregm /*&& s->Spreg2 == NOREG && !(pregm & XMMREGS)*/)
{
if (keepmsk & RMload)
{
Expand All @@ -1278,12 +1283,13 @@ code *getlvalue(code *pcs,elem *e,regm_t keepmsk)
pcs->Irm = modregrm(3,0,s->Spreg & 7);
if (s->Spreg & 8)
pcs->Irex |= REX_B;
regcon.used |= mask[s->Spreg];
regcon.used |= pregm;
break;
}
}
else
regcon.params &= ~mask[s->Spreg];
regcon.params &= ~pregm;
}
}
case FLtmp:
case FLbprel:
Expand Down Expand Up @@ -2252,7 +2258,7 @@ code *callclib(elem *e,unsigned clib,regm_t *pretregs,regm_t keepmask)
/*************************************************
* Helper function for converting OPparam's into array of Parameters.
*/
struct Parameter { elem *e; unsigned char reg; unsigned numalign; };
struct Parameter { elem *e; reg_t reg; reg_t reg2; unsigned numalign; };

void fillParameters(elem *e, Parameter *parameters, int *pi)
{
Expand Down Expand Up @@ -2344,8 +2350,11 @@ static int type_jparam2(type *t, tym_t ty)
return 0;
}

int FuncParamRegs::alloc(type *t, tym_t ty, unsigned char *preg1, unsigned char *preg2)
int FuncParamRegs::alloc(type *t, tym_t ty, reg_t *preg1, reg_t *preg2)
{
*preg1 = NOREG;
*preg2 = NOREG;

// If struct just wraps another type
if (tybasic(ty) == TYstruct && tybasic(t->Tty) == TYstruct)
{
Expand Down Expand Up @@ -2431,7 +2440,7 @@ code *cdfunc(elem *e,regm_t *pretregs)
for (int i = np; --i >= 0;)
{
elem *ep = parameters[i].e;
if (fpr.alloc(ep->ET, ep->Ety, &parameters[i].reg, NULL))
if (fpr.alloc(ep->ET, ep->Ety, &parameters[i].reg, &parameters[i].reg2))
continue; // goes in register, not stack

// Parameter i goes on the stack
Expand Down
85 changes: 48 additions & 37 deletions src/backend/cod3.c
Expand Up @@ -2959,7 +2959,9 @@ code *prolog()
{ symbol *s = globsym.tab[si];
if (debugr && s->Sclass == SCfastpar)
{
printf("symbol '%s' is fastpar in register %s\n", s->Sident, regm_str(mask[s->Spreg]));
printf("symbol '%s' is fastpar in register [%s,%s]\n", s->Sident,
regm_str(mask[s->Spreg]),
(s->Spreg2 == NOREG ? "NOREG" : regm_str(mask[s->Spreg2])));
if (s->Sfl == FLreg)
printf("\tassigned to register %s\n", regm_str(mask[s->Sreglsw]));
}
Expand All @@ -2975,7 +2977,6 @@ code *prolog()

if (s->Sclass == SCfastpar && s->Sfl != FLreg)
{ // Argument is passed in a register
unsigned preg = s->Spreg;

type *t = s->Stype;
if (tybasic(t->Tty) == TYstruct)
Expand All @@ -2998,54 +2999,62 @@ code *prolog()
else
{
targ_size_t offset = Aoff + BPoff + s->Soffset;
int op = 0x89; // MOV x[EBP],preg
if (preg >= XMM0 && preg <= XMM15)
{
op = xmmstore(t->Tty);
}
if (hasframe)
if (!hasframe)
offset += EBPtoESP;

unsigned preg = s->Spreg;
for (int i = 0; i < 2; ++i) // twice, once for each possible parameter register
{
if (!(pushalloc && preg == pushallocreg))
int op = 0x89; // MOV x[EBP],preg
if (XMM0 <= preg && preg <= XMM15)
op = xmmstore(t->Tty);
if (hasframe)
{
// MOV x[EBP],preg
code *c2 = genc1(CNIL,op,
modregxrm(2,preg,BPRM),FLconst, offset);
if (preg >= XMM0 && preg <= XMM15)
{
}
else
if (!(pushalloc && preg == pushallocreg))
{
// MOV x[EBP],preg
code *c2 = genc1(CNIL,op,
modregxrm(2,preg,BPRM),FLconst, offset);
if (XMM0 <= preg && preg <= XMM15)
{
}
else
{
//printf("%s Aoff = %d, BPoff = %d, Soffset = %d, sz = %d\n", s->Sident, (int)Aoff, (int)BPoff, (int)s->Soffset, (int)sz);
// if (offset & 2)
// c2->Iflags |= CFopsize;
if (I64 && sz == 8)
code_orrex(c2, REX_W);
if (I64 && sz == 8)
code_orrex(c2, REX_W);
}
c = cat(c, c2);
}
c = cat(c, c2);
}
}
else
{
offset += EBPtoESP;
if (!(pushalloc && preg == pushallocreg))
else
{
// MOV offset[ESP],preg
// BUG: byte size?
code *c2 = genc1(CNIL,op,
(modregrm(0,4,SP) << 8) |
modregxrm(2,preg,4),FLconst,offset);
if (preg >= XMM0 && preg <= XMM15)
{
}
else
if (!(pushalloc && preg == pushallocreg))
{
if (I64 && sz == 8)
c2->Irex |= REX_W;
// MOV offset[ESP],preg
// BUG: byte size?
code *c2 = genc1(CNIL,op,
(modregrm(0,4,SP) << 8) |
modregxrm(2,preg,4),FLconst,offset);
if (preg >= XMM0 && preg <= XMM15)
{
}
else
{
if (I64 && sz == 8)
c2->Irex |= REX_W;
// if (offset & 2)
// c2->Iflags |= CFopsize;
}
c = cat(c,c2);
}
c = cat(c,c2);
}
preg = s->Spreg2;
if (preg == NOREG)
break;
offset += REGSIZE;
}
}
}
Expand All @@ -3062,11 +3071,13 @@ code *prolog()
unsigned sz = type_size(s->Stype);

if (s->Sclass == SCfastpar)
namedargs |= mask[s->Spreg];
namedargs |= s->Spregm();

if (s->Sclass == SCfastpar && s->Sfl == FLreg)
{ // Argument is passed in a register
unsigned preg = s->Spreg;
assert(s->Spreg2 == NOREG); // currently register pairs are never assigned to
// parameters passed in a pair

type *t = s->Stype;
if (tybasic(t->Tty) == TYstruct)
Expand Down
8 changes: 8 additions & 0 deletions src/backend/code.h
Expand Up @@ -1081,6 +1081,14 @@ struct FuncParamRegs
const unsigned char* floatregs; // map to fp register
};

extern "C++" { extern const unsigned mask[32]; }

inline regm_t Symbol::Spregm()
{
/*assert(Sclass == SCfastpar);*/
return mask[Spreg] | (Spreg2 == NOREG ? 0 : mask[Spreg2]);
}


#if __cplusplus && TX86
}
Expand Down
1 change: 1 addition & 0 deletions src/backend/nteh.c
Expand Up @@ -815,6 +815,7 @@ code *nteh_monitor_prolog(Symbol *shandle)

if (shandle->Sclass == SCfastpar)
{ assert(shandle->Spreg != DX);
assert(shandle->Spreg2 == NOREG);
c = gen1(NULL,0x50 + shandle->Spreg); // PUSH shandle
}
else
Expand Down
3 changes: 2 additions & 1 deletion src/backend/out.c
Expand Up @@ -1044,9 +1044,10 @@ STATIC void writefunc2(symbol *sfunc)
case SCfastpar:
case SCregpar:
case SCparameter:
if (si == 0 && fpr.alloc(s->Stype, s->Stype->Tty, &s->Spreg, NULL))
if (si == 0 && fpr.alloc(s->Stype, s->Stype->Tty, &s->Spreg, &s->Spreg2))
{
assert(s->Spreg == ((tyf == TYmfunc) ? CX : AX));
assert(s->Spreg2 == NOREG);
assert(si == 0);
s->Sclass = SCfastpar;
s->Sfl = FLauto;
Expand Down
1 change: 1 addition & 0 deletions src/backend/var.c
Expand Up @@ -21,6 +21,7 @@
#include "type.h"
#include "go.h"
#include "ty.h"
#include "code.h"

#include "optab.c"
#include "tytab.c"
Expand Down

0 comments on commit 852708e

Please sign in to comment.