+ yield from self.check_write(info, name, output, carry_en)
+
+ nia_update = (yield from self.check_step_increment(results, rc_en,
+ asmop, ins_name))
+ if nia_update:
+ self.update_pc_next()
+
+ def check_replace_d(self, info, remap_active):
+ replace_d = False # update / replace constant in pseudocode
+ ldstmode = yield self.dec2.rm_dec.ldstmode
+ 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:
+ 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
+ if op == MicrOp.OP_LOAD.value:
+ if remap_active:
+ offsmul = yield self.dec2.in1_step
+ log("D-field REMAP src", imm, offsmul)
+ else:
+ offsmul = (srcstep * (subvl+1)) + ssubstep
+ log("D-field src", imm, offsmul)
+ elif op == MicrOp.OP_STORE.value:
+ # XXX NOTE! no bit-reversed STORE! this should not ever be used
+ offsmul = (dststep * (subvl+1)) + dsubstep
+ log("D-field dst", imm, offsmul)
+ # Unit-Strided LD/ST adds offset*width to immediate
+ if ldstmode == SVP64LDSTmode.UNITSTRIDE.value:
+ ldst_len = yield self.dec2.e.do.data_len
+ imm = SelectableInt(imm + offsmul * ldst_len, 32)
+ replace_d = True
+ # Element-strided multiplies the immediate by element step
+ elif ldstmode == SVP64LDSTmode.ELSTRIDE.value:
+ imm = SelectableInt(imm * offsmul, 32)
+ replace_d = True
+ if replace_d:
+ ldst_ra_vec = yield self.dec2.rm_dec.ldst_ra_vec
+ ldst_imz_in = yield self.dec2.rm_dec.ldst_imz_in
+ log("LDSTmode", SVP64LDSTmode(ldstmode),
+ offsmul, imm, ldst_ra_vec, ldst_imz_in)
+ # new replacement D... errr.. DS
+ if replace_d:
+ if info.form == 'DS':
+ # TODO: assert 2 LSBs are zero?
+ log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm.value))
+ imm.value = imm.value >> 2
+ self.namespace['DS'] = imm
+ else:
+ self.namespace['D'] = imm
+
+ def get_input(self, name):
+ # using PowerDecoder2, first, find the decoder index.
+ # (mapping name RA RB RC RS to in1, in2, in3)
+ regnum, is_vec = yield from get_pdecode_idx_in(self.dec2, name)
+ if regnum is None:
+ # doing this is not part of svp64, it's because output
+ # registers, to be modified, need to be in the namespace.
+ regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name)
+ if regnum is None:
+ regnum, is_vec = yield from get_pdecode_idx_out2(self.dec2, name)
+
+ # in case getting the register number is needed, _RA, _RB
+ regname = "_" + name
+ self.namespace[regname] = regnum
+ if not self.is_svp64_mode or not self.pred_src_zero:
+ log('reading reg %s %s' % (name, str(regnum)), is_vec)
+ if name in fregs:
+ reg_val = SelectableInt(self.fpr(regnum))
+ elif name is not None:
+ reg_val = SelectableInt(self.gpr(regnum))
+ else:
+ log('zero input reg %s %s' % (name, str(regnum)), is_vec)
+ reg_val = 0
+ return reg_val
+
+ def remap_debug(self, remaps):
+ # just some convenient debug info
+ for i in range(4):
+ sname = 'SVSHAPE%d' % i
+ shape = self.spr[sname]
+ log(sname, bin(shape.value))
+ log(" lims", shape.lims)
+ log(" mode", shape.mode)
+ log(" skip", shape.skip)
+
+ # set up the list of steps to remap
+ mi0 = self.svstate.mi0
+ mi1 = self.svstate.mi1
+ mi2 = self.svstate.mi2
+ mo0 = self.svstate.mo0
+ mo1 = self.svstate.mo1
+ steps = [(self.dec2.in1_step, mi0), # RA
+ (self.dec2.in2_step, mi1), # RB
+ (self.dec2.in3_step, mi2), # RC
+ (self.dec2.o_step, mo0), # RT
+ (self.dec2.o2_step, mo1), # EA
+ ]
+ remap_idxs = self.remap_idxs
+ rremaps = []
+ # now cross-index the required SHAPE for each of 3-in 2-out regs
+ rnames = ['RA', 'RB', 'RC', 'RT', 'EA']
+ for i, (dstep, shape_idx) in enumerate(steps):
+ (shape, remap) = remaps[shape_idx]
+ remap_idx = remap_idxs[shape_idx]
+ # zero is "disabled"
+ if shape.value == 0x0:
+ continue
+ # now set the actual requested step to the current index
+ yield dstep.eq(remap_idx)
+
+ # debug printout info
+ rremaps.append((shape.mode, i, rnames[i], shape_idx, remap_idx))
+ for x in rremaps:
+ log("shape remap", x)
+
+ def check_write(self, info, name, output, carry_en):
+ if name == 'overflow': # ignore, done already (above)
+ return
+ if isinstance(output, int):
+ output = SelectableInt(output, 256)
+ if name in ['CA', 'CA32']:
+ if carry_en:
+ log("writing %s to XER" % name, output)
+ self.spr['XER'][XER_bits[name]] = output.value
+ else:
+ log("NOT writing %s to XER" % name, output)
+ elif name in info.special_regs:
+ log('writing special %s' % name, output, special_sprs)
+ if name in special_sprs:
+ self.spr[name] = output
+ else:
+ self.namespace[name].eq(output)
+ if name == 'MSR':
+ log('msr written', hex(self.msr.value))
+ else:
+ regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name)
+ if regnum is None:
+ regnum, is_vec = yield from get_pdecode_idx_out2(
+ self.dec2, name)
+ if regnum is None:
+ # temporary hack for not having 2nd output
+ regnum = yield getattr(self.decoder, name)
+ is_vec = False
+ if self.is_svp64_mode and self.pred_dst_zero:
+ log('zeroing reg %d %s' % (regnum, str(output)),
+ is_vec)
+ output = SelectableInt(0, 256)
+ else:
+ if name in fregs:
+ ftype = 'fpr'