From e78777ebfef59356c72a3788483a78610f9ad0a2 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Mon, 24 Nov 2014 11:40:36 -0500 Subject: [PATCH] [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 --- src/cmd/9g/opt.h | 10 +++ src/cmd/9g/prog.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+) diff --git a/src/cmd/9g/opt.h b/src/cmd/9g/opt.h index 7f15b5a69f3..6a07b268f21 100644 --- a/src/cmd/9g/opt.h +++ b/src/cmd/9g/opt.h @@ -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 { diff --git a/src/cmd/9g/prog.c b/src/cmd/9g/prog.c index 51c132d183d..7c0f0c7959e 100644 --- a/src/cmd/9g/prog.c +++ b/src/cmd/9g/prog.c @@ -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; asas]; 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