pass GPR to SVSHAPEs in ISACaller
[openpower-isa.git] / src / openpower / decoder / isa / caller.py
index 941a89f0bb2eedfc323b3a51c52464bd8cbd03ef..7f57d29397e47e1cae713da2497e4197346afee3 100644 (file)
@@ -651,11 +651,11 @@ class ISACaller(ISACallerHelper, ISAFPHelpers):
         for i in range(4):
             sname = 'SVSHAPE%d' % i
             if sname not in self.spr:
-                self.spr[sname] = SVSHAPE(0)
+                val = 0
             else:
-                # make sure it's an SVSHAPE
                 val = self.spr[sname].value
-                self.spr[sname] = SVSHAPE(val)
+            # make sure it's an SVSHAPE
+            self.spr[sname] = SVSHAPE(val, self.gpr)
         self.last_op_svshape = False
 
         # "raw" memory
@@ -741,15 +741,18 @@ class ISACaller(ISACallerHelper, ISAFPHelpers):
         hence the default arguments.  when calling from inside ISACaller
         it is best to use call_trap()
         """
-        log("TRAP:", hex(trap_addr), hex(self.namespace['MSR'].value))
+        # https://bugs.libre-soc.org/show_bug.cgi?id=859
+        kaivb = self.spr['KAIVB'].value
+        msr = self.namespace['MSR'].value
+        log("TRAP:", hex(trap_addr), hex(msr), "kaivb", hex(kaivb))
         # store CIA(+4?) in SRR0, set NIA to 0x700
         # store MSR in SRR1, set MSR to um errr something, have to check spec
         # store SVSTATE (if enabled) in SVSRR0
         self.spr['SRR0'].value = self.pc.CIA.value
-        self.spr['SRR1'].value = self.namespace['MSR'].value
+        self.spr['SRR1'].value = msr
         if self.is_svp64_mode:
             self.spr['SVSRR0'] = self.namespace['SVSTATE'].value
-        self.trap_nia = SelectableInt(trap_addr, 64)
+        self.trap_nia = SelectableInt(trap_addr | (kaivb&~0x1fff), 64)
         self.spr['SRR1'][trap_bit] = 1  # change *copy* of MSR in SRR1
 
         # set exception bits.  TODO: this should, based on the address
@@ -1766,9 +1769,15 @@ class ISACaller(ISACallerHelper, ISAFPHelpers):
         self.allow_next_step_inc = submode.value + 1
         log("SVSTATE_NEXT mode", mode, submode, self.allow_next_step_inc)
         self.svstate_next_mode = mode
-        if self.svstate_next_mode > 0:
+        if self.svstate_next_mode > 0 and self.svstate_next_mode < 5:
             shape_idx = self.svstate_next_mode.value-1
             return SelectableInt(self.remap_idxs[shape_idx], 7)
+        if self.svstate_next_mode == 5:
+            self.svstate_next_mode = 0
+            return SelectableInt(self.svstate.srcstep, 7)
+        if self.svstate_next_mode == 6:
+            self.svstate_next_mode = 0
+            return SelectableInt(self.svstate.dststep, 7)
         return SelectableInt(0, 7)
 
     def svstate_pre_inc(self):