"""
import re
-from nmigen.back.pysim import Settle
+from nmigen.sim import Settle
from functools import wraps
from copy import copy, deepcopy
from openpower.decoder.orderedset import OrderedSet
'setvl', 'svindex', 'svremap', 'svstep', 'svshape',
'grev', 'ternlogi', 'bmask', 'cprop',
'absdu', 'absds', 'absdacs', 'absdacu', 'avgadd',
+ 'fmvis', 'fishmv',
]:
illegal = False
ins_name = dotstrp
# nop has to be supported, we could let the actual op calculate
# but PowerDecoder has a pattern for nop
- if ins_name is 'nop':
+ if ins_name == 'nop':
self.update_pc_next()
return
# main input registers (RT, RA ...)
inputs = []
for name in input_names:
+ log("name", name)
regval = (yield from self.get_input(name))
+ log("regval", regval)
inputs.append(regval)
# arrrrgh, awful hack, to get _RT into namespace
# any modified return results?
if info.write_regs:
for name, output in zip(output_names, results):
- yield from self.check_write(info, name, output)
+ yield from self.check_write(info, name, output, carry_en)
nia_update = (yield from self.check_step_increment(results, rc_en,
asmop, ins_name))
def check_replace_d(self, info, remap_active):
replace_d = False # update / replace constant in pseudocode
ldstmode = yield self.dec2.rm_dec.ldstmode
- # shift mode reads SVD (or SVDS - TODO)
- # *BUT*... because this is "overloading" of LD operations,
- # it gets *STORED* into D (or DS, TODO)
- if ldstmode == SVP64LDSTmode.SHIFT.value:
- imm = yield self.dec2.dec.fields.FormSVD.SVD[0:11]
- imm = exts(imm, 11) # sign-extend to integer
- log("shift SVD", imm)
- replace_d = True
+ vl = self.svstate.vl
+ subvl = yield self.dec2.rm_dec.rm_in.subvl
+ srcstep, dststep = self.new_srcstep, self.new_dststep
+ ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
+ if info.form == 'DS':
+ # DS-Form, multiply by 4 then knock 2 bits off after
+ imm = yield self.dec2.dec.fields.FormDS.DS[0:14] * 4
else:
- if info.form == 'DS':
- # DS-Form, multiply by 4 then knock 2 bits off after
- imm = yield self.dec2.dec.fields.FormDS.DS[0:14] * 4
- else:
- imm = yield self.dec2.dec.fields.FormD.D[0:16]
- imm = exts(imm, 16) # sign-extend to integer
+ imm = yield self.dec2.dec.fields.FormD.D[0:16]
+ imm = exts(imm, 16) # sign-extend to integer
# get the right step. LD is from srcstep, ST is dststep
op = yield self.dec2.e.do.insn_type
offsmul = 0
# XXX NOTE! no bit-reversed STORE! this should not ever be used
offsmul = (dststep * (subvl+1)) + dsubstep
log("D-field dst", imm, offsmul)
- # bit-reverse mode, rev already done through get_src_dst_steps()
- if ldstmode == SVP64LDSTmode.SHIFT.value:
- # manually look up RC, sigh
- RC = yield self.dec2.dec.RC[0:5]
- RC = self.gpr(RC)
- log("LD-SHIFT:", "VL", vl,
- "RC", RC.value, "imm", imm,
- "offs", bin(offsmul),
- )
- imm = SelectableInt((imm * offsmul) << RC.value, 32)
# Unit-Strided LD/ST adds offset*width to immediate
- elif ldstmode == SVP64LDSTmode.UNITSTRIDE.value:
+ if ldstmode == SVP64LDSTmode.UNITSTRIDE.value:
ldst_len = yield self.dec2.e.do.data_len
imm = SelectableInt(imm + offsmul * ldst_len, 32)
replace_d = True
for x in rremaps:
log("shape remap", x)
- def check_write(self, info, name, output):
+ def check_write(self, info, name, output, carry_en):
if name == 'overflow': # ignore, done already (above)
return
if isinstance(output, int):
# this is our Sub-Program-Counter loop from 0 to VL-1
pre = False
post = False
+ nia_update = True
if self.allow_next_step_inc:
log("SVSTATE_NEXT: inc requested, mode",
self.svstate_next_mode, self.allow_next_step_inc)
shape_idx = self.svstate_next_mode.value-1
endings = self.remap_loopends[shape_idx]
cr_field = SelectableInt((~endings) << 1 | endtest, 4)
- print("svstep Rc=1, CR0", cr_field)
+ log("svstep Rc=1, CR0", cr_field)
self.crl[0].eq(cr_field) # CR0
if end_src or end_dst:
# reset at end of loop including exit Vertical Mode
srcmask = dstmask = 0xffff_ffff_ffff_ffff
pmode = yield self.dec2.rm_dec.predmode
+ pack = yield self.dec2.rm_dec.pack
+ unpack = yield self.dec2.rm_dec.unpack
reverse_gear = yield self.dec2.rm_dec.reverse_gear
sv_ptype = yield self.dec2.dec.op.SV_Ptype
srcpred = yield self.dec2.rm_dec.srcpred
ssubstart = ssubstep == 0
dsubstart = dsubstep == 0
log(" pmode", pmode)
+ log(" pack/unpack", pack, unpack)
log(" reverse", reverse_gear)
log(" ptype", sv_ptype)
log(" srcpred", bin(srcpred))
log(" out_vec", out_vec)
log(" in_vec", in_vec)
log(" sv_ptype", sv_ptype, sv_ptype == SVPtype.P2.value)
- # check if srcstep needs incrementing by one, stop PC advancing
- # svp64 loop can end early if the dest is scalar for single-pred
- # but for 2-pred both src/dest have to be checked.
- # XXX this might not be true! it may just be LD/ST
- if sv_ptype == SVPtype.P2.value:
- svp64_is_vector = (out_vec or in_vec)
- else:
- svp64_is_vector = out_vec
# check if this was an sv.bc* and if so did it succeed
if self.is_svp64_mode and insn_name.startswith("sv.bc"):
end_loop = self.namespace['end_loop']
self.svp64_reset_loop()
self.update_pc_next()
return False
+ # check if srcstep needs incrementing by one, stop PC advancing
+ # but for 2-pred both src/dest have to be checked.
+ # XXX this might not be true! it may just be LD/ST
+ if sv_ptype == SVPtype.P2.value:
+ svp64_is_vector = (out_vec or in_vec)
+ else:
+ svp64_is_vector = out_vec
# loops end at the first "hit" (source or dest)
loopend = ((srcstep == vl-1 and ssubstep == subvl) or
(dststep == vl-1 and dsubstep == subvl))
- if svp64_is_vector and not loopend:
- yield from self.advance_svstate_steps()
- self.namespace['SVSTATE'] = self.svstate
- # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
- # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
- # this way we keep repeating the same instruction (with new steps)
- self.pc.NIA.value = self.pc.CIA.value
- self.namespace['NIA'] = self.pc.NIA
- log("end of sub-pc call", self.namespace['CIA'],
- self.namespace['NIA'])
- return False # DO NOT allow PC update whilst Sub-PC loop running
+ if not svp64_is_vector or loopend:
+ # reset loop to zero and update NIA
+ self.svp64_reset_loop()
+ self.update_nia()
- # reset loop to zero and update NIA
- self.svp64_reset_loop()
- self.update_nia()
+ return True
- return True
+ # still looping, advance and update NIA
+ yield from self.advance_svstate_steps()
+ self.namespace['SVSTATE'] = self.svstate
+ # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
+ # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
+ # this way we keep repeating the same instruction (with new steps)
+ self.pc.NIA.value = self.pc.CIA.value
+ self.namespace['NIA'] = self.pc.NIA
+ log("end of sub-pc call", self.namespace['CIA'], self.namespace['NIA'])
+ return False # DO NOT allow PC update whilst Sub-PC loop running
def advance_svstate_steps(self, end_src=False, end_dst=False):
""" advance sub/steps. note that Pack/Unpack *INVERTS* the order.