1 // See LICENSE for license details.
6 reg_t
FN(processor_t
* p
, insn_t s_insn
, reg_t pc
)
9 reg_t npc
= sext_xlen(pc
+ insn_length(INSNCODE
));
10 // messy way to do it: insn_t is used elsewhere in a union,
11 // so cannot create virtual functions.
12 // a workaround is to grab the bits from the insn_t
13 // and create an sv-variant. also an opportunity to pass
14 // in a stack of other things that are needed.
15 insn_bits_t bits
= s_insn
.bits();
17 int vlen
= p
->get_state()->vl
;
18 // need to know if register is used as float or int.
19 // REGS_PATTERN is generated by id_regs.py (per opcode)
20 unsigned int floatintmap
= REGS_PATTERN
;
21 reg_t dest_pred
= ~0x0;
24 #ifdef INSN_CATEGORY_TWINPREDICATION
25 reg_t src_pred
= ~0x0;
27 bool zeroingsrc
= false;
29 sv_insn_t
insn(p
, bits
, floatintmap
, PRED_ARGS
, OFFS_ARGS
);
32 fprintf(stderr
, "pre-ex reg %s %x rd %ld rs1 %ld rs2 %ld vlen %d\n",
33 xstr(INSN
), INSNCODE
, s_insn
.rd(), s_insn
.rs1(), s_insn
.rs2(),
35 #ifdef INSN_CATEGORY_TWINPREDICATION
36 src_pred
= insn
.predicate(s_insn
.SRC_REG(), SRC_PREDINT
, zeroingsrc
);
39 // use the ORIGINAL, i.e. NON-REDIRECTED, register here
40 dest_pred
= insn
.predicate(s_insn
.DEST_REG(), DEST_PREDINT
, zeroing
);
43 // identify which regs have had their CSR entries set as vectorised.
44 // really could do with a macro for-loop here... oh well...
45 // integer ops, RD, RS1, RS2, RS3 (use sv_int_tb)
46 if (insn
.sv_check_reg(true, 16))
48 fprintf(stderr
, "reg %s %x rd %ld rs1 %ld rs2 %ld vlen %d\n",
49 xstr(INSN
), INSNCODE
, s_insn
.rd(), s_insn
.rs1(), s_insn
.rs2(),
52 // if vectorop is set, one of the regs is not a scalar,
53 // so we must read the VL CSR and do a loop
56 vlen
= 1; // minimum of one loop
58 for (int voffs
=0; voffs
< vlen
; voffs
++)
60 insn
.reset_vloop_check();
61 #ifdef INSN_CATEGORY_TWINPREDICATION
62 if (src_offs
>= vlen
) {
65 if (dest_offs
>= vlen
) {
69 fprintf(stderr
, "pre twin reg %s src %d dest %d pred %lx %lx\n",
70 xstr(INSN
), src_offs
, dest_offs
, src_pred
, dest_pred
);
74 while ((src_pred
& (1<<src_offs
)) == 0) {
76 if (src_offs
>= vlen
) {
83 while ((dest_pred
& (1<<dest_offs
)) == 0) {
85 if (dest_offs
>= vlen
) {
90 if (src_offs
>= vlen
|| dest_offs
>= vlen
) {
91 break; // end vector loop if either src or dest pred reaches end
95 fprintf(stderr
, "twin reg %s src %d dest %d pred %lx %lx\n",
96 xstr(INSN
), src_offs
, dest_offs
, src_pred
, dest_pred
);
100 fprintf(stderr
, "pre loop reg %s %x vloop %d %d %d" \
101 "vlen %d stop %d pred %lx rdv %lx rd %d rvc2 %d\n",
102 xstr(INSN
), INSNCODE
, voffs
, src_offs
, dest_offs
,
103 vlen
, insn
.stop_vloop(),
104 dest_pred
& (1<<voffs
), READ_REG(insn
._rd()),
105 insn
._rd(), insn
._rvc_rs2());
109 // don't check inversion here as dest_pred has already been inverted
110 if (zeroing
&& ((dest_pred
& (1<<dest_offs
)) == 0))
112 // insn._rd() would be predicated: have to use insn._rd() here
113 WRITE_REG(insn
._DEST_REG(), 0);
118 #if defined(USING_REG_RD)
119 fprintf(stderr
, "reg %s %x vloop %d vlen %d stop %d pred %lx rd%lx\n",
120 xstr(INSN
), INSNCODE
, voffs
, vlen
, insn
.stop_vloop(),
121 dest_pred
& (1<<voffs
), READ_REG(insn
._rd()));
123 #if defined(USING_REG_FRD)
124 fprintf(stderr
, "reg %s %x vloop %d vlen %d stop %d pred %lx rd%lx\n",
125 xstr(INSN
), INSNCODE
, voffs
, vlen
, insn
.stop_vloop(),
126 dest_pred
& (1<<voffs
),
127 (READ_FREG(insn
._rd())));
130 if (insn
.stop_vloop())
134 #ifdef INSN_CATEGORY_TWINPREDICATION
143 trace_opcode(p
, INSNCODE
, insn
);