X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fsoc%2Fdecoder%2Fisa%2Fcaller.py;h=aea6d035b351f92c0115c7ebeff5a9f707130d7a;hb=f747ad69cedf95e6154a4de141530e4ebcd48279;hp=711c9650788a03e2b22a8528694014ff7006ad3f;hpb=f25aad525dfc184b5a8407e52b62a499dfb182f4;p=soc.git diff --git a/src/soc/decoder/isa/caller.py b/src/soc/decoder/isa/caller.py index 711c9650..aea6d035 100644 --- a/src/soc/decoder/isa/caller.py +++ b/src/soc/decoder/isa/caller.py @@ -14,8 +14,8 @@ from soc.decoder.orderedset import OrderedSet from soc.decoder.selectable_int import (FieldSelectableInt, SelectableInt, selectconcat) from soc.decoder.power_enums import (spr_dict, spr_byname, XER_bits, - insns, InternalOp) -from soc.decoder.helpers import exts, trunc_div, trunc_rem + insns, MicrOp) +from soc.decoder.helpers import exts from soc.consts import PI, MSR from collections import namedtuple @@ -250,7 +250,7 @@ class ISACaller: initial_insns=None, respect_pc=False, disassembly=None, initial_pc=0, - bigendian=True): + bigendian=False): self.bigendian = bigendian self.halted = False @@ -506,38 +506,50 @@ class ISACaller: asmcode = yield self.dec2.dec.op.asmcode print ("get assembly name asmcode", asmcode) asmop = insns.get(asmcode, None) + int_op = yield self.dec2.dec.op.internal_op # sigh reconstruct the assembly instruction name ov_en = yield self.dec2.e.do.oe.oe ov_ok = yield self.dec2.e.do.oe.ok - if ov_en & ov_ok: - asmop += "." + rc_en = yield self.dec2.e.do.rc.data + rc_ok = yield self.dec2.e.do.rc.ok + # grrrr have to special-case MUL op (see DecodeOE) + print ("ov en rc en", ov_ok, ov_en, rc_ok, rc_en, int_op) + if int_op in [MicrOp.OP_MUL_H64.value, MicrOp.OP_MUL_H32.value]: + print ("mul op") + if rc_en & rc_ok: + asmop += "." + else: + if ov_en & ov_ok: + asmop += "." lk = yield self.dec2.e.do.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]: + if int_op in [MicrOp.OP_B.value, MicrOp.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.do.insn - if dec_insn & (1<<20) != 0: # sigh + spr_msb = yield from self.get_spr_msb() + if int_op == MicrOp.OP_MFCR.value: + if spr_msb: asmop = 'mfocrf' else: asmop = 'mfcr' # 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.do.insn - if dec_insn & (1<<20) != 0: # sigh + if int_op == MicrOp.OP_MTCRF.value: + if spr_msb: asmop = 'mtocrf' else: asmop = 'mtcrf' return asmop + def get_spr_msb(self): + dec_insn = yield self.dec2.e.do.insn + return dec_insn & (1<<20) != 0 # sigh - XFF.spr[-1]? + def call(self, name): name = name.strip() # remove spaces if not already done so if self.halted: @@ -549,6 +561,28 @@ class ISACaller: asmop = yield from self.get_assembly_name() print ("call", name, asmop) + # check privileged + int_op = yield self.dec2.dec.op.internal_op + spr_msb = yield from self.get_spr_msb() + + instr_is_privileged = False + if int_op in [MicrOp.OP_ATTN.value, + MicrOp.OP_MFMSR.value, + MicrOp.OP_MTMSR.value, + MicrOp.OP_MTMSRD.value, + # TODO: OP_TLBIE + MicrOp.OP_RFID.value]: + instr_is_privileged = True + if int_op in [MicrOp.OP_MFSPR.value, + MicrOp.OP_MTSPR.value] and spr_msb: + instr_is_privileged = True + + print ("is priv", instr_is_privileged, self.msr[63-MSR.PR]) + # check MSR priv bit and whether op is privileged: if so, throw trap + if instr_is_privileged and self.msr[63-MSR.PR] == 1: + self.TRAP(0x700, PI.PRIV) + return + # check halted condition if name == 'attn': self.halted = True @@ -628,7 +662,7 @@ class ISACaller: ov_en = yield self.dec2.e.do.oe.oe ov_ok = yield self.dec2.e.do.oe.ok - print ("internal overflow", overflow) + print ("internal overflow", overflow, ov_en, ov_ok) if ov_en & ov_ok: yield from self.handle_overflow(inputs, results, overflow)