git subrepo pull (merge) --force deps/lightning
[pcsx_rearmed.git] / deps / lightning / lib / jit_riscv-cpu.c
CommitLineData
4a71579b 1/*
79bfeef6 2 * Copyright (C) 2019-2023 Free Software Foundation, Inc.
4a71579b
PC
3 *
4 * This file is part of GNU lightning.
5 *
6 * GNU lightning is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 3, or (at your option)
9 * any later version.
10 *
11 * GNU lightning is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 * License for more details.
15 *
16 * Authors:
17 * Paulo Cesar Pereira de Andrade
18 */
19
20#if PROTO
ba86ff93 21#define jit_unaligned_p() (jit_cpu.unaligned)
4a71579b
PC
22#define _ZERO_REGNO 0
23#define _RA_REGNO 1
24#define _SP_REGNO 2
25#define _FP_REGNO 8
26typedef union {
27# define ui jit_uint32_t
28 struct {
29 ui opcode : 7;
30 ui rd : 5;
31 ui funct3 : 3;
32 ui rs1 : 5;
33 ui rs2 : 5;
34 ui funct7 : 7;
35 } R;
36 struct {
37 ui opcode : 7;
38 ui rd : 5;
39 ui funct3 : 3;
40 ui rs1 : 5;
41 ui rs2 : 5;
42 ui funct2 : 2;
43 ui rs3 : 5;
44 } R4;
45 struct {
46 ui opcode : 7;
47 ui rd : 5;
48 ui funct3 : 3;
49 ui rs1 : 5;
50 ui imm11_0 : 12;
51 } I;
52# if __WORDSIZE == 64
53 struct {
54 ui opcode : 7;
55 ui rd : 5;
56 ui funct3 : 3;
57 ui rs1 : 5;
58 ui shamt : 6;
59 ui imm6_0 : 6;
60 } IS;
61# endif
62 struct {
63 ui opcode : 7;
64 ui imm4_0 : 5;
65 ui funct3 : 3;
66 ui rs1 : 5;
67 ui rs2 : 5;
68 ui imm11_5 : 7;
69 } S;
70 struct {
71 ui opcode : 7;
72 ui imm11 : 1;
73 ui imm4_1 : 4;
74 ui funct3 : 3;
75 ui rs1 : 5;
76 ui rs2 : 5;
77 ui imm10_5 : 6;
78 ui imm12 : 1;
79 } B;
80 struct {
81 ui opcode : 7;
82 ui rd : 5;
83 ui imm12_31 : 20;
84 } U;
85 struct {
86 ui opcode : 7;
87 ui rd : 5;
88 ui imm19_12 : 8;
89 ui imm11 : 1;
90 ui imm10_1 : 10;
91 ui imm20 : 1;
92 } J;
93 jit_int32_t w;
94# undef ui
95} instr_t;
96# define ii(i) *_jit->pc.ui++ = i
4a71579b
PC
97# define ldr(r0, r1) ldr_l(r0, r1)
98# define ldi(r0, im) ldi_l(r0, im)
99# define ldxr(r0, r1, r2) ldxr_l(r0, r1, r2)
100# define ldxi(r0, r1, im) ldxi_l(r0, r1, im)
101# define str(r0, r1) str_l(r0, r1)
102# define sti(im, r0) sti_l(im, r0)
103# define stxr(r0, r1, r2) stxr_l(r0, r1, r2)
104# define stxi(im, r0, r1) stxi_l(im, r0, r1)
105# define simm6_p(im) ((im) <= 31 && (im) >= -32)
106# define simm12_p(im) ((im) <= 2047 && (im) >= -2048)
107# define simm20_p(im) ((im) <= 524287 && (im) >= -524288)
108# define simm32_p(im) ((im) <= 2147483647LL && (im) >= -2147483648LL)
109
110/*
111 * RV32I Base Instruction Set
112 */
113# define LUI(rd, imm) Utype(55, rd, imm)
114# define AUIPC(rd, imm) Utype(23, rd, imm)
115# define JAL(rd, imm) Jtype(111, rd, imm)
116# define JALR(rd, rs1, imm) Itype(103, rd, 0, rs1, imm)
117# define BEQ(rs1, rs2, imm) Btype(99, 0, rs1, rs2, imm)
118# define BNE(rs1, rs2, imm) Btype(99, 1, rs1, rs2, imm)
119# define BLT(rs1, rs2, imm) Btype(99, 4, rs1, rs2, imm)
120# define BGE(rs1, rs2, imm) Btype(99, 5, rs1, rs2, imm)
121# define BLTU(rs1, rs2, imm) Btype(99, 6, rs1, rs2, imm)
122# define BGEU(rs1, rs2, imm) Btype(99, 7, rs1, rs2, imm)
123# define LB(rd, rs1, imm) Itype(3, rd, 0, rs1, imm)
124# define LH(rd, rs1, imm) Itype(3, rd, 1, rs1, imm)
125# define LW(rd, rs1, imm) Itype(3, rd, 2, rs1, imm)
126# define LBU(rd, rs1, imm) Itype(3, rd, 4, rs1, imm)
127# define LHU(rd, rs1, imm) Itype(3, rd, 5, rs1, imm)
128# define SB(rs1, rs2, imm) Stype(35, 0, rs1, rs2, imm)
129# define SH(rs1, rs2, imm) Stype(35, 1, rs1, rs2, imm)
130# define SW(rs1, rs2, imm) Stype(35, 2, rs1, rs2, imm)
131# define ADDI(rd, rs1, imm) Itype(19, rd, 0, rs1, imm)
132# define SLTI(rd, rs1, imm) Itype(19, rd, 2, rs1, imm)
133# define SLTIU(rd, rs1, imm) Itype(19, rd, 3, rs1, imm)
134# define XORI(rd, rs1, imm) Itype(19, rd, 4, rs1, imm)
135# define ORI(rd, rs1, imm) Itype(19, rd, 6, rs1, imm)
136# define ANDI(rd, rs1, imm) Itype(19, rd, 7, rs1, imm)
137# if __WORDSIZE == 32
138# define SLLI(rd, rs1, imm) Rtype(19, rd, 1, rs1, imm, 0)
139# define SRLI(rd, rs1, imm) Rtype(19, rd, 5, rs1, imm, 0)
140# define SRAI(rd, rs1, imm) Rtype(19, rd, 5, rs1, imm, 32)
141# endif
142# define ADD(rd, rs1, rs2) Rtype(51, rd, 0, rs1, rs2, 0)
143# define SUB(rd, rs1, rs2) Rtype(51, rd, 0, rs1, rs2, 32)
144# define SLL(rd, rs1, rs2) Rtype(51, rd, 1, rs1, rs2, 0)
145# define SLT(rd, rs1, rs2) Rtype(51, rd, 2, rs1, rs2, 0)
146# define SLTU(rd, rs1, rs2) Rtype(51, rd, 3, rs1, rs2, 0)
147# define XOR(rd, rs1, rs2) Rtype(51, rd, 4, rs1, rs2, 0)
148# define SRL(rd, rs1, rs2) Rtype(51, rd, 5, rs1, rs2, 0)
149# define SRA(rd, rs1, rs2) Rtype(51, rd, 5, rs1, rs2, 32)
150# define OR(rd, rs1, rs2) Rtype(51, rd, 6, rs1, rs2, 0)
151# define AND(rd, rs1, rs2) Rtype(51, rd, 7, rs1, rs2, 0)
152# define FENCE(imm) Itype(15, 0, 0, 0, im)
153# define FENCE_I(imm) Itype(15, 0, 1, 0, im)
154# define ECALL() Itype(115, 0, 0, 0, 0)
155# define EBREAK() Itype(115, 0, 0, 0, 1)
156# define CSRRW(rd, rs1, csr) Itype(115, rd, 1, rs1, csr)
157# define CSRRS(rd, rs1, csr) Itype(115, rd, 2, rs1, csr)
158# define CSRRC(rd, rs1, csr) Itype(115, rd, 3, rs1, csr)
159# define CSRRWI(rd, zimm, csr) Itype(115, rd, 5, zimm, csr)
160# define CSRRSI(rd, zimm, csr) Itype(115, rd, 6, zimm, csr)
161# define CSRRCI(rd, zimm, csr) Itype(115, rd, 7, zimm, csr)
162/*
163 * RV64I Base Instruction Set (in addition to RV32I)
164 */
165# define LWU(rd, rs1, imm) Itype(3, rd, 6, rs1, imm)
166# define LD(rd, rs1, imm) Itype(3, rd, 3, rs1, imm)
167# define SD(rs1, rs2, imm) Stype(35, 3, rs1, rs2, imm)
168# if __WORDSIZE == 64
169# define SLLI(rd, rs1, sh) IStype(19, rd, 1, rs1, sh, 0)
170# define SRLI(rd, rs1, sh) IStype(19, rd, 5, rs1, sh, 0)
171# define SRAI(rd, rs1, sh) IStype(19, rd, 5, rs1, sh, 16)
172# endif
173# define ADDIW(rd, rs1, imm) Itype(27, rd, 0, rs1, imm)
174# define SLLIW(rd, rs1, imm) Rtype(27, rd, 1, rs1, imm, 0)
175# define SRLIW(rd, rs1, imm) Rtype(27, rd, 3, rs1, imm, 0)
176# define SRAIW(rd, rs1, imm) Rtype(27, rd, 3, rs1, imm, 32)
177# define ADDW(rd, rs1, imm) Rtype(59, rd, 0, rs1, imm, 0)
178# define SUBW(rd, rs1, imm) Rtype(59, rd, 0, rs1, imm, 32)
179# define SLLW(rd, rs1, imm) Rtype(59, rd, 1, rs1, imm, 0)
180# define SRLW(rd, rs1, imm) Rtype(59, rd, 5, rs1, imm, 0)
181# define SRAW(rd, rs1, imm) Rtype(59, rd, 5, rs1, imm, 32)
182/*
183 * RV32M Standard Extension
184 */
185# define MUL(rd, rs1, rs2) Rtype(51, rd, 0, rs1, rs2, 1)
186# define MULH(rd, rs1, rs2) Rtype(51, rd, 1, rs1, rs2, 1)
187# define MULHSU(rd, rs1, rs2) Rtype(51, rd, 2, rs1, rs2, 1)
188# define MULHU(rd, rs1, rs2) Rtype(51, rd, 3, rs1, rs2, 1)
189# define DIV(rd, rs1, rs2) Rtype(51, rd, 4, rs1, rs2, 1)
190# define DIVU(rd, rs1, rs2) Rtype(51, rd, 5, rs1, rs2, 1)
191# define REM(rd, rs1, rs2) Rtype(51, rd, 6, rs1, rs2, 1)
192# define REMU(rd, rs1, rs2) Rtype(51, rd, 7, rs1, rs2, 1)
193/*
194 * RV64M Standard Extension (in addition to RV32M)
195 */
196# define MULW(rd, rs1, rs2) Rtype(59, rd, 0, rs1, rs2, 1)
197# define DIVW(rd, rs1, rs2) Rtype(59, rd, 4, rs1, rs2, 1)
198# define DIVUW(rd, rs1, rs2) Rtype(59, rd, 5, rs1, rs2, 1)
199# define REMW(rd, rs1, rs2) Rtype(59, rd, 6, rs1, rs2, 1)
200# define REMUW(rd, rs1, rs2) Rtype(59, rd, 7, rs1, rs2, 1)
201/*
202 * RV32A Standard Extension
203 */
204# define LR_W(rd, rs1) R4type(47, rd, 2, rs1, 0, 0, 2)
205# define SC_W(rd, rs1, rs2) R4type(47, rd, 2, rs1, rs2, 0, 3)
206# define AMOSWAP_W(rd, rs1, rs2) R4type(47, rd, 2, rs1, rs2, 0, 1)
207# define AMOADD_W(rd, rs1, rs2) R4type(47, rd, 2, rs1, rs2, 0, 0)
208# define AMOXOR_W(rd, rs1, rs2) R4type(47, rd, 2, rs1, rs2, 0, 4)
209# define AMOAND_W(rd, rs1, rs2) R4type(47, rd, 2, rs1, rs2, 0, 12)
210# define AMOOR_W(rd, rs1, rs2) R4type(47, rd, 2, rs1, rs2, 0, 8)
211# define AMOMIN_W(rd, rs1, rs2) R4type(47, rd, 2, rs1, rs2, 0, 16)
212# define AMOMAX_W(rd, rs1, rs2) R4type(47, rd, 2, rs1, rs2, 0, 20)
213# define AMOMINU_W(rd, rs1, rs2) R4type(47, rd, 2, rs1, rs2, 0, 24)
214# define AMOMAXU_W(rd, rs1, rs2) R4type(47, rd, 2, rs1, rs2, 0, 28)
215/*
216 * RV64A Standard Extension (in addition to RV32A)
217 */
218# define LR_D(rd, rs1) R4type(47, rd, 3, rs1, 0, 0, 2)
219# define SC_D(rd, rs1, rs2) R4type(47, rd, 3, rs1, rs2, 0, 3)
220# define AMOSWAP_D(rd, rs1, rs2) R4type(47, rd, 3, rs1, rs2, 0, 1)
221# define AMOADD_D(rd, rs1, rs2) R4type(47, rd, 3, rs1, rs2, 0, 0)
222# define AMOXOR_D(rd, rs1, rs2) R4type(47, rd, 3, rs1, rs2, 0, 4)
223# define AMOAND_D(rd, rs1, rs2) R4type(47, rd, 3, rs1, rs2, 0, 12)
224# define AMOOR_D(rd, rs1, rs2) R4type(47, rd, 3, rs1, rs2, 0, 8)
225# define AMOMIN_D(rd, rs1, rs2) R4type(47, rd, 3, rs1, rs2, 0, 16)
226# define AMOMAX_D(rd, rs1, rs2) R4type(47, rd, 3, rs1, rs2, 0, 20)
227# define AMOMINU_D(rd, rs1, rs2) R4type(47, rd, 3, rs1, rs2, 0, 24)
228# define AMOMAXU_D(rd, rs1, rs2) R4type(47, rd, 3, rs1, rs2, 0, 28)
229/*
230 * Pseudo Instructions
231 */
232# define NOP() ADDI(_ZERO_REGNO, _ZERO_REGNO, 0)
233# define MV(r0, r1) ADDI(r0, r1, 0)
234# define NOT(r0, r1) XORI(r0, r1, -1)
235# define NEG(r0, r1) SUB(r0, _ZERO_REGNO, r1)
236# define NEGW(r0, r1) SUBW(r0, _ZERO_REGNO, r1)
237# define SEXT_W(r0, r1) ADDIW(r0, r1, 0)
238# define RET() JALR(0, 1, 0)
239
240/*
241 * Enconding functions
242 */
243# define Rtype(op, rd, fct, rs1, rs2, fct2) \
244 _Rtype(_jit, op, rd, fct, rs1, rs2, fct2)
245static void _Rtype(jit_state_t*, jit_int32_t, jit_int32_t,
246 jit_int32_t, jit_int32_t, jit_int32_t, jit_int32_t);
247# define R4type(op, rd, fct, rs1,rs2,fct2,rs3) \
248 _R4type(_jit, op, rd, fct, rs1, rs2, fct2, rs3)
249static void _R4type(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t,
250 jit_int32_t, jit_int32_t, jit_int32_t, jit_int32_t);
251# define Itype(op, rd, fct, rs1, imm) \
252 _Itype(_jit, op, rd, fct, rs1, imm)
253static void _Itype(jit_state_t*, jit_int32_t, jit_int32_t,
254 jit_int32_t, jit_int32_t, jit_int32_t);
255# if __WORDSIZE == 64
256# define IStype(op, rd, fct, rs1, sh, imm) \
257 _IStype(_jit, op, rd, fct, rs1, sh, imm)
258static void _IStype(jit_state_t*, jit_int32_t, jit_int32_t,
259 jit_int32_t, jit_int32_t, jit_int32_t,jit_int32_t);
260# endif
261# define Stype(op, fct, rs1, rs2, imm) \
262 _Stype(_jit, op, fct, rs1, rs2, imm)
263static void _Stype(jit_state_t*, jit_int32_t, jit_int32_t,
264 jit_int32_t, jit_int32_t, jit_int32_t);
265# define Btype(op, fct, rs1, rs2, imm) \
266 _Btype(_jit, op, fct, rs1, rs2, imm)
267static void _Btype(jit_state_t*, jit_int32_t, jit_int32_t,
268 jit_int32_t, jit_int32_t, jit_int32_t);
269# define Utype(op, rd, imm) _Utype(_jit, op, rd, imm)
270static void _Utype(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
271# define Jtype(op, rd, imm) _Jtype(_jit, op, rd, imm)
272static void _Jtype(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
273/*
274 * Lightning instructions
275 */
276# define nop(im) _nop(_jit, im)
277static void _nop(jit_state_t*, jit_int32_t);
278# define addr(r0, r1, r2) ADD(r0, r1, r2)
279# define addi(r0, r1, im) _addi(_jit, r0, r1, im)
280static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
281# define addcr(r0, r1, r2) _addcr(_jit, r0, r1, r2)
282static void _addcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
283# define addci(r0, r1, im) _addci(_jit, r0, r1, im)
284static void _addci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
285# define addxr(r0, r1, r2) _addxr(_jit, r0, r1, r2)
286static void _addxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
287# define addxi(r0, r1, im) _addxi(_jit, r0, r1, im)
288static void _addxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
289# define subr(r0, r1, r2) SUB(r0, r1, r2)
290# define subi(r0, r1, im) _subi(_jit, r0, r1, im)
291static void _subi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
292# define subcr(r0, r1, r2) _subcr(_jit, r0, r1, r2)
293static void _subcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
294# define subci(r0, r1, im) _subci(_jit, r0, r1, im)
295static void _subci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
296# define subxr(r0, r1, r2) _subxr(_jit, r0, r1, r2)
297static void _subxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
298# define subxi(r0, r1, im) _subxi(_jit, r0, r1, im)
299static void _subxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
300# define rsbi(r0, r1, im) _rsbi(_jit, r0, r1, im)
301static void _rsbi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
302# define mulr(r0, r1, r2) MUL(r0, r1, r2)
303# define muli(r0, r1, im) _muli(_jit, r0, r1, im)
304static void _muli(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
ba86ff93
PC
305# define hmulr(r0, r1, r2) MULH(r0, r1, r2)
306# define hmuli(r0, r1, im) _hmuli(_jit, r0, r1, im)
307static void _hmuli(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
308# define hmulr_u(r0, r1, r2) MULHU(r0, r1, r2)
309# define hmuli_u(r0, r1, im) _hmuli_u(_jit, r0, r1, im)
310static void _hmuli_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
4a71579b
PC
311# define divr(r0, r1, r2) DIV(r0, r1, r2)
312# define divi(r0, r1, im) _divi(_jit, r0, r1, im)
313static void _divi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
314# define divr_u(r0, r1, r2) DIVU(r0, r1, r2)
315# define divi_u(r0, r1, im) _divi_u(_jit, r0, r1, im)
316static void _divi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
317# define remr(r0, r1, r2) REM(r0, r1, r2)
318# define remi(r0, r1, im) _remi(_jit, r0, r1, im)
319static void _remi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
320# define remr_u(r0, r1, r2) REMU(r0, r1, r2)
321# define remi_u(r0, r1, im) _remi_u(_jit, r0, r1, im)
322static void _remi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
323# define qmulr(r0, r1, r2, r3) _qmulr(_jit,r0,r1,r2,r3)
324static void _qmulr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
325# define qmuli(r0, r1, r2, i0) _qmuli(_jit,r0,r1,r2,i0)
326static void _qmuli(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t);
327# define qmulr_u(r0, r1, r2, r3) _qmulr_u(_jit,r0,r1,r2,r3)
328static void _qmulr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
329# define qmuli_u(r0, r1, r2, i0) _qmuli_u(_jit,r0,r1,r2,i0)
330static void _qmuli_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t);
331static void _iqdivr(jit_state_t*,jit_bool_t,
332 jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
333# define qdivr(r0,r1,r2,r3) _iqdivr(_jit,1,r0,r1,r2,r3)
334# define qdivr_u(r0,r1,r2,r3) _iqdivr(_jit,0,r0,r1,r2,r3)
335static void _iqdivr(jit_state_t*,jit_bool_t,
336 jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
337# define qdivi(r0,r1,r2,i0) _qdivi(_jit,r0,r1,r2,i0)
338static void _qdivi(jit_state_t*,jit_int32_t,
339 jit_int32_t,jit_int32_t,jit_word_t);
340# define qdivi_u(r0,r1,r2,i0) _qdivi_u(_jit,r0,r1,r2,i0)
341static void _qdivi_u(jit_state_t*,jit_int32_t,
342 jit_int32_t,jit_int32_t,jit_word_t);
343# define lshr(r0, r1, r2) SLL(r0, r1, r2)
344# define lshi(r0, r1, im) _lshi(_jit, r0, r1, im)
345static void _lshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
346# define rshr(r0, r1, r2) SRA(r0, r1, r2)
347# define rshi(r0, r1, im) _rshi(_jit, r0, r1, im)
348static void _rshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
349# define rshr_u(r0, r1, r2) SRL(r0, r1, r2)
350# define rshi_u(r0, r1, im) _rshi_u(_jit, r0, r1, im)
351static void _rshi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
352# define negr(r0, r1) NEG(r0, r1)
353# define comr(r0, r1) NOT(r0, r1)
354# define andr(r0, r1, r2) AND(r0, r1, r2)
355# define andi(r0, r1, im) _andi(_jit, r0, r1, im)
356static void _andi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
357# define orr(r0, r1, r2) OR(r0, r1, r2)
358# define ori(r0, r1, im) _ori(_jit, r0, r1, im)
359static void _ori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
360# define xorr(r0, r1, r2) XOR(r0, r1, r2)
361# define xori(r0, r1, im) _xori(_jit, r0, r1, im)
362static void _xori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
363# define ldr_c(r0, r1) LB(r0, r1, 0)
364# define ldi_c(r0, im) _ldi_c(_jit, r0, im)
365static void _ldi_c(jit_state_t*,jit_int32_t,jit_word_t);
366# define ldr_uc(r0, r1) LBU(r0, r1, 0)
367# define ldi_uc(r0, im) _ldi_uc(_jit, r0, im)
368static void _ldi_uc(jit_state_t*,jit_int32_t,jit_word_t);
369# define ldr_s(r0, r1) LH(r0, r1, 0)
370# define ldi_s(r0, im) _ldi_s(_jit, r0, im)
371static void _ldi_s(jit_state_t*,jit_int32_t,jit_word_t);
372# define ldr_us(r0, r1) LHU(r0, r1, 0)
373# define ldi_us(r0, im) _ldi_us(_jit, r0, im)
374static void _ldi_us(jit_state_t*,jit_int32_t,jit_word_t);
375# define ldr_i(r0, r1) LW(r0, r1, 0)
376# define ldi_i(r0, im) _ldi_i(_jit, r0, im)
377static void _ldi_i(jit_state_t*,jit_int32_t,jit_word_t);
378# define ldr_ui(r0, r1) LWU(r0, r1, 0)
379# define ldi_ui(r0, im) _ldi_ui(_jit, r0, im)
380static void _ldi_ui(jit_state_t*,jit_int32_t,jit_word_t);
381# define ldr_l(r0, r1) LD(r0, r1, 0)
382# define ldi_l(r0, im) _ldi_l(_jit, r0, im)
383static void _ldi_l(jit_state_t*,jit_int32_t,jit_word_t);
384# define ldxr_c(r0, r1, r2) _ldxr_c(_jit, r0, r1, r2)
385static void _ldxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
386# define ldxi_c(r0, r1, im) _ldxi_c(_jit, r0, r1, im)
387static void _ldxi_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
388# define ldxr_uc(r0, r1, r2) _ldxr_uc(_jit, r0, r1, r2)
389static void _ldxr_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
390# define ldxi_uc(r0, r1, im) _ldxi_uc(_jit, r0, r1, im)
391static void _ldxi_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
392# define ldxr_s(r0, r1, r2) _ldxr_s(_jit, r0, r1, r2)
393static void _ldxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
394# define ldxi_s(r0, r1, im) _ldxi_s(_jit, r0, r1, im)
395static void _ldxi_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
396# define ldxr_us(r0, r1, r2) _ldxr_us(_jit, r0, r1, r2)
397static void _ldxr_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
398# define ldxi_us(r0, r1, im) _ldxi_us(_jit, r0, r1, im)
399static void _ldxi_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
400# define ldxr_i(r0, r1, r2) _ldxr_i(_jit, r0, r1, r2)
401static void _ldxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
402# define ldxi_i(r0, r1, im) _ldxi_i(_jit, r0, r1, im)
403static void _ldxi_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
404# define ldxr_ui(r0, r1, r2) _ldxr_ui(_jit, r0, r1, r2)
405static void _ldxr_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
406# define ldxi_ui(r0, r1, im) _ldxi_ui(_jit, r0, r1, im)
407static void _ldxi_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
408# define ldxr_l(r0, r1, r2) _ldxr_l(_jit, r0, r1, r2)
409static void _ldxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
410# define ldxi_l(r0, r1, im) _ldxi_l(_jit, r0, r1, im)
411static void _ldxi_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
ba86ff93
PC
412# define unldr(r0, r1, i0) _unldr(_jit, r0, r1, i0)
413static void _unldr(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
414# define unldi(r0, i0, i1) _unldi(_jit, r0, i0, i1)
415static void _unldi(jit_state_t*, jit_int32_t, jit_word_t, jit_word_t);
416# define unldr_u(r0, r1, i0) _unldr_u(_jit, r0, r1, i0)
417static void _unldr_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
418# define unldi_u(r0, i0, i1) _unldi_u(_jit, r0, i0, i1)
419static void _unldi_u(jit_state_t*, jit_int32_t, jit_word_t, jit_word_t);
4a71579b
PC
420# define str_c(r0, r1) SB(r0, r1, 0)
421# define sti_c(im, r0) _sti_c(_jit, im, r0)
422static void _sti_c(jit_state_t*,jit_word_t,jit_int32_t);
423# define str_s(r0, r1) SH(r0, r1, 0)
424# define sti_s(im, r0) _sti_s(_jit, im, r0)
425static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t);
426# define str_i(r0, r1) SW(r0, r1, 0)
427# define sti_i(im, r0) _sti_i(_jit, im, r0)
428static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t);
429# define str_l(r0, r1) SD(r0, r1, 0)
430# define sti_l(im, r0) _sti_l(_jit, im, r0)
431static void _sti_l(jit_state_t*,jit_word_t,jit_int32_t);
432# define stxr_c(r0, r1, r2) _stxr_c(_jit, r0, r1, r2)
433static void _stxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
434# define stxi_c(i0, r0, r1) _stxi_c(_jit, i0, r0, r1)
435static void _stxi_c(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
436# define stxr_s(r0, r1, r2) _stxr_s(_jit, r0, r1, r2)
437static void _stxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
438# define stxi_s(i0, r0, r1) _stxi_s(_jit, i0, r0, r1)
439static void _stxi_s(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
440# define stxr_i(r0, r1, r2) _stxr_i(_jit, r0, r1, r2)
441static void _stxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
442# define stxi_i(i0, r0, r1) _stxi_i(_jit, i0, r0, r1)
443static void _stxi_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
444# define stxr_l(r0, r1, r2) _stxr_l(_jit, r0, r1, r2)
445static void _stxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
446# define stxi_l(i0, r0, r1) _stxi_l(_jit, i0, r0, r1)
447static void _stxi_l(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
ba86ff93
PC
448#define unstr(r0, r1, i0) _unstr(_jit, r0, r1, i0)
449static void _unstr(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
450#define unsti(i0, r0, i1) _unsti(_jit, i0, r0, i1)
451static void _unsti(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t);
40a44dcb
PC
452# define bswapr_us(r0, r1) generic_bswapr_us(_jit, r0, r1)
453# define bswapr_ui(r0, r1) generic_bswapr_ui(_jit, r0, r1)
454# define bswapr_ul(r0, r1) generic_bswapr_ul(_jit, r0, r1)
4a71579b
PC
455# define extr_c(r0, r1) _extr_c(_jit, r0, r1)
456static void _extr_c(jit_state_t*,jit_int32_t,jit_int32_t);
457# define extr_uc(r0, r1) andi(r0, r1, 0xff)
458# define extr_s(r0, r1) _extr_s(_jit, r0, r1)
459static void _extr_s(jit_state_t*,jit_int32_t,jit_int32_t);
460# define extr_us(r0, r1) _extr_us(_jit, r0, r1)
461static void _extr_us(jit_state_t*,jit_int32_t,jit_int32_t);
462# define extr_i(r0, r1) SEXT_W(r0, r1)
463# define extr_ui(r0, r1) _extr_ui(_jit, r0, r1)
464static void _extr_ui(jit_state_t*,jit_int32_t,jit_int32_t);
465# define movr(r0, r1) MV(r0, r1)
466# define movi(r0, im) _movi(_jit, r0, im)
467static void _movi(jit_state_t*,jit_int32_t,jit_word_t);
468# define movi_p(r0, im) _movi_p(_jit, r0, im)
469static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t);
40a44dcb
PC
470# define movnr(r0,r1,r2) _movnr(_jit,r0,r1,r2)
471static void _movnr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
472# define movzr(r0,r1,r2) _movzr(_jit,r0,r1,r2)
473static void _movzr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
c0c16242 474# define casx(r0, r1, r2, r3, i0) _casx(_jit, r0, r1, r2, r3, i0)
ba3814c1
PC
475static void _casx(jit_state_t *_jit,jit_int32_t,jit_int32_t,
476 jit_int32_t,jit_int32_t,jit_word_t);
477#define casr(r0, r1, r2, r3) casx(r0, r1, r2, r3, 0)
478#define casi(r0, i0, r1, r2) casx(r0, _NOREG, r1, r2, i0)
4a71579b
PC
479# define ltr(r0, r1, r2) SLT(r0, r1, r2)
480# define lti(r0, r1, im) _lti(_jit, r0, r1, im)
481static void _lti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
482# define ltr_u(r0, r1, r2) SLTU(r0, r1, r2)
483# define lti_u(r0, r1, im) _lti_u(_jit, r0, r1, im)
484static void _lti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
485# define ler(r0, r1, r2) _ler(_jit, r0, r1, r2)
486static void _ler(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
487# define lei(r0, r1, im) _lei(_jit, r0, r1, im)
488static void _lei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
489# define ler_u(r0, r1, r2) _ler_u(_jit, r0, r1, r2)
490static void _ler_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
491# define lei_u(r0, r1, im) _lei_u(_jit, r0, r1, im)
492static void _lei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
493# define eqr(r0, r1, r2) _eqr(_jit, r0, r1, r2)
494static void _eqr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
495# define eqi(r0, r1, im) _eqi(_jit, r0, r1, im)
496static void _eqi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
497# define ger(r0, r1, r2) _ger(_jit, r0, r1, r2)
498static void _ger(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
499# define gei(r0, r1, r2) _gei(_jit, r0, r1, r2)
500static void _gei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
501# define ger_u(r0, r1, r2) _ger_u(_jit, r0, r1, r2)
502static void _ger_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
503# define gei_u(r0, r1, im) _gei_u(_jit, r0, r1, im)
504static void _gei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
505# define gtr(r0, r1, r2) SLT(r0, r2, r1)
506# define gti(r0, r1, im) _gti(_jit, r0, r1, im)
507static void _gti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
508# define gtr_u(r0, r1, r2) SLTU(r0, r2, r1)
509# define gti_u(r0, r1, im) _gti_u(_jit, r0, r1, im)
510static void _gti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
511# define ner(r0, r1, r2) _ner(_jit, r0, r1, r2)
512static void _ner(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
513# define nei(r0, r1, im) _nei(_jit, r0, r1, im)
514static void _nei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
515# define bltr(br, r0, r1) _bltr(_jit, br, r0, r1)
516static jit_word_t _bltr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
517# define blti(br, r0, im) _blti(_jit, br, r0, im)
518static jit_word_t _blti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
519# define bltr_u(br, r0, r1) _bltr_u(_jit, br, r0, r1)
520static jit_word_t _bltr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
521# define blti_u(br, r0, im) _blti_u(_jit, br, r0, im)
522static jit_word_t _blti_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
523# define bler(br, r0, r1) _bler(_jit, br, r0, r1)
524static jit_word_t _bler(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
525# define blei(br, r0, im) _blei(_jit, br, r0, im)
526static jit_word_t _blei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
527# define bler_u(br, r0, r1) _bler_u(_jit, br, r0, r1)
528static jit_word_t _bler_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
529# define blei_u(br, r0, im) _blei_u(_jit, br, r0, im)
530static jit_word_t _blei_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
531# define beqr(br, r0, r1) _beqr(_jit, br, r0, r1)
532static jit_word_t _beqr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
533# define beqi(br, r0, im) _beqi(_jit, br, r0, im)
534static jit_word_t _beqi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
535# define bger(br, r0, r1) _bger(_jit, br, r0, r1)
536static jit_word_t _bger(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
537# define bgei(br, r0, im) _bgei(_jit, br, r0, im)
538static jit_word_t _bgei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
539# define bger_u(br, r0, r1) _bger_u(_jit, br, r0, r1)
540static jit_word_t _bger_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
541# define bgei_u(br, r0, im) _bgei_u(_jit, br, r0, im)
542static jit_word_t _bgei_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
543# define bgtr(br, r0, r1) _bgtr(_jit, br, r0, r1)
544static jit_word_t _bgtr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
545# define bgti(br, r0, im) _bgti(_jit, br, r0, im)
546static jit_word_t _bgti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
547# define bgtr_u(br, r0, r1) _bgtr_u(_jit, br, r0, r1)
548static jit_word_t _bgtr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
549# define bgti_u(br, r0, im) _bgti_u(_jit, br, r0, im)
550static jit_word_t _bgti_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
551# define bner(br, r0, r1) _bner(_jit, br, r0, r1)
552static jit_word_t _bner(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
553# define bnei(br, r0, im) _bnei(_jit, br, r0, im)
554static jit_word_t _bnei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
555# define boaddr(br, r0, r1) _boaddr(_jit, br, r0, r1)
556# define boaddi(br, r0, im) _boaddi(_jit, br, r0, im)
557static jit_word_t _boaddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
558static jit_word_t _boaddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
559# define boaddr_u(br, r0, r1) _boaddr_u(_jit, br, r0, r1)
560# define boaddi_u(br, r0, im) _boaddi_u(_jit, br, r0, im)
561static jit_word_t _boaddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
562static jit_word_t _boaddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
563# define bxaddr(br, r0, r1) _bxaddr(_jit, br, r0, r1)
564# define bxaddi(br, r0, im) _bxaddi(_jit, br, r0, im)
565static jit_word_t _bxaddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
566static jit_word_t _bxaddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
567# define bxaddr_u(br, r0, r1) _bxaddr_u(_jit, br, r0, r1)
568# define bxaddi_u(br, r0, im) _bxaddi_u(_jit, br, r0, im)
569static jit_word_t _bxaddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
570static jit_word_t _bxaddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
571# define bosubr(br, r0, r1) _bosubr(_jit, br, r0, r1)
572# define bosubi(br, r0, im) _bosubi(_jit, br, r0, im)
573static jit_word_t _bosubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
574static jit_word_t _bosubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
575# define bosubr_u(br, r0, r1) _bosubr_u(_jit, br, r0, r1)
576# define bosubi_u(br, r0, im) _bosubi_u(_jit, br, r0, im)
577static jit_word_t _bosubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
578static jit_word_t _bosubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
579# define bxsubr(br, r0, r1) _bxsubr(_jit, br, r0, r1)
580# define bxsubi(br, r0, im) _bxsubi(_jit, br, r0, im)
581static jit_word_t _bxsubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
582static jit_word_t _bxsubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
583# define bxsubr_u(br, r0, r1) _bxsubr_u(_jit, br, r0, r1)
584# define bxsubi_u(br, r0, im) _bxsubi_u(_jit, br, r0, im)
585static jit_word_t _bxsubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
586static jit_word_t _bxsubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
587# define bmsr(br, r0, r1) _bmsr(_jit, br, r0, r1)
588# define bmsi(br, r0, im) _bmsi(_jit, br, r0, im)
589static jit_word_t _bmsr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
590static jit_word_t _bmsi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
591# define bmcr(br, r0, r1) _bmcr(_jit, br, r0, r1)
592# define bmci(br, r0, im) _bmci(_jit, br, r0, im)
593static jit_word_t _bmcr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
594static jit_word_t _bmci(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
595# define jmpr(r0) JALR(_ZERO_REGNO, r0, 0)
596# define jmpi(im) _jmpi(_jit, im)
79bfeef6 597static jit_word_t _jmpi(jit_state_t*,jit_word_t);
4a71579b
PC
598# define jmpi_p(im) _jmpi_p(_jit, im)
599static jit_word_t _jmpi_p(jit_state_t*,jit_word_t);
600# define callr(r0) JALR(_RA_REGNO, r0, 0)
601# define calli(im) _calli(_jit, im)
79bfeef6 602static jit_word_t _calli(jit_state_t*,jit_word_t);
4a71579b
PC
603# define calli_p(im) _calli_p(_jit, im)
604static jit_word_t _calli_p(jit_state_t*,jit_word_t);
605# define prolog(i0) _prolog(_jit,i0)
606static void _prolog(jit_state_t*,jit_node_t*);
607# define epilog(i0) _epilog(_jit,i0)
608static void _epilog(jit_state_t*,jit_node_t*);
609# define vastart(r0) _vastart(_jit, r0)
610static void _vastart(jit_state_t*, jit_int32_t);
611# define vaarg(r0, r1) _vaarg(_jit, r0, r1)
612static void _vaarg(jit_state_t*, jit_int32_t, jit_int32_t);
613#define patch_abs(instr,label) _patch_at(_jit,instr,label)
614#define patch_at(instr,label) _patch_at(_jit,instr,label)
615static void _patch_at(jit_state_t*,jit_word_t,jit_word_t);
616#endif /* PROTO */
617
618#if CODE
619static void
620_Rtype(jit_state_t *_jit, jit_int32_t op, jit_int32_t rd,
621 jit_int32_t fct, jit_int32_t rs1, jit_int32_t rs2, jit_int32_t fct2)
622{
623 instr_t i;
624 assert(!(op & ~0x7f));
625 assert(!(rd & ~0x1f));
626 assert(!(fct & ~0x07));
627 assert(!(rs1 & ~0x1f));
628 assert(!(rs2 & ~0x1f));
629 assert(!(fct2 & ~0x7f));
630 i.R.opcode = op;
631 i.R.rd = rd;
632 i.R.funct3 = fct;
633 i.R.rs1 = rs1;
634 i.R.rs2 = rs2;
635 i.R.funct7 = fct2;
636 ii(i.w);
637}
638
639static void
640_R4type(jit_state_t *_jit, jit_int32_t op, jit_int32_t rd, jit_int32_t fct,
641 jit_int32_t rs1, jit_int32_t rs2, jit_int32_t fct2, jit_int32_t rs3)
642{
643 instr_t i;
644 assert(!(op & ~0x7f));
645 assert(!(rd & ~0x1f));
646 assert(!(fct & ~0x07));
647 assert(!(rs1 & ~0x1f));
648 assert(!(rs2 & ~0x1f));
649 assert(!(fct2 & ~0x03));
650 assert(!(rs3 & ~0x1f));
651 i.R4.opcode = op;
652 i.R4.rd = rd;
653 i.R4.funct3 = fct;
654 i.R4.rs1 = rs1;
655 i.R4.rs2 = rs2;
656 i.R4.funct2 = fct2;
657 i.R4.rs3 = rs3;
658 ii(i.w);
659}
660
661static void
662_Itype(jit_state_t *_jit, jit_int32_t op, jit_int32_t rd,
663 jit_int32_t fct, jit_int32_t rs1, jit_int32_t imm)
664{
665 instr_t i;
666 assert(!(op & ~0x7f));
667 assert(!(rd & ~0x1f));
668 assert(!(fct & ~0x07));
669 assert(!(rs1 & ~0x1f));
670 assert(simm12_p(imm));
671 i.I.opcode = op;
672 i.I.rd = rd;
673 i.I.funct3 = fct;
674 i.I.rs1 = rs1;
675 i.I.imm11_0 = imm;
676 ii(i.w);
677}
678
679# if __WORDSIZE == 64
680static void
681_IStype(jit_state_t *_jit, jit_int32_t op, jit_int32_t rd,
682 jit_int32_t fct, jit_int32_t rs1, jit_int32_t sh, jit_int32_t imm)
683{
684 instr_t i;
685 assert(!(op & ~0x7f));
686 assert(!(rd & ~0x1f));
687 assert(!(fct & ~0x07));
688 assert(!(rs1 & ~0x1f));
689 assert(!(sh & ~0x3f));
690 assert(simm6_p(imm));
691 i.IS.opcode = op;
692 i.IS.rd = rd;
693 i.IS.funct3 = fct;
694 i.IS.rs1 = rs1;
695 i.IS.shamt = sh;
696 i.IS.imm6_0 = imm;
697 ii(i.w);
698}
699# endif
700
701static void
702_Stype(jit_state_t *_jit, jit_int32_t op, jit_int32_t fct,
703 jit_int32_t rs1, jit_int32_t rs2, jit_int32_t imm)
704{
705 instr_t i;
706 assert(!(op & ~0x7f));
707 assert(!(fct & ~0x07));
708 assert(!(rs1 & ~0x1f));
709 assert(!(rs2 & ~0x1f));
710 assert(simm12_p(imm));
711 i.S.opcode = op;
712 i.S.imm4_0 = imm & 0x1f;
713 i.S.funct3 = fct;
714 i.S.rs1 = rs1;
715 i.S.rs2 = rs2;
716 i.S.imm11_5 = (imm >> 5) & 0x7f;
717 ii(i.w);
718}
719
720static void
721_Btype(jit_state_t *_jit, jit_int32_t op, jit_int32_t fct,
722 jit_int32_t rs1, jit_int32_t rs2, jit_int32_t imm)
723{
724 instr_t i;
725 assert(!(op & ~0x7f));
726 assert(!(fct & ~0x07));
727 assert(!(rs1 & ~0x1f));
728 assert(!(rs2 & ~0x1f));
729 assert(!(imm & 1) && simm12_p(imm));
730 i.B.opcode = op;
731 i.B.imm11 = (imm >> 11) & 0x1;
732 i.B.imm4_1 = (imm >> 1) & 0xf;
733 i.B.funct3 = fct;
734 i.B.rs1 = rs1;
735 i.B.rs2 = rs2;
736 i.B.imm10_5 = (imm >> 5) & 0x3f;
737 i.B.imm12 = (imm >> 12) & 0x1;
738 ii(i.w);
739}
740
741static void
742_Utype(jit_state_t *_jit, jit_int32_t op, jit_int32_t rd, jit_int32_t imm)
743{
744 instr_t i;
745 assert(!(op & ~0x7f));
746 assert(!(rd & ~0x1f));
747 assert(simm20_p(imm));
748 i.U.opcode = op;
749 i.U.rd = rd;
750 i.U.imm12_31= imm;
751 ii(i.w);
752}
753
754static void
755_Jtype(jit_state_t *_jit, jit_int32_t op, jit_int32_t rd, jit_int32_t imm)
756{
757 instr_t i;
758 assert(!(op & ~0x7f));
759 assert(!(rd & ~0x1f));
760 assert(!(imm & 1) && imm <= 1048575 && imm >= -1048576);
761 i.J.opcode = op;
762 i.J.rd = rd;
763 i.J.imm19_12= (imm >> 12) & 0xff;
764 i.J.imm11 = (imm >> 11) & 0x1;
765 i.J.imm10_1 = (imm >> 1) & 0x3ff;
766 i.J.imm20 = (imm >> 20) & 0x1;
767 ii(i.w);
768}
769
770static void
771_nop(jit_state_t *_jit, jit_int32_t im)
772{
773 for (; im > 0; im -= 4)
774 NOP();
775 assert(im == 0);
776}
777
778static void
779_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
780{
781 if (simm12_p(i0))
782 ADDI(r0, r1, i0);
783 else {
784 jit_int32_t t0;
785 t0 = jit_get_reg(jit_class_gpr);
786 movi(rn(t0), i0);
787 addr(r0, r1, rn(t0));
788 jit_unget_reg(t0);
789 }
790}
791
792static void
793_addcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
794{
795 jit_int32_t t0;
796 if (jit_carry == _NOREG)
797 jit_carry = jit_get_reg(jit_class_gpr);
798 if (r0 == r1) {
799 t0 = jit_get_reg(jit_class_gpr);
800 addr(rn(t0), r1, r2);
801 SLTU(rn(jit_carry), rn(t0), r1);
802 movr(r0, rn(t0));
803 jit_unget_reg(t0);
804 }
805 else {
806 addr(r0, r1, r2);
807 SLTU(rn(jit_carry), r0, r1);
808 }
809}
810
811static void
812_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
813{
814 jit_int32_t t0;
815 if (jit_carry == _NOREG)
816 jit_carry = jit_get_reg(jit_class_gpr);
817 if (r0 == r1) {
818 t0 = jit_get_reg(jit_class_gpr);
819 addi(rn(t0), r1, i0);
820 SLTU(rn(jit_carry), rn(t0), r1);
821 movr(r0, rn(t0));
822 jit_unget_reg(t0);
823 }
824 else {
825 addi(r0, r1, i0);
826 SLTU(rn(jit_carry), r0, r1);
827 }
828}
829
830static void
831_addxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
832{
833 jit_int32_t t0;
834 assert(jit_carry != _NOREG);
835 t0 = jit_get_reg(jit_class_gpr);
836 movr(rn(t0), rn(jit_carry));
837 addcr(r0, r1, r2);
838 addcr(r0, r0, rn(t0));
839 jit_unget_reg(t0);
840}
841
842static void
843_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
844{
845 jit_int32_t t0;
846 assert(jit_carry != _NOREG);
847 t0 = jit_get_reg(jit_class_gpr);
848 movr(rn(t0), rn(jit_carry));
849 addci(r0, r1, i0);
850 addcr(r0, r0, rn(t0));
851 jit_unget_reg(t0);
852}
853
854static void
855_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
856{
857 if (simm12_p(-i0))
858 ADDI(r0, r1, -i0);
859 else {
860 jit_int32_t t0;
861 t0 = jit_get_reg(jit_class_gpr);
862 movi(rn(t0), i0);
863 subr(r0, r1, rn(t0));
864 jit_unget_reg(t0);
865 }
866}
867
868static void
869_subcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
870{
871 jit_int32_t t0;
872 if (jit_carry == _NOREG)
873 jit_carry = jit_get_reg(jit_class_gpr);
874 if (r0 == r1) {
875 t0 = jit_get_reg(jit_class_gpr);
876 subr(rn(t0), r1, r2);
877 SLTU(rn(jit_carry), r1, rn(t0));
878 movr(r0, rn(t0));
879 jit_unget_reg(t0);
880 }
881 else {
882 subr(r0, r1, r2);
883 SLTU(rn(jit_carry), r1, r0);
884 }
885}
886
887static void
888_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
889{
890 jit_int32_t t0;
891 if (jit_carry == _NOREG)
892 jit_carry = jit_get_reg(jit_class_gpr);
893 if (r0 == r1) {
894 t0 = jit_get_reg(jit_class_gpr);
895 subi(rn(t0), r1, i0);
896 SLTU(rn(jit_carry), r1, rn(t0));
897 movr(r0, rn(t0));
898 jit_unget_reg(t0);
899 }
900 else {
901 subi(r0, r1, i0);
902 SLTU(rn(jit_carry), r1, r0);
903 }
904}
905
906static void
907_subxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
908{
909 jit_int32_t t0;
910 assert(jit_carry != _NOREG);
911 t0 = jit_get_reg(jit_class_gpr);
912 movr(rn(t0), rn(jit_carry));
913 subcr(r0, r1, r2);
914 subcr(r0, r0, rn(t0));
915 jit_unget_reg(t0);
916}
917
918static void
919_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
920{
921 jit_int32_t t0;
922 assert(jit_carry != _NOREG);
923 t0 = jit_get_reg(jit_class_gpr);
924 movr(rn(t0), rn(jit_carry));
925 subci(r0, r1, i0);
926 subcr(r0, r0, rn(t0));
927 jit_unget_reg(t0);
928}
929
930static void
931_rsbi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
932{
933 subi(r0, r1, i0);
934 negr(r0, r0);
935}
936
937static void
938_muli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
939{
940 jit_int32_t t0;
941 t0 = jit_get_reg(jit_class_gpr);
942 movi(rn(t0), i0);
943 mulr(r0, r1, rn(t0));
944 jit_unget_reg(t0);
945}
946
ba86ff93
PC
947static void
948_hmuli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
949{
950 jit_int32_t t0;
951 t0 = jit_get_reg(jit_class_gpr);
952 movi(rn(t0), i0);
953 hmulr(r0, r1, rn(t0));
954 jit_unget_reg(t0);
955}
956
957static void
958_hmuli_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
959{
960 jit_int32_t t0;
961 t0 = jit_get_reg(jit_class_gpr);
962 movi(rn(t0), i0);
963 hmulr_u(r0, r1, rn(t0));
964 jit_unget_reg(t0);
965}
966
4a71579b
PC
967static void
968_divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
969{
970 jit_int32_t t0;
971 t0 = jit_get_reg(jit_class_gpr);
972 movi(rn(t0), i0);
973 divr(r0, r1, rn(t0));
974 jit_unget_reg(t0);
975}
976
977static void
978_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
979{
980 jit_int32_t t0;
981 t0 = jit_get_reg(jit_class_gpr);
982 movi(rn(t0), i0);
983 divr_u(r0, r1, rn(t0));
984 jit_unget_reg(t0);
985}
986
987static void
988_remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
989{
990 jit_int32_t t0;
991 t0 = jit_get_reg(jit_class_gpr);
992 movi(rn(t0), i0);
993 remr(r0, r1, rn(t0));
994 jit_unget_reg(t0);
995}
996
997static void
998_remi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
999{
1000 jit_int32_t t0;
1001 t0 = jit_get_reg(jit_class_gpr);
1002 movi(rn(t0), i0);
1003 remr_u(r0, r1, rn(t0));
1004 jit_unget_reg(t0);
1005}
1006
1007static void
1008_qmulr(jit_state_t *_jit, jit_int32_t r0,
1009 jit_int32_t r1, jit_int32_t r2, jit_int32_t r3)
1010{
1011 jit_int32_t t0;
1012 if (r0 == r2 || r0 == r3) {
1013 t0 = jit_get_reg(jit_class_gpr);
1014 mulr(rn(t0), r2, r3);
1015 }
1016 else
1017 mulr(r0, r2, r3);
1018 MULH(r1, r2, r3);
1019 if (r0 == r2 || r0 == r3) {
1020 movr(r0, rn(t0));
1021 jit_unget_reg(t0);
1022 }
1023}
1024
1025static void
1026_qmuli(jit_state_t *_jit, jit_int32_t r0,
1027 jit_int32_t r1, jit_int32_t r2, jit_word_t i0)
1028{
1029 jit_int32_t t0;
1030 t0 = jit_get_reg(jit_class_gpr);
1031 movi(rn(t0), i0);
1032 qmulr(r0, r1, r2, rn(t0));
1033 jit_unget_reg(t0);
1034}
1035
1036static void
1037_qmulr_u(jit_state_t *_jit, jit_int32_t r0,
1038 jit_int32_t r1, jit_int32_t r2, jit_int32_t r3)
1039{
1040 jit_int32_t t0;
1041 if (r0 == r2 || r0 == r3) {
1042 t0 = jit_get_reg(jit_class_gpr);
1043 mulr(rn(t0), r2, r3);
1044 }
1045 else
1046 mulr(r0, r2, r3);
1047 MULHU(r1, r2, r3);
1048 if (r0 == r2 || r0 == r3) {
1049 movr(r0, rn(t0));
1050 jit_unget_reg(t0);
1051 }
1052}
1053
1054static void
1055_qmuli_u(jit_state_t *_jit, jit_int32_t r0,
1056 jit_int32_t r1, jit_int32_t r2, jit_word_t i0)
1057{
1058 jit_int32_t t0;
1059 t0 = jit_get_reg(jit_class_gpr);
1060 movi(rn(t0), i0);
1061 qmulr_u(r0, r1, r2, rn(t0));
1062 jit_unget_reg(t0);
1063}
1064
1065static void
1066_iqdivr(jit_state_t *_jit, jit_bool_t sign,
1067 jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3)
1068{
1069 jit_int32_t sv0, rg0;
1070 jit_int32_t sv1, rg1;
1071 if (r0 == r2 || r0 == r3) {
1072 sv0 = jit_get_reg(jit_class_gpr);
1073 rg0 = rn(sv0);
1074 }
1075 else
1076 rg0 = r0;
1077 if (r1 == r2 || r1 == r3) {
1078 sv1 = jit_get_reg(jit_class_gpr);
1079 rg1 = rn(sv1);
1080 }
1081 else
1082 rg1 = r1;
1083 if (sign)
1084 divr(rg0, r2, r3);
1085 else
1086 divr_u(rg0, r2, r3);
1087 mulr(rg1, r3, rg0);
1088 subr(rg1, r2, rg1);
1089 if (rg0 != r0) {
1090 movr(r0, rg0);
1091 jit_unget_reg(sv0);
1092 }
1093 if (rg1 != r1) {
1094 movr(r1, rg1);
1095 jit_unget_reg(sv1);
1096 }
1097}
1098
1099static void
1100_qdivi(jit_state_t *_jit, jit_int32_t r0,
1101 jit_int32_t r1, jit_int32_t r2, jit_word_t i0)
1102{
1103 jit_int32_t t0;
1104 t0 = jit_get_reg(jit_class_gpr);
1105 movi(rn(t0), i0);
1106 qdivr(r0, r1, r2, rn(t0));
1107 jit_unget_reg(t0);
1108}
1109
1110static void
1111_qdivi_u(jit_state_t *_jit, jit_int32_t r0,
1112 jit_int32_t r1, jit_int32_t r2, jit_word_t i0)
1113{
1114 jit_int32_t t0;
1115 t0 = jit_get_reg(jit_class_gpr);
1116 movi(rn(t0), i0);
1117 qdivr_u(r0, r1, r2, rn(t0));
1118 jit_unget_reg(t0);
1119}
1120
1121static void
1122_lshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1123{
1124 if (i0 == 0)
1125 movr(r0, r1);
1126 else {
1127 assert(i0 > 0 && i0 < 64);
1128 SLLI(r0, r1, i0);
1129 }
1130}
1131
1132static void
1133_rshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1134{
1135 if (i0 == 0)
1136 movr(r0, r1);
1137 else {
1138 assert(i0 > 0 && i0 < 64);
1139 SRAI(r0, r1, i0);
1140 }
1141}
1142
1143static void
1144_rshi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1145{
1146 if (i0 == 0)
1147 movr(r0, r1);
1148 else {
1149 assert(i0 > 0 && i0 < 64);
1150 SRLI(r0, r1, i0);
1151 }
1152}
1153
1154static void
1155_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1156{
1157 if (simm12_p(i0))
1158 ANDI(r0, r1, i0);
1159 else {
1160 jit_int32_t t0;
1161 t0 = jit_get_reg(jit_class_gpr);
1162 movi(rn(t0), i0);
1163 andr(r0, r1, rn(t0));
1164 jit_unget_reg(t0);
1165 }
1166}
1167
1168static void
1169_ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1170{
1171 if (simm12_p(i0))
1172 ORI(r0, r1, i0);
1173 else {
1174 jit_int32_t t0;
1175 t0 = jit_get_reg(jit_class_gpr);
1176 movi(rn(t0), i0);
1177 orr(r0, r1, rn(t0));
1178 jit_unget_reg(t0);
1179 }
1180}
1181
1182static void
1183_xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1184{
1185 if (simm12_p(i0))
1186 XORI(r0, r1, i0);
1187 else {
1188 jit_int32_t t0;
1189 t0 = jit_get_reg(jit_class_gpr);
1190 movi(rn(t0), i0);
1191 xorr(r0, r1, rn(t0));
1192 jit_unget_reg(t0);
1193 }
1194}
1195
1196# define DEFLD(T,O) \
1197static void \
1198_ldi_##T(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) \
1199{ \
1200 if (simm12_p(i0)) \
1201 L##O(r0, _ZERO_REGNO, i0); \
1202 else { \
1203 jit_int32_t t0; \
1204 t0 = jit_get_reg(jit_class_gpr); \
1205 movi(rn(t0), i0); \
1206 ldr_##T(r0, rn(t0)); \
1207 jit_unget_reg(t0); \
1208 } \
1209} \
1210 \
1211static void \
1212_ldxr_##T(jit_state_t *_jit,jit_int32_t r0,jit_int32_t r1,jit_int32_t r2)\
1213{ \
1214 jit_int32_t t0; \
1215 t0 = jit_get_reg(jit_class_gpr); \
1216 addr(rn(t0), r1, r2); \
1217 ldr_##T(r0, rn(t0)); \
1218 jit_unget_reg(t0); \
1219} \
1220 \
1221static void \
1222_ldxi_##T(jit_state_t *_jit,jit_int32_t r0,jit_int32_t r1,jit_word_t i0)\
1223{ \
1224 if (simm12_p(i0)) \
1225 L##O(r0, r1, i0); \
1226 else { \
1227 jit_int32_t t0; \
1228 t0 = jit_get_reg(jit_class_gpr); \
1229 addi(rn(t0), r1, i0); \
1230 ldr_##T(r0, rn(t0)); \
1231 jit_unget_reg(t0); \
1232 } \
1233}
1234
1235DEFLD(c,B)
1236DEFLD(uc,BU)
1237DEFLD(s,H)
1238DEFLD(us,HU)
1239DEFLD(i,W)
1240DEFLD(ui,WU)
1241DEFLD(l,D)
1242
ba86ff93
PC
1243static void
1244_unldr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1245{
1246 if (jit_unaligned_p())
1247 fallback_unldr(r0, r1, i0);
1248 else
1249 generic_unldr(r0, r1, i0);
1250}
1251
1252static void
1253_unldi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0, jit_word_t i1)
1254{
1255 jit_int32_t t0, r2;
1256 if (jit_unaligned_p())
1257 fallback_unldi(r0, i0, i1);
1258 else
1259 generic_unldi(r0, i0, i1);
1260}
1261
1262static void
1263_unldr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1264{
1265 if (jit_unaligned_p())
1266 fallback_unldr_u(r0, r1, i0);
1267 else
1268 generic_unldr_u(r0, r1, i0);
1269}
1270
1271static void
1272_unldi_u(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0, jit_word_t i1)
1273{
1274 jit_int32_t t0, r2;
1275 if (jit_unaligned_p())
1276 fallback_unldi_u(r0, i0, i1);
1277 else
1278 generic_unldi_u(r0, i0, i1);
1279}
1280
4a71579b
PC
1281# define DEFST(T, O) \
1282static void \
1283_sti_##T(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) \
1284{ \
1285 if (simm12_p(i0)) \
1286 S##O(_ZERO_REGNO, r0, i0); \
1287 else { \
1288 jit_int32_t t0; \
1289 t0 = jit_get_reg(jit_class_gpr); \
1290 movi(rn(t0), i0); \
1291 str_##T(rn(t0), r0); \
1292 jit_unget_reg(t0); \
1293 } \
1294} \
1295 \
1296static void \
1297_stxr_##T(jit_state_t *_jit,jit_int32_t r0,jit_int32_t r1,jit_int32_t r2)\
1298{ \
1299 jit_int32_t t0; \
1300 t0 = jit_get_reg(jit_class_gpr); \
1301 addr(rn(t0), r0, r1); \
1302 str_##T(rn(t0), r2); \
1303 jit_unget_reg(t0); \
1304} \
1305 \
1306static void \
1307_stxi_##T(jit_state_t *_jit,jit_word_t i0,jit_int32_t r0,jit_int32_t r1)\
1308{ \
1309 if (simm12_p(i0)) \
1310 S##O(r0, r1, i0); \
1311 else { \
1312 jit_int32_t t0; \
1313 t0 = jit_get_reg(jit_class_gpr); \
1314 addi(rn(t0), r0, i0); \
1315 str_##T(rn(t0), r1); \
1316 jit_unget_reg(t0); \
1317 } \
1318}
1319
1320DEFST(c, B)
1321DEFST(s, H)
1322DEFST(i, W)
1323DEFST(l, D)
1324
ba86ff93
PC
1325static void
1326_unstr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1327{
1328 if (jit_unaligned_p())
1329 fallback_unstr(r0, r1, i0);
1330 else
1331 generic_unstr(r0, r1, i0);
1332}
1333
1334static void
1335_unsti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
1336{
1337 if (jit_unaligned_p())
1338 fallback_unsti(i0, r0, i1);
1339 else
1340 generic_unsti(i0, r0, i1);
1341}
1342
4a71579b
PC
1343static void
1344_extr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1345{
1346 lshi(r0, r1, 56);
1347 rshi(r0, r0, 56);
1348}
1349
1350static void
1351_extr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1352{
1353 lshi(r0, r1, 48);
1354 rshi(r0, r0, 48);
1355}
1356
1357static void
1358_extr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1359{
1360 lshi(r0, r1, 48);
1361 rshi_u(r0, r0, 48);
1362}
1363
1364static void
1365_extr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1366{
1367 lshi(r0, r1, 32);
1368 rshi_u(r0, r0, 32);
1369}
1370
1371static void
1372_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1373{
c0c16242 1374# if __WORDSIZE == 64
4a71579b 1375 if (simm32_p(i0)) {
c0c16242 1376# endif
4a71579b
PC
1377 jit_int32_t lo = (jit_int32_t)i0 << 20 >> 20;
1378 jit_int32_t hi = i0 - lo;
1379 if (hi) {
1380 LUI(r0, hi >> 12);
1381 if (lo)
1382 ADDIW(r0, r0, lo);
1383 }
1384 else
1385 ADDIW(r0, _ZERO_REGNO, lo);
c0c16242 1386# if __WORDSIZE == 64
4a71579b 1387 }
c0c16242
PC
1388 else
1389 load_const(r0, i0);
1390# endif
4a71579b
PC
1391}
1392
1393static jit_word_t
1394_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1395{
1396 jit_word_t w;
4a71579b 1397 w = _jit->pc.w;
c0c16242
PC
1398# if __WORDSIZE == 64
1399 AUIPC(r0, 0);
1400 ADDI(r0, r0, 0);
1401 LD(r0, r0, 0);
1402# else
1403 LUI(r0, 0);
1404 ADDIW(r0, r0, 0);
1405# endif
4a71579b
PC
1406 return (w);
1407}
1408
40a44dcb
PC
1409static void
1410_movnr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1411{
1412 jit_word_t w;
1413 w = beqi(_jit->pc.w, r2, 0);
c0c16242 1414 movr(r0, r1);
40a44dcb
PC
1415 patch_at(w, _jit->pc.w);
1416}
1417
1418static void
1419_movzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1420{
1421 jit_word_t w;
1422 w = bnei(_jit->pc.w, r2, 0);
c0c16242 1423 movr(r0, r1);
40a44dcb
PC
1424 patch_at(w, _jit->pc.w);
1425}
1426
ba3814c1
PC
1427static void
1428_casx(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
1429 jit_int32_t r2, jit_int32_t r3, jit_word_t i0)
1430{
c0c16242
PC
1431 jit_int32_t t0, r1_reg, iscasi;
1432 jit_word_t retry, done, jump0, jump1;
1433 if ((iscasi = (r1 == _NOREG))) {
1434 r1_reg = jit_get_reg(jit_class_gpr);
1435 r1 = rn(r1_reg);
1436 movi(r1, i0);
1437 }
1438 t0 = jit_get_reg(jit_class_gpr);
1439 retry = _jit->pc.w;
1440# if __WORDSIZE == 32
1441 LR_W(r0, r1);
1442# else
1443 LR_D(r0, r1);
1444# endif
1445 jump0 = _jit->pc.w;
1446 BNE(r0, r2, 0);
1447# if __WORDSIZE == 32
1448 SC_W(rn(t0), r1, r3);
1449# else
1450 SC_D(rn(t0), r1, r3);
1451# endif
1452 jump1 = _jit->pc.w;
1453 BNE(rn(t0), _ZERO_REGNO, 0);
1454 done = _jit->pc.w;
1455 eqr(r0, r0, r2);
1456 patch_at(jump0, done);
1457 patch_at(jump1, retry);
1458 jit_unget_reg(t0);
1459 if (iscasi)
1460 jit_unget_reg(r1_reg);
ba3814c1
PC
1461}
1462
4a71579b
PC
1463static void
1464_lti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1465{
1466 if (simm12_p(i0))
1467 SLTI(r0, r1, i0);
1468 else {
1469 jit_int32_t t0;
1470 t0 = jit_get_reg(jit_class_gpr);
1471 movi(r0, i0);
1472 ltr(r0, r1, rn(t0));
1473 jit_unget_reg(t0);
1474 }
1475}
1476
1477static void
1478_lti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1479{
1480 if (simm12_p(i0))
1481 SLTIU(r0, r1, i0);
1482 else {
1483 jit_int32_t t0;
1484 t0 = jit_get_reg(jit_class_gpr);
1485 movi(r0, i0);
1486 ltr_u(r0, r1, rn(t0));
1487 jit_unget_reg(t0);
1488 }
1489}
1490
1491static void
1492_ler(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1493{
1494 SLT(r0, r2, r1);
1495 XORI(r0, r0, 1);
1496}
1497
1498static void
1499_lei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1500{
1501 jit_int32_t t0;
1502 if (i0 == 0) {
1503 SLT(r0, _ZERO_REGNO, r1);
1504 XORI(r0, r0, 1);
1505 }
1506 else {
1507 t0 = jit_get_reg(jit_class_gpr);
1508 movi(rn(t0), i0);
1509 ler(r0, r1, rn(t0));
1510 jit_unget_reg(t0);
1511 }
1512}
1513
1514static void
1515_ler_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1516{
1517 SLTU(r0, r2, r1);
1518 XORI(r0, r0, 1);
1519}
1520
1521static void
1522_lei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1523{
1524 jit_int32_t t0;
1525 if (i0 == 0) {
1526 SLTU(r0, _ZERO_REGNO, r1);
1527 XORI(r0, r0, 1);
1528 }
1529 else {
1530 t0 = jit_get_reg(jit_class_gpr);
1531 movi(rn(t0), i0);
1532 ler_u(r0, r1, rn(t0));
1533 jit_unget_reg(t0);
1534 }
1535}
1536
1537static void
1538_eqr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1539{
1540 subr(r0, r1, r2);
1541 SLTU(r0, _ZERO_REGNO, r0);
1542 XORI(r0, r0, 1);
1543}
1544
1545static void
1546_eqi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1547{
1548 if (i0) {
1549 subi(r0, r1, i0);
1550 SLTU(r0, _ZERO_REGNO, r0);
1551 }
1552 else
1553 SLTU(r0, _ZERO_REGNO, r1);
1554 XORI(r0, r0, 1);
1555}
1556
1557static void
1558_ger(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1559{
1560 SLT(r0, r1, r2);
1561 XORI(r0, r0, 1);
1562}
1563
1564static void
1565_gei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1566{
1567 jit_int32_t t0;
1568 t0 = jit_get_reg(jit_class_gpr);
1569 movi(rn(t0), i0);
1570 ger(r0, r1, rn(t0));
1571 jit_unget_reg(t0);
1572}
1573
1574static void
1575_ger_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1576{
1577 SLTU(r0, r1, r2);
1578 XORI(r0, r0, 1);
1579}
1580
1581static void
1582_gei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1583{
1584 jit_int32_t t0;
1585 t0 = jit_get_reg(jit_class_gpr);
1586 movi(rn(t0), i0);
1587 ger_u(r0, r1, rn(t0));
1588 jit_unget_reg(t0);
1589}
1590
1591static void
1592_gti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1593{
1594 jit_int32_t t0;
1595 t0 = jit_get_reg(jit_class_gpr);
1596 movi(r0, i0);
1597 ltr(r0, rn(t0), r1);
1598 jit_unget_reg(t0);
1599}
1600
1601static void
1602_gti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1603{
1604 jit_int32_t t0;
1605 t0 = jit_get_reg(jit_class_gpr);
1606 movi(r0, i0);
1607 ltr_u(r0, rn(t0), r1);
1608 jit_unget_reg(t0);
1609}
1610
1611static void
1612_ner(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1613{
1614 subr(r0, r1, r2);
1615 SLTU(r0, _ZERO_REGNO, r0);
1616}
1617
1618static void
1619_nei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1620{
1621 if (i0) {
1622 subi(r0, r1, i0);
1623 SLTU(r0, _ZERO_REGNO, r0);
1624 }
1625 else
1626 SLTU(r0, _ZERO_REGNO, r1);
1627}
1628
1629static jit_word_t
1630_bltr(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1)
1631{
1632 jit_word_t w;
1633 w = _jit->pc.w;
1634 BLT(r0, r1, br - w);
1635 return (w);
1636}
1637
1638static jit_word_t
1639_blti(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0)
1640{
1641 jit_word_t w;
1642 jit_reg_t t0;
1643 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1644 movi(rn(t0), i0);
1645 w = bltr(br, r0, rn(t0));
1646 jit_unget_reg(t0);
1647 return (w);
1648}
1649
1650static jit_word_t
1651_bltr_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1)
1652{
1653 jit_word_t w;
1654 w = _jit->pc.w;
1655 BLTU(r0, r1, br - w);
1656 return (w);
1657}
1658
1659static jit_word_t
1660_blti_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0)
1661{
1662 jit_word_t w;
1663 jit_reg_t t0;
1664 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1665 movi(rn(t0), i0);
1666 w = bltr_u(br, r0, rn(t0));
1667 jit_unget_reg(t0);
1668 return (w);
1669}
1670
1671static jit_word_t
1672_bler(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1)
1673{
1674 jit_word_t w;
1675 w = _jit->pc.w;
1676 BGE(r1, r0, br - w);
1677 return (w);
1678}
1679
1680static jit_word_t
1681_blei(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0)
1682{
1683 jit_word_t w;
1684 jit_reg_t t0;
1685 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1686 movi(rn(t0), i0);
1687 w = bler(br, r0, rn(t0));
1688 jit_unget_reg(t0);
1689 return (w);
1690}
1691
1692static jit_word_t
1693_bler_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1)
1694{
1695 jit_word_t w;
1696 w = _jit->pc.w;
1697 BGEU(r1, r0, br - w);
1698 return (w);
1699}
1700
1701static jit_word_t
1702_blei_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0)
1703{
1704 jit_word_t w;
1705 jit_reg_t t0;
1706 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1707 movi(rn(t0), i0);
1708 w = bler_u(br, r0, rn(t0));
1709 jit_unget_reg(t0);
1710 return (w);
1711}
1712
1713static jit_word_t
1714_beqr(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1)
1715{
1716 jit_word_t w;
1717 w = _jit->pc.w;
1718 BEQ(r1, r0, br - w);
1719 return (w);
1720}
1721
1722static jit_word_t
1723_beqi(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0)
1724{
1725 jit_word_t w;
1726 jit_reg_t t0;
1727 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1728 movi(rn(t0), i0);
1729 w = beqr(br, r0, rn(t0));
1730 jit_unget_reg(t0);
1731 return (w);
1732}
1733
1734static jit_word_t
1735_bger(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1)
1736{
1737 jit_word_t w;
1738 w = _jit->pc.w;
1739 BGE(r0, r1, br - w);
1740 return (w);
1741}
1742
1743static jit_word_t
1744_bgei(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0)
1745{
1746 jit_word_t w;
1747 jit_reg_t t0;
1748 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1749 movi(rn(t0), i0);
1750 w = bger(br, r0, rn(t0));
1751 jit_unget_reg(t0);
1752 return (w);
1753}
1754
1755static jit_word_t
1756_bger_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1)
1757{
1758 jit_word_t w;
1759 w = _jit->pc.w;
1760 BGEU(r0, r1, br - w);
1761 return (w);
1762}
1763
1764static jit_word_t
1765_bgei_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0)
1766{
1767 jit_word_t w;
1768 jit_reg_t t0;
1769 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1770 movi(rn(t0), i0);
1771 w = bger_u(br, r0, rn(t0));
1772 jit_unget_reg(t0);
1773 return (w);
1774}
1775
1776static jit_word_t
1777_bgtr(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1)
1778{
1779 jit_word_t w;
1780 w = _jit->pc.w;
1781 BLT(r1, r0, br - w);
1782 return (w);
1783}
1784
1785static jit_word_t
1786_bgti(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0)
1787{
1788 jit_word_t w;
1789 jit_reg_t t0;
1790 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1791 movi(rn(t0), i0);
1792 w = bgtr(br, r0, rn(t0));
1793 jit_unget_reg(t0);
1794 return (w);
1795}
1796
1797static jit_word_t
1798_bgtr_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1)
1799{
1800 jit_word_t w;
1801 w = _jit->pc.w;
1802 BLTU(r1, r0, br - w);
1803 return (w);
1804}
1805
1806static jit_word_t
1807_bgti_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0)
1808{
1809 jit_word_t w;
1810 jit_reg_t t0;
1811 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1812 movi(rn(t0), i0);
1813 w = bgtr_u(br, r0, rn(t0));
1814 jit_unget_reg(t0);
1815 return (w);
1816}
1817
1818static jit_word_t
1819_bner(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1)
1820{
1821 jit_word_t w;
1822 w = _jit->pc.w;
1823 BNE(r1, r0, br - w);
1824 return (w);
1825}
1826
1827static jit_word_t
1828_bnei(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0)
1829{
1830 jit_word_t w;
1831 jit_reg_t t0;
1832 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1833 movi(rn(t0), i0);
1834 w = bner(br, r0, rn(t0));
1835 jit_unget_reg(t0);
1836 return (w);
1837}
1838
1839static jit_word_t
1840_boaddr(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1)
1841{
1842 jit_word_t w, jal;
1843 jit_int32_t t0, t1;
1844 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1845 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1846 /* t0 = r1 < 0; */
1847 SLT(rn(t0), r1, _ZERO_REGNO);
1848 /* t1 = r0 */
1849 movr(rn(t1), r0);
1850 /* r0 = r0 + r1 */
1851 addr(r0, r0, r1);
1852 /* overflow = r1 < 0 ? t1 < r0 : r0 < t1 */
1853 w = _jit->pc.w;
1854 BNE(rn(t0), _ZERO_REGNO, 0);
1855 /* r1 >= 0 */
1856 SLT(rn(t1), r0, rn(t1));
1857 jal = _jit->pc.w;
1858 JAL(_ZERO_REGNO, 0);
1859 /* r1 < 0 */
1860 patch_at(w, _jit->pc.w);
1861 SLT(rn(t1), rn(t1), r0);
1862 /**/
1863 patch_at(jal, _jit->pc.w);
1864 w = _jit->pc.w;
1865 BNE(rn(t1), _ZERO_REGNO, br - w);
1866 jit_unget_reg(t1);
1867 jit_unget_reg(t0);
1868 return (w);
1869}
1870
1871static jit_word_t
1872_boaddi(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0)
1873{
1874 jit_word_t w;
1875 jit_int32_t t0;
1876 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1877 movi(rn(t0), i0);
1878 w = boaddr(br, r0, rn(t0));
1879 jit_unget_reg(t0);
1880 return (w);
1881}
1882
1883static jit_word_t
1884_boaddr_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1)
1885{
1886 jit_word_t w;
1887 jit_int32_t t0, t1;
1888 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1889 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1890 addr(rn(t0), r0, r1);
1891 SLTU(rn(t1), rn(t0), r0);
1892 movr(r0, rn(t0));
1893 w = _jit->pc.w;
1894 BNE(_ZERO_REGNO, rn(t1), br - w);
1895 jit_unget_reg(t1);
1896 jit_unget_reg(t0);
1897 return (w);
1898}
1899
1900static jit_word_t
1901_boaddi_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0)
1902{
1903 jit_word_t w;
1904 jit_int32_t t0;
1905 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1906 movi(rn(t0), i0);
1907 w = boaddr_u(br, r0, rn(t0));
1908 jit_unget_reg(t0);
1909 return (w);
1910}
1911
1912static jit_word_t
1913_bxaddr(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1)
1914{
1915 jit_word_t w, jal;
1916 jit_int32_t t0, t1;
1917 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1918 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1919 /* t0 = r1 < 0; */
1920 SLT(rn(t0), r1, _ZERO_REGNO);
1921 /* t1 = r0 */
1922 movr(rn(t1), r0);
1923 /* r0 = r0 + r1 */
1924 addr(r0, r0, r1);
1925 /* overflow = r1 < 0 ? t1 < r0 : r0 < t1 */
1926 w = _jit->pc.w;
1927 BNE(rn(t0), _ZERO_REGNO, 0);
1928 /* r1 >= 0 */
1929 SLT(rn(t1), r0, rn(t1));
1930 jal = _jit->pc.w;
1931 JAL(_ZERO_REGNO, 0);
1932 /* r1 < 0 */
1933 patch_at(w, _jit->pc.w);
1934 SLT(rn(t1), rn(t1), r0);
1935 /**/
1936 patch_at(jal, _jit->pc.w);
1937 w = _jit->pc.w;
1938 BEQ(rn(t1), _ZERO_REGNO, br - w);
1939 jit_unget_reg(t1);
1940 jit_unget_reg(t0);
1941 return (w);
1942}
1943
1944static jit_word_t
1945_bxaddi(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0)
1946{
1947 jit_word_t w;
1948 jit_int32_t t0;
1949 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1950 movi(rn(t0), i0);
1951 w = bxaddr(br, r0, rn(t0));
1952 jit_unget_reg(t0);
1953 return (w);
1954}
1955
1956static jit_word_t
1957_bxaddr_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1)
1958{
1959 jit_word_t w;
1960 jit_int32_t t0, t1;
1961 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1962 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1963 addr(rn(t0), r0, r1);
1964 SLTU(rn(t1), rn(t0), r0);
1965 movr(r0, rn(t0));
1966 w = _jit->pc.w;
1967 BEQ(_ZERO_REGNO, rn(t1), br - w);
1968 jit_unget_reg(t1);
1969 jit_unget_reg(t0);
1970 return (w);
1971}
1972
1973static jit_word_t
1974_bxaddi_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0)
1975{
1976 jit_word_t w;
1977 jit_int32_t t0;
1978 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1979 movi(rn(t0), i0);
1980 w = bxaddr_u(br, r0, rn(t0));
1981 jit_unget_reg(t0);
1982 return (w);
1983}
1984
1985static jit_word_t
1986_bosubr(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1)
1987{
1988 jit_word_t w, jal;
1989 jit_int32_t t0, t1;
1990 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1991 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
1992 /* t0 = 0 < r1; */
1993 SLT(rn(t0), _ZERO_REGNO, r1);
1994 /* t1 = r0 */
1995 movr(rn(t1), r0);
1996 /* r0 = r0 - r1 */
1997 subr(r0, r0, r1);
1998 /* overflow = r1 < 0 ? t1 < r0 : r0 < t1 */
1999 w = _jit->pc.w;
2000 BNE(rn(t0), _ZERO_REGNO, 0);
2001 /* r1 >= 0 */
2002 SLT(rn(t1), r0, rn(t1));
2003 jal = _jit->pc.w;
2004 JAL(_ZERO_REGNO, 0);
2005 /* r1 < 0 */
2006 patch_at(w, _jit->pc.w);
2007 SLT(rn(t1), rn(t1), r0);
2008 /**/
2009 patch_at(jal, _jit->pc.w);
2010 w = _jit->pc.w;
2011 BNE(rn(t1), _ZERO_REGNO, br - w);
2012 jit_unget_reg(t1);
2013 jit_unget_reg(t0);
2014 return (w);
2015}
2016
2017static jit_word_t
2018_bosubi(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0)
2019{
2020 jit_word_t w;
2021 jit_int32_t t0;
2022 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
2023 movi(rn(t0), i0);
2024 w = bosubr(br, r0, rn(t0));
2025 jit_unget_reg(t0);
2026 return (w);
2027}
2028
2029static jit_word_t
2030_bosubr_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1)
2031{
2032 jit_word_t w;
2033 jit_int32_t t0, t1;
2034 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
2035 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
2036 subr(rn(t0), r0, r1);
2037 SLTU(rn(t1), r0, rn(t0));
2038 movr(r0, rn(t0));
2039 w = _jit->pc.w;
2040 BNE(_ZERO_REGNO, rn(t1), br - w);
2041 jit_unget_reg(t1);
2042 jit_unget_reg(t0);
2043 return (w);
2044}
2045
2046static jit_word_t
2047_bosubi_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0)
2048{
2049 jit_word_t w;
2050 jit_int32_t t0;
2051 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
2052 movi(rn(t0), i0);
2053 w = bosubr_u(br, r0, rn(t0));
2054 jit_unget_reg(t0);
2055 return (w);
2056}
2057
2058static jit_word_t
2059_bxsubr(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1)
2060{
2061 jit_word_t w, jal;
2062 jit_int32_t t0, t1;
2063 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
2064 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
2065 /* t0 = r1 < 0; */
2066 SLT(rn(t0), _ZERO_REGNO, r1);
2067 /* t1 = r0 */
2068 movr(rn(t1), r0);
2069 /* r0 = r0 - r1 */
2070 subr(r0, r0, r1);
2071 /* overflow = r1 < 0 ? t1 < r0 : r0 < t1 */
2072 w = _jit->pc.w;
2073 BNE(rn(t0), _ZERO_REGNO, 0);
2074 /* r1 >= 0 */
2075 SLT(rn(t1), r0, rn(t1));
2076 jal = _jit->pc.w;
2077 JAL(_ZERO_REGNO, 0);
2078 /* r1 < 0 */
2079 patch_at(w, _jit->pc.w);
2080 SLT(rn(t1), rn(t1), r0);
2081 /**/
2082 patch_at(jal, _jit->pc.w);
2083 w = _jit->pc.w;
2084 BEQ(rn(t1), _ZERO_REGNO, br - w);
2085 jit_unget_reg(t1);
2086 jit_unget_reg(t0);
2087 return (w);
2088}
2089
2090static jit_word_t
2091_bxsubi(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0)
2092{
2093 jit_word_t w;
2094 jit_int32_t t0;
2095 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
2096 movi(rn(t0), i0);
2097 w = bxsubr(br, r0, rn(t0));
2098 jit_unget_reg(t0);
2099 return (w);
2100}
2101
2102static jit_word_t
2103_bxsubr_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1)
2104{
2105 jit_word_t w;
2106 jit_int32_t t0, t1;
2107 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
2108 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
2109 subr(rn(t0), r0, r1);
2110 SLTU(rn(t1), r0, rn(t0));
2111 movr(r0, rn(t0));
2112 w = _jit->pc.w;
2113 BEQ(_ZERO_REGNO, rn(t1), br - w);
2114 jit_unget_reg(t1);
2115 jit_unget_reg(t0);
2116 return (w);
2117}
2118
2119static jit_word_t
2120_bxsubi_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0)
2121{
2122 jit_word_t w;
2123 jit_int32_t t0;
2124 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
2125 movi(rn(t0), i0);
2126 w = bxsubr_u(br, r0, rn(t0));
2127 jit_unget_reg(t0);
2128 return (w);
2129}
2130
2131static jit_word_t
2132_bmsr(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1)
2133{
2134 jit_word_t w;
2135 jit_int32_t t0;
2136 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
2137 AND(rn(t0), r0, r1);
2138 w = _jit->pc.w;
2139 BNE(_ZERO_REGNO, rn(t0), br - w);
2140 jit_unget_reg(t0);
2141 return (w);
2142}
2143
2144static jit_word_t
2145_bmsi(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0)
2146{
2147 jit_word_t w;
2148 jit_int32_t t0;
2149 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
2150 movi(rn(t0), i0);
2151 w = bmsr(br, r0, rn(t0));
2152 jit_unget_reg(t0);
2153 return (w);
2154}
2155
2156static jit_word_t
2157_bmcr(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1)
2158{
2159 jit_word_t w;
2160 jit_int32_t t0;
2161 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
2162 AND(rn(t0), r0, r1);
2163 w = _jit->pc.w;
2164 BEQ(_ZERO_REGNO, rn(t0), br - w);
2165 jit_unget_reg(t0);
2166 return (w);
2167}
2168
2169static jit_word_t
2170_bmci(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0)
2171{
2172 jit_word_t w;
2173 jit_int32_t t0;
2174 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
2175 movi(rn(t0), i0);
2176 w = bmcr(br, r0, rn(t0));
2177 jit_unget_reg(t0);
2178 return (w);
2179}
2180
79bfeef6 2181static jit_word_t
4a71579b
PC
2182_jmpi(jit_state_t *_jit, jit_word_t i0)
2183{
2184 jit_int32_t t0;
79bfeef6
PC
2185 jit_word_t dsp, w;
2186 w = _jit->pc.w;
2187 dsp = i0 - w;
4a71579b
PC
2188 if (simm20_p(dsp))
2189 JAL(_ZERO_REGNO, dsp);
2190 else {
2191 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
2192 movi(rn(t0), i0);
2193 jmpr(rn(t0));
2194 jit_unget_reg(t0);
2195 }
79bfeef6 2196 return (w);
4a71579b
PC
2197}
2198
2199static jit_word_t
2200_jmpi_p(jit_state_t *_jit, jit_word_t i0)
2201{
2202 jit_word_t w;
2203 jit_int32_t t0;
2204 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
2205 w = movi_p(rn(t0), i0);
2206 jmpr(rn(t0));
2207 jit_unget_reg(t0);
2208 return (w);
2209}
2210
79bfeef6 2211static jit_word_t
4a71579b
PC
2212_calli(jit_state_t *_jit, jit_word_t i0)
2213{
2214 jit_int32_t t0;
79bfeef6
PC
2215 jit_word_t dsp, w;
2216 w = _jit->pc.w;
2217 dsp = i0 - w;
4a71579b
PC
2218 if (simm20_p(dsp))
2219 JAL(_RA_REGNO, dsp);
2220 else {
2221 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
2222 movi(rn(t0), i0);
2223 callr(rn(t0));
2224 jit_unget_reg(t0);
2225 }
79bfeef6 2226 return (w);
4a71579b
PC
2227}
2228
2229static jit_word_t
2230_calli_p(jit_state_t *_jit, jit_word_t i0)
2231{
2232 jit_word_t w;
2233 jit_int32_t t0;
2234 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
2235 w = movi_p(rn(t0), i0);
2236 callr(rn(t0));
2237 jit_unget_reg(t0);
2238 return (w);
2239}
2240
2241static void
2242_prolog(jit_state_t *_jit, jit_node_t *node)
2243{
79bfeef6 2244 jit_int32_t reg, offs;
4a71579b
PC
2245 if (_jitc->function->define_frame || _jitc->function->assume_frame) {
2246 jit_int32_t frame = -_jitc->function->frame;
79bfeef6 2247 jit_check_frame();
4a71579b
PC
2248 assert(_jitc->function->self.aoff >= frame);
2249 if (_jitc->function->assume_frame)
2250 return;
2251 _jitc->function->self.aoff = frame;
2252 }
2253 if (_jitc->function->allocar)
2254 _jitc->function->self.aoff &= -16;
2255 _jitc->function->stack = ((_jitc->function->self.alen -
2256 /* align stack at 16 bytes */
2257 _jitc->function->self.aoff) + 15) & -16;
79bfeef6
PC
2258
2259 if (_jitc->function->stack)
2260 _jitc->function->need_stack = 1;
2261 if (!_jitc->function->need_frame && !_jitc->function->need_stack) {
2262 /* check if any callee save register needs to be saved */
2263 for (reg = 0; reg < _jitc->reglen; ++reg)
2264 if (jit_regset_tstbit(&_jitc->function->regset, reg) &&
2265 (_rvs[reg].spec & jit_class_sav)) {
2266 _jitc->function->need_stack = 1;
2267 break;
2268 }
2269 }
2270
2271 if (_jitc->function->need_frame || _jitc->function->need_stack)
2272 subi(_SP_REGNO, _SP_REGNO, jit_framesize());
2273 if (_jitc->function->need_frame) {
2274 stxi(0, _SP_REGNO, _RA_REGNO);
2275 stxi(8, _SP_REGNO, _FP_REGNO);
2276 }
2277 /* callee save registers */
2278 for (reg = 0, offs = 16; reg < jit_size(iregs); reg++) {
2279 if (jit_regset_tstbit(&_jitc->function->regset, iregs[reg])) {
2280 stxi(offs, _SP_REGNO, rn(iregs[reg]));
2281 offs += sizeof(jit_word_t);
2282 }
2283 }
2284 for (reg = 0; reg < jit_size(fregs); reg++) {
2285 if (jit_regset_tstbit(&_jitc->function->regset, fregs[reg])) {
2286 stxi_d(offs, _SP_REGNO, rn(fregs[reg]));
2287 offs += sizeof(jit_float64_t);
2288 }
2289 }
2290
2291 if (_jitc->function->need_frame)
2292 movr(_FP_REGNO, _SP_REGNO);
4a71579b
PC
2293 if (_jitc->function->stack)
2294 subi(_SP_REGNO, _SP_REGNO, _jitc->function->stack);
2295 if (_jitc->function->allocar) {
2296 reg = jit_get_reg(jit_class_gpr);
2297 movi(rn(reg), _jitc->function->self.aoff);
2298 stxi_i(_jitc->function->aoffoff, _FP_REGNO, rn(reg));
2299 jit_unget_reg(reg);
2300 }
2301 if (_jitc->function->self.call & jit_call_varargs) {
2302 for (reg = _jitc->function->vagp; jit_arg_reg_p(reg); ++reg)
79bfeef6 2303 stxi(jit_framesize() - ((8 - reg) * 8),
4a71579b
PC
2304 _FP_REGNO, rn(JIT_RA0 - reg));
2305 }
2306}
2307
2308static void
2309_epilog(jit_state_t *_jit, jit_node_t *node)
2310{
79bfeef6 2311 jit_int32_t reg, offs;
4a71579b
PC
2312 if (_jitc->function->assume_frame)
2313 return;
79bfeef6
PC
2314 if (_jitc->function->need_frame) {
2315 movr(_SP_REGNO, _FP_REGNO);
2316 ldxi(_RA_REGNO, _SP_REGNO, 0);
2317 ldxi(_FP_REGNO, _SP_REGNO, 8);
2318 }
2319
2320 /* callee save registers */
2321 for (reg = 0, offs = 16; reg < jit_size(iregs); reg++) {
2322 if (jit_regset_tstbit(&_jitc->function->regset, iregs[reg])) {
2323 ldxi(rn(iregs[reg]), _SP_REGNO, offs);
2324 offs += sizeof(jit_word_t);
2325 }
2326 }
2327 for (reg = 0; reg < jit_size(fregs); reg++) {
2328 if (jit_regset_tstbit(&_jitc->function->regset, fregs[reg])) {
2329 ldxi_d(rn(fregs[reg]), _SP_REGNO, offs);
2330 offs += sizeof(jit_float64_t);
2331 }
2332 }
2333
2334 if (_jitc->function->need_frame || _jitc->function->need_stack)
2335 addi(_SP_REGNO, _SP_REGNO, jit_framesize());
4a71579b
PC
2336 RET();
2337}
2338
2339static void
2340_vastart(jit_state_t *_jit, jit_int32_t r0)
2341{
2342 assert(_jitc->function->self.call & jit_call_varargs);
2343 /* Initialize va_list to the first stack argument. */
2344 if (jit_arg_reg_p(_jitc->function->vagp))
79bfeef6 2345 addi(r0, _FP_REGNO, jit_framesize() - ((8 - _jitc->function->vagp) * 8));
4a71579b 2346 else
79bfeef6 2347 addi(r0, _FP_REGNO, jit_selfsize());
4a71579b
PC
2348}
2349
2350static void
2351_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
2352{
2353 assert(_jitc->function->self.call & jit_call_varargs);
2354 /* Load argument. */
2355 ldr(r0, r1);
2356 /* Update va_list. */
2357 addi(r1, r1, sizeof(jit_word_t));
2358}
2359
2360static void
2361_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label)
2362{
2363 instr_t i;
2364 union {
2365 jit_int32_t *i;
2366 jit_word_t w;
2367 } u;
2368 u.w = instr;
2369 i.w = u.i[0];
2370 /* movi_p? */
c0c16242
PC
2371# if __WORDSIZE == 64
2372 if (i.U.opcode == 23) { /* AUIPC */
2373 jit_int32_t lo, hi;
2374 jit_word_t address, relative;
2375 address = get_const(label);
2376 relative = address - instr;
2377 assert(simm32_p(relative));
2378 lo = (jit_int32_t)relative << 20 >> 20;
2379 hi = relative - lo;
2380 i.U.imm12_31 = hi >> 12;
2381 u.i[0] = i.w;
2382 i.w = u.i[1];
2383 if (i.I.opcode == 19 && i.I.funct3 == 0) { /* ADDI */
2384 i.I.imm11_0 = lo;
2385 u.i[1] = i.w;
2386 i.w = u.i[2];
2387 }
2388 else
2389 abort();
c0c16242
PC
2390 assert(i.I.opcode == 3 && i.I.funct3 == 3); /* LD */
2391 }
2392# else
4a71579b 2393 if (i.U.opcode == 55) { /* LUI */
c0c16242
PC
2394 jit_int32_t lo = (jit_int32_t)label << 20 >> 20;
2395 jit_int32_t hi = label - lo;
4a71579b
PC
2396 i.U.imm12_31 = hi >> 12;
2397 u.i[0] = i.w;
2398 i.w = u.i[1];
2399 if (i.I.opcode == 27 && i.I.funct3 == 0) { /* ADDIW */
c0c16242 2400 i.I.imm11_0 = lo;
4a71579b
PC
2401 u.i[1] = i.w;
2402 i.w = u.i[2];
4a71579b
PC
2403 }
2404 else
2405 abort();
2406 }
c0c16242 2407# endif
4a71579b
PC
2408 /* b{lt,le,eq,ge,gt,ne}{,_u}? */
2409 else if (i.B.opcode == 99) { /* B{EQ,NE,LT,GE,LTU,GEU} */
2410 jit_word_t jmp = label - instr;
2411 assert(simm12_p(jmp));
2412 i.B.imm11 = (jmp >> 11) & 0x1;
2413 i.B.imm4_1 = (jmp >> 1) & 0xf;
2414 i.B.imm10_5 = (jmp >> 5) & 0x3f;
2415 i.B.imm12 = (jmp >> 12) & 0x1;
2416 u.i[0] = i.w;
2417 }
2418 else if (i.J.opcode == 111) { /* JAL */
2419 jit_word_t jmp = label - instr;
2420 i.J.imm19_12 = (jmp >> 12) & 0xff;
2421 i.J.imm11 = (jmp >> 11) & 0x1;
2422 i.J.imm10_1 = (jmp >> 1) & 0x3ff;
2423 i.J.imm20 = (jmp >> 20) & 0x1;
2424 u.i[0] = i.w;
2425 }
2426 else
2427 abort();
2428}
2429#endif /* CODE */