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