format caller.py
[soc.git] / src / soc / decoder / isa / caller.py
index 8c5ec68ef0b4ddea08a274792a627b39d4149371..703721436b35e24464b8dbaf47ddb1e4cc6ca17d 100644 (file)
@@ -16,7 +16,7 @@ from soc.decoder.selectable_int import (FieldSelectableInt, SelectableInt,
                                         selectconcat)
 from soc.decoder.power_enums import (spr_dict, spr_byname, XER_bits,
                                      insns, MicrOp)
-from soc.decoder.helpers import exts
+from soc.decoder.helpers import exts, gtu, ltu
 from soc.consts import PIb, MSRb  # big-endian (PowerISA versions)
 
 from collections import namedtuple
@@ -131,13 +131,13 @@ class Mem:
         print("mem @ 0x{:x}: 0x{:x}".format(addr, self.mem[addr]))
 
     def __call__(self, addr, sz):
-        val = self.ld(addr.value, sz)
+        val = self.ld(addr.value, sz, swap=False)
         print("memread", addr, sz, val)
         return SelectableInt(val, sz*8)
 
     def memassign(self, addr, sz, val):
         print("memassign", addr, sz, val)
-        self.st(addr.value, val.value, sz)
+        self.st(addr.value, val.value, sz, swap=False)
 
 
 class GPR(dict):
@@ -216,6 +216,10 @@ class SPR(dict):
         if isinstance(key, int):
             key = spr_dict[key].SPR
         key = special_sprs.get(key, key)
+        if key == 'HSRR0':  # HACK!
+            key = 'SRR0'
+        if key == 'HSRR1':  # HACK!
+            key = 'SRR1'
         if key in self:
             res = dict.__getitem__(self, key)
         else:
@@ -235,6 +239,10 @@ class SPR(dict):
             key = spr_dict[key].SPR
             print("spr key", key)
         key = special_sprs.get(key, key)
+        if key == 'HSRR0':  # HACK!
+            self.__setitem__('SRR0', value)
+        if key == 'HSRR1':  # HACK!
+            self.__setitem__('SRR1', value)
         print("setting spr", key, value)
         dict.__setitem__(self, key, value)
 
@@ -306,8 +314,9 @@ class ISACaller:
         # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
 
         # create CR then allow portions of it to be "selectable" (below)
-        self._cr = SelectableInt(initial_cr, 64)  # underlying reg
-        self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
+        #rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
+        self.cr = SelectableInt(initial_cr, 64)  # underlying reg
+        #self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
 
         # "undefined", just set to variable-bit-width int (use exts "max")
         self.undefined = SelectableInt(0, 256)  # TODO, not hard-code 256!
@@ -333,7 +342,7 @@ class ISACaller:
         # field-selectable versions of Condition Register TODO check bitranges?
         self.crl = []
         for i in range(8):
-            bits = tuple(range(i*4, (i+1)*4))  # errr... maybe?
+            bits = tuple(range(i*4+32, (i+1)*4+32))  # errr... maybe?
             _cr = FieldSelectableInt(self.cr, bits)
             self.crl.append(_cr)
             self.namespace["CR%d" % i] = _cr
@@ -388,7 +397,10 @@ class ISACaller:
             else:
                 sig = getattr(fields, name)
             val = yield sig
-            if name in ['BF', 'BFA']:
+            # these are all opcode fields involved in index-selection of CR,
+            # and need to do "standard" arithmetic.  CR[BA+32] for example
+            # would, if using SelectableInt, only be 5-bit.
+            if name in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
                 self.namespace[name] = val
             else:
                 self.namespace[name] = SelectableInt(val, sig.width)
@@ -398,7 +410,7 @@ class ISACaller:
         self.namespace['CA32'] = self.spr['XER'][XER_bits['CA32']].value
 
     def handle_carry_(self, inputs, outputs, already_done):
-        inv_a = yield self.dec2.e.do.invert_a
+        inv_a = yield self.dec2.e.do.invert_in
         if inv_a:
             inputs[0] = ~inputs[0]
 
@@ -415,28 +427,45 @@ class ISACaller:
         gts = []
         for x in inputs:
             print("gt input", x, output)
-            gt = (x > output)
+            gt = (gtu(x, output))
             gts.append(gt)
         print(gts)
         cy = 1 if any(gts) else 0
+        print("CA", cy, gts)
         if not (1 & already_done):
             self.spr['XER'][XER_bits['CA']] = cy
 
-        print("inputs", inputs)
+        print("inputs", already_done, inputs)
         # 32 bit carry
-        gts = []
-        for x in inputs:
-            print("input", x, output)
-            gt = (x[32:64] > output[32:64]) == SelectableInt(1, 1)
-            gts.append(gt)
-        cy32 = 1 if any(gts) else 0
+        # ARGH... different for OP_ADD... *sigh*...
+        op = yield self.dec2.e.do.insn_type
+        if op == MicrOp.OP_ADD.value:
+            res32 = (output.value & (1 << 32)) != 0
+            a32 = (inputs[0].value & (1 << 32)) != 0
+            if len(inputs) >= 2:
+                b32 = (inputs[1].value & (1 << 32)) != 0
+            else:
+                b32 = False
+            cy32 = res32 ^ a32 ^ b32
+            print("CA32 ADD", cy32)
+        else:
+            gts = []
+            for x in inputs:
+                print("input", x, output)
+                print("     x[32:64]", x, x[32:64])
+                print("     o[32:64]", output, output[32:64])
+                gt = (gtu(x[32:64], output[32:64])) == SelectableInt(1, 1)
+                gts.append(gt)
+            cy32 = 1 if any(gts) else 0
+            print("CA32", cy32, gts)
         if not (2 & already_done):
             self.spr['XER'][XER_bits['CA32']] = cy32
 
     def handle_overflow(self, inputs, outputs, div_overflow):
-        inv_a = yield self.dec2.e.do.invert_a
-        if inv_a:
-            inputs[0] = ~inputs[0]
+        if hasattr(self.dec2.e.do, "invert_in"):
+            inv_a = yield self.dec2.e.do.invert_in
+            if inv_a:
+                inputs[0] = ~inputs[0]
 
         imm_ok = yield self.dec2.e.do.imm_data.ok
         if imm_ok:
@@ -476,7 +505,7 @@ class ISACaller:
     def handle_comparison(self, outputs):
         out = outputs[0]
         assert isinstance(out, SelectableInt), \
-                          "out zero not a SelectableInt %s" % repr(outputs)
+            "out zero not a SelectableInt %s" % repr(outputs)
         print("handle_comparison", out.bits, hex(out.value))
         # TODO - XXX *processor* in 32-bit mode
         # https://bugs.libre-soc.org/show_bug.cgi?id=424
@@ -539,24 +568,33 @@ class ISACaller:
         int_op = yield self.dec2.dec.op.internal_op
 
         # sigh reconstruct the assembly instruction name
-        ov_en = yield self.dec2.e.do.oe.oe
-        ov_ok = yield self.dec2.e.do.oe.ok
-        rc_en = yield self.dec2.e.do.rc.data
-        rc_ok = yield self.dec2.e.do.rc.ok
+        if hasattr(self.dec2.e.do, "oe"):
+            ov_en = yield self.dec2.e.do.oe.oe
+            ov_ok = yield self.dec2.e.do.oe.ok
+        else:
+            ov_en = False
+            ov_ok = False
+        if hasattr(self.dec2.e.do, "rc"):
+            rc_en = yield self.dec2.e.do.rc.rc
+            rc_ok = yield self.dec2.e.do.rc.ok
+        else:
+            rc_en = False
+            rc_ok = False
         # grrrr have to special-case MUL op (see DecodeOE)
-        print("ov %d en %d rc %d en %d op %d" % \
-                        (ov_ok, ov_en, rc_ok, rc_en, int_op))
+        print("ov %d en %d rc %d en %d op %d" %
+              (ov_ok, ov_en, rc_ok, rc_en, int_op))
         if int_op in [MicrOp.OP_MUL_H64.value, MicrOp.OP_MUL_H32.value]:
             print("mul op")
             if rc_en & rc_ok:
                 asmop += "."
         else:
-            if not asmop.endswith("."): # don't add "." to "andis."
+            if not asmop.endswith("."):  # don't add "." to "andis."
                 if rc_en & rc_ok:
                     asmop += "."
-        lk = yield self.dec2.e.do.lk
-        if lk:
-            asmop += "l"
+        if hasattr(self.dec2.e.do, "lk"):
+            lk = yield self.dec2.e.do.lk
+            if lk:
+                asmop += "l"
         print("int_op", int_op)
         if int_op in [MicrOp.OP_B.value, MicrOp.OP_BC.value]:
             AA = yield self.dec2.dec.fields.FormI.AA[0:-1]
@@ -629,7 +667,7 @@ class ISACaller:
             illegal = name != asmop
 
         if illegal:
-            print ("illegal", name, asmop)
+            print("illegal", name, asmop)
             self.TRAP(0x700, PIb.ILLEG)
             self.namespace['NIA'] = self.trap_nia
             self.pc.update(self.namespace)
@@ -686,7 +724,10 @@ class ISACaller:
                     already_done |= 2
 
         print("carry already done?", bin(already_done))
-        carry_en = yield self.dec2.e.do.output_carry
+        if hasattr(self.dec2.e.do, "output_carry"):
+            carry_en = yield self.dec2.e.do.output_carry
+        else:
+            carry_en = False
         if carry_en:
             yield from self.handle_carry_(inputs, results, already_done)
 
@@ -697,13 +738,20 @@ class ISACaller:
                 if name == 'overflow':
                     overflow = output
 
-        ov_en = yield self.dec2.e.do.oe.oe
-        ov_ok = yield self.dec2.e.do.oe.ok
+        if hasattr(self.dec2.e.do, "oe"):
+            ov_en = yield self.dec2.e.do.oe.oe
+            ov_ok = yield self.dec2.e.do.oe.ok
+        else:
+            ov_en = False
+            ov_ok = False
         print("internal overflow", overflow, ov_en, ov_ok)
         if ov_en & ov_ok:
             yield from self.handle_overflow(inputs, results, overflow)
 
-        rc_en = yield self.dec2.e.do.rc.data
+        if hasattr(self.dec2.e.do, "rc"):
+            rc_en = yield self.dec2.e.do.rc.rc
+        else:
+            rc_en = False
         if rc_en:
             self.handle_comparison(results)