40d2a9b398a992e3c61c0a4c139ecec557c60a82
[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 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();
16 #ifndef USING_NOREGS
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;
22 bool zeroing = false;
23 #ifdef INSN_CATEGORY_TWINPREDICATION
24 reg_t src_pred = ~0x0;
25 bool zeroingsrc = false;
26 #endif
27 sv_insn_t insn(p, bits, floatintmap, PRED_ARGS);
28 if (vlen > 0)
29 {
30 fprintf(stderr, "pre-ex reg %s %x rd %ld rs1 %ld rs2 %ld vlen %d\n",
31 xstr(INSN), INSNCODE, s_insn.rd(), s_insn.rs1(), s_insn.rs2(),
32 vlen);
33 #ifdef INSN_CATEGORY_TWINPREDICATION
34 src_pred = insn.predicate(s_insn.SRC_REG(), SRC_PREDINT, zeroingsrc);
35 #endif
36 #ifdef DEST_PREDINT
37 // use the ORIGINAL, i.e. NON-REDIRECTED, register here
38 dest_pred = insn.predicate(s_insn.DEST_REG(), DEST_PREDINT, zeroing);
39 #endif
40 }
41 // identify which regs have had their CSR entries set as vectorised.
42 // really could do with a macro for-loop here... oh well...
43 // integer ops, RD, RS1, RS2, RS3 (use sv_int_tb)
44 if (insn.sv_check_reg(true, 16))
45 {
46 fprintf(stderr, "reg %s %x rd %ld rs1 %ld rs2 %ld vlen %d\n",
47 xstr(INSN), INSNCODE, s_insn.rd(), s_insn.rs1(), s_insn.rs2(),
48 vlen);
49 }
50 // if vectorop is set, one of the regs is not a scalar,
51 // so we must read the VL CSR and do a loop
52 if (vlen == 0)
53 {
54 vlen = 1; // minimum of one loop
55 }
56 for (int voffs=0; voffs < vlen; voffs++)
57 {
58 insn.reset_vloop_check();
59 #ifdef INSN_CATEGORY_TWINPREDICATION
60 int srcoffs = insn.rs_offs();
61 if (!zeroingsrc)
62 {
63 while ((src_pred & (1<<srcoffs)) == 0) {
64 srcoffs = insn.rs_offs_inc();
65 if (srcoffs == vlen) {
66 break;
67 }
68 }
69 }
70 int destoffs = insn.rd_offs();
71 if (!zeroing)
72 {
73 while ((dest_pred & (1<<destoffs)) == 0) {
74 destoffs = insn.rd_offs_inc();
75 if (destoffs == vlen) {
76 break;
77 }
78 }
79 }
80 if (srcoffs == vlen || destoffs == vlen) {
81 break; // end vector loop if either src or dest pred reaches end
82 }
83 if (vlen > 1)
84 {
85 fprintf(stderr, "twin reg %s src %d dest %d pred %lx %lx\n",
86 xstr(INSN), srcoffs, destoffs, src_pred, dest_pred);
87 }
88 #endif
89 #ifdef INSN_C_MV
90 fprintf(stderr, "pre loop reg %s %x vloop %d " \
91 "vlen %d stop %d pred %lx rd%lx rvc2%d\n",
92 xstr(INSN), INSNCODE, voffs, vlen, insn.stop_vloop(),
93 dest_pred & (1<<voffs), READ_REG(insn._rd()), insn.rvc_rs2());
94 #endif
95 #include INCLUDEFILE
96 #ifdef DEST_PREDINT
97 // don't check inversion here as dest_pred has already been inverted
98 if (zeroing && ((dest_pred & (1<<insn.rd_offs())) == 0))
99 {
100 // insn._rd() would be predicated: have to use insn._rd() here
101 WRITE_REG(insn._DEST_REG(), 0);
102 }
103 #endif
104 if (vlen > 1)
105 {
106 insn.reset_caches(); // ready to increment offsets
107 #if defined(USING_REG_RD)
108 fprintf(stderr, "reg %s %x vloop %d vlen %d stop %d pred %lx rd%lx\n",
109 xstr(INSN), INSNCODE, voffs, vlen, insn.stop_vloop(),
110 dest_pred & (1<<voffs), READ_REG(insn._rd()));
111 #endif
112 #if defined(USING_REG_FRD)
113 fprintf(stderr, "reg %s %x vloop %d vlen %d stop %d pred %lx rd%lx\n",
114 xstr(INSN), INSNCODE, voffs, vlen, insn.stop_vloop(),
115 dest_pred & (1<<voffs),
116 (READ_FREG(insn._rd())));
117 #endif
118 }
119 if (insn.stop_vloop())
120 {
121 break;
122 }
123 }
124 #else
125 insn_t insn(bits);
126 #include INCLUDEFILE
127 #endif
128 trace_opcode(p, INSNCODE, insn);
129 return npc;
130 }
131