From: Luke Kenneth Casson Leighton Date: Thu, 27 May 2021 10:20:05 +0000 (+0100) Subject: slightly messy: qemu goes haywire at the last instruction. X-Git-Tag: xlen-bcd~536 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a2a100908dac2538ed1bd6ccebf3aa076521c0cc;p=openpower-isa.git slightly messy: qemu goes haywire at the last instruction. reset bigendian to sane value --- diff --git a/src/openpower/decoder/isa/caller.py b/src/openpower/decoder/isa/caller.py index 2ac4c320..c343b12c 100644 --- a/src/openpower/decoder/isa/caller.py +++ b/src/openpower/decoder/isa/caller.py @@ -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) diff --git a/src/openpower/decoder/isa/pypowersim.py b/src/openpower/decoder/isa/pypowersim.py index 7492c90f..6f561309 100644 --- a/src/openpower/decoder/isa/pypowersim.py +++ b/src/openpower/decoder/isa/pypowersim.py @@ -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: