insns, MicrOp,
In1Sel, In2Sel, In3Sel,
OutSel, CRInSel, CROutSel, LDSTMode,
+ SVMode,
SVP64RMMode, SVP64PredMode,
SVP64PredInt, SVP64PredCR,
SVP64LDSTmode, FPTRANS_INSNS)
# check failfirst
ffirst_hit = False
if self.is_svp64_mode:
- ffirst_hit = (yield from self.check_ffirst(rc_en, srcstep))
+ sv_mode = yield self.dec2.rm_dec.sv_mode
+ is_cr = sv_mode == SVMode.CROP.value
+ ffirst_hit = (yield from self.check_ffirst(rc_en or is_cr, srcstep))
# any modified return results?
yield from self.do_outregs_nia(asmop, ins_name, info, outs,
log(" RC1", RC1)
log(" vli", vli)
log(" cr_bit", cr_bit)
+ log(" rc_en", rc_en)
if not rc_en or rm_mode != SVP64RMMode.FFIRST.value:
return False
# get the CR vevtor, do BO-test
pack = self.svstate.pack
unpack = self.svstate.unpack
vl = self.svstate.vl
+ sv_mode = yield self.dec2.rm_dec.sv_mode
subvl = yield self.dec2.rm_dec.rm_in.subvl
rm_mode = yield self.dec2.rm_dec.mode
ff_inv = yield self.dec2.rm_dec.inv
log(" vl", vl)
log(" subvl", subvl)
log(" rm_mode", rm_mode)
+ log(" sv_mode", sv_mode)
log(" inv", ff_inv)
log(" cr_bit", cr_bit)
from nmigen.cli import rtlil, verilog
from openpower.decoder.power_enums import (Function, Form, MicrOp,
In1Sel, In2Sel, In3Sel, OutSel,
- SVEXTRA, SVEtype, SVPtype, # Simple-V
+ SVEXTRA, SVMode, # Simple-V
+ SVEtype, SVPtype, # Simple-V
RCOE, LdstLen, LDSTMode, CryIn,
single_bit_flags, CRInSel,
CROutSel, get_signal_name,
'asmcode': asmlen,
'SV_Etype': SVEtype,
'SV_Ptype': SVPtype,
+ 'SV_mode': SVMode,
'in1_sel': In1Sel,
'in2_sel': In2Sel,
'in3_sel': In3Sel,
'sv_cr_out': 'sv_cr_out',
'SV_Etype': 'SV_Etype',
'SV_Ptype': 'SV_Ptype',
+ 'SV_mode': 'SV_mode',
'cr_in': 'CR in',
'cr_out': 'CR out',
'ldst_len': 'ldst len',
if field not in power_op_csvmap:
continue
csvname = power_op_csvmap[field]
- # log(field, ptype, csvname, row)
+ log("_eq", field, ptype, csvname, row)
val = row[csvname]
if csvname == 'upd' and isinstance(val, int): # LDSTMode different
val = ptype(val)
record_names = {'insn_type': 'internal_op',
'fn_unit': 'function_unit',
'SV_Ptype': 'SV_Ptype',
+ 'SV_mode': 'SV_mode',
'rc': 'rc_sel',
'oe': 'rc_sel',
'zero_a': 'in1_sel',
# quickly determined, and the Decoder result MUXed over to
# the alternative decoder, svdecldst. what a mess... *sigh*
sv_ptype = self.op_get("SV_Ptype")
+ sv_mode = self.op_get("SV_mode")
fn = self.op_get("function_unit")
+ print ("sv_mode n", sv_mode)
+ comb += rm_dec.sv_mode.eq(sv_mode) # BRANCH/CROP/LDST_IMM etc.
comb += rm_dec.fn_in.eq(fn) # decode needs to know Fn type
comb += rm_dec.ptype_in.eq(sv_ptype) # Single/Twin predicated
comb += rm_dec.rc_in.eq(rc_out) # Rc=1
subset.add("sv_cr_out")
subset.add("SV_Etype")
subset.add("SV_Ptype")
+ subset.add("SV_mode")
# from SVP64RMModeDecode
for (field, _) in sv_input_record_layout:
subset.add(field)
class SVMode(Enum):
+ NONE = 0 # for non-SV instructions only
NORMAL = auto()
LDST_IDX = auto()
LDST_IMM = auto()
# dummy (blank) fields, first
entry.update({'EXTRA0': '0', 'EXTRA1': '0', 'EXTRA2': '0',
'EXTRA3': '0',
+ 'SV_mode': 'NONE',
'SV_Ptype': 'NONE', 'SV_Etype': 'NONE',
'sv_cr_in': 'NONE', 'sv_cr_out': 'NONE'})
for fname in ['in1', 'in2', 'in3', 'out', 'out2']:
svp64 = self.instrs[asmcode]
for k, v in {'EXTRA0': '0', 'EXTRA1': '1', 'EXTRA2': '2',
'EXTRA3': '3',
+ 'SV_mode': 'mode',
'SV_Ptype': 'Ptype', 'SV_Etype': 'Etype'}.items():
entry[k] = svp64[v]
print (entry)
minor_31 = isa.get_svp64_csv("minor_31.csv")
for entry in minor_31:
- print (entry)
+ if entry['comment'].startswith('cmp'):
+ print ("cmp", entry)
from nmigen import Elaboratable, Module, Signal, Const
from openpower.decoder.power_enums import (SVP64RMMode, Function, SVPtype,
+ SVMode,
SVP64PredMode, SVP64sat, SVP64LDSTmode,
SVP64BCPredMode, SVP64BCVLSETMode,
SVP64BCGate, SVP64BCCTRMode,
('sv_saturate', SVP64sat),
('sv_ldstmode', SVP64LDSTmode),
('SV_Ptype', SVPtype),
+ ('SV_mode', SVMode),
#('sv_RC1', 1),
]
##### inputs #####
self.rm_in = SVP64Rec(name=name)
self.fn_in = Signal(Function) # LD/ST and Branch is different
+ self.sv_mode = Signal(SVMode) # BRANCH/LDST_IMM/CROP etc.
self.svp64_vf_in = Signal() # Vertical-First Mode
self.ptype_in = Signal(SVPtype)
self.rc_in = Signal()
# decode pieces of mode
is_ldst = Signal()
is_bc = Signal()
+ is_cr = Signal()
comb += is_ldst.eq(self.fn_in == Function.LDST)
- comb += is_bc.eq(self.fn_in == Function.BRANCH)
+ comb += is_bc.eq(self.fn_in == Function.BRANCH) # XXX TODO use SV Mode
+ comb += is_cr.eq(self.sv_mode == SVMode.CROP.value)
mode2 = sel(m, mode, SVP64MODE.MOD2)
cr = sel(m, mode, SVP64MODE.CR)
comb += self.bc_lru.eq(self.rm_in.elwidth[0])
comb += self.bc_vsb.eq(self.rm_in.ewsrc[0])
+ with m.Elif(is_cr):
+ with m.Switch(mode2):
+ with m.Case(0, 1): # needs further decoding (LDST no mapreduce)
+ with m.If(mode[SVP64MODE.REDUCE]):
+ comb += self.mode.eq(SVP64RMMode.MAPREDUCE)
+ with m.Else():
+ comb += self.mode.eq(SVP64RMMode.NORMAL)
+ with m.Case(2,3):
+ comb += self.mode.eq(SVP64RMMode.FFIRST) # fail-first
+
with m.Else():
# combined arith / ldst decoding due to similarity
with m.Switch(mode2):