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 a workaround is to grab the bits from the insn_t
12 // and create an sv-variant. also an opportunity to pass
13 // in the loop index (voffs) which will be added on to
14 // any registers that are marked as "vectorised"
15 insn_bits_t bits
= s_insn
.bits();
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 sv_insn_t
insn(p
, bits
, floatintmap
);
23 // identify which regs have had their CSR entries set as vectorised.
24 // really could do with a macro for-loop here... oh well...
25 // integer ops, RD, RS1, RS2, RS3 (use sv_int_tb)
28 insn
.sv_check_reg(true, s_insn
.rd()) |
31 insn
.sv_check_reg(true, s_insn
.rs1()) |
34 insn
.sv_check_reg(true, s_insn
.rs2()) |
37 insn
.sv_check_reg(true, s_insn
.rs3()) |
39 // fp ops, RD, RS1, RS2, RS3 (use sv_fp_tb)
41 insn
.sv_check_reg(false, s_insn
.rd()) |
44 insn
.sv_check_reg(false, s_insn
.rs1()) |
47 insn
.sv_check_reg(false, s_insn
.rs2()) |
50 insn
.sv_check_reg(false, s_insn
.rs3()) |
52 false; // save a few cycles by |ing the checks together.
54 if (insn
.sv_check_reg(true, 16))
56 fprintf(stderr
, "reg %s %x rd %ld rs1 %ld rs2 %ld\n",
57 xstr(INSN
), INSNCODE
, s_insn
.rd(), s_insn
.rs1(), s_insn
.rs2());
59 // if vectorop is set, one of the regs is not a scalar,
60 // so we must read the VL CSR and do a loop
63 vlen
= p
->get_state()->vl
;
64 fprintf(stderr
, "vectorop %x vlen %d\n", INSNCODE
, vlen
);
66 for (int voffs
=0; voffs
< vlen
; voffs
++)
69 insn
.reset_caches(); // ready to increment offsets in next iteration
75 trace_opcode(p
, INSNCODE
, insn
);