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:
parent
6ddc2cb80c
commit
e78777ebfe
@ -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
|
||||
{
|
||||
|
@ -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];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user