add CR5Operand and CR3Operand to power_insns.py
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 11 Sep 2022 00:40:56 +0000 (01:40 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 11 Sep 2022 00:40:56 +0000 (01:40 +0100)
src/openpower/decoder/power_enums.py
src/openpower/decoder/power_insn.py

index daadc555e4a3e39b7f58fb66b88e55509aca909c..365ced69b20825c623ffc732d1f116e28d5851ea 100644 (file)
@@ -393,11 +393,11 @@ class RegType(Enum):
     FRS = FPR
     FRT = FPR
 
-    CR_REG = 2
+    CR_REG = 2  # actually CR Field. the CR register is 32-bit.
     BF = CR_REG
     BFA = CR_REG
 
-    CR_BIT = 3
+    CR_BIT = 3 # refers to one bit of the 32-bit CR register
     BA = CR_BIT
     BB = CR_BIT
     BC = CR_BIT
index 5a1bcc1aea7c8f62c16fc910e27e1347639561c4..63db6856844ea016a89b3953c2a69e887e9496bd 100644 (file)
@@ -651,11 +651,16 @@ class GPRFPROperand(RegisterOperand):
             bits = (len(span) + len(spec_span))
             value = _SelectableInt(value=value.value, bits=bits)
             spec = _SelectableInt(value=spec.value, bits=bits)
+            # this is silly these should be in a general base class,
+            # settable by constructor
+            vshift = 2
+            sshift = 5
+            spshft = 0
             if vector:
-                value = ((value << 2) | spec)
+                value = ((value << vshift) | (spec<<spshft))
                 span = (span + spec_span)
             else:
-                value = ((spec << 5) | value)
+                value = ((spec << sshift) | value)
                 span = (spec_span + span)
 
             return (value, span)
@@ -681,6 +686,75 @@ class FPROperand(GPRFPROperand):
             verbosity=verbosity, indent=indent)
 
 
+class CR3Operand(RegisterOperand):
+    def spec(self, insn, record):
+        def merge(vector, value, span, spec, spec_span):
+            bits = (len(span) + len(spec_span))
+            #print ("value", bin(value.value), value.bits)
+            value = _SelectableInt(value=value.value, bits=bits)
+            spec = _SelectableInt(value=spec.value, bits=bits)
+            #print ("spec", bin(spec.value), spec.bits)
+            #print ("value", bin(value.value), value.bits)
+            #print ("lsbs", bin(lsbs.value), lsbs.bits)
+            # this is silly these should be in a general base class,
+            # settable by constructor
+            vshift = 4
+            sshift = 3
+            spshft = 2
+            if vector:
+                value = ((value << vshift) | (spec<<spshft))
+                span = (span[0:3] + spec_span + ('{0}', '{0}') + span[3:5])
+            else:
+                value = ((spec << sshift) | value)
+                span = (('{0}', '{0}') + spec_span + span)
+
+            # add the 2 LSBs back in
+            #print ("after", bin(value.value), value.bits)
+            return (value, span)
+
+        return super().spec(insn=insn, record=record, merge=merge)
+
+
+# exactly the same as CR3Operand, should be exactly the same base class
+# which should also be exactly the same base class as GPR and FPR operand
+# which sohuld be taking a constructor with prefix "r" and "f" as options
+# as well as vshift, sshift and spsft as parameters, and whether
+# to skip 2 LSBs and put them back on afterwards.
+# it's all the exact same scheme, so why on earth duplicate code?
+class CR5Operand(RegisterOperand):
+    def spec(self, insn, record):
+        def merge(vector, value, span, spec, spec_span):
+            # record the 2 lsbs first
+            lsbs = _SelectableInt(value=value.value&3, bits=2)
+            bits = (len(span) + len(spec_span))
+            #print ("value", bin(value.value), value.bits)
+            value = _SelectableInt(value=value.value>>2, bits=bits)
+            spec = _SelectableInt(value=spec.value, bits=bits)
+            #print ("spec", bin(spec.value), spec.bits)
+            #print ("value", bin(value.value), value.bits)
+            #print ("lsbs", bin(lsbs.value), lsbs.bits)
+            # this is silly these should be in a general base class,
+            # settable by constructor
+            vshift = 4
+            sshift = 3
+            spshft = 2
+            if vector:
+                value = ((value << vshift) | (spec<<spshft))
+                span = (span[0:3] + spec_span + ('{0}', '{0}') + span[3:5])
+            else:
+                value = ((spec << sshift) | value)
+                span = (('{0}', '{0}') + spec_span + span)
+
+            # add the 2 LSBs back in
+            res = _SelectableInt(value=(value.value<<2)+lsbs.value, bits=bits+2)
+            #print ("after", bin(value.value), value.bits)
+            #print ("res", bin(res.value), res.bits)
+            return (res, span)
+
+        return super().spec(insn=insn, record=record, merge=merge)
+
+
+# this is silly, all of these should be the same base class
 class DynamicOperandCR(RegisterOperand):
     def spec(self, insn, record):
         def merge(vector, value, span, spec, spec_span):
@@ -851,6 +925,10 @@ class Operands(tuple):
                         dynamic_cls = GPROperand
                     elif regtype is _RegType.FPR:
                         dynamic_cls = FPROperand
+                    if regtype is _RegType.CR_BIT: # 5-bit
+                        dynamic_cls = CR5Operand
+                    if regtype is _RegType.CR_REG: # actually CR Field, 3-bit
+                        dynamic_cls = CR3Operand
 
                 operand = dynamic_cls(name=operand)
                 operands.append(operand)