add checks for RVC registers to sv template
[riscv-isa-sim.git] / riscv / insn_template_sv.cc
1 // See LICENSE for license details.
2
3 #define xstr(s) str(s)
4 #define str(s) #s
5
6 reg_t FN(processor_t* p, insn_t s_insn, reg_t pc)
7 {
8 int xlen = ISASZ;
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();
16 #ifndef USING_NOREGS
17 int vlen = 1;
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);
22 reg_t predicate = 0;
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)
26 bool vectorop =
27 #ifdef USING_REG_RD
28 insn.sv_check_reg(true, s_insn.rd()) |
29 #endif
30 #ifdef USING_REG_RS1
31 insn.sv_check_reg(true, s_insn.rs1()) |
32 #endif
33 #ifdef USING_REG_RS2
34 insn.sv_check_reg(true, s_insn.rs2()) |
35 #endif
36 #ifdef USING_REG_RS2
37 insn.sv_check_reg(true, s_insn.rs3()) |
38 #endif
39 #ifdef USING_REG_RVC_RS1
40 insn.sv_check_reg(true, s_insn.rvc_rs1()) |
41 #endif
42 #ifdef USING_REG_RVC_RS1S
43 insn.sv_check_reg(true, s_insn.rvc_rs1s()) |
44 #endif
45 #ifdef USING_REG_RVC_RS2
46 insn.sv_check_reg(true, s_insn.rvc_rs2()) |
47 #endif
48 #ifdef USING_REG_RVC_RS2S
49 insn.sv_check_reg(true, s_insn.rvc_rs2s()) |
50 #endif
51 // fp ops, RD, RS1, RS2, RS3 (use sv_fp_tb)
52 #ifdef USING_REG_FRD
53 insn.sv_check_reg(false, s_insn.rd()) |
54 #endif
55 #ifdef USING_REG_FRS1
56 insn.sv_check_reg(false, s_insn.rs1()) |
57 #endif
58 #ifdef USING_REG_FRS2
59 insn.sv_check_reg(false, s_insn.rs2()) |
60 #endif
61 #ifdef USING_REG_FRS2
62 insn.sv_check_reg(false, s_insn.rs3()) |
63 #endif
64 #ifdef USING_REG_RVC_FRS2
65 insn.sv_check_reg(false, s_insn.rvc_rs2()) |
66 #endif
67 #ifdef USING_REG_RVC_FRS2S
68 insn.sv_check_reg(false, s_insn.rvc_rs2s()) |
69 #endif
70 false; // save a few cycles by |ing the checks together.
71
72 if (insn.sv_check_reg(true, 16))
73 {
74 fprintf(stderr, "reg %s %x rd %ld rs1 %ld rs2 %ld\n",
75 xstr(INSN), INSNCODE, s_insn.rd(), s_insn.rs1(), s_insn.rs2());
76 }
77 // if vectorop is set, one of the regs is not a scalar,
78 // so we must read the VL CSR and do a loop
79 if (vectorop)
80 {
81 vlen = p->get_state()->vl;
82 fprintf(stderr, "vectorop %x vlen %d\n", INSNCODE, vlen);
83 }
84 for (int voffs=0; voffs < vlen; voffs++)
85 {
86 #include INCLUDEFILE
87 insn.reset_caches(); // ready to increment offsets in next iteration
88 }
89 #else
90 insn_t insn(bits);
91 #include INCLUDEFILE
92 #endif
93 trace_opcode(p, INSNCODE, insn);
94 return npc;
95 }
96