1
0
mirror of https://github.com/golang/go synced 2024-11-19 05:44:40 -07:00

[dev.cc] 9g: fill progtable for CC, V, and VCC instruction variants

This adds some utilities for converting between the CC, V, and
VCC variants of operations and uses these to derive the
ProgInfo entries for these variants (which are identical to
the ProgInfo for the base operations).

The 9g peephole optimizer will also use these conversion
utilities.

LGTM=minux, rsc
R=rsc, dave, minux
CC=golang-codereviews
https://golang.org/cl/180110044
This commit is contained in:
Austin Clements 2014-11-24 11:40:36 -05:00
parent 6ddc2cb80c
commit e78777ebfe
2 changed files with 172 additions and 0 deletions

View File

@ -225,6 +225,16 @@ enum
void proginfo(ProgInfo*, Prog*);
// Many Power ISA arithmetic and logical instructions come in four
// standard variants. These bits let us map between variants.
enum {
V_CC = 1<<0, // xCC (affect CR field 0 flags)
V_V = 1<<1, // xV (affect SO and OV flags)
};
int as2variant(int);
int variant2as(int, int);
// To allow use of AJMP, ACALL, ARET in ../gc/popt.c.
enum
{

View File

@ -101,9 +101,36 @@ static ProgInfo progtable[ALAST] = {
[ADUFFCOPY]= {Call},
};
static void
initproginfo(void)
{
static int initialized;
int addvariant[] = {V_CC, V_V, V_CC|V_V};
int as, as2, i, variant;
if(initialized)
return;
initialized = 1;
// Perform one-time expansion of instructions in progtable to
// their CC, V, and VCC variants
for(as=0; as<nelem(progtable); as++) {
if(progtable[as].flags == 0)
continue;
variant = as2variant(as);
for(i=0; i<nelem(addvariant); i++) {
as2 = variant2as(as, variant | addvariant[i]);
if(as2 != 0 && progtable[as2].flags == 0)
progtable[as2] = progtable[as];
}
}
}
void
proginfo(ProgInfo *info, Prog *p)
{
initproginfo();
*info = progtable[p->as];
if(info->flags == 0) {
*info = progtable[AADD];
@ -143,3 +170,138 @@ proginfo(ProgInfo *info, Prog *p)
info->regset |= RtoB(3) | RtoB(4);
}
}
// Instruction variants table. Initially this contains entries only
// for the "base" form of each instruction. On the first call to
// as2variant or variant2as, we'll add the variants to the table.
static int varianttable[ALAST][4] = {
[AADD]= {AADD, AADDCC, AADDV, AADDVCC},
[AADDC]= {AADDC, AADDCCC, AADDCV, AADDCVCC},
[AADDE]= {AADDE, AADDECC, AADDEV, AADDEVCC},
[AADDME]= {AADDME, AADDMECC, AADDMEV, AADDMEVCC},
[AADDZE]= {AADDZE, AADDZECC, AADDZEV, AADDZEVCC},
[AAND]= {AAND, AANDCC, 0, 0},
[AANDN]= {AANDN, AANDNCC, 0, 0},
[ACNTLZD]= {ACNTLZD, ACNTLZDCC, 0, 0},
[ACNTLZW]= {ACNTLZW, ACNTLZWCC, 0, 0},
[ADIVD]= {ADIVD, ADIVDCC, ADIVDV, ADIVDVCC},
[ADIVDU]= {ADIVDU, ADIVDUCC, ADIVDUV, ADIVDUVCC},
[ADIVW]= {ADIVW, ADIVWCC, ADIVWV, ADIVWVCC},
[ADIVWU]= {ADIVWU, ADIVWUCC, ADIVWUV, ADIVWUVCC},
[AEQV]= {AEQV, AEQVCC, 0, 0},
[AEXTSB]= {AEXTSB, AEXTSBCC, 0, 0},
[AEXTSH]= {AEXTSH, AEXTSHCC, 0, 0},
[AEXTSW]= {AEXTSW, AEXTSWCC, 0, 0},
[AFABS]= {AFABS, AFABSCC, 0, 0},
[AFADD]= {AFADD, AFADDCC, 0, 0},
[AFADDS]= {AFADDS, AFADDSCC, 0, 0},
[AFCFID]= {AFCFID, AFCFIDCC, 0, 0},
[AFCTID]= {AFCTID, AFCTIDCC, 0, 0},
[AFCTIDZ]= {AFCTIDZ, AFCTIDZCC, 0, 0},
[AFCTIW]= {AFCTIW, AFCTIWCC, 0, 0},
[AFCTIWZ]= {AFCTIWZ, AFCTIWZCC, 0, 0},
[AFDIV]= {AFDIV, AFDIVCC, 0, 0},
[AFDIVS]= {AFDIVS, AFDIVSCC, 0, 0},
[AFMADD]= {AFMADD, AFMADDCC, 0, 0},
[AFMADDS]= {AFMADDS, AFMADDSCC, 0, 0},
[AFMOVD]= {AFMOVD, AFMOVDCC, 0, 0},
[AFMSUB]= {AFMSUB, AFMSUBCC, 0, 0},
[AFMSUBS]= {AFMSUBS, AFMSUBSCC, 0, 0},
[AFMUL]= {AFMUL, AFMULCC, 0, 0},
[AFMULS]= {AFMULS, AFMULSCC, 0, 0},
[AFNABS]= {AFNABS, AFNABSCC, 0, 0},
[AFNEG]= {AFNEG, AFNEGCC, 0, 0},
[AFNMADD]= {AFNMADD, AFNMADDCC, 0, 0},
[AFNMADDS]= {AFNMADDS, AFNMADDSCC, 0, 0},
[AFNMSUB]= {AFNMSUB, AFNMSUBCC, 0, 0},
[AFNMSUBS]= {AFNMSUBS, AFNMSUBSCC, 0, 0},
[AFRES]= {AFRES, AFRESCC, 0, 0},
[AFRSP]= {AFRSP, AFRSPCC, 0, 0},
[AFRSQRTE]= {AFRSQRTE, AFRSQRTECC, 0, 0},
[AFSEL]= {AFSEL, AFSELCC, 0, 0},
[AFSQRT]= {AFSQRT, AFSQRTCC, 0, 0},
[AFSQRTS]= {AFSQRTS, AFSQRTSCC, 0, 0},
[AFSUB]= {AFSUB, AFSUBCC, 0, 0},
[AFSUBS]= {AFSUBS, AFSUBSCC, 0, 0},
[AMTFSB0]= {AMTFSB0, AMTFSB0CC, 0, 0},
[AMTFSB1]= {AMTFSB1, AMTFSB1CC, 0, 0},
[AMULHD]= {AMULHD, AMULHDCC, 0, 0},
[AMULHDU]= {AMULHDU, AMULHDUCC, 0, 0},
[AMULHW]= {AMULHW, AMULHWCC, 0, 0},
[AMULHWU]= {AMULHWU, AMULHWUCC, 0, 0},
[AMULLD]= {AMULLD, AMULLDCC, AMULLDV, AMULLDVCC},
[AMULLW]= {AMULLW, AMULLWCC, AMULLWV, AMULLWVCC},
[ANAND]= {ANAND, ANANDCC, 0, 0},
[ANEG]= {ANEG, ANEGCC, ANEGV, ANEGVCC},
[ANOR]= {ANOR, ANORCC, 0, 0},
[AOR]= {AOR, AORCC, 0, 0},
[AORN]= {AORN, AORNCC, 0, 0},
[AREM]= {AREM, AREMCC, AREMV, AREMVCC},
[AREMD]= {AREMD, AREMDCC, AREMDV, AREMDVCC},
[AREMDU]= {AREMDU, AREMDUCC, AREMDUV, AREMDUVCC},
[AREMU]= {AREMU, AREMUCC, AREMUV, AREMUVCC},
[ARLDC]= {ARLDC, ARLDCCC, 0, 0},
[ARLDCL]= {ARLDCL, ARLDCLCC, 0, 0},
[ARLDCR]= {ARLDCR, ARLDCRCC, 0, 0},
[ARLDMI]= {ARLDMI, ARLDMICC, 0, 0},
[ARLWMI]= {ARLWMI, ARLWMICC, 0, 0},
[ARLWNM]= {ARLWNM, ARLWNMCC, 0, 0},
[ASLD]= {ASLD, ASLDCC, 0, 0},
[ASLW]= {ASLW, ASLWCC, 0, 0},
[ASRAD]= {ASRAD, ASRADCC, 0, 0},
[ASRAW]= {ASRAW, ASRAWCC, 0, 0},
[ASRD]= {ASRD, ASRDCC, 0, 0},
[ASRW]= {ASRW, ASRWCC, 0, 0},
[ASUB]= {ASUB, ASUBCC, ASUBV, ASUBVCC},
[ASUBC]= {ASUBC, ASUBCCC, ASUBCV, ASUBCVCC},
[ASUBE]= {ASUBE, ASUBECC, ASUBEV, ASUBEVCC},
[ASUBME]= {ASUBME, ASUBMECC, ASUBMEV, ASUBMEVCC},
[ASUBZE]= {ASUBZE, ASUBZECC, ASUBZEV, ASUBZEVCC},
[AXOR]= {AXOR, AXORCC, 0, 0},
};
static void
initvariants(void)
{
static int initialized;
int i, j;
if(initialized)
return;
initialized = 1;
for(i=0; i<nelem(varianttable); i++) {
if(varianttable[i][0] == 0) {
// Instruction has no variants
varianttable[i][0] = i;
continue;
}
// Copy base form to other variants
if(varianttable[i][0] == i) {
for(j=0; j<nelem(varianttable[i]); j++)
memmove(&varianttable[varianttable[i][j]], &varianttable[i], sizeof(varianttable[i]));
}
}
}
// as2variant returns the variant (V_*) flags of instruction as.
int
as2variant(int as)
{
int i;
initvariants();
for(i=0; i<nelem(varianttable[as]); i++)
if(varianttable[as][i] == as)
return i;
fatal("as2variant: instruction %A is not a variant of itself", as);
return 0;
}
// variant2as returns the instruction as with the given variant (V_*) flags.
// If no such variant exists, this returns 0.
int
variant2as(int as, int flags)
{
initvariants();
return varianttable[as][flags];
}