from soc.decoder.orderedset import OrderedSet
from soc.decoder.selectable_int import (FieldSelectableInt, SelectableInt,
selectconcat)
-from soc.decoder.power_enums import spr_dict, XER_bits
+from soc.decoder.power_enums import spr_dict, XER_bits, insns, InternalOp
from soc.decoder.helpers import exts
from collections import namedtuple
import math
+import sys
instruction_info = namedtuple('instruction_info',
'func read_regs uninit_regs write_regs ' + \
return shifter, mask
# TODO: Implement ld/st of lesser width
- def ld(self, address, width=8, swap=True):
+ def ld(self, address, width=8, swap=True, check_in_mem=False):
print("ld from addr 0x{:x} width {:d}".format(address, width))
remainder = address & (self.bytes_per_word - 1)
address = address >> self.word_log2
assert remainder & (width - 1) == 0, "Unaligned access unsupported!"
if address in self.mem:
val = self.mem[address]
+ elif check_in_mem:
+ return None
else:
val = 0
print("mem @ 0x{:x} rem {:d} : 0x{:x}".format(address, remainder, val))
initial_insns = {}
assert self.respect_pc == False, "instructions required to honor pc"
+ print ("ISACaller insns", respect_pc, initial_insns, disassembly)
+
# "fake program counter" mode (for unit testing)
+ self.fake_pc = 0
if not respect_pc:
if isinstance(initial_mem, tuple):
self.fake_pc = initial_mem[0]
- else:
- self.fake_pc = 0
# disassembly: we need this for now (not given from the decoder)
self.disassembly = {}
pc = self.pc.CIA.value
else:
pc = self.fake_pc
- ins = yield self.imem.ld(pc, 4, False)
- yield self.pdecode2.dec.raw_opcode_in.eq(ins)
- yield self.pdecode2.dec.bigendian.eq(0) # little / big?
- self._pc
+ self._pc = pc
+ ins = self.imem.ld(pc, 4, False, True)
+ if ins is None:
+ raise KeyError("no instruction at 0x%x" % pc)
+ print("setup: 0x%x 0x%x %s" % (pc, ins & 0xffffffff, bin(ins)))
+ print ("NIA, CIA", self.pc.CIA.value, self.pc.NIA.value)
+
+ yield self.dec2.dec.raw_opcode_in.eq(ins)
+ yield self.dec2.dec.bigendian.eq(0) # little / big?
def execute_one(self):
"""execute one instruction
"""
# get the disassembly code for this instruction
code = self.disassembly[self._pc]
+ print("sim-execute", hex(self._pc), code)
opname = code.split(' ')[0]
- yield from call(opname)
+ yield from self.call(opname)
if not self.respect_pc:
self.fake_pc += 4
- #else:
- #self.pc.CIA.value = self.pc.NIA.value
+ print ("NIA, CIA", self.pc.CIA.value, self.pc.NIA.value)
def call(self, name):
# TODO, asmregs is from the spec, e.g. add RT,RA,RB
# see http://bugs.libre-riscv.org/show_bug.cgi?id=282
+ asmcode = yield self.dec2.dec.op.asmcode
+ asmop = insns.get(asmcode, None)
+
+ # sigh reconstruct the assembly instruction name
+ ov_en = yield self.dec2.e.oe.oe
+ ov_ok = yield self.dec2.e.oe.ok
+ if ov_en & ov_ok:
+ asmop += "."
+ lk = yield self.dec2.e.lk
+ if lk:
+ asmop += "l"
+ int_op = yield self.dec2.dec.op.internal_op
+ print ("int_op", int_op)
+ if int_op in [InternalOp.OP_B.value, InternalOp.OP_BC.value]:
+ AA = yield self.dec2.dec.fields.FormI.AA[0:-1]
+ print ("AA", AA)
+ if AA:
+ asmop += "a"
+ if int_op == InternalOp.OP_MFCR.value:
+ dec_insn = yield self.dec2.e.insn
+ if dec_insn & (1<<20): # sigh
+ asmop = 'mfocrf'
+ else:
+ asmop = 'mfcr'
+ if int_op == InternalOp.OP_MTCRF.value:
+ dec_insn = yield self.dec2.e.insn
+ if dec_insn & (1<<20): # sigh
+ asmop = 'mtocrf'
+ else:
+ asmop = 'mtcrf'
+ print ("call", name, asmcode, asmop)
+ assert name == asmop, "name %s != %s" % (name, asmop)
+
info = self.instrs[name]
yield from self.prep_namespace(info.form, info.op_fields)