Fix broken unit tests in test_caller
[soc.git] / src / soc / decoder / isa / caller.py
index 85bd96bc8504e7b39b31e1184f4845ec29d00b8a..299b74c0e136a65a0f1a68955e6ccda786e2cf99 100644 (file)
@@ -151,7 +151,8 @@ class SPR(dict):
             return dict.__getitem__(self, key)
         else:
             info = spr_dict[key]
-            return SelectableInt(0, info.length)
+            dict.__setitem__(self, key, SelectableInt(0, info.length))
+            return dict.__getitem__(self, key)
 
     def __setitem__(self, key, value):
         if isinstance(key, SelectableInt):
@@ -243,23 +244,56 @@ class ISACaller:
         inv_a = yield self.dec2.e.invert_a
         if inv_a:
             inputs[0] = ~inputs[0]
+
+        imm_ok = yield self.dec2.e.imm_data.ok
+        if imm_ok:
+            imm = yield self.dec2.e.imm_data.data
+            inputs.append(SelectableInt(imm, 64))
         assert len(outputs) >= 1
         output = outputs[0]
-        gts = [(x > output) == SelectableInt(1, 1) for x in inputs]
+        gts = [(x > output) for x in inputs]
         print(gts)
-        if any(gts):
-            cy = True
-        else:
-            cy = False
+        cy = 1 if any(gts) else 0
         self.spr['XER'][XER_bits['CA']] = cy
 
+
+        # 32 bit carry
+        gts = [(x[32:64] > output[32:64]) == SelectableInt(1, 1)
+               for x in inputs]
+        cy32 = 1 if any(gts) else 0
+        self.spr['XER'][XER_bits['CA32']] = cy32
+
+    def handle_overflow(self, inputs, outputs):
+        inv_a = yield self.dec2.e.invert_a
+        if inv_a:
+            inputs[0] = ~inputs[0]
+
+        imm_ok = yield self.dec2.e.imm_data.ok
+        if imm_ok:
+            imm = yield self.dec2.e.imm_data.data
+            inputs.append(SelectableInt(imm, 64))
+        assert len(outputs) >= 1
+        if len(inputs) >= 2:
+            output = outputs[0]
+            input_sgn = [exts(x.value, x.bits) < 0 for x in inputs]
+            output_sgn = exts(output.value, output.bits) < 0
+            ov = 1 if input_sgn[0] == input_sgn[1] and \
+                output_sgn != input_sgn[0] else 0
+
+            self.spr['XER'][XER_bits['OV']] = ov
+            so = self.spr['XER'][XER_bits['SO']]
+            so = so | ov
+            self.spr['XER'][XER_bits['SO']] = so
+
+
+
     def handle_comparison(self, outputs):
         out = outputs[0]
         out = exts(out.value, out.bits)
         zero = SelectableInt(out == 0, 1)
         positive = SelectableInt(out > 0, 1)
         negative = SelectableInt(out < 0, 1)
-        SO = SelectableInt(0, 1)
+        SO = self.spr['XER'][XER_bits['SO']]
         cr_field = selectconcat(negative, positive, zero, SO)
         self.crl[0].eq(cr_field)
 
@@ -298,11 +332,15 @@ class ISACaller:
         results = info.func(self, *inputs)
         print(results)
 
+        carry_en = yield self.dec2.e.output_carry
+        if carry_en:
+            yield from self.handle_carry_(inputs, results)
+        ov_en = yield self.dec2.e.oe
+        if ov_en:
+            yield from self.handle_overflow(inputs, results)
         rc_en = yield self.dec2.e.rc.data
         if rc_en:
             self.handle_comparison(results)
-        carry_en = yield self.dec2.e.output_carry
-        yield from self.handle_carry_(inputs, results)
 
         # any modified return results?
         if info.write_regs: