create a register cache for qemu machine interface, very slow
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 27 May 2021 08:59:53 +0000 (09:59 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 27 May 2021 09:04:53 +0000 (10:04 +0100)
src/openpower/decoder/isa/pypowersim.py
src/openpower/simulator/qemu.py
src/openpower/simulator/test_sim.py

index 14a4c53c40a280ca1915a4599e38c41ff6b76e02..7492c90f9690b05dfcc5bac32c5a6fad61a6c3e3 100644 (file)
@@ -102,7 +102,7 @@ def qemu_register_compare(sim, qemu, regs):
     print("sim xer", hex(sim_xer))
     #self.assertEqual(qpc, sim_pc)
     for reg in regs:
-        qemu_val = qemu.get_register(reg)
+        qemu_val = qemu.get_gpr(reg)
         sim_val = sim.gpr(reg).value
         log("expect %x got %x" % (qemu_val, sim_val))
         #self.assertEqual(qemu_val, sim_val,
index 8a0625dff6e88e51b8a518cdb715554b4cf75fba..00d0efa8c57933ea45e063595950cf76cbebb8bc 100644 (file)
@@ -29,6 +29,15 @@ class QemuController:
                                            stdin=subprocess.PIPE)
         self.gdb = GdbController(gdb_path='powerpc64-linux-gnu-gdb')
         self.bigendian = bigendian
+        self._reg_cache = {}
+
+    def _rcache_trash(self, key=None):
+        """cache of register values, trash it on call to step or continue
+        """
+        if key is None:
+            self._reg_cache = {}
+            return
+        self._reg_cache.pop(key, None)
 
     def __enter__(self):
         return self
@@ -82,12 +91,15 @@ class QemuController:
         return self.gdb.write('-data-list-register-values x')
 
     def _get_register(self, fmt):
+        if fmt in self._reg_cache:
+            return self._reg_cache[fmt] # return cached reg value
         res = self.gdb.write('-data-list-register-values '+fmt,
                              timeout_sec=1.0)  # increase this timeout if needed
         for x in res:
             if(x["type"] == "result"):
                 assert 'register-values' in x['payload']
                 res = int(x['payload']['register-values'][0]['value'], 0)
+                self._reg_cache[fmt] = res # cache reg value
                 return res
                 # return swap_order(res, 8)
         return None
@@ -105,10 +117,30 @@ class QemuController:
     def get_register(self, num):
         return self._get_register('x {}'.format(num))
 
+    def get_gpr(self, num):
+        return self.get_register(num)
+
+    def get_fpr(self, num):
+        return self.get_register(num+32)
+
+    def set_pc(self, pc):
+        self._rcache_trash('x 64')
+        self.gdb_eval('$pc=%d' % pc)
+
+    def set_msr(self, msr):
+        self._rcache_trash('x 65')
+        self.gdb_eval('$msr=%d' % msr)
+
+    def set_cr(self, cr):
+        self._rcache_trash('x 66')
+        self.gdb_eval('$cr=%d' % cr)
+
     def step(self):
+        self._rcache_trash()
         return self.gdb.write('-exec-step-instruction')
 
     def gdb_continue(self):
+        self._rcache_trash()
         return self.gdb.write('-exec-continue')
 
     def gdb_eval(self, expr):
@@ -138,7 +170,7 @@ def run_program(program, initial_mem=None, extra_break_addr=None,
         q.upload_mem(initial_mem)
 
     # Run to the start of the program
-    q.gdb_eval('$pc=%d' % start_addr)
+    q.set_pc(start_addr)
     pc = q.get_pc()
     print("pc", bigendian, hex(pc))
     q.break_address(start_addr) # set breakpoint at start
@@ -152,10 +184,10 @@ def run_program(program, initial_mem=None, extra_break_addr=None,
         msr = msr & ((1 << 64)-1)
     else:
         msr |= (1 << 0)
-    q.gdb_eval('$msr=%d' % msr)
+    q.set_msr(msr)
     print("msr set to", hex(msr))
     # set the CR to 0, matching the simulator
-    q.gdb_eval('$cr=0')
+    q.set_cr(0)
     # delete the previous breakpoint so loops don't screw things up
     q.delete_breakpoint()
     # allow run to end
@@ -179,7 +211,7 @@ if __name__ == '__main__':
     q.connect()
     q.break_address(0x20000000)
     q.gdb_continue()
-    print(q.get_register(1))
+    print(q.get_gpr(1))
     print(q.step())
-    print(q.get_register(1))
+    print(q.get_gpr(1))
     q.exit()
index 8c02081925d47669480c9fbeee37f48af3932478..03d7d8290a8da80e8346d386d790276d5062e066 100644 (file)
@@ -549,7 +549,7 @@ class DecoderBase:
         print("sim xer", hex(sim_xer))
         self.assertEqual(qpc, sim_pc)
         for reg in regs:
-            qemu_val = qemu.get_register(reg)
+            qemu_val = qemu.get_gpr(reg)
             sim_val = sim.gpr(reg).value
             self.assertEqual(qemu_val, sim_val,
                              "expect %x got %x" % (qemu_val, sim_val))