1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Common functionality for RV32 and RV64 BPF JIT compilers
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (c) 2019 Björn Töpel <bjorn.topel@gmail.com>
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #ifndef _BPF_JIT_H
10*4882a593Smuzhiyun #define _BPF_JIT_H
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #include <linux/bpf.h>
13*4882a593Smuzhiyun #include <linux/filter.h>
14*4882a593Smuzhiyun #include <asm/cacheflush.h>
15*4882a593Smuzhiyun
rvc_enabled(void)16*4882a593Smuzhiyun static inline bool rvc_enabled(void)
17*4882a593Smuzhiyun {
18*4882a593Smuzhiyun return IS_ENABLED(CONFIG_RISCV_ISA_C);
19*4882a593Smuzhiyun }
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun enum {
22*4882a593Smuzhiyun RV_REG_ZERO = 0, /* The constant value 0 */
23*4882a593Smuzhiyun RV_REG_RA = 1, /* Return address */
24*4882a593Smuzhiyun RV_REG_SP = 2, /* Stack pointer */
25*4882a593Smuzhiyun RV_REG_GP = 3, /* Global pointer */
26*4882a593Smuzhiyun RV_REG_TP = 4, /* Thread pointer */
27*4882a593Smuzhiyun RV_REG_T0 = 5, /* Temporaries */
28*4882a593Smuzhiyun RV_REG_T1 = 6,
29*4882a593Smuzhiyun RV_REG_T2 = 7,
30*4882a593Smuzhiyun RV_REG_FP = 8, /* Saved register/frame pointer */
31*4882a593Smuzhiyun RV_REG_S1 = 9, /* Saved register */
32*4882a593Smuzhiyun RV_REG_A0 = 10, /* Function argument/return values */
33*4882a593Smuzhiyun RV_REG_A1 = 11, /* Function arguments */
34*4882a593Smuzhiyun RV_REG_A2 = 12,
35*4882a593Smuzhiyun RV_REG_A3 = 13,
36*4882a593Smuzhiyun RV_REG_A4 = 14,
37*4882a593Smuzhiyun RV_REG_A5 = 15,
38*4882a593Smuzhiyun RV_REG_A6 = 16,
39*4882a593Smuzhiyun RV_REG_A7 = 17,
40*4882a593Smuzhiyun RV_REG_S2 = 18, /* Saved registers */
41*4882a593Smuzhiyun RV_REG_S3 = 19,
42*4882a593Smuzhiyun RV_REG_S4 = 20,
43*4882a593Smuzhiyun RV_REG_S5 = 21,
44*4882a593Smuzhiyun RV_REG_S6 = 22,
45*4882a593Smuzhiyun RV_REG_S7 = 23,
46*4882a593Smuzhiyun RV_REG_S8 = 24,
47*4882a593Smuzhiyun RV_REG_S9 = 25,
48*4882a593Smuzhiyun RV_REG_S10 = 26,
49*4882a593Smuzhiyun RV_REG_S11 = 27,
50*4882a593Smuzhiyun RV_REG_T3 = 28, /* Temporaries */
51*4882a593Smuzhiyun RV_REG_T4 = 29,
52*4882a593Smuzhiyun RV_REG_T5 = 30,
53*4882a593Smuzhiyun RV_REG_T6 = 31,
54*4882a593Smuzhiyun };
55*4882a593Smuzhiyun
is_creg(u8 reg)56*4882a593Smuzhiyun static inline bool is_creg(u8 reg)
57*4882a593Smuzhiyun {
58*4882a593Smuzhiyun return (1 << reg) & (BIT(RV_REG_FP) |
59*4882a593Smuzhiyun BIT(RV_REG_S1) |
60*4882a593Smuzhiyun BIT(RV_REG_A0) |
61*4882a593Smuzhiyun BIT(RV_REG_A1) |
62*4882a593Smuzhiyun BIT(RV_REG_A2) |
63*4882a593Smuzhiyun BIT(RV_REG_A3) |
64*4882a593Smuzhiyun BIT(RV_REG_A4) |
65*4882a593Smuzhiyun BIT(RV_REG_A5));
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun struct rv_jit_context {
69*4882a593Smuzhiyun struct bpf_prog *prog;
70*4882a593Smuzhiyun u16 *insns; /* RV insns */
71*4882a593Smuzhiyun int ninsns;
72*4882a593Smuzhiyun int epilogue_offset;
73*4882a593Smuzhiyun int *offset; /* BPF to RV */
74*4882a593Smuzhiyun unsigned long flags;
75*4882a593Smuzhiyun int stack_size;
76*4882a593Smuzhiyun };
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun /* Convert from ninsns to bytes. */
ninsns_rvoff(int ninsns)79*4882a593Smuzhiyun static inline int ninsns_rvoff(int ninsns)
80*4882a593Smuzhiyun {
81*4882a593Smuzhiyun return ninsns << 1;
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun struct rv_jit_data {
85*4882a593Smuzhiyun struct bpf_binary_header *header;
86*4882a593Smuzhiyun u8 *image;
87*4882a593Smuzhiyun struct rv_jit_context ctx;
88*4882a593Smuzhiyun };
89*4882a593Smuzhiyun
bpf_fill_ill_insns(void * area,unsigned int size)90*4882a593Smuzhiyun static inline void bpf_fill_ill_insns(void *area, unsigned int size)
91*4882a593Smuzhiyun {
92*4882a593Smuzhiyun memset(area, 0, size);
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun
bpf_flush_icache(void * start,void * end)95*4882a593Smuzhiyun static inline void bpf_flush_icache(void *start, void *end)
96*4882a593Smuzhiyun {
97*4882a593Smuzhiyun flush_icache_range((unsigned long)start, (unsigned long)end);
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun /* Emit a 4-byte riscv instruction. */
emit(const u32 insn,struct rv_jit_context * ctx)101*4882a593Smuzhiyun static inline void emit(const u32 insn, struct rv_jit_context *ctx)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun if (ctx->insns) {
104*4882a593Smuzhiyun ctx->insns[ctx->ninsns] = insn;
105*4882a593Smuzhiyun ctx->insns[ctx->ninsns + 1] = (insn >> 16);
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun ctx->ninsns += 2;
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun /* Emit a 2-byte riscv compressed instruction. */
emitc(const u16 insn,struct rv_jit_context * ctx)112*4882a593Smuzhiyun static inline void emitc(const u16 insn, struct rv_jit_context *ctx)
113*4882a593Smuzhiyun {
114*4882a593Smuzhiyun BUILD_BUG_ON(!rvc_enabled());
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun if (ctx->insns)
117*4882a593Smuzhiyun ctx->insns[ctx->ninsns] = insn;
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun ctx->ninsns++;
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun
epilogue_offset(struct rv_jit_context * ctx)122*4882a593Smuzhiyun static inline int epilogue_offset(struct rv_jit_context *ctx)
123*4882a593Smuzhiyun {
124*4882a593Smuzhiyun int to = ctx->epilogue_offset, from = ctx->ninsns;
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun return ninsns_rvoff(to - from);
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun /* Return -1 or inverted cond. */
invert_bpf_cond(u8 cond)130*4882a593Smuzhiyun static inline int invert_bpf_cond(u8 cond)
131*4882a593Smuzhiyun {
132*4882a593Smuzhiyun switch (cond) {
133*4882a593Smuzhiyun case BPF_JEQ:
134*4882a593Smuzhiyun return BPF_JNE;
135*4882a593Smuzhiyun case BPF_JGT:
136*4882a593Smuzhiyun return BPF_JLE;
137*4882a593Smuzhiyun case BPF_JLT:
138*4882a593Smuzhiyun return BPF_JGE;
139*4882a593Smuzhiyun case BPF_JGE:
140*4882a593Smuzhiyun return BPF_JLT;
141*4882a593Smuzhiyun case BPF_JLE:
142*4882a593Smuzhiyun return BPF_JGT;
143*4882a593Smuzhiyun case BPF_JNE:
144*4882a593Smuzhiyun return BPF_JEQ;
145*4882a593Smuzhiyun case BPF_JSGT:
146*4882a593Smuzhiyun return BPF_JSLE;
147*4882a593Smuzhiyun case BPF_JSLT:
148*4882a593Smuzhiyun return BPF_JSGE;
149*4882a593Smuzhiyun case BPF_JSGE:
150*4882a593Smuzhiyun return BPF_JSLT;
151*4882a593Smuzhiyun case BPF_JSLE:
152*4882a593Smuzhiyun return BPF_JSGT;
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun return -1;
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun
is_6b_int(long val)157*4882a593Smuzhiyun static inline bool is_6b_int(long val)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun return -(1L << 5) <= val && val < (1L << 5);
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun
is_7b_uint(unsigned long val)162*4882a593Smuzhiyun static inline bool is_7b_uint(unsigned long val)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun return val < (1UL << 7);
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun
is_8b_uint(unsigned long val)167*4882a593Smuzhiyun static inline bool is_8b_uint(unsigned long val)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun return val < (1UL << 8);
170*4882a593Smuzhiyun }
171*4882a593Smuzhiyun
is_9b_uint(unsigned long val)172*4882a593Smuzhiyun static inline bool is_9b_uint(unsigned long val)
173*4882a593Smuzhiyun {
174*4882a593Smuzhiyun return val < (1UL << 9);
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun
is_10b_int(long val)177*4882a593Smuzhiyun static inline bool is_10b_int(long val)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun return -(1L << 9) <= val && val < (1L << 9);
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun
is_10b_uint(unsigned long val)182*4882a593Smuzhiyun static inline bool is_10b_uint(unsigned long val)
183*4882a593Smuzhiyun {
184*4882a593Smuzhiyun return val < (1UL << 10);
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun
is_12b_int(long val)187*4882a593Smuzhiyun static inline bool is_12b_int(long val)
188*4882a593Smuzhiyun {
189*4882a593Smuzhiyun return -(1L << 11) <= val && val < (1L << 11);
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun
is_12b_check(int off,int insn)192*4882a593Smuzhiyun static inline int is_12b_check(int off, int insn)
193*4882a593Smuzhiyun {
194*4882a593Smuzhiyun if (!is_12b_int(off)) {
195*4882a593Smuzhiyun pr_err("bpf-jit: insn=%d 12b < offset=%d not supported yet!\n",
196*4882a593Smuzhiyun insn, (int)off);
197*4882a593Smuzhiyun return -1;
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun return 0;
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun
is_13b_int(long val)202*4882a593Smuzhiyun static inline bool is_13b_int(long val)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun return -(1L << 12) <= val && val < (1L << 12);
205*4882a593Smuzhiyun }
206*4882a593Smuzhiyun
is_21b_int(long val)207*4882a593Smuzhiyun static inline bool is_21b_int(long val)
208*4882a593Smuzhiyun {
209*4882a593Smuzhiyun return -(1L << 20) <= val && val < (1L << 20);
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun
rv_offset(int insn,int off,struct rv_jit_context * ctx)212*4882a593Smuzhiyun static inline int rv_offset(int insn, int off, struct rv_jit_context *ctx)
213*4882a593Smuzhiyun {
214*4882a593Smuzhiyun int from, to;
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun off++; /* BPF branch is from PC+1, RV is from PC */
217*4882a593Smuzhiyun from = (insn > 0) ? ctx->offset[insn - 1] : 0;
218*4882a593Smuzhiyun to = (insn + off > 0) ? ctx->offset[insn + off - 1] : 0;
219*4882a593Smuzhiyun return ninsns_rvoff(to - from);
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun /* Instruction formats. */
223*4882a593Smuzhiyun
rv_r_insn(u8 funct7,u8 rs2,u8 rs1,u8 funct3,u8 rd,u8 opcode)224*4882a593Smuzhiyun static inline u32 rv_r_insn(u8 funct7, u8 rs2, u8 rs1, u8 funct3, u8 rd,
225*4882a593Smuzhiyun u8 opcode)
226*4882a593Smuzhiyun {
227*4882a593Smuzhiyun return (funct7 << 25) | (rs2 << 20) | (rs1 << 15) | (funct3 << 12) |
228*4882a593Smuzhiyun (rd << 7) | opcode;
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun
rv_i_insn(u16 imm11_0,u8 rs1,u8 funct3,u8 rd,u8 opcode)231*4882a593Smuzhiyun static inline u32 rv_i_insn(u16 imm11_0, u8 rs1, u8 funct3, u8 rd, u8 opcode)
232*4882a593Smuzhiyun {
233*4882a593Smuzhiyun return (imm11_0 << 20) | (rs1 << 15) | (funct3 << 12) | (rd << 7) |
234*4882a593Smuzhiyun opcode;
235*4882a593Smuzhiyun }
236*4882a593Smuzhiyun
rv_s_insn(u16 imm11_0,u8 rs2,u8 rs1,u8 funct3,u8 opcode)237*4882a593Smuzhiyun static inline u32 rv_s_insn(u16 imm11_0, u8 rs2, u8 rs1, u8 funct3, u8 opcode)
238*4882a593Smuzhiyun {
239*4882a593Smuzhiyun u8 imm11_5 = imm11_0 >> 5, imm4_0 = imm11_0 & 0x1f;
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun return (imm11_5 << 25) | (rs2 << 20) | (rs1 << 15) | (funct3 << 12) |
242*4882a593Smuzhiyun (imm4_0 << 7) | opcode;
243*4882a593Smuzhiyun }
244*4882a593Smuzhiyun
rv_b_insn(u16 imm12_1,u8 rs2,u8 rs1,u8 funct3,u8 opcode)245*4882a593Smuzhiyun static inline u32 rv_b_insn(u16 imm12_1, u8 rs2, u8 rs1, u8 funct3, u8 opcode)
246*4882a593Smuzhiyun {
247*4882a593Smuzhiyun u8 imm12 = ((imm12_1 & 0x800) >> 5) | ((imm12_1 & 0x3f0) >> 4);
248*4882a593Smuzhiyun u8 imm4_1 = ((imm12_1 & 0xf) << 1) | ((imm12_1 & 0x400) >> 10);
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun return (imm12 << 25) | (rs2 << 20) | (rs1 << 15) | (funct3 << 12) |
251*4882a593Smuzhiyun (imm4_1 << 7) | opcode;
252*4882a593Smuzhiyun }
253*4882a593Smuzhiyun
rv_u_insn(u32 imm31_12,u8 rd,u8 opcode)254*4882a593Smuzhiyun static inline u32 rv_u_insn(u32 imm31_12, u8 rd, u8 opcode)
255*4882a593Smuzhiyun {
256*4882a593Smuzhiyun return (imm31_12 << 12) | (rd << 7) | opcode;
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun
rv_j_insn(u32 imm20_1,u8 rd,u8 opcode)259*4882a593Smuzhiyun static inline u32 rv_j_insn(u32 imm20_1, u8 rd, u8 opcode)
260*4882a593Smuzhiyun {
261*4882a593Smuzhiyun u32 imm;
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun imm = (imm20_1 & 0x80000) | ((imm20_1 & 0x3ff) << 9) |
264*4882a593Smuzhiyun ((imm20_1 & 0x400) >> 2) | ((imm20_1 & 0x7f800) >> 11);
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun return (imm << 12) | (rd << 7) | opcode;
267*4882a593Smuzhiyun }
268*4882a593Smuzhiyun
rv_amo_insn(u8 funct5,u8 aq,u8 rl,u8 rs2,u8 rs1,u8 funct3,u8 rd,u8 opcode)269*4882a593Smuzhiyun static inline u32 rv_amo_insn(u8 funct5, u8 aq, u8 rl, u8 rs2, u8 rs1,
270*4882a593Smuzhiyun u8 funct3, u8 rd, u8 opcode)
271*4882a593Smuzhiyun {
272*4882a593Smuzhiyun u8 funct7 = (funct5 << 2) | (aq << 1) | rl;
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun return rv_r_insn(funct7, rs2, rs1, funct3, rd, opcode);
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun /* RISC-V compressed instruction formats. */
278*4882a593Smuzhiyun
rv_cr_insn(u8 funct4,u8 rd,u8 rs2,u8 op)279*4882a593Smuzhiyun static inline u16 rv_cr_insn(u8 funct4, u8 rd, u8 rs2, u8 op)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun return (funct4 << 12) | (rd << 7) | (rs2 << 2) | op;
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun
rv_ci_insn(u8 funct3,u32 imm6,u8 rd,u8 op)284*4882a593Smuzhiyun static inline u16 rv_ci_insn(u8 funct3, u32 imm6, u8 rd, u8 op)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun u32 imm;
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun imm = ((imm6 & 0x20) << 7) | ((imm6 & 0x1f) << 2);
289*4882a593Smuzhiyun return (funct3 << 13) | (rd << 7) | op | imm;
290*4882a593Smuzhiyun }
291*4882a593Smuzhiyun
rv_css_insn(u8 funct3,u32 uimm,u8 rs2,u8 op)292*4882a593Smuzhiyun static inline u16 rv_css_insn(u8 funct3, u32 uimm, u8 rs2, u8 op)
293*4882a593Smuzhiyun {
294*4882a593Smuzhiyun return (funct3 << 13) | (uimm << 7) | (rs2 << 2) | op;
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun
rv_ciw_insn(u8 funct3,u32 uimm,u8 rd,u8 op)297*4882a593Smuzhiyun static inline u16 rv_ciw_insn(u8 funct3, u32 uimm, u8 rd, u8 op)
298*4882a593Smuzhiyun {
299*4882a593Smuzhiyun return (funct3 << 13) | (uimm << 5) | ((rd & 0x7) << 2) | op;
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun
rv_cl_insn(u8 funct3,u32 imm_hi,u8 rs1,u32 imm_lo,u8 rd,u8 op)302*4882a593Smuzhiyun static inline u16 rv_cl_insn(u8 funct3, u32 imm_hi, u8 rs1, u32 imm_lo, u8 rd,
303*4882a593Smuzhiyun u8 op)
304*4882a593Smuzhiyun {
305*4882a593Smuzhiyun return (funct3 << 13) | (imm_hi << 10) | ((rs1 & 0x7) << 7) |
306*4882a593Smuzhiyun (imm_lo << 5) | ((rd & 0x7) << 2) | op;
307*4882a593Smuzhiyun }
308*4882a593Smuzhiyun
rv_cs_insn(u8 funct3,u32 imm_hi,u8 rs1,u32 imm_lo,u8 rs2,u8 op)309*4882a593Smuzhiyun static inline u16 rv_cs_insn(u8 funct3, u32 imm_hi, u8 rs1, u32 imm_lo, u8 rs2,
310*4882a593Smuzhiyun u8 op)
311*4882a593Smuzhiyun {
312*4882a593Smuzhiyun return (funct3 << 13) | (imm_hi << 10) | ((rs1 & 0x7) << 7) |
313*4882a593Smuzhiyun (imm_lo << 5) | ((rs2 & 0x7) << 2) | op;
314*4882a593Smuzhiyun }
315*4882a593Smuzhiyun
rv_ca_insn(u8 funct6,u8 rd,u8 funct2,u8 rs2,u8 op)316*4882a593Smuzhiyun static inline u16 rv_ca_insn(u8 funct6, u8 rd, u8 funct2, u8 rs2, u8 op)
317*4882a593Smuzhiyun {
318*4882a593Smuzhiyun return (funct6 << 10) | ((rd & 0x7) << 7) | (funct2 << 5) |
319*4882a593Smuzhiyun ((rs2 & 0x7) << 2) | op;
320*4882a593Smuzhiyun }
321*4882a593Smuzhiyun
rv_cb_insn(u8 funct3,u32 imm6,u8 funct2,u8 rd,u8 op)322*4882a593Smuzhiyun static inline u16 rv_cb_insn(u8 funct3, u32 imm6, u8 funct2, u8 rd, u8 op)
323*4882a593Smuzhiyun {
324*4882a593Smuzhiyun u32 imm;
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun imm = ((imm6 & 0x20) << 7) | ((imm6 & 0x1f) << 2);
327*4882a593Smuzhiyun return (funct3 << 13) | (funct2 << 10) | ((rd & 0x7) << 7) | op | imm;
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun /* Instructions shared by both RV32 and RV64. */
331*4882a593Smuzhiyun
rv_addi(u8 rd,u8 rs1,u16 imm11_0)332*4882a593Smuzhiyun static inline u32 rv_addi(u8 rd, u8 rs1, u16 imm11_0)
333*4882a593Smuzhiyun {
334*4882a593Smuzhiyun return rv_i_insn(imm11_0, rs1, 0, rd, 0x13);
335*4882a593Smuzhiyun }
336*4882a593Smuzhiyun
rv_andi(u8 rd,u8 rs1,u16 imm11_0)337*4882a593Smuzhiyun static inline u32 rv_andi(u8 rd, u8 rs1, u16 imm11_0)
338*4882a593Smuzhiyun {
339*4882a593Smuzhiyun return rv_i_insn(imm11_0, rs1, 7, rd, 0x13);
340*4882a593Smuzhiyun }
341*4882a593Smuzhiyun
rv_ori(u8 rd,u8 rs1,u16 imm11_0)342*4882a593Smuzhiyun static inline u32 rv_ori(u8 rd, u8 rs1, u16 imm11_0)
343*4882a593Smuzhiyun {
344*4882a593Smuzhiyun return rv_i_insn(imm11_0, rs1, 6, rd, 0x13);
345*4882a593Smuzhiyun }
346*4882a593Smuzhiyun
rv_xori(u8 rd,u8 rs1,u16 imm11_0)347*4882a593Smuzhiyun static inline u32 rv_xori(u8 rd, u8 rs1, u16 imm11_0)
348*4882a593Smuzhiyun {
349*4882a593Smuzhiyun return rv_i_insn(imm11_0, rs1, 4, rd, 0x13);
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun
rv_slli(u8 rd,u8 rs1,u16 imm11_0)352*4882a593Smuzhiyun static inline u32 rv_slli(u8 rd, u8 rs1, u16 imm11_0)
353*4882a593Smuzhiyun {
354*4882a593Smuzhiyun return rv_i_insn(imm11_0, rs1, 1, rd, 0x13);
355*4882a593Smuzhiyun }
356*4882a593Smuzhiyun
rv_srli(u8 rd,u8 rs1,u16 imm11_0)357*4882a593Smuzhiyun static inline u32 rv_srli(u8 rd, u8 rs1, u16 imm11_0)
358*4882a593Smuzhiyun {
359*4882a593Smuzhiyun return rv_i_insn(imm11_0, rs1, 5, rd, 0x13);
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun
rv_srai(u8 rd,u8 rs1,u16 imm11_0)362*4882a593Smuzhiyun static inline u32 rv_srai(u8 rd, u8 rs1, u16 imm11_0)
363*4882a593Smuzhiyun {
364*4882a593Smuzhiyun return rv_i_insn(0x400 | imm11_0, rs1, 5, rd, 0x13);
365*4882a593Smuzhiyun }
366*4882a593Smuzhiyun
rv_lui(u8 rd,u32 imm31_12)367*4882a593Smuzhiyun static inline u32 rv_lui(u8 rd, u32 imm31_12)
368*4882a593Smuzhiyun {
369*4882a593Smuzhiyun return rv_u_insn(imm31_12, rd, 0x37);
370*4882a593Smuzhiyun }
371*4882a593Smuzhiyun
rv_auipc(u8 rd,u32 imm31_12)372*4882a593Smuzhiyun static inline u32 rv_auipc(u8 rd, u32 imm31_12)
373*4882a593Smuzhiyun {
374*4882a593Smuzhiyun return rv_u_insn(imm31_12, rd, 0x17);
375*4882a593Smuzhiyun }
376*4882a593Smuzhiyun
rv_add(u8 rd,u8 rs1,u8 rs2)377*4882a593Smuzhiyun static inline u32 rv_add(u8 rd, u8 rs1, u8 rs2)
378*4882a593Smuzhiyun {
379*4882a593Smuzhiyun return rv_r_insn(0, rs2, rs1, 0, rd, 0x33);
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun
rv_sub(u8 rd,u8 rs1,u8 rs2)382*4882a593Smuzhiyun static inline u32 rv_sub(u8 rd, u8 rs1, u8 rs2)
383*4882a593Smuzhiyun {
384*4882a593Smuzhiyun return rv_r_insn(0x20, rs2, rs1, 0, rd, 0x33);
385*4882a593Smuzhiyun }
386*4882a593Smuzhiyun
rv_sltu(u8 rd,u8 rs1,u8 rs2)387*4882a593Smuzhiyun static inline u32 rv_sltu(u8 rd, u8 rs1, u8 rs2)
388*4882a593Smuzhiyun {
389*4882a593Smuzhiyun return rv_r_insn(0, rs2, rs1, 3, rd, 0x33);
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun
rv_and(u8 rd,u8 rs1,u8 rs2)392*4882a593Smuzhiyun static inline u32 rv_and(u8 rd, u8 rs1, u8 rs2)
393*4882a593Smuzhiyun {
394*4882a593Smuzhiyun return rv_r_insn(0, rs2, rs1, 7, rd, 0x33);
395*4882a593Smuzhiyun }
396*4882a593Smuzhiyun
rv_or(u8 rd,u8 rs1,u8 rs2)397*4882a593Smuzhiyun static inline u32 rv_or(u8 rd, u8 rs1, u8 rs2)
398*4882a593Smuzhiyun {
399*4882a593Smuzhiyun return rv_r_insn(0, rs2, rs1, 6, rd, 0x33);
400*4882a593Smuzhiyun }
401*4882a593Smuzhiyun
rv_xor(u8 rd,u8 rs1,u8 rs2)402*4882a593Smuzhiyun static inline u32 rv_xor(u8 rd, u8 rs1, u8 rs2)
403*4882a593Smuzhiyun {
404*4882a593Smuzhiyun return rv_r_insn(0, rs2, rs1, 4, rd, 0x33);
405*4882a593Smuzhiyun }
406*4882a593Smuzhiyun
rv_sll(u8 rd,u8 rs1,u8 rs2)407*4882a593Smuzhiyun static inline u32 rv_sll(u8 rd, u8 rs1, u8 rs2)
408*4882a593Smuzhiyun {
409*4882a593Smuzhiyun return rv_r_insn(0, rs2, rs1, 1, rd, 0x33);
410*4882a593Smuzhiyun }
411*4882a593Smuzhiyun
rv_srl(u8 rd,u8 rs1,u8 rs2)412*4882a593Smuzhiyun static inline u32 rv_srl(u8 rd, u8 rs1, u8 rs2)
413*4882a593Smuzhiyun {
414*4882a593Smuzhiyun return rv_r_insn(0, rs2, rs1, 5, rd, 0x33);
415*4882a593Smuzhiyun }
416*4882a593Smuzhiyun
rv_sra(u8 rd,u8 rs1,u8 rs2)417*4882a593Smuzhiyun static inline u32 rv_sra(u8 rd, u8 rs1, u8 rs2)
418*4882a593Smuzhiyun {
419*4882a593Smuzhiyun return rv_r_insn(0x20, rs2, rs1, 5, rd, 0x33);
420*4882a593Smuzhiyun }
421*4882a593Smuzhiyun
rv_mul(u8 rd,u8 rs1,u8 rs2)422*4882a593Smuzhiyun static inline u32 rv_mul(u8 rd, u8 rs1, u8 rs2)
423*4882a593Smuzhiyun {
424*4882a593Smuzhiyun return rv_r_insn(1, rs2, rs1, 0, rd, 0x33);
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun
rv_mulhu(u8 rd,u8 rs1,u8 rs2)427*4882a593Smuzhiyun static inline u32 rv_mulhu(u8 rd, u8 rs1, u8 rs2)
428*4882a593Smuzhiyun {
429*4882a593Smuzhiyun return rv_r_insn(1, rs2, rs1, 3, rd, 0x33);
430*4882a593Smuzhiyun }
431*4882a593Smuzhiyun
rv_divu(u8 rd,u8 rs1,u8 rs2)432*4882a593Smuzhiyun static inline u32 rv_divu(u8 rd, u8 rs1, u8 rs2)
433*4882a593Smuzhiyun {
434*4882a593Smuzhiyun return rv_r_insn(1, rs2, rs1, 5, rd, 0x33);
435*4882a593Smuzhiyun }
436*4882a593Smuzhiyun
rv_remu(u8 rd,u8 rs1,u8 rs2)437*4882a593Smuzhiyun static inline u32 rv_remu(u8 rd, u8 rs1, u8 rs2)
438*4882a593Smuzhiyun {
439*4882a593Smuzhiyun return rv_r_insn(1, rs2, rs1, 7, rd, 0x33);
440*4882a593Smuzhiyun }
441*4882a593Smuzhiyun
rv_jal(u8 rd,u32 imm20_1)442*4882a593Smuzhiyun static inline u32 rv_jal(u8 rd, u32 imm20_1)
443*4882a593Smuzhiyun {
444*4882a593Smuzhiyun return rv_j_insn(imm20_1, rd, 0x6f);
445*4882a593Smuzhiyun }
446*4882a593Smuzhiyun
rv_jalr(u8 rd,u8 rs1,u16 imm11_0)447*4882a593Smuzhiyun static inline u32 rv_jalr(u8 rd, u8 rs1, u16 imm11_0)
448*4882a593Smuzhiyun {
449*4882a593Smuzhiyun return rv_i_insn(imm11_0, rs1, 0, rd, 0x67);
450*4882a593Smuzhiyun }
451*4882a593Smuzhiyun
rv_beq(u8 rs1,u8 rs2,u16 imm12_1)452*4882a593Smuzhiyun static inline u32 rv_beq(u8 rs1, u8 rs2, u16 imm12_1)
453*4882a593Smuzhiyun {
454*4882a593Smuzhiyun return rv_b_insn(imm12_1, rs2, rs1, 0, 0x63);
455*4882a593Smuzhiyun }
456*4882a593Smuzhiyun
rv_bne(u8 rs1,u8 rs2,u16 imm12_1)457*4882a593Smuzhiyun static inline u32 rv_bne(u8 rs1, u8 rs2, u16 imm12_1)
458*4882a593Smuzhiyun {
459*4882a593Smuzhiyun return rv_b_insn(imm12_1, rs2, rs1, 1, 0x63);
460*4882a593Smuzhiyun }
461*4882a593Smuzhiyun
rv_bltu(u8 rs1,u8 rs2,u16 imm12_1)462*4882a593Smuzhiyun static inline u32 rv_bltu(u8 rs1, u8 rs2, u16 imm12_1)
463*4882a593Smuzhiyun {
464*4882a593Smuzhiyun return rv_b_insn(imm12_1, rs2, rs1, 6, 0x63);
465*4882a593Smuzhiyun }
466*4882a593Smuzhiyun
rv_bgtu(u8 rs1,u8 rs2,u16 imm12_1)467*4882a593Smuzhiyun static inline u32 rv_bgtu(u8 rs1, u8 rs2, u16 imm12_1)
468*4882a593Smuzhiyun {
469*4882a593Smuzhiyun return rv_bltu(rs2, rs1, imm12_1);
470*4882a593Smuzhiyun }
471*4882a593Smuzhiyun
rv_bgeu(u8 rs1,u8 rs2,u16 imm12_1)472*4882a593Smuzhiyun static inline u32 rv_bgeu(u8 rs1, u8 rs2, u16 imm12_1)
473*4882a593Smuzhiyun {
474*4882a593Smuzhiyun return rv_b_insn(imm12_1, rs2, rs1, 7, 0x63);
475*4882a593Smuzhiyun }
476*4882a593Smuzhiyun
rv_bleu(u8 rs1,u8 rs2,u16 imm12_1)477*4882a593Smuzhiyun static inline u32 rv_bleu(u8 rs1, u8 rs2, u16 imm12_1)
478*4882a593Smuzhiyun {
479*4882a593Smuzhiyun return rv_bgeu(rs2, rs1, imm12_1);
480*4882a593Smuzhiyun }
481*4882a593Smuzhiyun
rv_blt(u8 rs1,u8 rs2,u16 imm12_1)482*4882a593Smuzhiyun static inline u32 rv_blt(u8 rs1, u8 rs2, u16 imm12_1)
483*4882a593Smuzhiyun {
484*4882a593Smuzhiyun return rv_b_insn(imm12_1, rs2, rs1, 4, 0x63);
485*4882a593Smuzhiyun }
486*4882a593Smuzhiyun
rv_bgt(u8 rs1,u8 rs2,u16 imm12_1)487*4882a593Smuzhiyun static inline u32 rv_bgt(u8 rs1, u8 rs2, u16 imm12_1)
488*4882a593Smuzhiyun {
489*4882a593Smuzhiyun return rv_blt(rs2, rs1, imm12_1);
490*4882a593Smuzhiyun }
491*4882a593Smuzhiyun
rv_bge(u8 rs1,u8 rs2,u16 imm12_1)492*4882a593Smuzhiyun static inline u32 rv_bge(u8 rs1, u8 rs2, u16 imm12_1)
493*4882a593Smuzhiyun {
494*4882a593Smuzhiyun return rv_b_insn(imm12_1, rs2, rs1, 5, 0x63);
495*4882a593Smuzhiyun }
496*4882a593Smuzhiyun
rv_ble(u8 rs1,u8 rs2,u16 imm12_1)497*4882a593Smuzhiyun static inline u32 rv_ble(u8 rs1, u8 rs2, u16 imm12_1)
498*4882a593Smuzhiyun {
499*4882a593Smuzhiyun return rv_bge(rs2, rs1, imm12_1);
500*4882a593Smuzhiyun }
501*4882a593Smuzhiyun
rv_lw(u8 rd,u16 imm11_0,u8 rs1)502*4882a593Smuzhiyun static inline u32 rv_lw(u8 rd, u16 imm11_0, u8 rs1)
503*4882a593Smuzhiyun {
504*4882a593Smuzhiyun return rv_i_insn(imm11_0, rs1, 2, rd, 0x03);
505*4882a593Smuzhiyun }
506*4882a593Smuzhiyun
rv_lbu(u8 rd,u16 imm11_0,u8 rs1)507*4882a593Smuzhiyun static inline u32 rv_lbu(u8 rd, u16 imm11_0, u8 rs1)
508*4882a593Smuzhiyun {
509*4882a593Smuzhiyun return rv_i_insn(imm11_0, rs1, 4, rd, 0x03);
510*4882a593Smuzhiyun }
511*4882a593Smuzhiyun
rv_lhu(u8 rd,u16 imm11_0,u8 rs1)512*4882a593Smuzhiyun static inline u32 rv_lhu(u8 rd, u16 imm11_0, u8 rs1)
513*4882a593Smuzhiyun {
514*4882a593Smuzhiyun return rv_i_insn(imm11_0, rs1, 5, rd, 0x03);
515*4882a593Smuzhiyun }
516*4882a593Smuzhiyun
rv_sb(u8 rs1,u16 imm11_0,u8 rs2)517*4882a593Smuzhiyun static inline u32 rv_sb(u8 rs1, u16 imm11_0, u8 rs2)
518*4882a593Smuzhiyun {
519*4882a593Smuzhiyun return rv_s_insn(imm11_0, rs2, rs1, 0, 0x23);
520*4882a593Smuzhiyun }
521*4882a593Smuzhiyun
rv_sh(u8 rs1,u16 imm11_0,u8 rs2)522*4882a593Smuzhiyun static inline u32 rv_sh(u8 rs1, u16 imm11_0, u8 rs2)
523*4882a593Smuzhiyun {
524*4882a593Smuzhiyun return rv_s_insn(imm11_0, rs2, rs1, 1, 0x23);
525*4882a593Smuzhiyun }
526*4882a593Smuzhiyun
rv_sw(u8 rs1,u16 imm11_0,u8 rs2)527*4882a593Smuzhiyun static inline u32 rv_sw(u8 rs1, u16 imm11_0, u8 rs2)
528*4882a593Smuzhiyun {
529*4882a593Smuzhiyun return rv_s_insn(imm11_0, rs2, rs1, 2, 0x23);
530*4882a593Smuzhiyun }
531*4882a593Smuzhiyun
rv_amoadd_w(u8 rd,u8 rs2,u8 rs1,u8 aq,u8 rl)532*4882a593Smuzhiyun static inline u32 rv_amoadd_w(u8 rd, u8 rs2, u8 rs1, u8 aq, u8 rl)
533*4882a593Smuzhiyun {
534*4882a593Smuzhiyun return rv_amo_insn(0, aq, rl, rs2, rs1, 2, rd, 0x2f);
535*4882a593Smuzhiyun }
536*4882a593Smuzhiyun
537*4882a593Smuzhiyun /* RVC instrutions. */
538*4882a593Smuzhiyun
rvc_addi4spn(u8 rd,u32 imm10)539*4882a593Smuzhiyun static inline u16 rvc_addi4spn(u8 rd, u32 imm10)
540*4882a593Smuzhiyun {
541*4882a593Smuzhiyun u32 imm;
542*4882a593Smuzhiyun
543*4882a593Smuzhiyun imm = ((imm10 & 0x30) << 2) | ((imm10 & 0x3c0) >> 4) |
544*4882a593Smuzhiyun ((imm10 & 0x4) >> 1) | ((imm10 & 0x8) >> 3);
545*4882a593Smuzhiyun return rv_ciw_insn(0x0, imm, rd, 0x0);
546*4882a593Smuzhiyun }
547*4882a593Smuzhiyun
rvc_lw(u8 rd,u32 imm7,u8 rs1)548*4882a593Smuzhiyun static inline u16 rvc_lw(u8 rd, u32 imm7, u8 rs1)
549*4882a593Smuzhiyun {
550*4882a593Smuzhiyun u32 imm_hi, imm_lo;
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun imm_hi = (imm7 & 0x38) >> 3;
553*4882a593Smuzhiyun imm_lo = ((imm7 & 0x4) >> 1) | ((imm7 & 0x40) >> 6);
554*4882a593Smuzhiyun return rv_cl_insn(0x2, imm_hi, rs1, imm_lo, rd, 0x0);
555*4882a593Smuzhiyun }
556*4882a593Smuzhiyun
rvc_sw(u8 rs1,u32 imm7,u8 rs2)557*4882a593Smuzhiyun static inline u16 rvc_sw(u8 rs1, u32 imm7, u8 rs2)
558*4882a593Smuzhiyun {
559*4882a593Smuzhiyun u32 imm_hi, imm_lo;
560*4882a593Smuzhiyun
561*4882a593Smuzhiyun imm_hi = (imm7 & 0x38) >> 3;
562*4882a593Smuzhiyun imm_lo = ((imm7 & 0x4) >> 1) | ((imm7 & 0x40) >> 6);
563*4882a593Smuzhiyun return rv_cs_insn(0x6, imm_hi, rs1, imm_lo, rs2, 0x0);
564*4882a593Smuzhiyun }
565*4882a593Smuzhiyun
rvc_addi(u8 rd,u32 imm6)566*4882a593Smuzhiyun static inline u16 rvc_addi(u8 rd, u32 imm6)
567*4882a593Smuzhiyun {
568*4882a593Smuzhiyun return rv_ci_insn(0, imm6, rd, 0x1);
569*4882a593Smuzhiyun }
570*4882a593Smuzhiyun
rvc_li(u8 rd,u32 imm6)571*4882a593Smuzhiyun static inline u16 rvc_li(u8 rd, u32 imm6)
572*4882a593Smuzhiyun {
573*4882a593Smuzhiyun return rv_ci_insn(0x2, imm6, rd, 0x1);
574*4882a593Smuzhiyun }
575*4882a593Smuzhiyun
rvc_addi16sp(u32 imm10)576*4882a593Smuzhiyun static inline u16 rvc_addi16sp(u32 imm10)
577*4882a593Smuzhiyun {
578*4882a593Smuzhiyun u32 imm;
579*4882a593Smuzhiyun
580*4882a593Smuzhiyun imm = ((imm10 & 0x200) >> 4) | (imm10 & 0x10) | ((imm10 & 0x40) >> 3) |
581*4882a593Smuzhiyun ((imm10 & 0x180) >> 6) | ((imm10 & 0x20) >> 5);
582*4882a593Smuzhiyun return rv_ci_insn(0x3, imm, RV_REG_SP, 0x1);
583*4882a593Smuzhiyun }
584*4882a593Smuzhiyun
rvc_lui(u8 rd,u32 imm6)585*4882a593Smuzhiyun static inline u16 rvc_lui(u8 rd, u32 imm6)
586*4882a593Smuzhiyun {
587*4882a593Smuzhiyun return rv_ci_insn(0x3, imm6, rd, 0x1);
588*4882a593Smuzhiyun }
589*4882a593Smuzhiyun
rvc_srli(u8 rd,u32 imm6)590*4882a593Smuzhiyun static inline u16 rvc_srli(u8 rd, u32 imm6)
591*4882a593Smuzhiyun {
592*4882a593Smuzhiyun return rv_cb_insn(0x4, imm6, 0, rd, 0x1);
593*4882a593Smuzhiyun }
594*4882a593Smuzhiyun
rvc_srai(u8 rd,u32 imm6)595*4882a593Smuzhiyun static inline u16 rvc_srai(u8 rd, u32 imm6)
596*4882a593Smuzhiyun {
597*4882a593Smuzhiyun return rv_cb_insn(0x4, imm6, 0x1, rd, 0x1);
598*4882a593Smuzhiyun }
599*4882a593Smuzhiyun
rvc_andi(u8 rd,u32 imm6)600*4882a593Smuzhiyun static inline u16 rvc_andi(u8 rd, u32 imm6)
601*4882a593Smuzhiyun {
602*4882a593Smuzhiyun return rv_cb_insn(0x4, imm6, 0x2, rd, 0x1);
603*4882a593Smuzhiyun }
604*4882a593Smuzhiyun
rvc_sub(u8 rd,u8 rs)605*4882a593Smuzhiyun static inline u16 rvc_sub(u8 rd, u8 rs)
606*4882a593Smuzhiyun {
607*4882a593Smuzhiyun return rv_ca_insn(0x23, rd, 0, rs, 0x1);
608*4882a593Smuzhiyun }
609*4882a593Smuzhiyun
rvc_xor(u8 rd,u8 rs)610*4882a593Smuzhiyun static inline u16 rvc_xor(u8 rd, u8 rs)
611*4882a593Smuzhiyun {
612*4882a593Smuzhiyun return rv_ca_insn(0x23, rd, 0x1, rs, 0x1);
613*4882a593Smuzhiyun }
614*4882a593Smuzhiyun
rvc_or(u8 rd,u8 rs)615*4882a593Smuzhiyun static inline u16 rvc_or(u8 rd, u8 rs)
616*4882a593Smuzhiyun {
617*4882a593Smuzhiyun return rv_ca_insn(0x23, rd, 0x2, rs, 0x1);
618*4882a593Smuzhiyun }
619*4882a593Smuzhiyun
rvc_and(u8 rd,u8 rs)620*4882a593Smuzhiyun static inline u16 rvc_and(u8 rd, u8 rs)
621*4882a593Smuzhiyun {
622*4882a593Smuzhiyun return rv_ca_insn(0x23, rd, 0x3, rs, 0x1);
623*4882a593Smuzhiyun }
624*4882a593Smuzhiyun
rvc_slli(u8 rd,u32 imm6)625*4882a593Smuzhiyun static inline u16 rvc_slli(u8 rd, u32 imm6)
626*4882a593Smuzhiyun {
627*4882a593Smuzhiyun return rv_ci_insn(0, imm6, rd, 0x2);
628*4882a593Smuzhiyun }
629*4882a593Smuzhiyun
rvc_lwsp(u8 rd,u32 imm8)630*4882a593Smuzhiyun static inline u16 rvc_lwsp(u8 rd, u32 imm8)
631*4882a593Smuzhiyun {
632*4882a593Smuzhiyun u32 imm;
633*4882a593Smuzhiyun
634*4882a593Smuzhiyun imm = ((imm8 & 0xc0) >> 6) | (imm8 & 0x3c);
635*4882a593Smuzhiyun return rv_ci_insn(0x2, imm, rd, 0x2);
636*4882a593Smuzhiyun }
637*4882a593Smuzhiyun
rvc_jr(u8 rs1)638*4882a593Smuzhiyun static inline u16 rvc_jr(u8 rs1)
639*4882a593Smuzhiyun {
640*4882a593Smuzhiyun return rv_cr_insn(0x8, rs1, RV_REG_ZERO, 0x2);
641*4882a593Smuzhiyun }
642*4882a593Smuzhiyun
rvc_mv(u8 rd,u8 rs)643*4882a593Smuzhiyun static inline u16 rvc_mv(u8 rd, u8 rs)
644*4882a593Smuzhiyun {
645*4882a593Smuzhiyun return rv_cr_insn(0x8, rd, rs, 0x2);
646*4882a593Smuzhiyun }
647*4882a593Smuzhiyun
rvc_jalr(u8 rs1)648*4882a593Smuzhiyun static inline u16 rvc_jalr(u8 rs1)
649*4882a593Smuzhiyun {
650*4882a593Smuzhiyun return rv_cr_insn(0x9, rs1, RV_REG_ZERO, 0x2);
651*4882a593Smuzhiyun }
652*4882a593Smuzhiyun
rvc_add(u8 rd,u8 rs)653*4882a593Smuzhiyun static inline u16 rvc_add(u8 rd, u8 rs)
654*4882a593Smuzhiyun {
655*4882a593Smuzhiyun return rv_cr_insn(0x9, rd, rs, 0x2);
656*4882a593Smuzhiyun }
657*4882a593Smuzhiyun
rvc_swsp(u32 imm8,u8 rs2)658*4882a593Smuzhiyun static inline u16 rvc_swsp(u32 imm8, u8 rs2)
659*4882a593Smuzhiyun {
660*4882a593Smuzhiyun u32 imm;
661*4882a593Smuzhiyun
662*4882a593Smuzhiyun imm = (imm8 & 0x3c) | ((imm8 & 0xc0) >> 6);
663*4882a593Smuzhiyun return rv_css_insn(0x6, imm, rs2, 0x2);
664*4882a593Smuzhiyun }
665*4882a593Smuzhiyun
666*4882a593Smuzhiyun /*
667*4882a593Smuzhiyun * RV64-only instructions.
668*4882a593Smuzhiyun *
669*4882a593Smuzhiyun * These instructions are not available on RV32. Wrap them below a #if to
670*4882a593Smuzhiyun * ensure that the RV32 JIT doesn't emit any of these instructions.
671*4882a593Smuzhiyun */
672*4882a593Smuzhiyun
673*4882a593Smuzhiyun #if __riscv_xlen == 64
674*4882a593Smuzhiyun
rv_addiw(u8 rd,u8 rs1,u16 imm11_0)675*4882a593Smuzhiyun static inline u32 rv_addiw(u8 rd, u8 rs1, u16 imm11_0)
676*4882a593Smuzhiyun {
677*4882a593Smuzhiyun return rv_i_insn(imm11_0, rs1, 0, rd, 0x1b);
678*4882a593Smuzhiyun }
679*4882a593Smuzhiyun
rv_slliw(u8 rd,u8 rs1,u16 imm11_0)680*4882a593Smuzhiyun static inline u32 rv_slliw(u8 rd, u8 rs1, u16 imm11_0)
681*4882a593Smuzhiyun {
682*4882a593Smuzhiyun return rv_i_insn(imm11_0, rs1, 1, rd, 0x1b);
683*4882a593Smuzhiyun }
684*4882a593Smuzhiyun
rv_srliw(u8 rd,u8 rs1,u16 imm11_0)685*4882a593Smuzhiyun static inline u32 rv_srliw(u8 rd, u8 rs1, u16 imm11_0)
686*4882a593Smuzhiyun {
687*4882a593Smuzhiyun return rv_i_insn(imm11_0, rs1, 5, rd, 0x1b);
688*4882a593Smuzhiyun }
689*4882a593Smuzhiyun
rv_sraiw(u8 rd,u8 rs1,u16 imm11_0)690*4882a593Smuzhiyun static inline u32 rv_sraiw(u8 rd, u8 rs1, u16 imm11_0)
691*4882a593Smuzhiyun {
692*4882a593Smuzhiyun return rv_i_insn(0x400 | imm11_0, rs1, 5, rd, 0x1b);
693*4882a593Smuzhiyun }
694*4882a593Smuzhiyun
rv_addw(u8 rd,u8 rs1,u8 rs2)695*4882a593Smuzhiyun static inline u32 rv_addw(u8 rd, u8 rs1, u8 rs2)
696*4882a593Smuzhiyun {
697*4882a593Smuzhiyun return rv_r_insn(0, rs2, rs1, 0, rd, 0x3b);
698*4882a593Smuzhiyun }
699*4882a593Smuzhiyun
rv_subw(u8 rd,u8 rs1,u8 rs2)700*4882a593Smuzhiyun static inline u32 rv_subw(u8 rd, u8 rs1, u8 rs2)
701*4882a593Smuzhiyun {
702*4882a593Smuzhiyun return rv_r_insn(0x20, rs2, rs1, 0, rd, 0x3b);
703*4882a593Smuzhiyun }
704*4882a593Smuzhiyun
rv_sllw(u8 rd,u8 rs1,u8 rs2)705*4882a593Smuzhiyun static inline u32 rv_sllw(u8 rd, u8 rs1, u8 rs2)
706*4882a593Smuzhiyun {
707*4882a593Smuzhiyun return rv_r_insn(0, rs2, rs1, 1, rd, 0x3b);
708*4882a593Smuzhiyun }
709*4882a593Smuzhiyun
rv_srlw(u8 rd,u8 rs1,u8 rs2)710*4882a593Smuzhiyun static inline u32 rv_srlw(u8 rd, u8 rs1, u8 rs2)
711*4882a593Smuzhiyun {
712*4882a593Smuzhiyun return rv_r_insn(0, rs2, rs1, 5, rd, 0x3b);
713*4882a593Smuzhiyun }
714*4882a593Smuzhiyun
rv_sraw(u8 rd,u8 rs1,u8 rs2)715*4882a593Smuzhiyun static inline u32 rv_sraw(u8 rd, u8 rs1, u8 rs2)
716*4882a593Smuzhiyun {
717*4882a593Smuzhiyun return rv_r_insn(0x20, rs2, rs1, 5, rd, 0x3b);
718*4882a593Smuzhiyun }
719*4882a593Smuzhiyun
rv_mulw(u8 rd,u8 rs1,u8 rs2)720*4882a593Smuzhiyun static inline u32 rv_mulw(u8 rd, u8 rs1, u8 rs2)
721*4882a593Smuzhiyun {
722*4882a593Smuzhiyun return rv_r_insn(1, rs2, rs1, 0, rd, 0x3b);
723*4882a593Smuzhiyun }
724*4882a593Smuzhiyun
rv_divuw(u8 rd,u8 rs1,u8 rs2)725*4882a593Smuzhiyun static inline u32 rv_divuw(u8 rd, u8 rs1, u8 rs2)
726*4882a593Smuzhiyun {
727*4882a593Smuzhiyun return rv_r_insn(1, rs2, rs1, 5, rd, 0x3b);
728*4882a593Smuzhiyun }
729*4882a593Smuzhiyun
rv_remuw(u8 rd,u8 rs1,u8 rs2)730*4882a593Smuzhiyun static inline u32 rv_remuw(u8 rd, u8 rs1, u8 rs2)
731*4882a593Smuzhiyun {
732*4882a593Smuzhiyun return rv_r_insn(1, rs2, rs1, 7, rd, 0x3b);
733*4882a593Smuzhiyun }
734*4882a593Smuzhiyun
rv_ld(u8 rd,u16 imm11_0,u8 rs1)735*4882a593Smuzhiyun static inline u32 rv_ld(u8 rd, u16 imm11_0, u8 rs1)
736*4882a593Smuzhiyun {
737*4882a593Smuzhiyun return rv_i_insn(imm11_0, rs1, 3, rd, 0x03);
738*4882a593Smuzhiyun }
739*4882a593Smuzhiyun
rv_lwu(u8 rd,u16 imm11_0,u8 rs1)740*4882a593Smuzhiyun static inline u32 rv_lwu(u8 rd, u16 imm11_0, u8 rs1)
741*4882a593Smuzhiyun {
742*4882a593Smuzhiyun return rv_i_insn(imm11_0, rs1, 6, rd, 0x03);
743*4882a593Smuzhiyun }
744*4882a593Smuzhiyun
rv_sd(u8 rs1,u16 imm11_0,u8 rs2)745*4882a593Smuzhiyun static inline u32 rv_sd(u8 rs1, u16 imm11_0, u8 rs2)
746*4882a593Smuzhiyun {
747*4882a593Smuzhiyun return rv_s_insn(imm11_0, rs2, rs1, 3, 0x23);
748*4882a593Smuzhiyun }
749*4882a593Smuzhiyun
rv_amoadd_d(u8 rd,u8 rs2,u8 rs1,u8 aq,u8 rl)750*4882a593Smuzhiyun static inline u32 rv_amoadd_d(u8 rd, u8 rs2, u8 rs1, u8 aq, u8 rl)
751*4882a593Smuzhiyun {
752*4882a593Smuzhiyun return rv_amo_insn(0, aq, rl, rs2, rs1, 3, rd, 0x2f);
753*4882a593Smuzhiyun }
754*4882a593Smuzhiyun
755*4882a593Smuzhiyun /* RV64-only RVC instructions. */
756*4882a593Smuzhiyun
rvc_ld(u8 rd,u32 imm8,u8 rs1)757*4882a593Smuzhiyun static inline u16 rvc_ld(u8 rd, u32 imm8, u8 rs1)
758*4882a593Smuzhiyun {
759*4882a593Smuzhiyun u32 imm_hi, imm_lo;
760*4882a593Smuzhiyun
761*4882a593Smuzhiyun imm_hi = (imm8 & 0x38) >> 3;
762*4882a593Smuzhiyun imm_lo = (imm8 & 0xc0) >> 6;
763*4882a593Smuzhiyun return rv_cl_insn(0x3, imm_hi, rs1, imm_lo, rd, 0x0);
764*4882a593Smuzhiyun }
765*4882a593Smuzhiyun
rvc_sd(u8 rs1,u32 imm8,u8 rs2)766*4882a593Smuzhiyun static inline u16 rvc_sd(u8 rs1, u32 imm8, u8 rs2)
767*4882a593Smuzhiyun {
768*4882a593Smuzhiyun u32 imm_hi, imm_lo;
769*4882a593Smuzhiyun
770*4882a593Smuzhiyun imm_hi = (imm8 & 0x38) >> 3;
771*4882a593Smuzhiyun imm_lo = (imm8 & 0xc0) >> 6;
772*4882a593Smuzhiyun return rv_cs_insn(0x7, imm_hi, rs1, imm_lo, rs2, 0x0);
773*4882a593Smuzhiyun }
774*4882a593Smuzhiyun
rvc_subw(u8 rd,u8 rs)775*4882a593Smuzhiyun static inline u16 rvc_subw(u8 rd, u8 rs)
776*4882a593Smuzhiyun {
777*4882a593Smuzhiyun return rv_ca_insn(0x27, rd, 0, rs, 0x1);
778*4882a593Smuzhiyun }
779*4882a593Smuzhiyun
rvc_addiw(u8 rd,u32 imm6)780*4882a593Smuzhiyun static inline u16 rvc_addiw(u8 rd, u32 imm6)
781*4882a593Smuzhiyun {
782*4882a593Smuzhiyun return rv_ci_insn(0x1, imm6, rd, 0x1);
783*4882a593Smuzhiyun }
784*4882a593Smuzhiyun
rvc_ldsp(u8 rd,u32 imm9)785*4882a593Smuzhiyun static inline u16 rvc_ldsp(u8 rd, u32 imm9)
786*4882a593Smuzhiyun {
787*4882a593Smuzhiyun u32 imm;
788*4882a593Smuzhiyun
789*4882a593Smuzhiyun imm = ((imm9 & 0x1c0) >> 6) | (imm9 & 0x38);
790*4882a593Smuzhiyun return rv_ci_insn(0x3, imm, rd, 0x2);
791*4882a593Smuzhiyun }
792*4882a593Smuzhiyun
rvc_sdsp(u32 imm9,u8 rs2)793*4882a593Smuzhiyun static inline u16 rvc_sdsp(u32 imm9, u8 rs2)
794*4882a593Smuzhiyun {
795*4882a593Smuzhiyun u32 imm;
796*4882a593Smuzhiyun
797*4882a593Smuzhiyun imm = (imm9 & 0x38) | ((imm9 & 0x1c0) >> 6);
798*4882a593Smuzhiyun return rv_css_insn(0x7, imm, rs2, 0x2);
799*4882a593Smuzhiyun }
800*4882a593Smuzhiyun
801*4882a593Smuzhiyun #endif /* __riscv_xlen == 64 */
802*4882a593Smuzhiyun
803*4882a593Smuzhiyun /* Helper functions that emit RVC instructions when possible. */
804*4882a593Smuzhiyun
emit_jalr(u8 rd,u8 rs,s32 imm,struct rv_jit_context * ctx)805*4882a593Smuzhiyun static inline void emit_jalr(u8 rd, u8 rs, s32 imm, struct rv_jit_context *ctx)
806*4882a593Smuzhiyun {
807*4882a593Smuzhiyun if (rvc_enabled() && rd == RV_REG_RA && rs && !imm)
808*4882a593Smuzhiyun emitc(rvc_jalr(rs), ctx);
809*4882a593Smuzhiyun else if (rvc_enabled() && !rd && rs && !imm)
810*4882a593Smuzhiyun emitc(rvc_jr(rs), ctx);
811*4882a593Smuzhiyun else
812*4882a593Smuzhiyun emit(rv_jalr(rd, rs, imm), ctx);
813*4882a593Smuzhiyun }
814*4882a593Smuzhiyun
emit_mv(u8 rd,u8 rs,struct rv_jit_context * ctx)815*4882a593Smuzhiyun static inline void emit_mv(u8 rd, u8 rs, struct rv_jit_context *ctx)
816*4882a593Smuzhiyun {
817*4882a593Smuzhiyun if (rvc_enabled() && rd && rs)
818*4882a593Smuzhiyun emitc(rvc_mv(rd, rs), ctx);
819*4882a593Smuzhiyun else
820*4882a593Smuzhiyun emit(rv_addi(rd, rs, 0), ctx);
821*4882a593Smuzhiyun }
822*4882a593Smuzhiyun
emit_add(u8 rd,u8 rs1,u8 rs2,struct rv_jit_context * ctx)823*4882a593Smuzhiyun static inline void emit_add(u8 rd, u8 rs1, u8 rs2, struct rv_jit_context *ctx)
824*4882a593Smuzhiyun {
825*4882a593Smuzhiyun if (rvc_enabled() && rd && rd == rs1 && rs2)
826*4882a593Smuzhiyun emitc(rvc_add(rd, rs2), ctx);
827*4882a593Smuzhiyun else
828*4882a593Smuzhiyun emit(rv_add(rd, rs1, rs2), ctx);
829*4882a593Smuzhiyun }
830*4882a593Smuzhiyun
emit_addi(u8 rd,u8 rs,s32 imm,struct rv_jit_context * ctx)831*4882a593Smuzhiyun static inline void emit_addi(u8 rd, u8 rs, s32 imm, struct rv_jit_context *ctx)
832*4882a593Smuzhiyun {
833*4882a593Smuzhiyun if (rvc_enabled() && rd == RV_REG_SP && rd == rs && is_10b_int(imm) && imm && !(imm & 0xf))
834*4882a593Smuzhiyun emitc(rvc_addi16sp(imm), ctx);
835*4882a593Smuzhiyun else if (rvc_enabled() && is_creg(rd) && rs == RV_REG_SP && is_10b_uint(imm) &&
836*4882a593Smuzhiyun !(imm & 0x3) && imm)
837*4882a593Smuzhiyun emitc(rvc_addi4spn(rd, imm), ctx);
838*4882a593Smuzhiyun else if (rvc_enabled() && rd && rd == rs && imm && is_6b_int(imm))
839*4882a593Smuzhiyun emitc(rvc_addi(rd, imm), ctx);
840*4882a593Smuzhiyun else
841*4882a593Smuzhiyun emit(rv_addi(rd, rs, imm), ctx);
842*4882a593Smuzhiyun }
843*4882a593Smuzhiyun
emit_li(u8 rd,s32 imm,struct rv_jit_context * ctx)844*4882a593Smuzhiyun static inline void emit_li(u8 rd, s32 imm, struct rv_jit_context *ctx)
845*4882a593Smuzhiyun {
846*4882a593Smuzhiyun if (rvc_enabled() && rd && is_6b_int(imm))
847*4882a593Smuzhiyun emitc(rvc_li(rd, imm), ctx);
848*4882a593Smuzhiyun else
849*4882a593Smuzhiyun emit(rv_addi(rd, RV_REG_ZERO, imm), ctx);
850*4882a593Smuzhiyun }
851*4882a593Smuzhiyun
emit_lui(u8 rd,s32 imm,struct rv_jit_context * ctx)852*4882a593Smuzhiyun static inline void emit_lui(u8 rd, s32 imm, struct rv_jit_context *ctx)
853*4882a593Smuzhiyun {
854*4882a593Smuzhiyun if (rvc_enabled() && rd && rd != RV_REG_SP && is_6b_int(imm) && imm)
855*4882a593Smuzhiyun emitc(rvc_lui(rd, imm), ctx);
856*4882a593Smuzhiyun else
857*4882a593Smuzhiyun emit(rv_lui(rd, imm), ctx);
858*4882a593Smuzhiyun }
859*4882a593Smuzhiyun
emit_slli(u8 rd,u8 rs,s32 imm,struct rv_jit_context * ctx)860*4882a593Smuzhiyun static inline void emit_slli(u8 rd, u8 rs, s32 imm, struct rv_jit_context *ctx)
861*4882a593Smuzhiyun {
862*4882a593Smuzhiyun if (rvc_enabled() && rd && rd == rs && imm && (u32)imm < __riscv_xlen)
863*4882a593Smuzhiyun emitc(rvc_slli(rd, imm), ctx);
864*4882a593Smuzhiyun else
865*4882a593Smuzhiyun emit(rv_slli(rd, rs, imm), ctx);
866*4882a593Smuzhiyun }
867*4882a593Smuzhiyun
emit_andi(u8 rd,u8 rs,s32 imm,struct rv_jit_context * ctx)868*4882a593Smuzhiyun static inline void emit_andi(u8 rd, u8 rs, s32 imm, struct rv_jit_context *ctx)
869*4882a593Smuzhiyun {
870*4882a593Smuzhiyun if (rvc_enabled() && is_creg(rd) && rd == rs && is_6b_int(imm))
871*4882a593Smuzhiyun emitc(rvc_andi(rd, imm), ctx);
872*4882a593Smuzhiyun else
873*4882a593Smuzhiyun emit(rv_andi(rd, rs, imm), ctx);
874*4882a593Smuzhiyun }
875*4882a593Smuzhiyun
emit_srli(u8 rd,u8 rs,s32 imm,struct rv_jit_context * ctx)876*4882a593Smuzhiyun static inline void emit_srli(u8 rd, u8 rs, s32 imm, struct rv_jit_context *ctx)
877*4882a593Smuzhiyun {
878*4882a593Smuzhiyun if (rvc_enabled() && is_creg(rd) && rd == rs && imm && (u32)imm < __riscv_xlen)
879*4882a593Smuzhiyun emitc(rvc_srli(rd, imm), ctx);
880*4882a593Smuzhiyun else
881*4882a593Smuzhiyun emit(rv_srli(rd, rs, imm), ctx);
882*4882a593Smuzhiyun }
883*4882a593Smuzhiyun
emit_srai(u8 rd,u8 rs,s32 imm,struct rv_jit_context * ctx)884*4882a593Smuzhiyun static inline void emit_srai(u8 rd, u8 rs, s32 imm, struct rv_jit_context *ctx)
885*4882a593Smuzhiyun {
886*4882a593Smuzhiyun if (rvc_enabled() && is_creg(rd) && rd == rs && imm && (u32)imm < __riscv_xlen)
887*4882a593Smuzhiyun emitc(rvc_srai(rd, imm), ctx);
888*4882a593Smuzhiyun else
889*4882a593Smuzhiyun emit(rv_srai(rd, rs, imm), ctx);
890*4882a593Smuzhiyun }
891*4882a593Smuzhiyun
emit_sub(u8 rd,u8 rs1,u8 rs2,struct rv_jit_context * ctx)892*4882a593Smuzhiyun static inline void emit_sub(u8 rd, u8 rs1, u8 rs2, struct rv_jit_context *ctx)
893*4882a593Smuzhiyun {
894*4882a593Smuzhiyun if (rvc_enabled() && is_creg(rd) && rd == rs1 && is_creg(rs2))
895*4882a593Smuzhiyun emitc(rvc_sub(rd, rs2), ctx);
896*4882a593Smuzhiyun else
897*4882a593Smuzhiyun emit(rv_sub(rd, rs1, rs2), ctx);
898*4882a593Smuzhiyun }
899*4882a593Smuzhiyun
emit_or(u8 rd,u8 rs1,u8 rs2,struct rv_jit_context * ctx)900*4882a593Smuzhiyun static inline void emit_or(u8 rd, u8 rs1, u8 rs2, struct rv_jit_context *ctx)
901*4882a593Smuzhiyun {
902*4882a593Smuzhiyun if (rvc_enabled() && is_creg(rd) && rd == rs1 && is_creg(rs2))
903*4882a593Smuzhiyun emitc(rvc_or(rd, rs2), ctx);
904*4882a593Smuzhiyun else
905*4882a593Smuzhiyun emit(rv_or(rd, rs1, rs2), ctx);
906*4882a593Smuzhiyun }
907*4882a593Smuzhiyun
emit_and(u8 rd,u8 rs1,u8 rs2,struct rv_jit_context * ctx)908*4882a593Smuzhiyun static inline void emit_and(u8 rd, u8 rs1, u8 rs2, struct rv_jit_context *ctx)
909*4882a593Smuzhiyun {
910*4882a593Smuzhiyun if (rvc_enabled() && is_creg(rd) && rd == rs1 && is_creg(rs2))
911*4882a593Smuzhiyun emitc(rvc_and(rd, rs2), ctx);
912*4882a593Smuzhiyun else
913*4882a593Smuzhiyun emit(rv_and(rd, rs1, rs2), ctx);
914*4882a593Smuzhiyun }
915*4882a593Smuzhiyun
emit_xor(u8 rd,u8 rs1,u8 rs2,struct rv_jit_context * ctx)916*4882a593Smuzhiyun static inline void emit_xor(u8 rd, u8 rs1, u8 rs2, struct rv_jit_context *ctx)
917*4882a593Smuzhiyun {
918*4882a593Smuzhiyun if (rvc_enabled() && is_creg(rd) && rd == rs1 && is_creg(rs2))
919*4882a593Smuzhiyun emitc(rvc_xor(rd, rs2), ctx);
920*4882a593Smuzhiyun else
921*4882a593Smuzhiyun emit(rv_xor(rd, rs1, rs2), ctx);
922*4882a593Smuzhiyun }
923*4882a593Smuzhiyun
emit_lw(u8 rd,s32 off,u8 rs1,struct rv_jit_context * ctx)924*4882a593Smuzhiyun static inline void emit_lw(u8 rd, s32 off, u8 rs1, struct rv_jit_context *ctx)
925*4882a593Smuzhiyun {
926*4882a593Smuzhiyun if (rvc_enabled() && rs1 == RV_REG_SP && rd && is_8b_uint(off) && !(off & 0x3))
927*4882a593Smuzhiyun emitc(rvc_lwsp(rd, off), ctx);
928*4882a593Smuzhiyun else if (rvc_enabled() && is_creg(rd) && is_creg(rs1) && is_7b_uint(off) && !(off & 0x3))
929*4882a593Smuzhiyun emitc(rvc_lw(rd, off, rs1), ctx);
930*4882a593Smuzhiyun else
931*4882a593Smuzhiyun emit(rv_lw(rd, off, rs1), ctx);
932*4882a593Smuzhiyun }
933*4882a593Smuzhiyun
emit_sw(u8 rs1,s32 off,u8 rs2,struct rv_jit_context * ctx)934*4882a593Smuzhiyun static inline void emit_sw(u8 rs1, s32 off, u8 rs2, struct rv_jit_context *ctx)
935*4882a593Smuzhiyun {
936*4882a593Smuzhiyun if (rvc_enabled() && rs1 == RV_REG_SP && is_8b_uint(off) && !(off & 0x3))
937*4882a593Smuzhiyun emitc(rvc_swsp(off, rs2), ctx);
938*4882a593Smuzhiyun else if (rvc_enabled() && is_creg(rs1) && is_creg(rs2) && is_7b_uint(off) && !(off & 0x3))
939*4882a593Smuzhiyun emitc(rvc_sw(rs1, off, rs2), ctx);
940*4882a593Smuzhiyun else
941*4882a593Smuzhiyun emit(rv_sw(rs1, off, rs2), ctx);
942*4882a593Smuzhiyun }
943*4882a593Smuzhiyun
944*4882a593Smuzhiyun /* RV64-only helper functions. */
945*4882a593Smuzhiyun #if __riscv_xlen == 64
946*4882a593Smuzhiyun
emit_addiw(u8 rd,u8 rs,s32 imm,struct rv_jit_context * ctx)947*4882a593Smuzhiyun static inline void emit_addiw(u8 rd, u8 rs, s32 imm, struct rv_jit_context *ctx)
948*4882a593Smuzhiyun {
949*4882a593Smuzhiyun if (rvc_enabled() && rd && rd == rs && is_6b_int(imm))
950*4882a593Smuzhiyun emitc(rvc_addiw(rd, imm), ctx);
951*4882a593Smuzhiyun else
952*4882a593Smuzhiyun emit(rv_addiw(rd, rs, imm), ctx);
953*4882a593Smuzhiyun }
954*4882a593Smuzhiyun
emit_ld(u8 rd,s32 off,u8 rs1,struct rv_jit_context * ctx)955*4882a593Smuzhiyun static inline void emit_ld(u8 rd, s32 off, u8 rs1, struct rv_jit_context *ctx)
956*4882a593Smuzhiyun {
957*4882a593Smuzhiyun if (rvc_enabled() && rs1 == RV_REG_SP && rd && is_9b_uint(off) && !(off & 0x7))
958*4882a593Smuzhiyun emitc(rvc_ldsp(rd, off), ctx);
959*4882a593Smuzhiyun else if (rvc_enabled() && is_creg(rd) && is_creg(rs1) && is_8b_uint(off) && !(off & 0x7))
960*4882a593Smuzhiyun emitc(rvc_ld(rd, off, rs1), ctx);
961*4882a593Smuzhiyun else
962*4882a593Smuzhiyun emit(rv_ld(rd, off, rs1), ctx);
963*4882a593Smuzhiyun }
964*4882a593Smuzhiyun
emit_sd(u8 rs1,s32 off,u8 rs2,struct rv_jit_context * ctx)965*4882a593Smuzhiyun static inline void emit_sd(u8 rs1, s32 off, u8 rs2, struct rv_jit_context *ctx)
966*4882a593Smuzhiyun {
967*4882a593Smuzhiyun if (rvc_enabled() && rs1 == RV_REG_SP && is_9b_uint(off) && !(off & 0x7))
968*4882a593Smuzhiyun emitc(rvc_sdsp(off, rs2), ctx);
969*4882a593Smuzhiyun else if (rvc_enabled() && is_creg(rs1) && is_creg(rs2) && is_8b_uint(off) && !(off & 0x7))
970*4882a593Smuzhiyun emitc(rvc_sd(rs1, off, rs2), ctx);
971*4882a593Smuzhiyun else
972*4882a593Smuzhiyun emit(rv_sd(rs1, off, rs2), ctx);
973*4882a593Smuzhiyun }
974*4882a593Smuzhiyun
emit_subw(u8 rd,u8 rs1,u8 rs2,struct rv_jit_context * ctx)975*4882a593Smuzhiyun static inline void emit_subw(u8 rd, u8 rs1, u8 rs2, struct rv_jit_context *ctx)
976*4882a593Smuzhiyun {
977*4882a593Smuzhiyun if (rvc_enabled() && is_creg(rd) && rd == rs1 && is_creg(rs2))
978*4882a593Smuzhiyun emitc(rvc_subw(rd, rs2), ctx);
979*4882a593Smuzhiyun else
980*4882a593Smuzhiyun emit(rv_subw(rd, rs1, rs2), ctx);
981*4882a593Smuzhiyun }
982*4882a593Smuzhiyun
983*4882a593Smuzhiyun #endif /* __riscv_xlen == 64 */
984*4882a593Smuzhiyun
985*4882a593Smuzhiyun void bpf_jit_build_prologue(struct rv_jit_context *ctx);
986*4882a593Smuzhiyun void bpf_jit_build_epilogue(struct rv_jit_context *ctx);
987*4882a593Smuzhiyun
988*4882a593Smuzhiyun int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
989*4882a593Smuzhiyun bool extra_pass);
990*4882a593Smuzhiyun
991*4882a593Smuzhiyun #endif /* _BPF_JIT_H */
992