slightly messy: qemu goes haywire at the last instruction.
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 27 May 2021 10:20:05 +0000 (11:20 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 27 May 2021 10:20:05 +0000 (11:20 +0100)
reset bigendian to sane value

src/openpower/decoder/isa/caller.py
src/openpower/decoder/isa/pypowersim.py

index 2ac4c320f6f3bc00044431bac702767f15939e6a..c343b12c1a12d839eb6c0bfa26bfb8f9c19d5814 100644 (file)
@@ -819,17 +819,28 @@ class ISACaller:
         self.namespace['NIA'] = SelectableInt(pc_val, 64)
         self.pc.update(self.namespace, self.is_svp64_mode)
 
-    def setup_one(self):
-        """set up one instruction
+    def get_next_insn(self):
+        """check instruction
         """
         if self.respect_pc:
             pc = self.pc.CIA.value
         else:
             pc = self.fake_pc
-        self._pc = pc
         ins = self.imem.ld(pc, 4, False, True, instr_fetch=True)
         if ins is None:
             raise KeyError("no instruction at 0x%x" % pc)
+        return pc, ins
+
+    def setup_one(self):
+        """set up one instruction
+        """
+        pc, insn = self.get_next_insn()
+        self.setup_next_insn(pc, insn)
+
+    def setup_next_insn(self, pc, ins):
+        """set up next instruction
+        """
+        self._pc = pc
         log("setup: 0x%x 0x%x %s" % (pc, ins & 0xffffffff, bin(ins)))
         log("CIA NIA", self.respect_pc, self.pc.CIA.value, self.pc.NIA.value)
 
index 7492c90f9690b05dfcc5bac32c5a6fad61a6c3e3..6f561309c75f6e6d5a92da2a140b3f2cff0aaf0c 100644 (file)
@@ -88,7 +88,7 @@ def read_entries(fname, listqty=None):
 
     return result
 
-def qemu_register_compare(sim, qemu, regs):
+def qemu_register_compare(sim, qemu, regs, fprs):
     qpc, qxer, qcr = qemu.get_pc(), qemu.get_xer(), qemu.get_cr()
     sim_cr = sim.cr.value
     sim_pc = sim.pc.CIA.value
@@ -107,6 +107,12 @@ def qemu_register_compare(sim, qemu, regs):
         log("expect %x got %x" % (qemu_val, sim_val))
         #self.assertEqual(qemu_val, sim_val,
         #                 "expect %x got %x" % (qemu_val, sim_val))
+    for fpr in fprs:
+        qemu_val = qemu.get_fpr(fpr)
+        sim_val = sim.fpr(fpr).value
+        log("expect fpr %x got %x" % (qemu_val, sim_val))
+        #self.assertEqual(qemu_val, sim_val,
+        #                 "expect %x got %x" % (qemu_val, sim_val))
     #self.assertEqual(qcr, sim_cr)
 
 
@@ -161,12 +167,19 @@ def run_tst(args, generator, qemu,
         yield pdecode2.dec.bigendian.eq(0)  # little / big?
         pc = simulator.pc.CIA.value
         index = pc//4
+
+        # rather awkward: qemu will go wonky if stepped over the
+        # last instruction.  use ISACaller to check if this is
+        # the last instruction, and leave qemu pointing at it
+        # rather than trigger an exception in the remote-qemu program
+        try:
+            _pc, _ins = simulator.get_next_insn()
+        except KeyError:  # indicates instruction not in imem: stop
+            return
+
         while not simulator.halted:
             log("instr pc", pc)
-            try:
-                yield from simulator.setup_one()
-            except KeyError:  # indicates instruction not in imem: stop
-                break
+            yield from simulator.setup_next_insn(_pc, _ins)
             yield Settle()
 
             if False:
@@ -185,11 +198,25 @@ def run_tst(args, generator, qemu,
             #index = pc//4
 
             if not qemu:
+                try:
+                    _pc, _ins = simulator.get_next_insn()
+                except KeyError:  # indicates instruction not in imem: stop
+                    return
                 continue
 
-            # check qemu co-sim: run one instruction
+            # check qemu co-sim: run one instruction, but first check
+            # in ISACaller if there *is* a next instruction.  if there
+            # is, "recover" qemu by switching bigendian back
+            try:
+                _pc, _ins = simulator.get_next_insn()
+            except KeyError:  # indicates instruction not in imem: stop
+                _pc, _insn = (None, None)
             qemu.step()
-            qemu_register_compare(simulator, qemu, range(32))
+            if _pc and not simulator.halted:
+                qemu.set_endian(True)
+            qemu_register_compare(simulator, qemu, range(32), range(32))
+            if _pc is None:
+                break
 
         # cleanup
         if qemu: