if self.is_svp64_mode:
vl = self.svstate.vl.asint(msb0=True)
srcstep = self.svstate.srcstep.asint(msb0=True)
+ dststep = self.svstate.srcstep.asint(msb0=True)
sv_a_nz = yield self.dec2.sv_a_nz
in1 = yield self.dec2.e.read_reg1.data
- print ("SVP64: VL, srcstep, sv_a_nz, in1",
- vl, srcstep, sv_a_nz, in1)
+ print ("SVP64: VL, srcstep, dststep, sv_a_nz, in1",
+ vl, srcstep, dststep, sv_a_nz, in1)
# get predicate mask
srcmask = dstmask = 0xffff_ffff_ffff_ffff
while (((1<<srcstep) & srcmask) == 0) and (srcstep != vl):
print (" skip", bin(1<<srcstep))
srcstep += 1
+ dststep += 1
# update SVSTATE with new srcstep
self.svstate.srcstep[0:7] = srcstep
+ self.svstate.dststep[0:7] = dststep
self.namespace['SVSTATE'] = self.svstate.spr
yield self.dec2.state.svstate.eq(self.svstate.spr.value)
yield Settle() # let decoder update
srcstep = self.svstate.srcstep.asint(msb0=True)
+ dststep = self.svstate.dststep.asint(msb0=True)
print (" srcstep", srcstep)
+ print (" dststep", dststep)
# check if end reached (we let srcstep overrun, above)
# nothing needs doing (TODO zeroing): just do next instruction
vl = self.svstate.vl.asint(msb0=True)
mvl = self.svstate.maxvl.asint(msb0=True)
srcstep = self.svstate.srcstep.asint(msb0=True)
+ dststep = self.svstate.srcstep.asint(msb0=True)
sv_ptype = yield self.dec2.dec.op.SV_Ptype
no_out_vec = not (yield self.dec2.no_out_vec)
no_in_vec = not (yield self.dec2.no_in_vec)
print (" svstate.vl", vl)
print (" svstate.mvl", mvl)
print (" svstate.srcstep", srcstep)
+ print (" svstate.dststep", dststep)
print (" no_out_vec", no_out_vec)
print (" no_in_vec", no_in_vec)
print (" sv_ptype", sv_ptype, sv_ptype == SVPtype.P2.value)
svp64_is_vector = no_out_vec
if svp64_is_vector and srcstep != vl-1:
self.svstate.srcstep += SelectableInt(1, 7)
+ self.svstate.dststep += SelectableInt(1, 7)
self.pc.NIA.value = self.pc.CIA.value
self.namespace['NIA'] = self.pc.NIA
self.namespace['SVSTATE'] = self.svstate.spr
def svp64_reset_loop(self):
self.svstate.srcstep[0:7] = 0
+ self.svstate.dststep[0:7] = 0
print (" svstate.srcstep loop end (PC to update)")
self.pc.update_nia(self.is_svp64_mode)
self.namespace['NIA'] = self.pc.NIA
comb += crin_svdec_b.idx.eq(cr_b_idx) # SVP64 CR in B
comb += crin_svdec_o.idx.eq(op.sv_cr_out) # SVP64 CR out
- # get SVSTATE srcstep (TODO: elwidth, dststep etc.) needed below
+ # get SVSTATE srcstep (TODO: elwidth etc.) needed below
srcstep = Signal.like(self.state.svstate.srcstep)
+ dststep = Signal.like(self.state.svstate.dststep)
comb += srcstep.eq(self.state.svstate.srcstep)
+ comb += dststep.eq(self.state.svstate.dststep)
# registers a, b, c and out and out2 (LD/ST EA)
- for to_reg, fromreg, svdec in (
- (e.read_reg1, dec_a.reg_out, in1_svdec),
- (e.read_reg2, dec_b.reg_out, in2_svdec),
- (e.read_reg3, dec_c.reg_out, in3_svdec),
- (e.write_reg, dec_o.reg_out, o_svdec),
- (e.write_ea, dec_o2.reg_out, o2_svdec)):
+ for to_reg, fromreg, svdec, out in (
+ (e.read_reg1, dec_a.reg_out, in1_svdec, False),
+ (e.read_reg2, dec_b.reg_out, in2_svdec, False),
+ (e.read_reg3, dec_c.reg_out, in3_svdec, False),
+ (e.write_reg, dec_o.reg_out, o_svdec, True),
+ (e.write_ea, dec_o2.reg_out, o2_svdec, True)):
comb += svdec.extra.eq(extra) # EXTRA field of SVP64 RM
comb += svdec.etype.eq(op.SV_Etype) # EXTRA2/3 for this insn
comb += svdec.reg_in.eq(fromreg.data) # 3-bit (CR0/BC/BFA)
comb += to_reg.ok.eq(fromreg.ok)
- # detect if Vectorised: add srcstep if yes. TODO: a LOT.
- # this trick only holds when elwidth=default and in single-pred
+ # detect if Vectorised: add srcstep/dststep if yes.
+ # to_reg is 7-bits, outs get dststep added, ins get srcstep
with m.If(svdec.isvec):
- comb += to_reg.data.eq(srcstep+svdec.reg_out) # 7-bit output
+ step = dststep if out else srcstep
+ comb += to_reg.data.eq(step+svdec.reg_out)
with m.Else():
- comb += to_reg.data.eq(svdec.reg_out) # 7-bit output
+ comb += to_reg.data.eq(svdec.reg_out)
comb += in1_svdec.idx.eq(op.sv_in1) # SVP64 reg #1 (in1_sel)
comb += in2_svdec.idx.eq(op.sv_in2) # SVP64 reg #2 (in2_sel)
comb += loop.eq(0)
# condition registers (CR)
- for to_reg, cr, name, svdec in (
- (e.read_cr1, self.dec_cr_in, "cr_bitfield", crin_svdec),
- (e.read_cr2, self.dec_cr_in, "cr_bitfield_b", crin_svdec_b),
- (e.read_cr3, self.dec_cr_in, "cr_bitfield_o", crin_svdec_o),
- (e.write_cr, self.dec_cr_out, "cr_bitfield", crout_svdec)):
+ for to_reg, cr, name, svdec, out in (
+ (e.read_cr1, self.dec_cr_in, "cr_bitfield", crin_svdec, 0),
+ (e.read_cr2, self.dec_cr_in, "cr_bitfield_b", crin_svdec_b, 0),
+ (e.read_cr3, self.dec_cr_in, "cr_bitfield_o", crin_svdec_o, 0),
+ (e.write_cr, self.dec_cr_out, "cr_bitfield", crout_svdec, 1)):
fromreg = getattr(cr, name)
comb += svdec.extra.eq(extra) # EXTRA field of SVP64 RM
comb += svdec.etype.eq(op.SV_Etype) # EXTRA2/3 for this insn
# check if this is CR0 or CR1: treated differently
# (does not "listen" to EXTRA2/3 spec for a start)
# also: the CRs start from completely different locations
+ step = dststep if out else srcstep
with m.If(cr.sv_override == 1): # CR0
offs = SVP64CROffs.CR0
- comb += to_reg.data.eq(srcstep+offs)
+ comb += to_reg.data.eq(step+offs)
with m.Elif(cr.sv_override == 2): # CR1
offs = SVP64CROffs.CR1
- comb += to_reg.data.eq(srcstep+1)
+ comb += to_reg.data.eq(step+1)
with m.Else():
- comb += to_reg.data.eq(srcstep+svdec.cr_out) # 7-bit out
+ comb += to_reg.data.eq(step+svdec.cr_out) # 7-bit out
with m.Else():
comb += to_reg.data.eq(svdec.cr_out) # 7-bit output
comb += to_reg.ok.eq(fromreg.ok)