# "fake program counter" mode (for unit testing)
self.fake_pc = 0
+ disasm_start = 0
if not respect_pc:
if isinstance(initial_mem, tuple):
self.fake_pc = initial_mem[0]
self.decoder = decoder2.dec
self.dec2 = decoder2
- def TRAP(self, trap_addr=0x700):
+ def TRAP(self, trap_addr=0x700, trap_bit=PI.TRAP):
print ("TRAP:", hex(trap_addr))
# store CIA(+4?) in SRR0, set NIA to 0x700
# store MSR in SRR1, set MSR to um errr something, have to check spec
self.spr['SRR0'] = self.pc.CIA
self.spr['SRR1'] = self.namespace['MSR']
self.trap_nia = SelectableInt(trap_addr, 64)
- self.namespace['MSR'][63-PI.TRAP] = 1 # bit 45, "this is a trap"
+ self.namespace['MSR'][63-trap_bit] = 1
def memassign(self, ea, sz, val):
self.mem.memassign(ea, sz, val)
self.namespace['CA32'] = self.spr['XER'][XER_bits['CA32']].value
def handle_carry_(self, inputs, outputs, already_done):
- inv_a = yield self.dec2.e.invert_a
+ inv_a = yield self.dec2.e.do.invert_a
if inv_a:
inputs[0] = ~inputs[0]
- imm_ok = yield self.dec2.e.imm_data.ok
+ imm_ok = yield self.dec2.e.do.imm_data.ok
if imm_ok:
- imm = yield self.dec2.e.imm_data.data
+ imm = yield self.dec2.e.do.imm_data.data
inputs.append(SelectableInt(imm, 64))
assert len(outputs) >= 1
print ("outputs", repr(outputs))
self.spr['XER'][XER_bits['CA32']] = cy32
def handle_overflow(self, inputs, outputs, div_overflow):
- inv_a = yield self.dec2.e.invert_a
+ inv_a = yield self.dec2.e.do.invert_a
if inv_a:
inputs[0] = ~inputs[0]
- imm_ok = yield self.dec2.e.imm_data.ok
+ imm_ok = yield self.dec2.e.do.imm_data.ok
if imm_ok:
- imm = yield self.dec2.e.imm_data.data
+ imm = yield self.dec2.e.do.imm_data.data
inputs.append(SelectableInt(imm, 64))
assert len(outputs) >= 1
print ("handle_overflow", inputs, outputs, div_overflow)
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
+ ov_en = yield self.dec2.e.do.oe.oe
+ ov_ok = yield self.dec2.e.do.oe.ok
if ov_en & ov_ok:
asmop += "."
- lk = yield self.dec2.e.lk
+ lk = yield self.dec2.e.do.lk
if lk:
asmop += "l"
int_op = yield self.dec2.dec.op.internal_op
if AA:
asmop += "a"
if int_op == InternalOp.OP_MFCR.value:
- dec_insn = yield self.dec2.e.insn
+ dec_insn = yield self.dec2.e.do.insn
if dec_insn & (1<<20) != 0: # sigh
asmop = 'mfocrf'
else:
# XXX TODO: for whatever weird reason this doesn't work
# https://bugs.libre-soc.org/show_bug.cgi?id=390
if int_op == InternalOp.OP_MTCRF.value:
- dec_insn = yield self.dec2.e.insn
+ dec_insn = yield self.dec2.e.do.insn
if dec_insn & (1<<20) != 0: # sigh
asmop = 'mtocrf'
else:
# see http://bugs.libre-riscv.org/show_bug.cgi?id=282
asmop = yield from self.get_assembly_name()
print ("call", name, asmop)
+ illegal = False
if name not in ['mtcrf', 'mtocrf']:
- assert name == asmop, "name %s != %s" % (name, asmop)
+ illegal = name != asmop
+
+ if illegal:
+ self.TRAP(0x700, PI.ILLEG)
+ self.namespace['NIA'] = self.trap_nia
+ self.pc.update(self.namespace)
+ return
info = self.instrs[name]
yield from self.prep_namespace(info.form, info.op_fields)
# preserve order of register names
- input_names = create_args(list(info.read_regs) + list(info.uninit_regs))
+ input_names = create_args(list(info.read_regs) +
+ list(info.uninit_regs))
print(input_names)
# main registers (RT, RA ...)
already_done |= 2
print ("carry already done?", bin(already_done))
- carry_en = yield self.dec2.e.output_carry
+ carry_en = yield self.dec2.e.do.output_carry
if carry_en:
yield from self.handle_carry_(inputs, results, already_done)
if name == 'overflow':
overflow = output
- ov_en = yield self.dec2.e.oe.oe
- ov_ok = yield self.dec2.e.oe.ok
+ ov_en = yield self.dec2.e.do.oe.oe
+ ov_ok = yield self.dec2.e.do.oe.ok
print ("internal overflow", overflow)
if ov_en & ov_ok:
yield from self.handle_overflow(inputs, results, overflow)
- rc_en = yield self.dec2.e.rc.data
+ rc_en = yield self.dec2.e.do.rc.data
if rc_en:
self.handle_comparison(results)