test/runner: allow disabling VCD using SIM_NO_VCD=1 env var
[openpower-isa.git] / src / openpower / consts.py
index f55eedc350569bf0fd161853fafcac45f7bdda9e..2197f218ca86f3d3be5a18b7a8cecaed9d0efccd 100644 (file)
@@ -1,15 +1,4 @@
-# just... don't ask.  MSB0 is a massive pain in the neck.
-# this module, aside from creating various field constants,
-# helps out by creating alternative (identical) classes with
-# a "b" name to indicate "MSB0 big-endian".
-
-
-# sigh create little-ended versions of bitfield flags
-def botchify(bekls, lekls, msb=63):
-    for attr in dir(bekls):
-        if attr[0] == '_':
-            continue
-        setattr(lekls, attr, msb-getattr(bekls, attr))
+import enum
 
 
 # Can't think of a better place to put these functions.
@@ -83,10 +72,40 @@ def field(r, msb0_start, msb0_end=None, field_width=64):
         return r[field_slice(msb0_start, msb0_end, field_width)]
 
 
+# just... don't ask.  MSB0 is a massive pain in the neck.
+# this module, aside from creating various field constants,
+# helps out by creating alternative (identical) classes with
+# a "b" name to indicate "MSB0 big-endian".
+class _Const(enum.IntEnum):
+    pass
+
+
+class _ConstLEMeta(enum.EnumMeta):
+    def __call__(metacls, *args, **kwargs):
+        if len(args) > 1:
+            names = args[1]
+        else:
+            names = kwargs.pop("names")
+
+        if isinstance(names, type) and issubclass(names, enum.Enum):
+            names = dict(names.__members__)
+        if isinstance(names, dict):
+            names = tuple(names.items())
+
+        msb = kwargs.pop("msb")
+        names = {key:(msb - value) for (key, value) in names}
+
+        return super().__call__(*args, names=names, **kwargs)
+
+
+class _ConstLE(_Const, metaclass=_ConstLEMeta):
+    pass
+
+
 # Listed in V3.0B Book III Chap 4.2.1
 # MSR bit numbers, *bigendian* order (PowerISA format)
 # use this in the simulator
-class MSRb:
+class MSRb(_Const):
     SF  = 0     # Sixty-Four bit mode
     HV  = 3     # Hypervisor state
     UND = 5     # Undefined behavior state (see Bk 2, Sect. 3.2.1)
@@ -111,10 +130,11 @@ class MSRb:
     LE  = 63    # Little Endian
 
 # use this inside the HDL (where everything is little-endian)
-class MSR:
-    pass
+MSR = _ConstLE("MSR", names=MSRb, msb=63)
 
-botchify(MSRb, MSR)
+# default MSR value for unit tests, since 0 isn't a good default
+DEFAULT_MSR = sum(1 << i for i in (
+    MSR.SF, MSR.HV, MSR.FP, MSR.FE0, MSR.FE1, MSR.RI, MSR.LE))
 
 # Listed in V3.0B Book III 7.5.9 "Program Interrupt"
 
@@ -124,7 +144,7 @@ botchify(MSRb, MSR)
 # to expand traptype to cope with the increased range
 
 # use this in the simulator
-class PIb:
+class PIb(_Const):
     INVALID      = 33    # 1 for an invalid mem err
     PERMERR      = 35    # 1 for an permanent mem err
     TM_BAD_THING = 42    # 1 for a TM Bad Thing type interrupt
@@ -135,10 +155,8 @@ class PIb:
     ADR          = 47    # 0 if SRR0 = address of instruction causing exception
 
 # and use this in the HDL
-class PI:
-    pass
+PI = _ConstLE("PI", names=PIb, msb=63)
 
-botchify(PIb, PI)
 
 # see traptype (and trap main_stage.py)
 # IMPORTANT: when adding extra bits here it is CRITICALLY IMPORTANT
@@ -158,7 +176,7 @@ class TT:
 
 
 # EXTRA3 3-bit subfield (spec)
-class SPECb:
+class SPECb(_Const):
     VEC = 0  # 1 for vector, 0 for scalar
     MSB = 1  # augmented register number, MSB
     LSB = 2  # augmented register number, LSB
@@ -166,13 +184,12 @@ class SPECb:
 
 SPEC_SIZE = 3
 SPEC_AUG_SIZE = 2  # augmented subfield size (MSB+LSB above)
-class SPEC:
-    pass
-botchify(SPECb, SPEC, SPEC_SIZE-1)
+SPEC = _ConstLE("SPEC", names=SPECb, msb=SPEC_SIZE-1)
+
 
 
 # EXTRA field, with EXTRA2 subfield encoding
-class EXTRA2b:
+class EXTRA2b(_Const):
     IDX0_VEC = 0
     IDX0_MSB = 1
     IDX1_VEC = 2
@@ -185,9 +202,14 @@ class EXTRA2b:
 
 
 EXTRA2_SIZE = 9
-class EXTRA2:
-    pass
-botchify(EXTRA2b, EXTRA2, EXTRA2_SIZE-1)
+EXTRA2 = _ConstLE("EXTRA2", names=EXTRA2b, msb=EXTRA2_SIZE-1)
+
+# sigh, make these convenience-modifications afterwards (aliases)
+# see RM-2P-1S1D-PU in https://libre-soc.org/openpower/sv/svp64
+EXTRA2b.PACK_en   = EXTRA2b.IDX2_VEC
+EXTRA2b.UNPACK_en = EXTRA2b.IDX2_MSB
+EXTRA2.PACK_en    = EXTRA2.IDX2_VEC
+EXTRA2.UNPACK_en  = EXTRA2.IDX2_MSB
 
 
 # EXTRA field, with EXTRA3 subfield encoding
@@ -218,32 +240,43 @@ class SVP64CROffs:
     CRPred = 4 # TODO: increase when CRs are expanded to 128
 
 
-class SVP64MODEb:
+class SVP64MODEb(_Const):
     # mode bits
     MOD2_MSB = 0
     MOD2_LSB = 1
-    LDST_SHIFT = 2 # set =1 for shift mode
+    MOD3 = 3
+    SEA = 2
     # when predicate not set: 0=ignore/skip 1=zero
     DZ = 3  # for destination
-    BC_SNZ = 3  # for branch-conditional mode
     SZ = 4  # for source
+    ZZ = 3  # for both sz/dz, on all but CR-ops, which, whoops, is RM bit 6.
+    # for branch-conditional
+    BC_SNZ = 3  # for branch-conditional mode
+    BC_VLI = 2  # for VL include/exclude on VLSET mode
+    BC_VLSET = 1 # VLSET mode
+    BC_CTRTEST = 0 # CTR-test mode
     # reduce mode
     REDUCE = 2  # 0=normal predication 1=reduce mode
-    PARALLEL = 3 # 1=parallel reduce, 0=scalar reduce
-    SVM = 3  # subvector reduce mode 0=independent 1=horizontal
     CRM = 4  # CR mode on reduce (Rc=1) 0=some 1=all
     RG = 4   # Reverse-gear on reduce
+    CROP_RG = 3   # Reverse-gear on reduce CR-ops
     # saturation mode
     N = 2  # saturation signed mode 0=signed 1=unsigned
     # ffirst and predicate result modes
     INV = 2  # invert CR sense 0=set 1=unset
     CR_MSB = 3  # CR bit to update (with Rc=1)
     CR_LSB = 4
+    VLI = 0
     RC1 = 4  # update CR as if Rc=1 (when Rc=0)
     # LD immediate els (element-stride) locations, depending on mode
     ELS_NORMAL = 4
     ELS_FFIRST_PRED = 3
-    ELS_SAT = 4
+    LDI_PI = 2 # LD-Immediate Post-Increment
+    LDI_FF = 4 # LD-Immediate Fault-First
+    # LDST element-strided
+    LDST_ELS = 0 # Indexed element-strided
+    # LDST VLI for ffirst is in bit 0
+    LDST_VLI = 0
     # BO bits
     BO_MSB = 2
     BO_LSB = 4
@@ -252,11 +285,8 @@ class SVP64MODEb:
 SVP64MODE_SIZE = 5
 
 
-class SVP64MODE:
-    pass
-
+SVP64MODE = _ConstLE("SVP64MODE", names=SVP64MODEb, msb=SVP64MODE_SIZE-1)
 
-botchify(SVP64MODEb, SVP64MODE, SVP64MODE_SIZE-1)
 
 # add subfields to use with nmutil.sel
 SVP64MODE.MOD2 = [0, 1]
@@ -264,7 +294,7 @@ SVP64MODE.CR = [3, 4]
 
 
 # CR sub-fields
-class CRb:
+class CRb(_Const):
     LT = 0
     GT = 1
     EQ = 2
@@ -274,11 +304,7 @@ class CRb:
 CR_SIZE = 4
 
 
-class CR:
-    pass
-
-
-botchify(CRb, CR, CR_SIZE-1)
+CR = _ConstLE("CR", names=CRb, msb=CR_SIZE-1)
 
 
 # POWER9 Register Files
@@ -292,20 +318,29 @@ class StateRegsEnum:
     PC = 0
     MSR = 1
     SVSTATE = 2
-    N_REGS = 3 # maximum number of regs
+    DEC = 3
+    TB = 4
+    N_REGS = 5 # maximum number of regs
 
 # Fast SPRs Regfile
 class FastRegsEnum:
-    CTR = 0
-    LR = 1
-    TAR = 2
-    SRR0 = 3
-    SRR1 = 4
-    XER = 5 # non-XER bits
-    DEC = 6
-    TB = 7
-    SVSRR0 = 8
-    N_REGS = 9 # maximum number of regs
+    LR = 0
+    CTR = 1
+    SRR0 = 2
+    SRR1 = 3
+    HSRR0 = 4
+    HSRR1 = 5
+    SPRG0 = 6
+    SPRG1 = 7
+    SPRG2 = 8
+    SPRG3 = 9
+    HSPRG0 = 10
+    HSPRG1 = 11
+    XER = 12 # non-XER bits
+    TAR = 13
+    SVSRR0 = 14
+    # only one spare!
+    N_REGS = 15 # maximum number of regs
 
 # XER Regfile
 class XERRegsEnum:
@@ -313,3 +348,10 @@ class XERRegsEnum:
     CA=1 # CA and CA32
     OV=2 # OV and OV32
     N_REGS = 3 # maximum number of regs
+
+
+if __name__ == '__main__':
+    print("EXTRA2 pack", EXTRA2.PACK_en, EXTRA2.PACK_en.value)
+    for field in MSR:
+        if DEFAULT_MSR & (1 << field.value):
+            print(field)