class Enum(_Enum):
@classmethod
- def _missing_(cls, value):
- if isinstance(value, str):
+ def _missing_(cls, desc):
+ if isinstance(desc, str):
try:
- if value == "":
- value = 0
+ if desc == "":
+ desc = 0
else:
- value = int(value, 0)
+ desc = int(desc, 0)
except ValueError:
pass
keys = {item.name:item for item in cls}
- values = {item.value:item for item in cls}
- item = keys.get(value, values.get(value))
- if item is None:
- raise ValueError(value)
- return item
+ descs = {item.value:item for item in cls}
+ return keys.get(desc, descs.get(desc))
# this corresponds to which Function Unit (pipeline-with-Reservation-Stations)
VA2 = 39
SVC = 40
SVR = 41
+ CRB = 42 # crternlogi / crbinlut
+ MM = 43 # [f]minmax[s][.]
+ CW = 44
+ CW2 = 45
+ DCT = 46 # fdmadds
# Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
@unique
-class SVPtype(Enum):
+class SVPType(Enum):
NONE = 0
P1 = 1
P2 = 2
+ P2M = 3 # for mixed EXTRA3/3/2 where MASK_SRC is RM[6,7,18]
@classmethod
- def _missing_(cls, value):
- return {"1P": SVPtype.P1, "2P": SVPtype.P2}[value]
+ def _missing_(cls, desc):
+ return {"1P": SVPType.P1, "2P": SVPType.P2, "2PM": SVPType.P2M}.get(desc)
def __repr__(self):
return {
- SVPtype.NONE: "NONE",
- SVPtype.P1: "1P",
- SVPtype.P2: "2P",
+ SVPType.NONE: "NONE",
+ SVPType.P1: "1P",
+ SVPType.P2: "2P",
+ SVPType.P2M: "2PM",
}[self]
@unique
-class SVEtype(Enum):
+class SVEType(Enum):
+ """SVEType
+ * EXTRA2 : 0: [10,11] 1: [12,13] 2: [14,15] 3: [16,17] unused: [18]
+ * EXTRA3 : 0: [10,11,12] 1: [13,14,15] mask: [16,17,18]
+ * EXTRA32: 0: [10,11,12] 1: [13,14,15] 2: [16,17] mask: [6,7,18]
+ """
NONE = 0
EXTRA2 = 1
EXTRA3 = 2
+ EXTRA32 = 3 # mixed EXTRA3 and EXTRA2 using RM bits 6&7 for MASK_SRC
def __repr__(self):
return self.name
@unique
-class SVmask_src(Enum):
+class SVMaskSrc(Enum):
NO = 0
EN = 1
def __repr__(self):
return {
- SVExtra.NONE: "NONE",
- SVExtra.Idx0: "[0]",
- SVExtra.Idx1: "[1]",
- SVExtra.Idx2: "[2]",
- SVExtra.Idx3: "[3]",
- SVExtra.Idx_1_2: "[1:2]",
+ SVExtra.NONE: "none",
+ SVExtra.Idx0: "extra0",
+ SVExtra.Idx1: "extra1",
+ SVExtra.Idx2: "extra2",
+ SVExtra.Idx3: "extra3",
+ SVExtra.Idx_1_2: "extra1/extra2",
}[self]
# Backward compatibility
SVEXTRA = SVExtra
-class SVExtraRegType(Enum):
- NONE = None
- SRC = 's'
- DST = 'd'
-
-
class SVExtraReg(Enum):
NONE = auto()
RA = auto()
BFT = auto()
WHOLE_REG = auto()
SPR = auto()
+ RSp = auto()
+ RTp = auto()
+ FRAp = auto()
+ FRBp = auto()
+ FRSp = auto()
+ FRTp = auto()
@classmethod
- def _missing_(cls, value):
+ def _missing_(cls, desc):
selectors = (
In1Sel, In2Sel, In3Sel, CRInSel, CRIn2Sel,
OutSel, CROutSel,
)
- if isinstance(value, selectors):
- return cls.__members__[value.name]
- return super()._missing_(value)
+ if isinstance(desc, selectors):
+ return cls.__members__.get(desc.name)
+
+ return cls.__members__.get(desc)
+
+ @property
+ def alias(self):
+ alias = {
+ SVExtraReg.RSp: SVExtraReg.RS,
+ SVExtraReg.RTp: SVExtraReg.RT,
+ SVExtraReg.FRAp: SVExtraReg.FRA,
+ SVExtraReg.FRBp: SVExtraReg.FRB,
+ SVExtraReg.FRSp: SVExtraReg.FRS,
+ SVExtraReg.FRTp: SVExtraReg.FRT,
+ }.get(self)
+ if alias is not None:
+ return alias
+
+ alias = {
+ SVExtraReg.RA_OR_ZERO: SVExtraReg.RA,
+ SVExtraReg.RT_OR_ZERO: SVExtraReg.RT,
+ }.get(self)
+ if alias is not None:
+ return alias
+
+ return self
@unique
ALWAYS = 0
INT = 1
CR = 2
+ RC1 = 3
@unique
class SVP64PredInt(Enum):
- ALWAYS = 0
- R3_UNARY = 1
- R3 = 2
- R3_N = 3
- R10 = 4
- R10_N = 5
- R30 = 6
- R30_N = 7
+ ALWAYS = 0b000
+ R3_UNARY = 0b001
+ R3 = 0b010
+ R3_N = 0b011
+ R10 = 0b100
+ R10_N = 0b101
+ R30 = 0b110
+ R30_N = 0b111
+
+ @classmethod
+ def _missing_(cls, desc):
+ if isinstance(desc, str):
+ value = desc
+ values = {
+ "^r3": cls.R3_UNARY,
+ "r3": cls.R3,
+ "~r3": cls.R3_N,
+ "r10": cls.R10,
+ "~r10": cls.R10_N,
+ "r30": cls.R30,
+ "~r30": cls.R30_N,
+ }
+ if value.startswith("~"):
+ value = f"~{value[1:].strip()}"
+ elif "<<" in value: # 1 << r3
+ (lhs, _, rhs) = value.partition("<<")
+ lhs = lhs.strip().lower()
+ rhs = rhs.strip().lower()
+ if (lhs == "1") and (rhs in ("r3", "%r3")):
+ value = "^r3"
+
+ return values.get(value)
+
+ return super()._missing_(desc)
+
+ def __str__(self):
+ return {
+ self.__class__.ALWAYS: "",
+ self.__class__.R3_UNARY: "^r3",
+ self.__class__.R3: "r3",
+ self.__class__.R3_N: "~r3",
+ self.__class__.R10: "r10",
+ self.__class__.R10_N: "~r10",
+ self.__class__.R30: "r30",
+ self.__class__.R30_N: "~r30",
+ }[self]
+
+ def __repr__(self):
+ return f"{self.__class__.__name__}({str(self)})"
+
+ def __int__(self):
+ return self.value
+
+ @property
+ def mode(self):
+ return SVP64PredMode.INT
+
+ @property
+ def inv(self):
+ return (self.value & 0b1)
+
+ @property
+ def state(self):
+ return (self.value >> 1)
-@unique
class SVP64PredCR(Enum):
LT = 0
GE = 1
+ NL = GE
GT = 2
LE = 3
+ NG = LE
EQ = 4
NE = 5
SO = 6
+ UN = SO
NS = 7
+ NU = NS
+ @classmethod
+ def _missing_(cls, desc):
+ if isinstance(desc, str):
+ name = desc.upper()
+ return cls.__members__.get(name)
-@unique
-class SVP64RMMode(Enum):
- NORMAL = 0
- MAPREDUCE = 1
- FFIRST = 2
- SATURATE = 3
- PREDRES = 4
- BRANCH = 5
+ return super()._missing_(desc)
+ def __int__(self):
+ return self.value
-@unique
-class SVP64BCPredMode(Enum):
- NONE = 0
- MASKZERO = 1
- MASKONE = 2
+ @property
+ def mode(self):
+ return SVP64PredMode.CR
+
+ @property
+ def inv(self):
+ return (self.value & 0b1)
+
+ @property
+ def state(self):
+ return (self.value >> 1)
@unique
-class SVP64Predicate(Enum):
- # Integer
- BITSEL_R3 = ("^r3", True, 0b00)
- R3 = ("r3", False, 0b01)
- R3_INV = ("~r3", True, 0b01)
- R10 = ("r10", False, 0b10)
- R10_INV = ("~r10", True, 0b10)
- R30 = ("r30", False, 0b11)
- R30_INV = ("~r30", True, 0b11)
-
- # CR
- LT = ("lt", False, 0b00)
- NL = ("nl", True, 0b00)
- GE = ("ge", True, 0b00)
- GT = ("gt", False, 0b01)
- NG = ("ng", True, 0b01)
- LE = ("le", True, 0b01)
- EQ = ("eq", False, 0b10)
- NE = ("ne", True, 0b10)
- SO = ("so", False, 0b11)
- UN = ("un", False, 0b11)
- NS = ("ns", True, 0b11)
- NU = ("nu", True, 0b11)
-
- # RC1
- RC1 = ("RC1", False, 0b1)
- RC1_INV = ("~RC1", True, 0b1)
+class SVP64PredRC1(Enum):
+ RC1 = 0
+ RC1_N = 1
@classmethod
- def _missing_(cls, value):
- if isinstance(value, str):
- members = {}
- for (name, member) in cls.__members__.items():
- members[str(member)] = member.name
-
- member = value
- if "RC1" not in member:
- member = member.lower()
-
- if member.startswith("~"):
- member = f"~{member[1:].strip()}"
- elif "<<" in member:
- # 1 << r3
- (lhs, _, rhs) = member.partition("<<")
- lhs = lhs.strip().lower()
- rhs = rhs.strip().lower()
- if (lhs == "1") and (rhs in ("r3", "%r3")):
- member = "^r3"
- member = members.get(member, member)
- return cls[member]
-
- return super()._missing_(value)
+ def _missing_(cls, desc):
+ return {
+ "RC1": SVP64PredRC1.RC1,
+ "~RC1": SVP64PredRC1.RC1_N,
+ }.get(desc)
- def __str__(self):
- return self.value[0]
+ def __int__(self):
+ return 1
@property
- def type(self):
- return SVP64PredicateType(self)
+ def mode(self):
+ return SVP64PredMode.RC1
@property
def inv(self):
- return self.value[1]
+ return (self is SVP64PredRC1.RC1_N)
@property
def state(self):
- return self.value[2]
+ return 1
+
+
+class SVP64Pred(Enum):
+ ALWAYS = SVP64PredInt.ALWAYS
+ R3_UNARY = SVP64PredInt.R3_UNARY
+ R3 = SVP64PredInt.R3
+ R3_N = SVP64PredInt.R3_N
+ R10 = SVP64PredInt.R10
+ R10_N = SVP64PredInt.R10_N
+ R30 = SVP64PredInt.R30
+ R30_N = SVP64PredInt.R30_N
+
+ LT = SVP64PredCR.LT
+ GE = SVP64PredCR.GE
+ GT = SVP64PredCR.GT
+ LE = SVP64PredCR.LE
+ EQ = SVP64PredCR.EQ
+ NE = SVP64PredCR.NE
+ SO = SVP64PredCR.SO
+ NS = SVP64PredCR.NS
+
+ RC1 = SVP64PredRC1.RC1
+ RC1_N = SVP64PredRC1.RC1_N
+
+ @classmethod
+ def _missing_(cls, desc):
+ if isinstance(desc, str):
+ values = {item.value:item for item in cls}
+ for subcls in (SVP64PredInt, SVP64PredCR, SVP64PredRC1):
+ try:
+ return values.get(subcls(desc))
+ except ValueError:
+ pass
+ return None
+
+ return super()._missing_(desc)
+
+ def __int__(self):
+ return int(self.value)
@property
- def mask(self):
- return ((int(self.state) << 1) | (int(self.inv) << 0))
+ def mode(self):
+ return self.value.mode
+ @property
+ def inv(self):
+ return self.value.inv
-class SVP64PredicateType(Enum):
- INTEGER = auto()
- BITSEL_R3 = INTEGER
- R3 = INTEGER
- R3_INV = INTEGER
- R10 = INTEGER
- R10_INV = INTEGER
- R30 = INTEGER
- R30_INV = INTEGER
+ @property
+ def state(self):
+ return self.value.state
- CR = auto()
- LT = CR
- NL = CR
- GE = CR
- GT = CR
- NG = CR
- LE = CR
- EQ = CR
- NE = CR
- SO = CR
- UN = CR
- NS = CR
- NU = CR
-
- RC1 = auto()
- RC1_INV = RC1
- @classmethod
- def _missing_(cls, value):
- if isinstance(value, SVP64Predicate):
- return cls.__members__[value.name]
- return super()._missing_(value)
+@unique
+class SVP64RMMode(Enum):
+ NORMAL = 0
+ MAPREDUCE = 1
+ FFIRST = 2
+ SATURATE = 3
+ BRANCH = 5
+
+
+@unique
+class SVP64BCPredMode(Enum):
+ NONE = 0
+ MASKZERO = 1
+ MASKONE = 2
@unique
@unique
-class SVP64width(Enum):
+class SVP64Width(Enum):
DEFAULT = 0
EW_32 = 1
EW_16 = 2
EW_8 = 3
+ @classmethod
+ def _missing_(cls, desc):
+ if isinstance(desc, str):
+ return {
+ "32": SVP64Width.EW_32,
+ "16": SVP64Width.EW_16,
+ "8": SVP64Width.EW_8,
+ }.get(desc)
+
+ return super()._missing_(desc)
+
@unique
-class SVP64subvl(Enum):
+class SVP64SubVL(Enum):
VEC1 = 0
VEC2 = 1
VEC3 = 2
def _missing_(cls, desc):
if isinstance(desc, str):
name = desc.upper()
- value = cls.__members__.get(name)
- if value is None:
- raise ValueError(desc)
- return value
- return super()._missing_(desc)
+ return cls.__members__.get(name)
-SVP64SubVL = SVP64subvl
+ return super()._missing_(desc)
@unique
-class SVP64sat(Enum):
+class SVP64Sat(Enum):
NONE = 0
SIGNED = 1
UNSIGNED = 2
RB = GPR
RC = GPR
RS = GPR
+ RSp = RS
RT = GPR
+ RTp = RT
FPR = 1
FRA = FPR
+ FRAp = FRA
FRB = FPR
+ FRBp = FRB
FRC = FPR
FRS = FPR
+ FRSp = FRS
FRT = FPR
+ FRTp = FRT
- CR_5BIT = 2 # CR field; the CR register is 32-bit
- BF = CR_5BIT
- BFA = CR_5BIT
+ CR_3BIT = 2 # CR field; the CR register is 32-bit
+ BF = CR_3BIT
+ BFA = CR_3BIT
- CR_3BIT = 3 # bit of the 32-bit CR register
- BA = CR_3BIT
- BB = CR_3BIT
- BC = CR_3BIT
- BI = CR_3BIT
- BT = CR_3BIT
+ CR_5BIT = 3 # bit of the 32-bit CR register
+ BA = CR_5BIT
+ BB = CR_5BIT
+ BC = CR_5BIT
+ BI = CR_5BIT
+ BT = CR_5BIT
XER_BIT = 4 # XER bits, includes OV, OV32, SO, CA, CA32
OV = XER_BIT
@classmethod
def _missing_(cls, value):
if isinstance(value, SVExtraReg):
- return cls.__members__[value.name]
- return super()._missing_(value)
+ return cls.__members__.get(value.name)
-
-class CRType(Enum):
- CR5BIT = 0
- CR3BIT = 1
+ return super()._missing_(value)
FPTRANS_INSNS = (
"fasinh", "fasinhs",
"facosh", "facoshs",
"fatanh", "fatanhs",
- "fminnum08", "fminnum08s",
- "fmaxnum08", "fmaxnum08s",
- "fmin19", "fmin19s",
- "fmax19", "fmax19s",
- "fminnum19", "fminnum19s",
- "fmaxnum19", "fmaxnum19s",
- "fminc", "fmincs",
- "fmaxc", "fmaxcs",
- "fminmagnum08", "fminmagnum08s",
- "fmaxmagnum08", "fmaxmagnum08s",
- "fminmag19", "fminmag19s",
- "fmaxmag19", "fmaxmag19s",
- "fminmagnum19", "fminmagnum19s",
- "fmaxmagnum19", "fmaxmagnum19s",
- "fminmagc", "fminmagcs",
- "fmaxmagc", "fmaxmagcs",
+ # fmin*/fmax* need to be replaced with fminmax
+ # https://bugs.libre-soc.org/show_bug.cgi?id=1057
+ # commented for now to make space for fmv/cvt
+ # "fminnum08", "fminnum08s",
+ # "fmaxnum08", "fmaxnum08s",
+ # "fmin19", "fmin19s",
+ # "fmax19", "fmax19s",
+ # "fminnum19", "fminnum19s",
+ # "fmaxnum19", "fmaxnum19s",
+ # "fminc", "fmincs",
+ # "fmaxc", "fmaxcs",
+ # "fminmagnum08", "fminmagnum08s",
+ # "fmaxmagnum08", "fmaxmagnum08s",
+ # "fminmag19", "fminmag19s",
+ # "fmaxmag19", "fmaxmag19s",
+ # "fminmagnum19", "fminmagnum19s",
+ # "fmaxmagnum19", "fmaxmagnum19s",
+ # "fminmagc", "fminmagcs",
+ # "fmaxmagc", "fmaxmagcs",
"fmod", "fmods",
"fremainder", "fremainders",
)
"NONE", "add", "addc", "addco", "adde", "addeo",
"addi", "addic", "addic.", "addis",
"addme", "addmeo", "addo", "addze", "addzeo",
+ "addex",
"addg6s",
"and", "andc", "andi.", "andis.",
"attn",
"divmod2du",
"divw", "divwe", "divweo",
"divweu", "divweuo", "divwo", "divwu", "divwuo",
- "dsld", "dsrd",
+ "dsld", "dsld.", "dsrd", "dsrd.",
"eieio", "eqv",
"extsb", "extsh", "extsw", "extswsli",
"fadd", "fadds", "fsub", "fsubs", # FP add / sub
"fmr", "fabs", "fnabs", "fneg", "fcpsgn", # FP move/abs/neg
"fmvis", # FP load immediate
"fishmv", # Float Replace Lower-Half Single, Immediate
+ "fcvttg", "fcvttgo", "fcvttgs", "fcvttgso",
+ "fmvtg", "fmvtgs",
+ "fcvtfg", "fcvtfgs",
+ "fmvfg", "fmvfgs",
'grev', 'grev.', 'grevi', 'grevi.',
'grevw', 'grevw.', 'grevwi', 'grevwi.',
"hrfid", "icbi", "icbt", "isel", "isync",
# "lwzbr", "lwzubr", # more load word SVP64 bit-reversed
"maddedu", "maddedus",
"maddhd", "maddhdu", "maddld", # INT multiply-and-add
+ "maddsubrs", # Integer DCT Butterfly Add Sub and Round Shift
+ "maddrs", # Integer DCT Butterfly Add and Accumulate and Round Shift
"mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf", # CR mvs
"mfmsr", "mfspr",
- "mins", "maxs", "minu", "maxu", # AV bitmanip
+ "minmax", # AV bitmanip
"modsd", "modsw", "modud", "moduw",
"mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr",
"mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo",
"svshape2", # https://libre-soc.org/openpower/sv/remap/discussion TODO
"svstep", # https://libre-soc.org/openpower/sv/setvl
"sim_cfg",
- "shadd", "shadduw",
+ "sadd", "saddw", "sadduw",
"slbia", "sld", "slw", "srad", "sradi",
"sraw", "srawi", "srd", "srw",
"stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
OP_DSHL = 101
OP_DSHR = 102
OP_SHADD = 103
+ OP_MADDSUBRS = 104
+ OP_MADDRS = 105
+
+
+class SelType(Enum):
+ NONE = None
+ SRC = 's'
+ DST = 'd'
+
+ def __repr__(self):
+ return {
+ SelType.NONE: "none",
+ SelType.SRC: "src",
+ SelType.DST: "dst",
+ }[self]
-@unique
class In1Sel(Enum):
NONE = 0
RA = 1
RA_OR_ZERO = 2
SPR = 3
RS = 4 # for some ALU/Logical operations
+ RSp = RS
FRA = 5
+ FRAp = FRA
FRS = 6
- CIA = 7 # for addpcis
+ FRSp = FRS
+ FRT = 7
+ CIA = 8 # for addpcis
+ RT = 9
+
+ @property
+ def type(self):
+ if self is In1Sel.NONE:
+ return SelType.NONE
+ return SelType.SRC
-@unique
class In2Sel(Enum):
NONE = 0
RB = 1
CONST_SH32 = 11
SPR = 12
RS = 13 # for shiftrot (M-Form)
+ RSp = RS
FRB = 14
+ FRBp = FRB
CONST_SVD = 15 # for SVD-Form
CONST_SVDS = 16 # for SVDS-Form
CONST_XBI = 17
CONST_DXHI4 = 18 # for addpcis
CONST_DQ = 19 # for ld/st-quad
+ @property
+ def type(self):
+ if self is In2Sel.NONE:
+ return SelType.NONE
+ return SelType.SRC
+
-@unique
class In3Sel(Enum):
NONE = 0
RS = 1
+ RSp = RS
RB = 2 # for shiftrot (M-Form)
FRS = 3
+ FRSp = FRS
FRC = 4
RC = 5 # for SVP64 bit-reverse LD/ST
RT = 6 # for ternlog[i]
+ RTp = RT
+ FRA = 7
+
+ @property
+ def type(self):
+ if self is In3Sel.NONE:
+ return SelType.NONE
+ return SelType.SRC
-@unique
class OutSel(Enum):
NONE = 0
RT = 1
+ RTp = RT
RA = 2
SPR = 3
RT_OR_ZERO = 4
FRT = 5
+ FRTp = FRT
FRS = 6
+ FRSp = FRS
RS = 7
+ RSp = RS
+ FRA = 8
+
+ @property
+ def type(self):
+ if self is OutSel.NONE:
+ return SelType.NONE
+ return SelType.DST
@unique
CR1 = 7
BA = 8
+ @property
+ def type(self):
+ if self is CRInSel.NONE:
+ return SelType.NONE
+ return SelType.SRC
+
@unique
class CRIn2Sel(Enum):
NONE = 0
BB = 1
+ @property
+ def type(self):
+ if self is CRIn2Sel.NONE:
+ return SelType.NONE
+ return SelType.SRC
+
@unique
class CROutSel(Enum):
WHOLE_REG = 4
CR1 = 5
+ @property
+ def type(self):
+ if self is CROutSel.NONE:
+ return SelType.NONE
+ return SelType.DST
+
# SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
# http://libre-riscv.org/openpower/isatables/sprs.csv
MSRSpec = namedtuple("MSRSpec", ["dr", "pr", "sf"])
+# flags for bfp_* functions
+BFP_FLAG_NAMES = (
+ 'vxsnan_flag',
+ 'vximz_flag',
+ 'vxidi_flag',
+ 'vxisi_flag',
+ 'vxzdz_flag',
+ 'vxsqrt_flag',
+ 'vxcvi_flag',
+ 'vxvc_flag',
+ 'ox_flag',
+ 'ux_flag',
+ 'xx_flag',
+ 'zx_flag',
+ 'inc_flag',
+)
+
if __name__ == '__main__':
# find out what the heck is in SPR enum :)
print("sprs full", len(SPRfull))