1 #ifndef _RISCV_DECODE_H
2 #define _RISCV_DECODE_H
4 #define __STDC_LIMIT_MACROS
10 typedef int int128_t
__attribute__((mode(TI
)));
11 typedef unsigned int uint128_t
__attribute__((mode(TI
)));
13 typedef int64_t sreg_t
;
14 typedef uint64_t reg_t
;
15 typedef uint64_t freg_t
;
17 const int OPCODE_BITS
= 7;
19 const int XPRID_BITS
= 5;
20 const int NXPR
= 1 << XPRID_BITS
;
22 const int FPR_BITS
= 64;
23 const int FPRID_BITS
= 5;
24 const int NFPR
= 1 << FPRID_BITS
;
26 const int IMM_BITS
= 12;
27 const int IMMLO_BITS
= 7;
28 const int TARGET_BITS
= 25;
29 const int FUNCT_BITS
= 3;
30 const int FUNCTR_BITS
= 7;
31 const int FFUNCT_BITS
= 2;
32 const int RM_BITS
= 3;
33 const int BIGIMM_BITS
= 20;
34 const int BRANCH_ALIGN_BITS
= 1;
35 const int JUMP_ALIGN_BITS
= 1;
43 #define FSR_RD_SHIFT 5
44 #define FSR_RD (0x7 << FSR_RD_SHIFT)
52 #define FSR_AEXC_SHIFT 0
53 #define FSR_NVA (FPEXC_NV << FSR_AEXC_SHIFT)
54 #define FSR_OFA (FPEXC_OF << FSR_AEXC_SHIFT)
55 #define FSR_UFA (FPEXC_UF << FSR_AEXC_SHIFT)
56 #define FSR_DZA (FPEXC_DZ << FSR_AEXC_SHIFT)
57 #define FSR_NXA (FPEXC_NX << FSR_AEXC_SHIFT)
58 #define FSR_AEXC (FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA)
60 #define FSR_ZERO ~(FSR_RD | FSR_AEXC)
62 // note: bit fields are in little-endian order
65 unsigned opcode
: OPCODE_BITS
;
66 unsigned funct
: FUNCT_BITS
;
67 signed imm12
: IMM_BITS
;
68 unsigned rs1
: XPRID_BITS
;
69 unsigned rd
: XPRID_BITS
;
74 unsigned opcode
: OPCODE_BITS
;
75 unsigned funct
: FUNCT_BITS
;
76 unsigned immlo
: IMMLO_BITS
;
77 unsigned rs2
: XPRID_BITS
;
78 unsigned rs1
: XPRID_BITS
;
79 signed immhi
: IMM_BITS
-IMMLO_BITS
;
84 unsigned jump_opcode
: OPCODE_BITS
;
85 signed target
: TARGET_BITS
;
90 unsigned opcode
: OPCODE_BITS
;
91 unsigned funct
: FUNCT_BITS
;
92 unsigned functr
: FUNCTR_BITS
;
93 unsigned rs2
: XPRID_BITS
;
94 unsigned rs1
: XPRID_BITS
;
95 unsigned rd
: XPRID_BITS
;
100 unsigned opcode
: OPCODE_BITS
;
101 unsigned bigimm
: BIGIMM_BITS
;
102 unsigned rd
: XPRID_BITS
;
107 unsigned opcode
: OPCODE_BITS
;
108 unsigned ffunct
: FFUNCT_BITS
;
109 unsigned rm
: RM_BITS
;
110 unsigned rs3
: FPRID_BITS
;
111 unsigned rs2
: FPRID_BITS
;
112 unsigned rs1
: FPRID_BITS
;
113 unsigned rd
: FPRID_BITS
;
132 write_port_t(T
& _t
) : t(_t
) {}
133 T
& operator = (const T
& rhs
)
144 template <class T
, size_t N
, bool zero_reg
>
150 memset(data
, 0, sizeof(data
));
152 write_port_t
<T
> write_port(size_t i
)
154 return write_port_t
<T
>(data
[i
]);
156 const T
& operator [] (size_t i
) const
159 const_cast<T
&>(data
[0]) = 0;
166 #define throw_illegal_instruction \
167 ({ if (utmode) throw trap_vector_illegal_instruction; \
168 else throw trap_illegal_instruction; })
170 // helpful macros, etc
171 #define RS1 XPR[insn.rtype.rs1]
172 #define RS2 XPR[insn.rtype.rs2]
173 #define RD XPR.write_port(insn.rtype.rd)
174 #define RA XPR.write_port(1)
175 #define FRS1 FPR[insn.ftype.rs1]
176 #define FRS2 FPR[insn.ftype.rs2]
177 #define FRS3 FPR[insn.ftype.rs3]
178 #define FRD FPR.write_port(insn.ftype.rd)
179 #define BIGIMM insn.ltype.bigimm
180 #define SIMM insn.itype.imm12
181 #define BIMM ((signed)insn.btype.immlo | (insn.btype.immhi << IMMLO_BITS))
182 #define SHAMT (insn.itype.imm12 & 0x3F)
183 #define SHAMTW (insn.itype.imm12 & 0x1F)
184 #define TARGET insn.jtype.target
185 #define BRANCH_TARGET (pc + (BIMM << BRANCH_ALIGN_BITS))
186 #define JUMP_TARGET (pc + (TARGET << JUMP_ALIGN_BITS))
187 #define RM ({ int rm = insn.ftype.rm; \
188 if(rm == 7) rm = (fsr & FSR_RD) >> FSR_RD_SHIFT; \
189 if(rm > 4) throw_illegal_instruction; \
192 #define xpr64 (xprlen == 64)
194 #define require_supervisor if(unlikely(!(sr & SR_S))) throw trap_privileged_instruction
195 #define require_xpr64 if(unlikely(!xpr64)) throw_illegal_instruction
196 #define require_xpr32 if(unlikely(xpr64)) throw_illegal_instruction
197 #ifndef RISCV_ENABLE_FPU
198 # define require_fp throw trap_illegal_instruction
200 # define require_fp if(unlikely(!(sr & SR_EF))) throw trap_fp_disabled
202 #ifndef RISCV_ENABLE_VEC
203 # define require_vector throw trap_illegal_instruction
205 # define require_vector \
206 ({ if(!(sr & SR_EV)) throw trap_vector_disabled; \
207 else if (!utmode && (vecbanks_count < 3)) throw trap_vector_bank; \
211 #define cmp_trunc(reg) (reg_t(reg) << (64-xprlen))
212 #define set_fp_exceptions ({ set_fsr(fsr | \
213 (softfloat_exceptionFlags << FSR_AEXC_SHIFT)); \
214 softfloat_exceptionFlags = 0; })
216 #define sext32(x) ((sreg_t)(int32_t)(x))
217 #define zext32(x) ((reg_t)(uint32_t)(x))
218 #define sext_xprlen(x) (((sreg_t)(x) << (64-xprlen)) >> (64-xprlen))
219 #define zext_xprlen(x) (((reg_t)(x) << (64-xprlen)) >> (64-xprlen))
223 #define INSN_IS_RVC(x) (((x) & 0x3) < 0x3)
224 #define insn_length(x) (INSN_IS_RVC(x) ? 2 : 4)
225 #define require_rvc if(!(sr & SR_EC)) throw_illegal_instruction
227 #define CRD_REGNUM ((insn.bits >> 5) & 0x1f)
228 #define CRD XPR.write_port(CRD_REGNUM)
229 #define CRS1 XPR[(insn.bits >> 10) & 0x1f]
230 #define CRS2 XPR[(insn.bits >> 5) & 0x1f]
231 #define CIMM6 ((int32_t)((insn.bits >> 10) & 0x3f) << 26 >> 26)
232 #define CIMM5U ((insn.bits >> 5) & 0x1f)
233 #define CIMM5 ((int32_t)CIMM5U << 27 >> 27)
234 #define CIMM10 ((int32_t)((insn.bits >> 5) & 0x3ff) << 22 >> 22)
235 #define CBRANCH_TARGET (pc + (CIMM5 << BRANCH_ALIGN_BITS))
236 #define CJUMP_TARGET (pc + (CIMM10 << JUMP_ALIGN_BITS))
238 static const int rvc_rs1_regmap
[8] = { 20, 21, 2, 3, 4, 5, 6, 7 };
239 #define rvc_rd_regmap rvc_rs1_regmap
240 #define rvc_rs2b_regmap rvc_rs1_regmap
241 static const int rvc_rs2_regmap
[8] = { 20, 21, 2, 3, 4, 5, 6, 0 };
242 #define CRDS XPR.write_port(rvc_rd_regmap[(insn.bits >> 13) & 0x7])
243 #define FCRDS FPR.write_port(rvc_rd_regmap[(insn.bits >> 13) & 0x7])
244 #define CRS1S XPR[rvc_rs1_regmap[(insn.bits >> 10) & 0x7]]
245 #define CRS2S XPR[rvc_rs2_regmap[(insn.bits >> 13) & 0x7]]
246 #define CRS2BS XPR[rvc_rs2b_regmap[(insn.bits >> 5) & 0x7]]
247 #define FCRS2S FPR[rvc_rs2_regmap[(insn.bits >> 13) & 0x7]]
252 #define UT_RS1(idx) uts[idx]->XPR[insn.rtype.rs1]
253 #define UT_RS2(idx) uts[idx]->XPR[insn.rtype.rs2]
254 #define UT_RD(idx) uts[idx]->XPR.write_port(insn.rtype.rd)
255 #define UT_RA(idx) uts[idx]->XPR.write_port(1)
256 #define UT_FRS1(idx) uts[idx]->FPR[insn.ftype.rs1]
257 #define UT_FRS2(idx) uts[idx]->FPR[insn.ftype.rs2]
258 #define UT_FRS3(idx) uts[idx]->FPR[insn.ftype.rs3]
259 #define UT_FRD(idx) uts[idx]->FPR.write_port(insn.ftype.rd)
260 #define UT_RM(idx) ((insn.ftype.rm != 7) ? insn.ftype.rm : \
261 ((uts[idx]->fsr & FSR_RD) >> FSR_RD_SHIFT))
263 #define UT_LOOP_START for (int i=0;i<VL; i++) {
264 #define UT_LOOP_END }
265 #define UT_LOOP_RS1 UT_RS1(i)
266 #define UT_LOOP_RS2 UT_RS2(i)
267 #define UT_LOOP_RD UT_RD(i)
268 #define UT_LOOP_RA UT_RA(i)
269 #define UT_LOOP_FRS1 UT_FRS1(i)
270 #define UT_LOOP_FRS2 UT_FRS2(i)
271 #define UT_LOOP_FRS3 UT_FRS3(i)
272 #define UT_LOOP_FRD UT_FRD(i)
273 #define UT_LOOP_RM UT_RM(i)
275 #define VEC_LOAD(dst, func, inc) \
278 UT_LOOP_##dst = mmu.func(addr); \
282 #define VEC_STORE(src, func, inc) \
285 mmu.func(addr, UT_LOOP_##src); \