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, insns, InternalOp
-from soc.decoder.helpers import exts
+from soc.decoder.power_enums import (spr_dict, spr_byname, XER_bits,
+ insns, InternalOp)
+from soc.decoder.helpers import exts, trunc_div, trunc_rem
from collections import namedtuple
import math
import sys
def __init__(self, dec2, initial_sprs={}):
self.sd = dec2
dict.__init__(self)
- self.update(initial_sprs)
+ for key, v in initial_sprs.items():
+ if isinstance(key, SelectableInt):
+ key = key.value
+ key = special_sprs.get(key, key)
+ if isinstance(key, int):
+ info = spr_dict[key]
+ else:
+ info = spr_byname[key]
+ if not isinstance(v, SelectableInt):
+ v = SelectableInt(v, info.length)
+ self[key] = v
def __getitem__(self, key):
+ print ("get spr", key)
+ print ("dict", self.items())
# if key in special_sprs get the special spr, otherwise return key
if isinstance(key, SelectableInt):
key = key.value
+ if isinstance(key, int):
+ key = spr_dict[key].SPR
key = special_sprs.get(key, key)
if key in self:
- return dict.__getitem__(self, key)
+ res = dict.__getitem__(self, key)
else:
- info = spr_dict[key]
+ if isinstance(key, int):
+ info = spr_dict[key]
+ else:
+ info = spr_byname[key]
dict.__setitem__(self, key, SelectableInt(0, info.length))
- return dict.__getitem__(self, key)
+ res = dict.__getitem__(self, key)
+ print ("spr returning", key, res)
+ return res
def __setitem__(self, key, value):
if isinstance(key, SelectableInt):
key = key.value
+ if isinstance(key, int):
+ key = spr_dict[key].SPR
+ print ("spr key", key)
key = special_sprs.get(key, key)
+ print ("setting spr", key, value)
dict.__setitem__(self, key, value)
def __call__(self, ridx):
# "undefined", just set to variable-bit-width int (use exts "max")
self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
- self.namespace = {'GPR': self.gpr,
+ self.namespace = {}
+ self.namespace.update(self.spr)
+ self.namespace.update({'GPR': self.gpr,
'MEM': self.mem,
'SPR': self.spr,
'memassign': self.memassign,
'undefined': self.undefined,
'mode_is_64bit': True,
'SO': XER_bits['SO']
- }
+ })
+
# field-selectable versions of Condition Register TODO check bitranges?
self.crl = []
def TRAP(self, trap_addr=0x700):
print ("TRAP: TODO")
+ #self.namespace['NIA'] = trap_addr
+ #self.SRR0 = self.namespace['CIA'] + 4
+ #self.SRR1 = self.namespace['MSR']
+ #self.namespace['MSR'][45] = 1
# store CIA(+4?) in SRR0, set NIA to 0x700
# store MSR in SRR1, set MSR to um errr something, have to check spec
imm = yield self.dec2.e.imm_data.data
inputs.append(SelectableInt(imm, 64))
assert len(outputs) >= 1
- output = outputs[0]
- gts = [(x > output) for x in inputs]
+ print ("outputs", repr(outputs))
+ if isinstance(outputs, list) or isinstance(outputs, tuple):
+ output = outputs[0]
+ else:
+ output = outputs
+ gts = []
+ for x in inputs:
+ print ("gt input", x, output)
+ gt = (x > output)
+ gts.append(gt)
print(gts)
cy = 1 if any(gts) else 0
if not (1 & already_done):
print ("inputs", inputs)
# 32 bit carry
- gts = [(x[32:64] > output[32:64]) == SelectableInt(1, 1)
- for x in inputs]
+ gts = []
+ for x in inputs:
+ print ("input", x, output)
+ gt = (x[32:64] > output[32:64]) == SelectableInt(1, 1)
+ gts.append(gt)
cy32 = 1 if any(gts) else 0
if not (2 & already_done):
self.spr['XER'][XER_bits['CA32']] = cy32
- def handle_overflow(self, inputs, outputs):
+ def handle_overflow(self, inputs, outputs, div_overflow):
inv_a = yield self.dec2.e.invert_a
if inv_a:
inputs[0] = ~inputs[0]
imm = yield self.dec2.e.imm_data.data
inputs.append(SelectableInt(imm, 64))
assert len(outputs) >= 1
- print ("handle_overflow", inputs, outputs)
- if len(inputs) >= 2:
+ print ("handle_overflow", inputs, outputs, div_overflow)
+ if len(inputs) < 2 and div_overflow != 1:
+ return
+
+ # div overflow is different: it's returned by the pseudo-code
+ # because it's more complex than can be done by analysing the output
+ if div_overflow == 1:
+ ov, ov32 = 1, 1
+ # arithmetic overflow can be done by analysing the input and output
+ elif len(inputs) >= 2:
output = outputs[0]
# OV (64-bit)
ov32 = 1 if input32_sgn[0] == input32_sgn[1] and \
output32_sgn != input32_sgn[0] else 0
- self.spr['XER'][XER_bits['OV']] = ov
- self.spr['XER'][XER_bits['OV32']] = ov32
- so = self.spr['XER'][XER_bits['SO']]
- so = so | ov
- self.spr['XER'][XER_bits['SO']] = so
+ self.spr['XER'][XER_bits['OV']] = ov
+ self.spr['XER'][XER_bits['OV32']] = ov32
+ so = self.spr['XER'][XER_bits['SO']]
+ so = so | ov
+ self.spr['XER'][XER_bits['SO']] = so
def handle_comparison(self, outputs):
out = outputs[0]
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.raw_opcode_in.eq(ins & 0xffffffff)
yield self.dec2.dec.bigendian.eq(0) # little / big?
def execute_one(self):
asmop = 'mfocrf'
else:
asmop = 'mfcr'
- # for whatever weird reason this doesn't work
+ # 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
- print ("mtcrf", bin(dec_insn), (dec_insn & (1<<20)))
- if dec_insn & (1<<21) != 0: # sigh
+ if dec_insn & (1<<20) != 0: # sigh
asmop = 'mtocrf'
else:
asmop = 'mtcrf'
carry_en = yield self.dec2.e.output_carry
if carry_en:
yield from self.handle_carry_(inputs, results, already_done)
+
+ # detect if overflow was in return result
+ overflow = None
+ if info.write_regs:
+ for name, output in zip(output_names, results):
+ if name == 'overflow':
+ overflow = output
+
ov_en = yield self.dec2.e.oe.oe
ov_ok = yield self.dec2.e.oe.ok
+ print ("internal overflow", overflow)
if ov_en & ov_ok:
- yield from self.handle_overflow(inputs, results)
+ yield from self.handle_overflow(inputs, results, overflow)
+
rc_en = yield self.dec2.e.rc.data
if rc_en:
self.handle_comparison(results)
# any modified return results?
if info.write_regs:
for name, output in zip(output_names, results):
+ if name == 'overflow': # ignore, done already (above)
+ continue
if isinstance(output, int):
output = SelectableInt(output, 256)
if name in ['CA', 'CA32']:
self.spr[name] = output
else:
self.namespace[name].eq(output)
+ if name == 'MSR':
+ print ('msr written', hex(self.msr.value))
else:
regnum = yield getattr(self.decoder, name)
print('writing reg %d %s' % (regnum, str(output)))