for (fname, insn) in files:
regsname = "regs_%s.h" % insn
regsname = os.path.join(insns_dir, regsname)
+ twin_predication = False
with open(regsname, "w") as f:
txt = find_registers(fname)
txt += "\n#define INSN_%s\n" % insn.upper()
if insn in ['beq', 'bne', 'blt', 'bltu', 'bge', 'bgeu']:
txt += "#define INSN_TYPE_BRANCH\n"
if insn in ['lb', 'lbu', 'lw', 'lwu', 'ld', 'ldu']:
+ twin_predication = True
txt += "#define INSN_TYPE_LOAD\n"
elif insn in ['c_lwsp', 'c_ldsp', 'c_lqsp', 'c_flwsp', 'c_fldsp']:
txt += "\n#define INSN_TYPE_C_STACK_LD\n"
txt += "\n#define INSN_TYPE_C_STACK_ST\n"
elif insn in ['c_lw', 'c_ld', 'c_lq', 'c_flw', 'c_fld']:
txt += "\n#define INSN_TYPE_C_LD\n"
+ twin_predication = True
elif insn in ['c_sw', 'c_sd', 'c_sq', 'c_fsw', 'c_fsd']:
txt += "\n#define INSN_TYPE_C_ST\n"
+ twin_predication = True
elif insn in ['c_beqz', 'c_bnez']:
txt += "\n#define INSN_TYPE_C_BRANCH\n"
+ elif insn in ['c_mv']:
+ twin_predication = True
elif insn.startswith("c_"):
txt += "#define INSN_TYPE_C\n"
elif insn.startswith("fmv") or \
insn.startswith("flt") or \
insn.startswith("fle"):
txt += "#define INSN_TYPE_FP_BRANCH\n"
+ if twin_predication:
+ txt += "\n#define INSN_CATEGORY_TWINPREDICATION\n"
f.write(txt)
// REGS_PATTERN is generated by id_regs.py (per opcode)
unsigned int floatintmap = REGS_PATTERN;
reg_t dest_pred = ~0x0;
- bool ldimm_sv = false;
+#ifdef INSN_CATEGORY_TWINPREDICATION
+ reg_t src_pred = ~0x0;
+#endif
sv_insn_t insn(p, bits, floatintmap,
- dest_pred, dest_pred, dest_pred, dest_pred);
+ dest_pred,
+#ifdef INSN_CATEGORY_TWINPREDICATION
+// twin-predication ONLY applies to dual-op operands: MV, FCVT, LD/ST.
+// however we don't know which register any of those will use, so
+// pass src_pred to each of rs1-3 and let the instruction sort it out.
+src_pred, src_pred, src_pred
+#else
+dest_pred, dest_pred, dest_pred
+#endif
+ );
bool zeroing;
+#ifdef INSN_CATEGORY_TWINPREDICATION
+#ifdef USING_REG_RS1
+ #define SRCREG s_insn.rs1()
+#endif
+#ifdef USING_REG_RS2
+ #define SRCREG s_insn.rs2()
+#endif
+#ifdef USING_REG_RS3
+ #define SRCREG s_insn.rs3()
+#endif
+#if (defined(USING_REG_RVC_RS1) || defined(USING_REG_RVC_RS1S))
+ #define SRCREG s_insn.rvc_rs1()
+#endif
+#if (defined(USING_REG_RVC_RS2) || defined(USING_REG_RVC_RS2S))
+ #define SRCREG s_insn.rvc_rs2()
+#endif
+ src_pred = insn.predicate(SRCREG, floatintmap & (REG_RS1|REG_RS2|REG_RS3),
+ zeroing);
+#endif
#if defined(USING_REG_RD) || defined(USING_REG_FRD)
// use the ORIGINAL, i.e. NON-REDIRECTED, register here
dest_pred = insn.predicate(s_insn.rd(), floatintmap & REG_RD, zeroing);