git subrepo pull --force deps/lightning
[pcsx_rearmed.git] / deps / lightning / lib / jit_aarch64-cpu.c
CommitLineData
4a71579b
PC
1/*
2 * Copyright (C) 2013-2019 Free Software Foundation, Inc.
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
21typedef union {
22/* aarch64-opc.c */
23# define ui jit_uint32_t
24# if __BYTE_ORDER == __LITTLE_ENDIAN
25 /* cond2: condition in truly conditional-executed inst. */
26 struct { ui b: 4; } cond2;
27 /* nzcv: flag bit specifier, encoded in the "nzcv" field. */
28 struct { ui b: 4; } nzcv;
29 /* defgh: d:e:f:g:h bits in AdvSIMD modified immediate. */
30 struct { ui _: 5; ui b: 5; } defgh;
31 /* abc: a:b:c bits in AdvSIMD modified immediate. */
32 struct { ui _: 16; ui b: 3; } abc;
33 /* imm19: e.g. in CBZ. */
34 struct { ui _: 5; ui b: 19; } imm19;
35 /* immhi: e.g. in ADRP. */
36 struct { ui _: 5; ui b: 19; } immhi;
37 /* immlo: e.g. in ADRP. */
38 struct { ui _: 29; ui b: 2; } immlo;
39 /* size: in most AdvSIMD and floating-point instructions. */
40 struct { ui _: 22; ui b: 2; } size;
41 /* vldst_size: size field in the AdvSIMD load/store inst. */
42 struct { ui _: 10; ui b: 2; } vldst_size;
43 /* op: in AdvSIMD modified immediate instructions. */
44 struct { ui _: 29; ui b: 1; } op;
45 /* Q: in most AdvSIMD instructions. */
46 struct { ui _: 30; ui b: 1; } Q;
47 /* Rt: in load/store instructions. */
48 struct { ui b: 5; } Rt;
49 /* Rd: in many integer instructions. */
50 struct { ui b: 5; } Rd;
51 /* Rn: in many integer instructions. */
52 struct { ui _: 5; ui b: 5; } Rn;
53 /* Rt2: in load/store pair instructions. */
54 struct { ui _: 10; ui b: 5; } Rt2;
55 /* Ra: in fp instructions. */
56 struct { ui _: 10; ui b: 5; } Ra;
57 /* op2: in the system instructions. */
58 struct { ui _: 5; ui b: 3; } op2;
59 /* CRm: in the system instructions. */
60 struct { ui _: 8; ui b: 4; } CRm;
61 /* CRn: in the system instructions. */
62 struct { ui _: 12; ui b: 4; } CRn;
63 /* op1: in the system instructions. */
64 struct { ui _: 16; ui b: 3; } op1;
65 /* op0: in the system instructions. */
66 struct { ui _: 19; ui b: 2; } op0;
67 /* imm3: in add/sub extended reg instructions. */
68 struct { ui _: 10; ui b: 3; } imm3;
69 /* cond: condition flags as a source operand. */
70 struct { ui _: 12; ui b: 4; } cond;
71 /* opcode: in advsimd load/store instructions. */
72 struct { ui _: 12; ui b: 4; } opcode;
73 /* cmode: in advsimd modified immediate instructions. */
74 struct { ui _: 12; ui b: 4; } cmode;
75 /* asisdlso_opcode: opcode in advsimd ld/st single element. */
76 struct { ui _: 13; ui b: 3; } asisdlso_opcode;
77 /* len: in advsimd tbl/tbx instructions. */
78 struct { ui _: 13; ui b: 2; } len;
79 /* Rm: in ld/st reg offset and some integer inst. */
80 struct { ui _: 16; ui b: 5; } Rm;
81 /* Rs: in load/store exclusive instructions. */
82 struct { ui _: 16; ui b: 5; } Rs;
83 /* option: in ld/st reg offset + add/sub extended reg inst. */
84 struct { ui _: 13; ui b: 3; } option;
85 /* S: in load/store reg offset instructions. */
86 struct { ui _: 12; ui b: 1; } S;
87 /* hw: in move wide constant instructions. */
88 struct { ui _: 21; ui b: 2; } hw;
89 /* opc: in load/store reg offset instructions. */
90 struct { ui _: 22; ui b: 2; } opc;
91 /* opc1: in load/store reg offset instructions. */
92 struct { ui _: 23; ui b: 1; } opc1;
93 /* shift: in add/sub reg/imm shifted instructions. */
94 struct { ui _: 22; ui b: 2; } shift;
95 /* type: floating point type field in fp data inst. */
96 struct { ui _: 22; ui b: 2; } type;
97 /* ldst_size: size field in ld/st reg offset inst. */
98 struct { ui _: 30; ui b: 2; } ldst_size;
99 /* imm6: in add/sub reg shifted instructions. */
100 struct { ui _: 10; ui b: 6; } imm6;
101 /* imm4: in advsimd ext and advsimd ins instructions. */
102 struct { ui _: 11; ui b: 4; } imm4;
103 /* imm5: in conditional compare (immediate) instructions. */
104 struct { ui _: 16; ui b: 5; } imm5;
105 /* imm7: in load/store pair pre/post index instructions. */
106 struct { ui _: 15; ui b: 7; } imm7;
107 /* imm8: in floating-point scalar move immediate inst. */
108 struct { ui _: 13; ui b: 8; } imm8;
109 /* imm9: in load/store pre/post index instructions. */
110 struct { ui _: 12; ui b: 9; } imm9;
111 /* imm12: in ld/st unsigned imm or add/sub shifted inst. */
112 struct { ui _: 10; ui b: 12; } imm12;
113 /* imm14: in test bit and branch instructions. */
114 struct { ui _: 5; ui b: 14; } imm14;
115 /* imm16: in exception instructions. */
116 struct { ui _: 5; ui b: 16; } imm16;
117 /* imm26: in unconditional branch instructions. */
118 struct { ui b: 26; } imm26;
119 /* imms: in bitfield and logical immediate instructions. */
120 struct { ui _: 10; ui b: 6; } imms;
121 /* immr: in bitfield and logical immediate instructions. */
122 struct { ui _: 16; ui b: 6; } immr;
123 /* immb: in advsimd shift by immediate instructions. */
124 struct { ui _: 16; ui b: 3; } immb;
125 /* immh: in advsimd shift by immediate instructions. */
126 struct { ui _: 19; ui b: 4; } immh;
127 /* N: in logical (immediate) instructions. */
128 struct { ui _: 22; ui b: 1; } N;
129 /* index: in ld/st inst deciding the pre/post-index. */
130 struct { ui _: 11; ui b: 1; } index;
131 /* index2: in ld/st pair inst deciding the pre/post-index. */
132 struct { ui _: 24; ui b: 1; } index2;
133 /* sf: in integer data processing instructions. */
134 struct { ui _: 31; ui b: 1; } sf;
135 /* H: in advsimd scalar x indexed element instructions. */
136 struct { ui _: 11; ui b: 1; } H;
137 /* L: in advsimd scalar x indexed element instructions. */
138 struct { ui _: 21; ui b: 1; } L;
139 /* M: in advsimd scalar x indexed element instructions. */
140 struct { ui _: 20; ui b: 1; } M;
141 /* b5: in the test bit and branch instructions. */
142 struct { ui _: 31; ui b: 1; } b5;
143 /* b40: in the test bit and branch instructions. */
144 struct { ui _: 19; ui b: 5; } b40;
145 /* scale: in the fixed-point scalar to fp converting inst. */
146 struct { ui _: 10; ui b: 6; } scale;
147# else
148 struct { ui _: 28; ui b: 4; } cond2;
149 struct { ui _: 28; ui b: 4; } nzcv;
150 struct { ui _: 22; ui b: 5; } defgh;
151 struct { ui _: 13; ui b: 3; } abc;
152 struct { ui _: 8; ui b: 19; } imm19;
153 struct { ui _: 8; ui b: 19; } immhi;
154 struct { ui _: 1; ui b: 29; } immlo;
155 struct { ui _: 8; ui b: 2; } size;
156 struct { ui _: 20; ui b: 2; } vldst_size;
157 struct { ui _: 2; ui b: 1; } op;
158 struct { ui _: 1; ui b: 1; } Q;
159 struct { ui _: 27; ui b: 1; } Rt;
160 struct { ui _: 27; ui b: 1; } Rd;
161 struct { ui _: 22; ui b: 5; } Rn;
162 struct { ui _: 17; ui b: 5; } Rt2;
163 struct { ui _: 17; ui b: 5; } Ra;
164 struct { ui _: 24; ui b: 3; } op2;
165 struct { ui _: 20; ui b: 4; } CRm;
166 struct { ui _: 16; ui b: 4; } CRn;
167 struct { ui _: 13; ui b: 3; } op1;
168 struct { ui _: 11; ui b: 2; } op0;
169 struct { ui _: 19; ui b: 3; } imm3;
170 struct { ui _: 16; ui b: 4; } cond;
171 struct { ui _: 16; ui b: 4; } opcode;
172 struct { ui _: 16; ui b: 4; } cmode;
173 struct { ui _: 16; ui b: 3; } asisdlso_opcode;
174 struct { ui _: 17; ui b: 2; } len;
175 struct { ui _: 11; ui b: 5; } Rm;
176 struct { ui _: 11; ui b: 5; } Rs;
177 struct { ui _: 16; ui b: 3; } option;
178 struct { ui _: 19; ui b: 1; } S;
179 struct { ui _: 9; ui b: 2; } hw;
180 struct { ui _: 8; ui b: 2; } opc;
181 struct { ui _: 8; ui b: 1; } opc1;
182 struct { ui _: 8; ui b: 2; } shift;
183 struct { ui _: 8; ui b: 2; } type;
184 struct { ui b: 2; } ldst_size;
185 struct { ui _: 16; ui b: 6; } imm6;
186 struct { ui _: 17; ui b: 4; } imm4;
187 struct { ui _: 11; ui b: 5; } imm5;
188 struct { ui _: 10; ui b: 7; } imm7;
189 struct { ui _: 11; ui b: 8; } imm8;
190 struct { ui _: 11; ui b: 9; } imm9;
191 struct { ui _: 10; ui b: 12; } imm12;
192 struct { ui _: 13; ui b: 14; } imm14;
193 struct { ui _: 11; ui b: 16; } imm16;
194 struct { ui _: 6; ui b: 26; } imm26;
195 struct { ui _: 16; ui b: 6; } imms;
196 struct { ui _: 10; ui b: 6; } immr;
197 struct { ui _: 13; ui b: 3; } immb;
198 struct { ui _: 9; ui b: 4; } immh;
199 struct { ui _: 9; ui b: 1; } N;
200 struct { ui _: 20; ui b: 1; } index;
201 struct { ui _: 7; ui b: 1; } index2;
202 struct { ui b: 1; } sf;
203 struct { ui _: 20; ui b: 1; } H;
204 struct { ui _: 10; ui b: 1; } L;
205 struct { ui _: 11; ui b: 1; } M;
206 struct { ui b: 1; } b5;
207 struct { ui _: 8; ui b: 5; } b40;
208 struct { ui _: 16; ui b: 6; } scale;
209# endif
210 jit_int32_t w;
211# undef ui
212} instr_t;
213# define stack_framesize 160
214# define ii(i) *_jit->pc.ui++ = i
215# define ldr(r0,r1) ldr_l(r0,r1)
216# define ldxr(r0,r1,r2) ldxr_l(r0,r1,r2)
217# define ldxi(r0,r1,i0) ldxi_l(r0,r1,i0)
218# define stxi(i0,r0,r1) stxi_l(i0,r0,r1)
219# define FP_REGNO 0x1d
220# define LR_REGNO 0x1e
221# define SP_REGNO 0x1f
222# define XZR_REGNO 0x1f
223# define WZR_REGNO XZR_REGNO
224# define LSL_12 0x00400000
225# define MOVI_LSL_16 0x00200000
226# define MOVI_LSL_32 0x00400000
227# define MOVI_LSL_48 0x00600000
228# define XS 0x80000000 /* Wn -> Xn */
229# define DS 0x00400000 /* Sn -> Dn */
230# define CC_NE 0x0
231# define CC_EQ 0x1
232# define CC_CC 0x2
233# define CC_LO CC_CC
234# define CC_CS 0x3
235# define CC_HS CC_CS
236# define CC_PL 0x4
237# define CC_MI 0x5
238# define CC_VC 0x6
239# define CC_VS 0x7
240# define CC_LS 0x8
241# define CC_HI 0x9
242# define CC_LT 0xa
243# define CC_GE 0xb
244# define CC_LE 0xc
245# define CC_GT 0xd
246# define CC_NV 0xe
247# define CC_AL 0xf
248/* Branches need inverted condition */
249# define BCC_EQ 0x0
250# define BCC_NE 0x1
251# define BCC_CS 0x2
252# define BCC_HS BCC_CS
253# define BCC_CC 0x3
254# define BCC_LO BCC_CC
255# define BCC_MI 0x4
256# define BCC_PL 0x5
257# define BCC_VS 0x6
258# define BCC_VC 0x7
259# define BCC_HI 0x8
260# define BCC_LS 0x9
261# define BCC_GE 0xa
262# define BCC_LT 0xb
263# define BCC_GT 0xc
264# define BCC_LE 0xd
265# define BCC_AL 0xe
266# define BCC_NV 0xf
267/* adapted and cut down to only tested and required by lightning,
268 * from data in binutils/aarch64-tbl.h */
269# define A64_ADCS 0x3a000000
270# define A64_SBCS 0x7a000000
271# define A64_ADDI 0x11000000
272# define A64_ADDSI 0xb1000000
273# define A64_SUBI 0x51000000
274# define A64_SUBSI 0x71000000
275# define A64_ADD 0x0b000000
276# define A64_ADDS 0x2b000000
277# define A64_SUB 0x4b000000
278# define A64_NEG 0x4b0003e0
279# define A64_SUBS 0x6b000000
280# define A64_CMP 0x6b00001f
281# define A64_SBFM 0x93400000
282# define A64_UBFM 0x53400000
283# define A64_UBFX 0x53000000
284# define A64_B 0x14000000
285# define A64_BL 0x94000000
286# define A64_BR 0xd61f0000
287# define A64_BLR 0xd63f0000
288# define A64_RET 0xd65f0000
289# define A64_CBZ 0x34000000
290# define A64_CBNZ 0x35000000
291# define A64_B_C 0x54000000
292# define A64_CSINC 0x1a800400
e0659411 293# define A64_CSSEL 0x1a800000
4a71579b
PC
294# define A64_REV 0xdac00c00
295# define A64_UDIV 0x1ac00800
296# define A64_SDIV 0x1ac00c00
297# define A64_LSL 0x1ac02000
298# define A64_LSR 0x1ac02400
299# define A64_ASR 0x1ac02800
300# define A64_MUL 0x1b007c00
301# define A64_SMULL 0x9b207c00
302# define A64_SMULH 0x9b407c00
303# define A64_UMULL 0x9ba07c00
304# define A64_UMULH 0x9bc07c00
305# define A64_STRBI 0x39000000
306# define A64_LDRBI 0x39400000
307# define A64_LDRSBI 0x39800000
308# define A64_STRI 0xf9000000
309# define A64_LDRI 0xf9400000
310# define A64_STRHI 0x79000000
311# define A64_LDRHI 0x79400000
312# define A64_LDRSHI 0x79800000
313# define A64_STRWI 0xb9000000
314# define A64_LDRWI 0xb9400000
315# define A64_LDRSWI 0xb9800000
316# define A64_STRB 0x38206800
317# define A64_LDRB 0x38606800
318# define A64_LDRSB 0x38e06800
319# define A64_STR 0xf8206800
320# define A64_LDR 0xf8606800
321# define A64_STRH 0x78206800
322# define A64_LDRH 0x78606800
323# define A64_LDRSH 0x78a06800
324# define A64_STRW 0xb8206800
325# define A64_LDRW 0xb8606800
326# define A64_LDRSW 0xb8a06800
327# define A64_STURB 0x38000000
328# define A64_LDURB 0x38400000
329# define A64_LDURSB 0x38800000
330# define A64_STUR 0xf8000000
331# define A64_LDUR 0xf8400000
332# define A64_STURH 0x78000000
333# define A64_LDURH 0x78400000
334# define A64_LDURSH 0x78800000
335# define A64_STURW 0xb8000000
336# define A64_LDURW 0xb8400000
337# define A64_LDURSW 0xb8800000
338# define A64_STP 0x29000000
339# define A64_LDP 0x29400000
340# define A64_STP_POS 0x29800000
341# define A64_LDP_PRE 0x28c00000
342# define A64_ANDI 0x12400000
343# define A64_ORRI 0x32400000
344# define A64_EORI 0x52400000
345# define A64_ANDSI 0x72000000
346# define A64_AND 0x0a000000
347# define A64_ORR 0x2a000000
348# define A64_MOV 0x2a0003e0 /* AKA orr Rd,xzr,Rm */
349# define A64_MVN 0x2a2003e0
350# define A64_UXTW 0x2a0003e0 /* AKA MOV */
351# define A64_EOR 0x4a000000
352# define A64_ANDS 0x6a000000
353# define A64_MOVN 0x12800000
354# define A64_MOVZ 0x52800000
355# define A64_MOVK 0x72800000
356# define SBFM(Rd,Rn,ImmR,ImmS) oxxrs(A64_SBFM|XS,Rd,Rn,ImmR,ImmS)
357# define UBFM(Rd,Rn,ImmR,ImmS) oxxrs(A64_UBFM|XS,Rd,Rn,ImmR,ImmS)
358# define UBFX(Rd,Rn,ImmR,ImmS) oxxrs(A64_UBFX,Rd,Rn,ImmR,ImmS)
359# define CMP(Rn,Rm) oxx_(A64_CMP|XS,Rn,Rm)
360# define CMPI(Rn,Imm12) oxxi(A64_SUBSI|XS,XZR_REGNO,Rn,Imm12)
361# define CMPI_12(Rn,Imm12) oxxi(A64_SUBSI|XS|LSL_12,XZR_REGNO,Rn,Imm12)
362# define CMNI(Rn,Imm12) oxxi(A64_ADDSI|XS,XZR_REGNO,Rn,Imm12)
363# define CMNI_12(Rn,Imm12) oxxi(A64_ADDSI|XS|LSL_12,XZR_REGNO,Rn,Imm12)
364# define CSINC(Rd,Rn,Rm,Cc) oxxxc(A64_CSINC|XS,Rd,Rn,Rm,Cc)
365# define TST(Rn,Rm) oxxx(A64_ANDS|XS,XZR_REGNO,Rn,Rm)
366/* actually should use oxxrs but logical_immediate returns proper encoding */
367# define TSTI(Rn,Imm12) oxxi(A64_ANDSI,XZR_REGNO,Rn,Imm12)
368# define MOV(Rd,Rm) ox_x(A64_MOV|XS,Rd,Rm)
369# define MVN(Rd,Rm) ox_x(A64_MVN|XS,Rd,Rm)
370# define NEG(Rd,Rm) ox_x(A64_NEG|XS,Rd,Rm)
371# define MOVN(Rd,Imm16) ox_h(A64_MOVN|XS,Rd,Imm16)
372# define MOVN_16(Rd,Imm16) ox_h(A64_MOVN|XS|MOVI_LSL_16,Rd,Imm16)
373# define MOVN_32(Rd,Imm16) ox_h(A64_MOVN|XS|MOVI_LSL_32,Rd,Imm16)
374# define MOVN_48(Rd,Imm16) ox_h(A64_MOVN|XS|MOVI_LSL_48,Rd,Imm16)
375# define MOVZ(Rd,Imm16) ox_h(A64_MOVZ|XS,Rd,Imm16)
376# define MOVZ_16(Rd,Imm16) ox_h(A64_MOVZ|XS|MOVI_LSL_16,Rd,Imm16)
377# define MOVZ_32(Rd,Imm16) ox_h(A64_MOVZ|XS|MOVI_LSL_32,Rd,Imm16)
378# define MOVZ_48(Rd,Imm16) ox_h(A64_MOVZ|XS|MOVI_LSL_48,Rd,Imm16)
379# define MOVK(Rd,Imm16) ox_h(A64_MOVK|XS,Rd,Imm16)
380# define MOVK_16(Rd,Imm16) ox_h(A64_MOVK|XS|MOVI_LSL_16,Rd,Imm16)
381# define MOVK_32(Rd,Imm16) ox_h(A64_MOVK|XS|MOVI_LSL_32,Rd,Imm16)
382# define MOVK_48(Rd,Imm16) ox_h(A64_MOVK|XS|MOVI_LSL_48,Rd,Imm16)
383# define ADD(Rd,Rn,Rm) oxxx(A64_ADD|XS,Rd,Rn,Rm)
384# define ADDI(Rd,Rn,Imm12) oxxi(A64_ADDI|XS,Rd,Rn,Imm12)
385# define ADDI_12(Rd,Rn,Imm12) oxxi(A64_ADDI|XS|LSL_12,Rd,Rn,Imm12)
386# define MOV_XSP(Rd,Rn) ADDI(Rd,Rn,0)
387# define ADDS(Rd,Rn,Rm) oxxx(A64_ADDS|XS,Rd,Rn,Rm)
388# define ADDSI(Rd,Rn,Imm12) oxxi(A64_ADDSI|XS,Rd,Rn,Imm12)
389# define ADDSI_12(Rd,Rn,Imm12) oxxi(A64_ADDSI|XS|LSL_12,Rd,Rn,Imm12)
390# define ADCS(Rd,Rn,Rm) oxxx(A64_ADCS|XS,Rd,Rn,Rm)
391# define SUB(Rd,Rn,Rm) oxxx(A64_SUB|XS,Rd,Rn,Rm)
392# define SUBI(Rd,Rn,Imm12) oxxi(A64_SUBI|XS,Rd,Rn,Imm12)
393# define SUBI_12(Rd,Rn,Imm12) oxxi(A64_SUBI|XS|LSL_12,Rd,Rn,Imm12)
394# define SUBS(Rd,Rn,Rm) oxxx(A64_SUBS|XS,Rd,Rn,Rm)
395# define SUBSI(Rd,Rn,Imm12) oxxi(A64_SUBSI|XS,Rd,Rn,Imm12)
396# define SUBSI_12(Rd,Rn,Imm12) oxxi(A64_SUBSI|XS|LSL_12,Rd,Rn,Imm12)
397# define SBCS(Rd,Rn,Rm) oxxx(A64_SBCS|XS,Rd,Rn,Rm)
398# define MUL(Rd,Rn,Rm) oxxx(A64_MUL|XS,Rd,Rn,Rm)
399# define SMULL(Rd,Rn,Rm) oxxx(A64_SMULL,Rd,Rn,Rm)
400# define SMULH(Rd,Rn,Rm) oxxx(A64_SMULH,Rd,Rn,Rm)
401# define UMULL(Rd,Rn,Rm) oxxx(A64_UMULL,Rd,Rn,Rm)
402# define UMULH(Rd,Rn,Rm) oxxx(A64_UMULH,Rd,Rn,Rm)
403# define SDIV(Rd,Rn,Rm) oxxx(A64_SDIV|XS,Rd,Rn,Rm)
404# define UDIV(Rd,Rn,Rm) oxxx(A64_UDIV|XS,Rd,Rn,Rm)
405# define LSL(Rd,Rn,Rm) oxxx(A64_LSL|XS,Rd,Rn,Rm)
406# define LSLI(r0,r1,i0) UBFM(r0,r1,(64-i0)&63,63-i0)
407# define ASR(Rd,Rn,Rm) oxxx(A64_ASR|XS,Rd,Rn,Rm)
408# define ASRI(r0,r1,i0) SBFM(r0,r1,i0,63)
409# define LSR(Rd,Rn,Rm) oxxx(A64_LSR|XS,Rd,Rn,Rm)
410# define LSRI(r0,r1,i0) UBFM(r0,r1,i0,63)
411# define AND(Rd,Rn,Rm) oxxx(A64_AND|XS,Rd,Rn,Rm)
412/* actually should use oxxrs but logical_immediate returns proper encoding */
413# define ANDI(Rd,Rn,Imm12) oxxi(A64_ANDI|XS,Rd,Rn,Imm12)
414# define ORR(Rd,Rn,Rm) oxxx(A64_ORR|XS,Rd,Rn,Rm)
415/* actually should use oxxrs but logical_immediate returns proper encoding */
416# define ORRI(Rd,Rn,Imm12) oxxi(A64_ORRI|XS,Rd,Rn,Imm12)
417# define EOR(Rd,Rn,Rm) oxxx(A64_EOR|XS,Rd,Rn,Rm)
418/* actually should use oxxrs but logical_immediate returns proper encoding */
419# define EORI(Rd,Rn,Imm12) oxxi(A64_EORI|XS,Rd,Rn,Imm12)
420# define SXTB(Rd,Rn) SBFM(Rd,Rn,0,7)
421# define SXTH(Rd,Rn) SBFM(Rd,Rn,0,15)
422# define SXTW(Rd,Rn) SBFM(Rd,Rn,0,31)
423# define UXTB(Rd,Rn) UBFX(Rd,Rn,0,7)
424# define UXTH(Rd,Rn) UBFX(Rd,Rn,0,15)
425# define UXTW(Rd,Rm) ox_x(A64_UXTW,Rd,Rm)
426# define REV(Rd,Rn) o_xx(A64_REV,Rd,Rn)
427# define LDRSB(Rt,Rn,Rm) oxxx(A64_LDRSB,Rt,Rn,Rm)
428# define LDRSBI(Rt,Rn,Imm12) oxxi(A64_LDRSBI,Rt,Rn,Imm12)
429# define LDURSB(Rt,Rn,Imm9) oxx9(A64_LDURSB,Rt,Rn,Imm9)
430# define LDRB(Rt,Rn,Rm) oxxx(A64_LDRB,Rt,Rn,Rm)
431# define LDRBI(Rt,Rn,Imm12) oxxi(A64_LDRBI,Rt,Rn,Imm12)
432# define LDURB(Rt,Rn,Imm9) oxx9(A64_LDURB,Rt,Rn,Imm9)
433# define LDRSH(Rt,Rn,Rm) oxxx(A64_LDRSH,Rt,Rn,Rm)
434# define LDRSHI(Rt,Rn,Imm12) oxxi(A64_LDRSHI,Rt,Rn,Imm12)
435# define LDURSH(Rt,Rn,Imm9) oxx9(A64_LDURSH,Rt,Rn,Imm9)
436# define LDRH(Rt,Rn,Rm) oxxx(A64_LDRH,Rt,Rn,Rm)
437# define LDRHI(Rt,Rn,Imm12) oxxi(A64_LDRHI,Rt,Rn,Imm12)
438# define LDURH(Rt,Rn,Imm9) oxx9(A64_LDURH,Rt,Rn,Imm9)
439# define LDRSW(Rt,Rn,Rm) oxxx(A64_LDRSW,Rt,Rn,Rm)
440# define LDRSWI(Rt,Rn,Imm12) oxxi(A64_LDRSWI,Rt,Rn,Imm12)
441# define LDURSW(Rt,Rn,Imm9) oxx9(A64_LDURSW,Rt,Rn,Imm9)
442# define LDRW(Rt,Rn,Rm) oxxx(A64_LDRW,Rt,Rn,Rm)
443# define LDRWI(Rt,Rn,Imm12) oxxi(A64_LDRWI,Rt,Rn,Imm12)
444# define LDURW(Rt,Rn,Imm9) oxx9(A64_LDURW,Rt,Rn,Imm9)
445# define LDR(Rt,Rn,Rm) oxxx(A64_LDR,Rt,Rn,Rm)
446# define LDRI(Rt,Rn,Imm12) oxxi(A64_LDRI,Rt,Rn,Imm12)
447# define LDUR(Rt,Rn,Imm9) oxx9(A64_LDUR,Rt,Rn,Imm9)
448# define STRB(Rt,Rn,Rm) oxxx(A64_STRB,Rt,Rn,Rm)
449# define STRBI(Rt,Rn,Imm12) oxxi(A64_STRBI,Rt,Rn,Imm12)
450# define STURB(Rt,Rn,Imm9) oxx9(A64_STURB,Rt,Rn,Imm9)
451# define STRH(Rt,Rn,Rm) oxxx(A64_STRH,Rt,Rn,Rm)
452# define STRHI(Rt,Rn,Imm12) oxxi(A64_STRHI,Rt,Rn,Imm12)
453# define STURH(Rt,Rn,Imm9) oxx9(A64_STURH,Rt,Rn,Imm9)
454# define STRW(Rt,Rn,Rm) oxxx(A64_STRW,Rt,Rn,Rm)
455# define STRWI(Rt,Rn,Imm12) oxxi(A64_STRWI,Rt,Rn,Imm12)
456# define STURW(Rt,Rn,Imm9) oxx9(A64_STURW,Rt,Rn,Imm9)
457# define STR(Rt,Rn,Rm) oxxx(A64_STR,Rt,Rn,Rm)
458# define STRI(Rt,Rn,Imm12) oxxi(A64_STRI,Rt,Rn,Imm12)
459# define STUR(Rt,Rn,Imm9) oxx9(A64_STUR,Rt,Rn,Imm9)
460# define LDPI(Rt,Rt2,Rn,Simm7) oxxx7(A64_LDP|XS,Rt,Rt2,Rn,Simm7)
461# define STPI(Rt,Rt2,Rn,Simm7) oxxx7(A64_STP|XS,Rt,Rt2,Rn,Simm7)
462# define LDPI_PRE(Rt,Rt2,Rn,Simm7) oxxx7(A64_LDP_PRE|XS,Rt,Rt2,Rn,Simm7)
463# define STPI_POS(Rt,Rt2,Rn,Simm7) oxxx7(A64_STP_POS|XS,Rt,Rt2,Rn,Simm7)
464# define CSET(Rd,Cc) CSINC(Rd,XZR_REGNO,XZR_REGNO,Cc)
e0659411 465# define CSEL(Rd,Rn,Rm,Cc) oxxxc(A64_CSSEL|XS,Rd,Rn,Rm,Cc)
4a71579b
PC
466# define B(Simm26) o26(A64_B,Simm26)
467# define BL(Simm26) o26(A64_BL,Simm26)
468# define BR(Rn) o_x_(A64_BR,Rn)
469# define BLR(Rn) o_x_(A64_BLR,Rn)
470# define RET() o_x_(A64_RET,LR_REGNO)
471# define B_C(Cc,Simm19) oc19(A64_B_C,Cc,Simm19)
472# define CBZ(Rd,Simm19) ox19(A64_CBZ|XS,Rd,Simm19)
473# define CBNZ(Rd,Simm19) ox19(A64_CBNZ|XS,Rd,Simm19)
474# define NOP() ii(0xd503201f)
475static jit_int32_t logical_immediate(jit_word_t);
476# define oxxx(Op,Rd,Rn,Rm) _oxxx(_jit,Op,Rd,Rn,Rm)
477static void _oxxx(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
478# define oxxi(Op,Rd,Rn,Imm12) _oxxi(_jit,Op,Rd,Rn,Imm12)
479static void _oxxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
480# define oxx9(Op,Rd,Rn,Imm9) _oxx9(_jit,Op,Rd,Rn,Imm9)
481static void _oxx9(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
482# define ox19(Op,Rd,Simm19) _ox19(_jit,Op,Rd,Simm19)
483static void _ox19(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
484# define oc19(Op,Cc,Simm19) _oc19(_jit,Op,Cc,Simm19)
485static void _oc19(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
486# define o26(Op,Simm26) _o26(_jit,Op,Simm26)
487static void _oc26(jit_state_t*,jit_int32_t,jit_int32_t);
488# define ox_x(Op,Rd,Rn) _ox_x(_jit,Op,Rd,Rn)
489static void _ox_x(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
490# define o_xx(Op,Rd,Rn) _o_xx(_jit,Op,Rd,Rn)
491static void _o_xx(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
492# define oxx_(Op,Rn,Rm) _oxx_(_jit,Op,Rn,Rm)
493static void _oxx_(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
494# define o_x_(Op,Rn) _o_x_(_jit,Op,Rn)
495static void _o_x_(jit_state_t*,jit_int32_t,jit_int32_t);
496# define ox_h(Op,Rd,Imm16) _ox_h(_jit,Op,Rd,Imm16)
497static void _ox_h(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
498# define oxxrs(Op,Rd,Rn,R,S) _oxxrs(_jit,Op,Rd,Rn,R,S)
499static void _oxxrs(jit_state_t*,jit_int32_t,jit_int32_t,
500 jit_int32_t,jit_int32_t,jit_int32_t);
501# define oxxxc(Op,Rd,Rn,Rm,Cc) _oxxxc(_jit,Op,Rd,Rn,Rm,Cc)
502static void _oxxxc(jit_state_t*,jit_int32_t,jit_int32_t,
503 jit_int32_t,jit_int32_t,jit_int32_t);
504# define oxxx7(Op,Rt,Rt2,Rn,Simm7) _oxxx7(_jit,Op,Rt,Rt2,Rn,Simm7)
505static void _oxxx7(jit_state_t*,jit_int32_t,
506 jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
507# define nop(i0) _nop(_jit,i0)
508static void _nop(jit_state_t*,jit_int32_t);
509# define addr(r0,r1,r2) ADD(r0,r1,r2)
510# define addi(r0,r1,i0) _addi(_jit,r0,r1,i0)
511static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
512# define addcr(r0,r1,r2) ADDS(r0,r1,r2)
513# define addci(r0,r1,i0) _addci(_jit,r0,r1,i0)
514static void _addci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
515# define addxr(r0,r1,r2) ADCS(r0,r1,r2)
516# define addxi(r0,r1,i0) _addxi(_jit,r0,r1,i0)
517static void _addxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
518# define subr(r0,r1,r2) SUB(r0,r1,r2)
519# define subi(r0,r1,i0) _subi(_jit,r0,r1,i0)
520static void _subi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
521# define subcr(r0,r1,r2) SUBS(r0,r1,r2)
522# define subci(r0,r1,i0) _subci(_jit,r0,r1,i0)
523static void _subci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
524# define subxr(r0,r1,r2) SBCS(r0,r1,r2)
525# define subxi(r0,r1,i0) _subxi(_jit,r0,r1,i0)
526static void _subxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
527# define rsbi(r0, r1, i0) _rsbi(_jit, r0, r1, i0)
528static void _rsbi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
529# define mulr(r0,r1,r2) MUL(r0,r1,r2)
530# define muli(r0,r1,i0) _muli(_jit,r0,r1,i0)
531static void _muli(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
532# define qmulr(r0,r1,r2,r3) _qmulr(_jit,r0,r1,r2,r3)
533static void _qmulr(jit_state_t*,jit_int32_t,
534 jit_int32_t,jit_int32_t,jit_int32_t);
535# define qmuli(r0,r1,r2,i0) _qmuli(_jit,r0,r1,r2,i0)
536static void _qmuli(jit_state_t*,jit_int32_t,
537 jit_int32_t,jit_int32_t,jit_word_t);
538# define qmulr_u(r0,r1,r2,r3) _qmulr_u(_jit,r0,r1,r2,r3)
539static void _qmulr_u(jit_state_t*,jit_int32_t,
540 jit_int32_t,jit_int32_t,jit_int32_t);
541# define qmuli_u(r0,r1,r2,i0) _qmuli_u(_jit,r0,r1,r2,i0)
542static void _qmuli_u(jit_state_t*,jit_int32_t,
543 jit_int32_t,jit_int32_t,jit_word_t);
544# define divr(r0,r1,r2) SDIV(r0,r1,r2)
545# define divi(r0,r1,i0) _divi(_jit,r0,r1,i0)
546static void _divi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
547# define divr_u(r0,r1,r2) UDIV(r0,r1,r2)
548# define divi_u(r0,r1,i0) _divi_u(_jit,r0,r1,i0)
549static void _divi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
550# define qdivr(r0,r1,r2,r3) _iqdivr(_jit,1,r0,r1,r2,r3)
551# define qdivr_u(r0,r1,r2,r3) _iqdivr(_jit,0,r0,r1,r2,r3)
552static void _iqdivr(jit_state_t*,jit_bool_t,
553 jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
554# define qdivi(r0,r1,r2,i0) _qdivi(_jit,r0,r1,r2,i0)
555static void _qdivi(jit_state_t*,jit_int32_t,
556 jit_int32_t,jit_int32_t,jit_word_t);
557# define qdivi_u(r0,r1,r2,i0) _qdivi_u(_jit,r0,r1,r2,i0)
558static void _qdivi_u(jit_state_t*,jit_int32_t,
559 jit_int32_t,jit_int32_t,jit_word_t);
560# define remr(r0,r1,r2) _remr(_jit,r0,r1,r2)
561static void _remr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
562# define remi(r0,r1,i0) _remi(_jit,r0,r1,i0)
563static void _remi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
564# define remr_u(r0,r1,r2) _remr_u(_jit,r0,r1,r2)
565static void _remr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
566# define remi_u(r0,r1,i0) _remi_u(_jit,r0,r1,i0)
567static void _remi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
568# define lshr(r0,r1,r2) LSL(r0,r1,r2)
569# define lshi(r0,r1,i0) _lshi(_jit,r0,r1,i0)
570static void _lshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
571# define rshr(r0,r1,r2) ASR(r0,r1,r2)
572# define rshi(r0,r1,i0) _rshi(_jit,r0,r1,i0)
573static void _rshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
574# define rshr_u(r0,r1,r2) LSR(r0,r1,r2)
575# define rshi_u(r0,r1,i0) _rshi_u(_jit,r0,r1,i0)
576static void _rshi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
e0659411
PC
577# define movnr(r0,r1,r2) _movnr(_jit,r0,r1,r2)
578static void _movnr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
579# define movzr(r0,r1,r2) _movzr(_jit,r0,r1,r2)
580static void _movzr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
4a71579b
PC
581# define negr(r0,r1) NEG(r0,r1)
582# define comr(r0,r1) MVN(r0,r1)
583# define andr(r0,r1,r2) AND(r0,r1,r2)
584# define andi(r0,r1,i0) _andi(_jit,r0,r1,i0)
585static void _andi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
586# define orr(r0,r1,r2) ORR(r0,r1,r2)
587# define ori(r0,r1,i0) _ori(_jit,r0,r1,i0)
588static void _ori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
589# define xorr(r0,r1,r2) EOR(r0,r1,r2)
590# define xori(r0,r1,i0) _xori(_jit,r0,r1,i0)
591static void _xori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
592# define ldr_c(r0,r1) LDRSBI(r0,r1,0)
593# define ldi_c(r0,i0) _ldi_c(_jit,r0,i0)
594static void _ldi_c(jit_state_t*,jit_int32_t,jit_word_t);
595# define ldr_uc(r0,r1) _ldr_uc(_jit,r0,r1)
596static void _ldr_uc(jit_state_t*,jit_int32_t,jit_int32_t);
597# define ldi_uc(r0,i0) _ldi_uc(_jit,r0,i0)
598static void _ldi_uc(jit_state_t*,jit_int32_t,jit_word_t);
599# define ldr_s(r0,r1) LDRSHI(r0,r1,0)
600# define ldi_s(r0,i0) _ldi_s(_jit,r0,i0)
601static void _ldi_s(jit_state_t*,jit_int32_t,jit_word_t);
602# define ldr_us(r0,r1) _ldr_us(_jit,r0,r1)
603static void _ldr_us(jit_state_t*,jit_int32_t,jit_int32_t);
604# define ldi_us(r0,i0) _ldi_us(_jit,r0,i0)
605static void _ldi_us(jit_state_t*,jit_int32_t,jit_word_t);
606# define ldr_i(r0,r1) LDRSWI(r0,r1,0)
607# define ldi_i(r0,i0) _ldi_i(_jit,r0,i0)
608static void _ldi_i(jit_state_t*,jit_int32_t,jit_word_t);
609# define ldr_ui(r0,r1) _ldr_ui(_jit,r0,r1)
610static void _ldr_ui(jit_state_t*,jit_int32_t,jit_int32_t);
611# define ldi_ui(r0,i0) _ldi_ui(_jit,r0,i0)
612static void _ldi_ui(jit_state_t*,jit_int32_t,jit_word_t);
613# define ldr_l(r0,r1) LDRI(r0,r1,0)
614static void _ldr_l(jit_state_t*,jit_int32_t,jit_int32_t);
615# define ldi_l(r0,i0) _ldi_l(_jit,r0,i0)
616static void _ldi_l(jit_state_t*,jit_int32_t,jit_word_t);
617# define ldxr_c(r0,r1,r2) _ldxr_c(_jit,r0,r1,r2)
618static void _ldxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
619# define ldxi_c(r0,r1,i0) _ldxi_c(_jit,r0,r1,i0)
620static void _ldxi_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
621# define ldxr_uc(r0,r1,r2) _ldxr_uc(_jit,r0,r1,r2)
622static void _ldxr_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
623# define ldxi_uc(r0,r1,i0) _ldxi_uc(_jit,r0,r1,i0)
624static void _ldxi_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
625# define ldxr_s(r0,r1,r2) LDRSH(r0,r1,r2)
626# define ldxi_s(r0,r1,i0) _ldxi_s(_jit,r0,r1,i0)
627static void _ldxi_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
628# define ldxr_us(r0,r1,r2) _ldxr_us(_jit,r0,r1,r2)
629static void _ldxr_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
630# define ldxi_us(r0,r1,i0) _ldxi_us(_jit,r0,r1,i0)
631static void _ldxi_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
632# define ldxr_i(r0,r1,r2) LDRSW(r0,r1,r2)
633# define ldxi_i(r0,r1,i0) _ldxi_i(_jit,r0,r1,i0)
634static void _ldxi_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
635# define ldxr_ui(r0,r1,r2) _ldxr_ui(_jit,r0,r1,r2)
636static void _ldxr_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
637# define ldxi_ui(r0,r1,i0) _ldxi_ui(_jit,r0,r1,i0)
638static void _ldxi_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
639# define ldxr_l(r0,r1,r2) LDR(r0,r1,r2)
640# define ldxi_l(r0,r1,i0) _ldxi_l(_jit,r0,r1,i0)
641static void _ldxi_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
642# define str_c(r0,r1) STRBI(r1,r0,0)
643# define sti_c(i0,r0) _sti_c(_jit,i0,r0)
644static void _sti_c(jit_state_t*,jit_word_t,jit_int32_t);
645# define str_s(r0,r1) STRHI(r1,r0,0)
646# define sti_s(i0,r0) _sti_s(_jit,i0,r0)
647static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t);
648# define str_i(r0,r1) STRWI(r1,r0,0)
649# define sti_i(i0,r0) _sti_i(_jit,i0,r0)
650static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t);
651# define str_l(r0,r1) STRI(r1,r0,0)
652# define sti_l(i0,r0) _sti_l(_jit,i0,r0)
653static void _sti_l(jit_state_t*,jit_word_t,jit_int32_t);
654# define stxr_c(r0,r1,r2) STRB(r2,r1,r0)
655# define stxi_c(i0,r0,r1) _stxi_c(_jit,i0,r0,r1)
656static void _stxi_c(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
657# define stxr_s(r0,r1,r2) STRH(r2,r1,r0)
658# define stxi_s(i0,r0,r1) _stxi_s(_jit,i0,r0,r1)
659static void _stxi_s(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
660# define stxr_i(r0,r1,r2) STRW(r2,r1,r0)
661# define stxi_i(i0,r0,r1) _stxi_i(_jit,i0,r0,r1)
662static void _stxi_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
663# define stxr_l(r0,r1,r2) STR(r2,r1,r0)
664# define stxi_l(i0,r0,r1) _stxi_l(_jit,i0,r0,r1)
665static void _stxi_l(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
666# if __BYTE_ORDER == __LITTLE_ENDIAN
667# define htonr_us(r0,r1) _htonr_us(_jit,r0,r1)
668static void _htonr_us(jit_state_t*,jit_int32_t,jit_int32_t);
669# define htonr_ui(r0,r1) _htonr_ui(_jit,r0,r1)
670static void _htonr_ui(jit_state_t*,jit_int32_t,jit_int32_t);
671# define htonr_ul(r0,r1) REV(r0,r1)
672# else
673# define htonr_us(r0,r1) extr_us(r0,r1)
674# define htonr_ui(r0,r1) extr_ui(r0,r1)
675# define htonr_ul(r0,r1) movr(r0,r1)
676# endif
677# define extr_c(r0,r1) SXTB(r0,r1)
678# define extr_uc(r0,r1) UXTB(r0,r1)
679# define extr_s(r0,r1) SXTH(r0,r1)
680# define extr_us(r0,r1) UXTH(r0,r1)
681# define extr_i(r0,r1) SXTW(r0,r1)
682# define extr_ui(r0,r1) UXTW(r0,r1)
683# define movr(r0,r1) _movr(_jit,r0,r1)
684static void _movr(jit_state_t*,jit_int32_t,jit_int32_t);
685# define movi(r0,i0) _movi(_jit,r0,i0)
686static void _movi(jit_state_t*,jit_int32_t,jit_word_t);
687# define movi_p(r0,i0) _movi_p(_jit,r0,i0)
688static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t);
689# define ccr(cc,r0,r1,r2) _ccr(_jit,cc,r0,r1,r2)
690static void _ccr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
691# define cci(cc,r0,r1,i0) _cci(_jit,cc,r0,r1,i0)
692static void _cci(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t);
693# define ltr(r0,r1,r2) ccr(CC_LT,r0,r1,r2)
694# define lti(r0,r1,i0) cci(CC_LT,r0,r1,i0)
695# define ltr_u(r0,r1,r2) ccr(CC_CC,r0,r1,r2)
696# define lti_u(r0,r1,i0) cci(CC_CC,r0,r1,i0)
697# define ler(r0,r1,r2) ccr(CC_LE,r0,r1,r2)
698# define lei(r0,r1,i0) cci(CC_LE,r0,r1,i0)
699# define ler_u(r0,r1,r2) ccr(CC_LS,r0,r1,r2)
700# define lei_u(r0,r1,i0) cci(CC_LS,r0,r1,i0)
701# define eqr(r0,r1,r2) ccr(CC_EQ,r0,r1,r2)
702# define eqi(r0,r1,i0) cci(CC_EQ,r0,r1,i0)
703# define ger(r0,r1,r2) ccr(CC_GE,r0,r1,r2)
704# define gei(r0,r1,i0) cci(CC_GE,r0,r1,i0)
705# define ger_u(r0,r1,r2) ccr(CC_CS,r0,r1,r2)
706# define gei_u(r0,r1,i0) cci(CC_CS,r0,r1,i0)
707# define gtr(r0,r1,r2) ccr(CC_GT,r0,r1,r2)
708# define gti(r0,r1,i0) cci(CC_GT,r0,r1,i0)
709# define gtr_u(r0,r1,r2) ccr(CC_HI,r0,r1,r2)
710# define gti_u(r0,r1,i0) cci(CC_HI,r0,r1,i0)
711# define ner(r0,r1,r2) ccr(CC_NE,r0,r1,r2)
712# define nei(r0,r1,i0) cci(CC_NE,r0,r1,i0)
713# define bccr(cc,i0,r0,r1) _bccr(_jit,cc,i0,r0,r1)
714static jit_word_t
715_bccr(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t);
716# define bcci(cc,i0,r0,i1) _bcci(_jit,cc,i0,r0,i1)
717static jit_word_t
718_bcci(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_word_t);
719# define bltr(i0,r0,r1) bccr(BCC_LT,i0,r0,r1)
720# define blti(i0,r0,i1) bcci(BCC_LT,i0,r0,i1)
721# define bltr_u(i0,r0,r1) bccr(BCC_CC,i0,r0,r1)
722# define blti_u(i0,r0,i1) bcci(BCC_CC,i0,r0,i1)
723# define bler(i0,r0,r1) bccr(BCC_LE,i0,r0,r1)
724# define blei(i0,r0,i1) bcci(BCC_LE,i0,r0,i1)
725# define bler_u(i0,r0,r1) bccr(BCC_LS,i0,r0,r1)
726# define blei_u(i0,r0,i1) bcci(BCC_LS,i0,r0,i1)
727# define beqr(i0,r0,r1) bccr(BCC_EQ,i0,r0,r1)
728# define beqi(i0,r0,i1) _beqi(_jit,i0,r0,i1)
729static jit_word_t _beqi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
730# define bger(i0,r0,r1) bccr(BCC_GE,i0,r0,r1)
731# define bgei(i0,r0,i1) bcci(BCC_GE,i0,r0,i1)
732# define bger_u(i0,r0,r1) bccr(BCC_CS,i0,r0,r1)
733# define bgei_u(i0,r0,i1) bcci(BCC_CS,i0,r0,i1)
734# define bgtr(i0,r0,r1) bccr(BCC_GT,i0,r0,r1)
735# define bgti(i0,r0,i1) bcci(BCC_GT,i0,r0,i1)
736# define bgtr_u(i0,r0,r1) bccr(BCC_HI,i0,r0,r1)
737# define bgti_u(i0,r0,i1) bcci(BCC_HI,i0,r0,i1)
738# define bner(i0,r0,r1) bccr(BCC_NE,i0,r0,r1)
739# define bnei(i0,r0,i1) _bnei(_jit,i0,r0,i1)
740static jit_word_t _bnei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
741# define baddr(cc,i0,r0,r1) _baddr(_jit,cc,i0,r0,r1)
742static jit_word_t
743_baddr(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t);
744# define baddi(cc,i0,r0,i1) _baddi(_jit,cc,i0,r0,i1)
745static jit_word_t
746_baddi(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_word_t);
747# define boaddr(i0,r0,r1) baddr(BCC_VS,i0,r0,r1)
748# define boaddi(i0,r0,i1) baddi(BCC_VS,i0,r0,i1)
749# define boaddr_u(i0,r0,r1) baddr(BCC_HS,i0,r0,r1)
750# define boaddi_u(i0,r0,i1) baddi(BCC_HS,i0,r0,i1)
751# define bxaddr(i0,r0,r1) baddr(BCC_VC,i0,r0,r1)
752# define bxaddi(i0,r0,i1) baddi(BCC_VC,i0,r0,i1)
753# define bxaddr_u(i0,r0,r1) baddr(BCC_LO,i0,r0,r1)
754# define bxaddi_u(i0,r0,i1) baddi(BCC_LO,i0,r0,i1)
755# define bsubr(cc,i0,r0,r1) _bsubr(_jit,cc,i0,r0,r1)
756static jit_word_t
757_bsubr(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t);
758# define bsubi(cc,i0,r0,i1) _bsubi(_jit,cc,i0,r0,i1)
759static jit_word_t
760_bsubi(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_word_t);
761# define bosubr(i0,r0,r1) bsubr(BCC_VS,i0,r0,r1)
762# define bosubi(i0,r0,i1) bsubi(BCC_VS,i0,r0,i1)
763# define bosubr_u(i0,r0,r1) bsubr(BCC_LO,i0,r0,r1)
764# define bosubi_u(i0,r0,i1) bsubi(BCC_LO,i0,r0,i1)
765# define bxsubr(i0,r0,r1) bsubr(BCC_VC,i0,r0,r1)
766# define bxsubi(i0,r0,i1) bsubi(BCC_VC,i0,r0,i1)
767# define bxsubr_u(i0,r0,r1) bsubr(BCC_HS,i0,r0,r1)
768# define bxsubi_u(i0,r0,i1) bsubi(BCC_HS,i0,r0,i1)
769# define bmxr(cc,i0,r0,r1) _bmxr(_jit,cc,i0,r0,r1)
770static jit_word_t
771_bmxr(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t);
772# define bmxi(cc,i0,r0,r1) _bmxi(_jit,cc,i0,r0,r1)
773static jit_word_t
774_bmxi(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_word_t);
775# define bmsr(i0,r0,r1) bmxr(BCC_NE,i0,r0,r1)
776# define bmsi(i0,r0,i1) bmxi(BCC_NE,i0,r0,i1)
777# define bmcr(i0,r0,r1) bmxr(BCC_EQ,i0,r0,r1)
778# define bmci(i0,r0,i1) bmxi(BCC_EQ,i0,r0,i1)
779# define jmpr(r0) BR(r0)
780# define jmpi(i0) _jmpi(_jit,i0)
781static void _jmpi(jit_state_t*,jit_word_t);
782# define jmpi_p(i0) _jmpi_p(_jit,i0)
783static jit_word_t _jmpi_p(jit_state_t*,jit_word_t);
784# define callr(r0) BLR(r0)
785# define calli(i0) _calli(_jit,i0)
786static void _calli(jit_state_t*,jit_word_t);
787# define calli_p(i0) _calli_p(_jit,i0)
788static jit_word_t _calli_p(jit_state_t*,jit_word_t);
789# define prolog(i0) _prolog(_jit,i0)
790static void _prolog(jit_state_t*,jit_node_t*);
791# define epilog(i0) _epilog(_jit,i0)
792static void _epilog(jit_state_t*,jit_node_t*);
793# define vastart(r0) _vastart(_jit, r0)
794static void _vastart(jit_state_t*, jit_int32_t);
795# define vaarg(r0, r1) _vaarg(_jit, r0, r1)
796static void _vaarg(jit_state_t*, jit_int32_t, jit_int32_t);
797# define patch_at(jump,label) _patch_at(_jit,jump,label)
798static void _patch_at(jit_state_t*,jit_word_t,jit_word_t);
799#endif
800
801#if CODE
802static jit_int32_t
803logical_immediate(jit_word_t imm)
804{
805 /* There are 5334 possible immediate values, but to avoid the
806 * need of either too complex code or large lookup tables,
807 * only check for (simply) encodable common/small values */
808 switch (imm) {
809 case -16: return (0xf3b);
810 case -15: return (0xf3c);
811 case -13: return (0xf3d);
812 case -9: return (0xf3e);
813 case -8: return (0xf7c);
814 case -7: return (0xf7d);
815 case -5: return (0xf7e);
816 case -4: return (0xfbd);
817 case -3: return (0xfbe);
818 case -2: return (0xffe);
819 case 1: return (0x000);
820 case 2: return (0xfc0);
821 case 3: return (0x001);
822 case 4: return (0xf80);
823 case 6: return (0xfc1);
824 case 7: return (0x002);
825 case 8: return (0xf40);
826 case 12: return (0xf81);
827 case 14: return (0xfc2);
828 case 15: return (0x003);
829 case 16: return (0xf00);
830 default: return (-1);
831 }
832}
833
834static void
835_oxxx(jit_state_t *_jit, jit_int32_t Op,
836 jit_int32_t Rd, jit_int32_t Rn, jit_int32_t Rm)
837{
838 instr_t i;
839 assert(!(Rd & ~0x1f));
840 assert(!(Rn & ~0x1f));
841 assert(!(Rm & ~0x1f));
842 assert(!(Op & ~0xffe0fc00));
843 i.w = Op;
844 i.Rd.b = Rd;
845 i.Rn.b = Rn;
846 i.Rm.b = Rm;
847 ii(i.w);
848}
849
850static void
851_oxxi(jit_state_t *_jit, jit_int32_t Op,
852 jit_int32_t Rd, jit_int32_t Rn, jit_int32_t Imm12)
853{
854 instr_t i;
855 assert(!(Rd & ~0x1f));
856 assert(!(Rn & ~0x1f));
857 assert(!(Imm12 & ~0xfff));
858 assert(!(Op & ~0xffe00000));
859 i.w = Op;
860 i.Rd.b = Rd;
861 i.Rn.b = Rn;
862 i.imm12.b = Imm12;
863 ii(i.w);
864}
865
866static void
867_oxx9(jit_state_t *_jit, jit_int32_t Op,
868 jit_int32_t Rd, jit_int32_t Rn, jit_int32_t Imm9)
869{
870 instr_t i;
871 assert(!(Rd & ~0x1f));
872 assert(!(Rn & ~0x1f));
873 assert(!(Imm9 & ~0x1ff));
874 assert(!(Op & ~0xffe00000));
875 i.w = Op;
876 i.Rd.b = Rd;
877 i.Rn.b = Rn;
878 i.imm9.b = Imm9;
879 ii(i.w);
880}
881
882static void
883_ox19(jit_state_t *_jit, jit_int32_t Op, jit_int32_t Rd, jit_int32_t Simm19)
884{
885 instr_t i;
886 assert(!(Rd & ~0x1f));
887 assert(Simm19 >= -262148 && Simm19 <= 262143);
888 assert(!(Op & ~0xff000000));
889 i.w = Op;
890 i.Rd.b = Rd;
891 i.imm19.b = Simm19;
892 ii(i.w);
893}
894
895static void
896_oc19(jit_state_t *_jit, jit_int32_t Op, jit_int32_t Cc, jit_int32_t Simm19)
897{
898 instr_t i;
899 assert(!(Cc & ~0xf));
900 assert(Simm19 >= -262148 && Simm19 <= 262143);
901 assert(!(Op & ~0xff000000));
902 i.w = Op;
903 i.cond2.b = Cc;
904 i.imm19.b = Simm19;
905 ii(i.w);
906}
907
908static void
909_o26(jit_state_t *_jit, jit_int32_t Op, jit_int32_t Simm26)
910{
911 instr_t i;
912 assert(Simm26 >= -33554432 && Simm26 <= 33554431);
913 assert(!(Op & ~0xfc000000));
914 i.w = Op;
915 i.imm26.b = Simm26;
916 ii(i.w);
917}
918
919static void
920_ox_x(jit_state_t *_jit, jit_int32_t Op, jit_int32_t Rd, jit_int32_t Rm)
921{
922 instr_t i;
923 assert(!(Rd & ~0x1f));
924 assert(!(Rm & ~0x1f));
925 assert(!(Op & ~0xffe0ffe0));
926 i.w = Op;
927 i.Rd.b = Rd;
928 i.Rm.b = Rm;
929 ii(i.w);
930}
931
932static void
933_o_xx(jit_state_t *_jit, jit_int32_t Op, jit_int32_t Rd, jit_int32_t Rn)
934{
935 instr_t i;
936 assert(!(Rd & ~0x1f));
937 assert(!(Rn & ~0x1f));
938 assert(!(Op & ~0xfffffc00));
939 i.w = Op;
940 i.Rd.b = Rd;
941 i.Rn.b = Rn;
942 ii(i.w);
943}
944
945static void
946_oxx_(jit_state_t *_jit, jit_int32_t Op, jit_int32_t Rn, jit_int32_t Rm)
947{
948 instr_t i;
949 assert(!(Rn & ~0x1f));
950 assert(!(Rm & ~0x1f));
951 assert(!(Op & ~0xffc0fc1f));
952 i.w = Op;
953 i.Rn.b = Rn;
954 i.Rm.b = Rm;
955 ii(i.w);
956}
957
958static void
959_o_x_(jit_state_t *_jit, jit_int32_t Op, jit_int32_t Rn)
960{
961 instr_t i;
962 assert(!(Rn & ~0x1f));
963 assert(!(Op & 0x3e0));
964 i.w = Op;
965 i.Rn.b = Rn;
966 ii(i.w);
967}
968
969static void
970_ox_h(jit_state_t *_jit, jit_int32_t Op, jit_int32_t Rd, jit_int32_t Imm16)
971{
972 instr_t i;
973 assert(!(Rd & ~0x1f));
974 assert(!(Imm16 & ~0xffff));
975 assert(!(Op & ~0xffe00000));
976 i.w = Op;
977 i.Rd.b = Rd;
978 i.imm16.b = Imm16;
979 ii(i.w);
980}
981
982static void
983_oxxrs(jit_state_t *_jit, jit_int32_t Op,
984 jit_int32_t Rd, jit_int32_t Rn, jit_int32_t R, jit_int32_t S)
985{
986 instr_t i;
987 assert(!(Rd & ~0x1f));
988 assert(!(Rn & ~0x1f));
989 assert(!(R & ~0x3f));
990 assert(!(S & ~0x3f));
991 assert(!(Op & ~0xffc00000));
992 i.w = Op;
993 i.Rd.b = Rd;
994 i.Rn.b = Rn;
995 i.immr.b = R;
996 i.imms.b = S;
997 ii(i.w);
998}
999
1000static void
1001_oxxxc(jit_state_t *_jit, jit_int32_t Op,
1002 jit_int32_t Rd, jit_int32_t Rn, jit_int32_t Rm, jit_int32_t Cc)
1003{
1004 instr_t i;
1005 assert(!(Rd & ~0x1f));
1006 assert(!(Rn & ~0x1f));
1007 assert(!(Rm & ~0x1f));
1008 assert(!(Cc & ~0xf));
1009 assert(!(Op & ~0xffc00c00));
1010 i.w = Op;
1011 i.Rd.b = Rd;
1012 i.Rn.b = Rn;
1013 i.Rm.b = Rm;
1014 i.cond.b = Cc;
1015 ii(i.w);
1016}
1017
1018static void
1019_oxxx7(jit_state_t *_jit, jit_int32_t Op,
1020 jit_int32_t Rt, jit_int32_t Rt2, jit_int32_t Rn, jit_int32_t Simm7)
1021{
1022 instr_t i;
1023 assert(!(Rt & ~0x1f));
1024 assert(!(Rt2 & ~0x1f));
1025 assert(!(Rn & ~0x1f));
1026 assert(Simm7 >= -128 && Simm7 <= 127);
1027 assert(!(Op & ~0xffc003e0));
1028 i.w = Op;
1029 i.Rt.b = Rt;
1030 i.Rt2.b = Rt2;
1031 i.Rn.b = Rn;
1032 i.imm7.b = Simm7;
1033 ii(i.w);
1034}
1035
1036static void
1037_nop(jit_state_t *_jit, jit_int32_t i0)
1038{
1039 for (; i0 > 0; i0 -= 4)
1040 NOP();
1041 assert(i0 == 0);
1042}
1043
1044static void
1045_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1046{
1047 jit_int32_t reg;
1048 jit_word_t is = i0 >> 12;
1049 jit_word_t in = -i0;
1050 jit_word_t iS = in >> 12;
1051 if ( i0 >= 0 && i0 <= 0xfff)
1052 ADDI (r0, r1, i0);
1053 else if ((is << 12) == i0 && is >= 0 && is <= 0xfff)
1054 ADDI_12(r0, r1, is);
1055 else if ( in >= 0 && in <= 0xfff)
1056 SUBI (r0, r1, in);
1057 else if ((iS << 12) == is && iS >= 0 && iS <= 0xfff)
1058 SUBI_12(r0, r1, iS);
1059 else {
1060 reg = jit_get_reg(jit_class_gpr);
1061 movi(rn(reg), i0);
1062 addr(r0, r1, rn(reg));
1063 jit_unget_reg(reg);
1064 }
1065}
1066
1067static void
1068_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1069{
1070 jit_int32_t reg;
1071 jit_word_t is = i0 >> 12;
1072 jit_word_t in = -i0;
1073 jit_word_t iS = in >> 12;
1074 if ( i0 >= 0 && i0 <= 0xfff)
1075 ADDSI (r0, r1, i0);
1076 else if ((is << 12) == i0 && is >= 0 && is <= 0xfff)
1077 ADDSI_12(r0, r1, is);
1078 else if ( in >= 0 && in <= 0xfff)
1079 SUBSI (r0, r1, in);
1080 else if ((iS << 12) == is && iS >= 0 && iS <= 0xfff)
1081 SUBSI_12(r0, r1, iS);
1082 else {
1083 reg = jit_get_reg(jit_class_gpr);
1084 movi(rn(reg), i0);
1085 addcr(r0, r1, rn(reg));
1086 jit_unget_reg(reg);
1087 }
1088}
1089
1090static void
1091_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1092{
1093 jit_int32_t reg;
1094 reg = jit_get_reg(jit_class_gpr);
1095 movi(rn(reg), i0);
1096 addxr(r0, r1, rn(reg));
1097 jit_unget_reg(reg);
1098}
1099
1100static void
1101_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1102{
1103 jit_int32_t reg;
1104 jit_word_t is = i0 >> 12;
1105 if ( i0 >= 0 && i0 <= 0xfff)
1106 SUBI (r0, r1, i0);
1107 else if ((is << 12) == i0 && is >= 0 && is <= 0xfff)
1108 SUBI_12(r0, r1, is);
1109 else {
1110 reg = jit_get_reg(jit_class_gpr);
1111 movi(rn(reg), i0);
1112 subr(r0, r1, rn(reg));
1113 jit_unget_reg(reg);
1114 }
1115}
1116
1117static void
1118_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1119{
1120 jit_int32_t reg;
1121 jit_word_t is = i0 >> 12;
1122 if ( i0 >= 0 && i0 <= 0xfff)
1123 SUBSI (r0, r1, i0);
1124 else if ((is << 12) == i0 && is >= 0 && is <= 0xfff)
1125 SUBSI_12(r0, r1, is);
1126 else {
1127 reg = jit_get_reg(jit_class_gpr);
1128 movi(rn(reg), i0);
1129 subcr(r0, r1, rn(reg));
1130 jit_unget_reg(reg);
1131 }
1132}
1133
1134static void
1135_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1136{
1137 jit_int32_t reg;
1138 reg = jit_get_reg(jit_class_gpr);
1139 movi(rn(reg), i0);
1140 subxr(r0, r1, rn(reg));
1141 jit_unget_reg(reg);
1142}
1143
1144static void
1145_rsbi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1146{
1147 subi(r0, r1, i0);
1148 negr(r0, r0);
1149}
1150
1151static void
1152_muli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1153{
1154 jit_int32_t reg;
1155 reg = jit_get_reg(jit_class_gpr);
1156 movi(rn(reg), i0);
1157 mulr(r0, r1, rn(reg));
1158 jit_unget_reg(reg);
1159}
1160
1161static void
1162_qmulr(jit_state_t *_jit, jit_int32_t r0,
1163 jit_int32_t r1, jit_int32_t r2, jit_int32_t r3)
1164{
1165 jit_int32_t reg;
1166 if (r0 == r2 || r0 == r3) {
1167 reg = jit_get_reg(jit_class_gpr);
1168 mulr(rn(reg), r2, r3);
1169 }
1170 else
1171 mulr(r0, r2, r3);
1172 SMULH(r1, r2, r3);
1173 if (r0 == r2 || r0 == r3) {
1174 movr(r0, rn(reg));
1175 jit_unget_reg(reg);
1176 }
1177}
1178
1179static void
1180_qmuli(jit_state_t *_jit, jit_int32_t r0,
1181 jit_int32_t r1, jit_int32_t r2, jit_word_t i0)
1182{
1183 jit_int32_t reg;
1184 reg = jit_get_reg(jit_class_gpr);
1185 movi(rn(reg), i0);
1186 qmulr(r0, r1, r2, rn(reg));
1187 jit_unget_reg(reg);
1188}
1189
1190static void
1191_qmulr_u(jit_state_t *_jit, jit_int32_t r0,
1192 jit_int32_t r1, jit_int32_t r2, jit_int32_t r3)
1193{
1194 jit_int32_t reg;
1195 if (r0 == r2 || r0 == r3) {
1196 reg = jit_get_reg(jit_class_gpr);
1197 mulr(rn(reg), r2, r3);
1198 }
1199 else
1200 mulr(r0, r2, r3);
1201 UMULH(r1, r2, r3);
1202 if (r0 == r2 || r0 == r3) {
1203 movr(r0, rn(reg));
1204 jit_unget_reg(reg);
1205 }
1206}
1207
1208static void
1209_qmuli_u(jit_state_t *_jit, jit_int32_t r0,
1210 jit_int32_t r1, jit_int32_t r2, jit_word_t i0)
1211{
1212 jit_int32_t reg;
1213 reg = jit_get_reg(jit_class_gpr);
1214 movi(rn(reg), i0);
1215 qmulr_u(r0, r1, r2, rn(reg));
1216 jit_unget_reg(reg);
1217}
1218
1219static void
1220_divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1221{
1222 jit_int32_t reg;
1223 reg = jit_get_reg(jit_class_gpr);
1224 movi(rn(reg), i0);
1225 divr(r0, r1, rn(reg));
1226 jit_unget_reg(reg);
1227}
1228
1229static void
1230_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1231{
1232 jit_int32_t reg;
1233 reg = jit_get_reg(jit_class_gpr);
1234 movi(rn(reg), i0);
1235 divr_u(r0, r1, rn(reg));
1236 jit_unget_reg(reg);
1237}
1238
1239static void
1240_iqdivr(jit_state_t *_jit, jit_bool_t sign,
1241 jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3)
1242{
1243 jit_int32_t sv0, rg0;
1244 jit_int32_t sv1, rg1;
1245 if (r0 == r2 || r0 == r3) {
1246 sv0 = jit_get_reg(jit_class_gpr);
1247 rg0 = rn(sv0);
1248 }
1249 else
1250 rg0 = r0;
1251 if (r1 == r2 || r1 == r3) {
1252 sv1 = jit_get_reg(jit_class_gpr);
1253 rg1 = rn(sv1);
1254 }
1255 else
1256 rg1 = r1;
1257 if (sign)
1258 divr(rg0, r2, r3);
1259 else
1260 divr_u(rg0, r2, r3);
1261 mulr(rg1, r3, rg0);
1262 subr(rg1, r2, rg1);
1263 if (rg0 != r0) {
1264 movr(r0, rg0);
1265 jit_unget_reg(sv0);
1266 }
1267 if (rg1 != r1) {
1268 movr(r1, rg1);
1269 jit_unget_reg(sv1);
1270 }
1271}
1272
1273static void
1274_qdivi(jit_state_t *_jit, jit_int32_t r0,
1275 jit_int32_t r1, jit_int32_t r2, jit_word_t i0)
1276{
1277 jit_int32_t reg;
1278 reg = jit_get_reg(jit_class_gpr);
1279 movi(rn(reg), i0);
1280 qdivr(r0, r1, r2, rn(reg));
1281 jit_unget_reg(reg);
1282}
1283
1284static void
1285_qdivi_u(jit_state_t *_jit, jit_int32_t r0,
1286 jit_int32_t r1, jit_int32_t r2, jit_word_t i0)
1287{
1288 jit_int32_t reg;
1289 reg = jit_get_reg(jit_class_gpr);
1290 movi(rn(reg), i0);
1291 qdivr_u(r0, r1, r2, rn(reg));
1292 jit_unget_reg(reg);
1293}
1294
1295static void
1296_remr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1297{
1298 jit_int32_t reg;
1299 if (r0 == r1 || r0 == r2) {
1300 reg = jit_get_reg(jit_class_gpr);
1301 divr(rn(reg), r1, r2);
1302 mulr(rn(reg), r2, rn(reg));
1303 subr(r0, r1, rn(reg));
1304 jit_unget_reg(reg);
1305 }
1306 else {
1307 divr(r0, r1, r2);
1308 mulr(r0, r2, r0);
1309 subr(r0, r1, r0);
1310 }
1311}
1312
1313static void
1314_remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1315{
1316 jit_int32_t reg;
1317 reg = jit_get_reg(jit_class_gpr);
1318 movi(rn(reg), i0);
1319 remr(r0, r1, rn(reg));
1320 jit_unget_reg(reg);
1321}
1322
1323static void
1324_remr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1325{
1326 jit_int32_t reg;
1327 if (r0 == r1 || r0 == r2) {
1328 reg = jit_get_reg(jit_class_gpr);
1329 divr_u(rn(reg), r1, r2);
1330 mulr(rn(reg), r2, rn(reg));
1331 subr(r0, r1, rn(reg));
1332 jit_unget_reg(reg);
1333 }
1334 else {
1335 divr_u(r0, r1, r2);
1336 mulr(r0, r2, r0);
1337 subr(r0, r1, r0);
1338 }
1339}
1340
1341static void
1342_remi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1343{
1344 jit_int32_t reg;
1345 reg = jit_get_reg(jit_class_gpr);
1346 movi(rn(reg), i0);
1347 remr_u(r0, r1, rn(reg));
1348 jit_unget_reg(reg);
1349}
1350
1351static void
1352_lshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1353{
1354 if (i0 == 0)
1355 movr(r0, r1);
1356 else {
1357 assert(i0 > 0 && i0 < 64);
1358 LSLI(r0, r1, i0);
1359 }
1360}
1361
1362static void
1363_rshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1364{
1365 if (i0 == 0)
1366 movr(r0, r1);
1367 else {
1368 assert(i0 > 0 && i0 < 64);
1369 ASRI(r0, r1, i0);
1370 }
1371}
1372
1373static void
1374_rshi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1375{
1376 if (i0 == 0)
1377 movr(r0, r1);
1378 else {
1379 assert(i0 > 0 && i0 < 64);
1380 LSRI(r0, r1, i0);
1381 }
1382}
1383
e0659411
PC
1384static void
1385_movnr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1386{
1387 CMPI(r2, 0);
1388 CSEL(r0, r0, r1, CC_NE);
1389}
1390
1391static void
1392_movzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1393{
1394 CMPI(r2, 0);
1395 CSEL(r0, r0, r1, CC_EQ);
1396}
1397
4a71579b
PC
1398static void
1399_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1400{
1401 jit_int32_t reg;
1402 jit_int32_t imm;
1403 if (i0 == 0)
1404 movi(r0, 0);
1405 else if (i0 == -1)
1406 movr(r0, r1);
1407 else {
1408 imm = logical_immediate(i0);
1409 if (imm != -1)
1410 ANDI(r0, r1, imm);
1411 else {
1412 reg = jit_get_reg(jit_class_gpr);
1413 movi(rn(reg), i0);
1414 andr(r0, r1, rn(reg));
1415 jit_unget_reg(reg);
1416 }
1417 }
1418}
1419
1420static void
1421_ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1422{
1423 jit_int32_t reg;
1424 jit_int32_t imm;
1425 if (i0 == 0)
1426 movr(r0, r1);
1427 else if (i0 == -1)
1428 movi(r0, -1);
1429 else {
1430 imm = logical_immediate(i0);
1431 if (imm != -1)
1432 ORRI(r0, r1, imm);
1433 else {
1434 reg = jit_get_reg(jit_class_gpr);
1435 movi(rn(reg), i0);
1436 orr(r0, r1, rn(reg));
1437 jit_unget_reg(reg);
1438 }
1439 }
1440}
1441
1442static void
1443_xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1444{
1445 jit_int32_t reg;
1446 jit_int32_t imm;
1447 if (i0 == 0)
1448 movr(r0, r1);
1449 else if (i0 == -1)
1450 comr(r0, r1);
1451 else {
1452 imm = logical_immediate(i0);
1453 if (imm != -1)
1454 EORI(r0, r1, imm);
1455 else {
1456 reg = jit_get_reg(jit_class_gpr);
1457 movi(rn(reg), i0);
1458 xorr(r0, r1, rn(reg));
1459 jit_unget_reg(reg);
1460 }
1461 }
1462}
1463
1464#if __BYTE_ORDER == __LITTLE_ENDIAN
1465static void
1466_htonr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1467{
1468 htonr_ul(r0, r1);
1469 rshi_u(r0, r0, 48);
1470}
1471
1472static void
1473_htonr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1474{
1475 htonr_ul(r0, r1);
1476 rshi_u(r0, r0, 32);
1477}
1478#endif
1479
1480static void
1481_ldi_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1482{
1483 jit_int32_t reg;
1484 reg = jit_get_reg(jit_class_gpr);
1485 movi(rn(reg), i0);
1486 ldr_c(r0, rn(reg));
1487 jit_unget_reg(reg);
1488}
1489
1490static void
1491_ldr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1492{
1493 LDRBI(r0, r1, 0);
1494#if 0
1495 extr_uc(r0, r0);
1496#endif
1497}
1498
1499static void
1500_ldi_uc(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1501{
1502 jit_int32_t reg;
1503 reg = jit_get_reg(jit_class_gpr);
1504 movi(rn(reg), i0);
1505 ldr_uc(r0, rn(reg));
1506 jit_unget_reg(reg);
1507}
1508
1509static void
1510_ldi_s(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1511{
1512 jit_int32_t reg;
1513 reg = jit_get_reg(jit_class_gpr);
1514 movi(rn(reg), i0);
1515 ldr_s(r0, rn(reg));
1516 jit_unget_reg(reg);
1517}
1518
1519static void
1520_ldr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1521{
1522 LDRHI(r0, r1, 0);
1523#if 0
1524 extr_us(r0, r0);
1525#endif
1526}
1527
1528static void
1529_ldi_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1530{
1531 jit_int32_t reg;
1532 reg = jit_get_reg(jit_class_gpr);
1533 movi(rn(reg), i0);
1534 ldr_us(r0, rn(reg));
1535 jit_unget_reg(reg);
1536}
1537
1538static void
1539_ldi_i(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1540{
1541 jit_int32_t reg;
1542 reg = jit_get_reg(jit_class_gpr);
1543 movi(rn(reg), i0);
1544 ldr_i(r0, rn(reg));
1545 jit_unget_reg(reg);
1546}
1547
1548static void
1549_ldr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1550{
1551 LDRWI(r0, r1, 0);
1552#if 0
1553 extr_ui(r0, r0);
1554#endif
1555}
1556
1557static void
1558_ldi_ui(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1559{
1560 jit_int32_t reg;
1561 reg = jit_get_reg(jit_class_gpr);
1562 movi(rn(reg), i0);
1563 ldr_ui(r0, rn(reg));
1564 jit_unget_reg(reg);
1565}
1566
1567static void
1568_ldi_l(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1569{
1570 jit_int32_t reg;
1571 reg = jit_get_reg(jit_class_gpr);
1572 movi(rn(reg), i0);
1573 ldr_l(r0, rn(reg));
1574 jit_unget_reg(reg);
1575}
1576
1577static void
1578_ldxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1579{
1580 LDRSB(r0, r1, r2);
1581 extr_c(r0, r0);
1582}
1583
1584static void
1585_ldxi_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1586{
1587 jit_int32_t reg;
1588 if (i0 >= 0 && i0 <= 4095)
1589 LDRSBI(r0, r1, i0);
1590 else if (i0 > -256 && i0 < 0)
1591 LDURSB(r0, r1, i0 & 0x1ff);
1592 else {
1593 reg = jit_get_reg(jit_class_gpr);
1594 movi(rn(reg), i0);
1595 LDRSB(r0, r1, rn(reg));
1596 jit_unget_reg(reg);
1597 }
1598 extr_c(r0, r0);
1599}
1600
1601static void
1602_ldxr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1603{
1604 LDRB(r0, r1, r2);
1605#if 0
1606 extr_uc(r0, r0);
1607#endif
1608}
1609
1610static void
1611_ldxi_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1612{
1613 jit_int32_t reg;
1614 if (i0 >= 0 && i0 <= 4095)
1615 LDRBI(r0, r1, i0);
1616 else if (i0 > -256 && i0 < 0)
1617 LDURB(r0, r1, i0 & 0x1ff);
1618 else {
1619 reg = jit_get_reg(jit_class_gpr);
1620 addi(rn(reg), r1, i0);
1621 ldr_uc(r0, rn(reg));
1622 jit_unget_reg(reg);
1623 }
1624#if 0
1625 extr_uc(r0, r0);
1626#endif
1627}
1628
1629static void
1630_ldxi_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1631{
1632 jit_int32_t reg;
519a9ea1 1633 if (i0 >= 0 && i0 <= 8191 && !(i0 & 1))
4a71579b
PC
1634 LDRSHI(r0, r1, i0 >> 1);
1635 else if (i0 > -256 && i0 < 0)
1636 LDURSH(r0, r1, i0 & 0x1ff);
1637 else {
1638 reg = jit_get_reg(jit_class_gpr);
1639 movi(rn(reg), i0);
1640 LDRSH(r0, r1, rn(reg));
1641 jit_unget_reg(reg);
1642 }
1643}
1644
1645static void
1646_ldxr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1647{
1648 LDRH(r0, r1, r2);
1649#if 0
1650 extr_us(r0, r0);
1651#endif
1652}
1653
1654static void
1655_ldxi_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1656{
1657 jit_int32_t reg;
519a9ea1 1658 if (i0 >= 0 && i0 <= 8191 && !(i0 & 1))
4a71579b
PC
1659 LDRHI(r0, r1, i0 >> 1);
1660 else if (i0 > -256 && i0 < 0)
1661 LDURH(r0, r1, i0 & 0x1ff);
1662 else {
1663 reg = jit_get_reg(jit_class_gpr);
1664 movi(rn(reg), i0);
1665 LDRH(r0, r1, rn(reg));
1666 jit_unget_reg(reg);
1667 }
1668#if 0
1669 extr_us(r0, r0);
1670#endif
1671}
1672
1673static void
1674_ldxi_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1675{
1676 jit_int32_t reg;
519a9ea1 1677 if (i0 >= 0 && i0 <= 16383 && !(i0 & 3))
4a71579b
PC
1678 LDRSWI(r0, r1, i0 >> 2);
1679 else if (i0 > -256 && i0 < 0)
1680 LDURSW(r0, r1, i0 & 0x1ff);
1681 else {
1682 reg = jit_get_reg(jit_class_gpr);
1683 addi(rn(reg), r1, i0);
1684 ldr_i(r0, rn(reg));
1685 jit_unget_reg(reg);
1686 }
1687}
1688
1689static void
1690_ldxr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1691{
1692 LDRW(r0, r1, r2);
1693#if 0
1694 extr_ui(r0, r0);
1695#endif
1696}
1697
1698static void
1699_ldxi_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1700{
1701 jit_int32_t reg;
519a9ea1 1702 if (i0 >= 0 && i0 <= 16383 && !(i0 & 3))
4a71579b
PC
1703 LDRWI(r0, r1, i0 >> 2);
1704 else if (i0 > -256 && i0 < 0)
1705 LDURW(r0, r1, i0 & 0x1ff);
1706 else {
1707 reg = jit_get_reg(jit_class_gpr);
1708 movi(rn(reg), i0);
1709 LDRW(r0, r1, rn(reg));
1710 jit_unget_reg(reg);
1711 }
1712#if 0
1713 extr_ui(r0, r0);
1714#endif
1715}
1716
1717static void
1718_ldxi_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1719{
1720 jit_int32_t reg;
519a9ea1 1721 if (i0 >= 0 && i0 <= 32767 && !(i0 & 7))
4a71579b
PC
1722 LDRI(r0, r1, i0 >> 3);
1723 else if (i0 > -256 && i0 < 0)
1724 LDUR(r0, r1, i0 & 0x1ff);
1725 else {
1726 reg = jit_get_reg(jit_class_gpr);
1727 addi(rn(reg), r1, i0);
1728 ldr_l(r0, rn(reg));
1729 jit_unget_reg(reg);
1730 }
1731}
1732
1733static void
1734_sti_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
1735{
1736 jit_int32_t reg;
1737 reg = jit_get_reg(jit_class_gpr);
1738 movi(rn(reg), i0);
1739 str_c(rn(reg), r0);
1740 jit_unget_reg(reg);
1741}
1742
1743static void
1744_sti_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
1745{
1746 jit_int32_t reg;
1747 reg = jit_get_reg(jit_class_gpr);
1748 movi(rn(reg), i0);
1749 str_s(rn(reg), r0);
1750 jit_unget_reg(reg);
1751}
1752
1753static void
1754_sti_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
1755{
1756 jit_int32_t reg;
1757 reg = jit_get_reg(jit_class_gpr);
1758 movi(rn(reg), i0);
1759 str_i(rn(reg), r0);
1760 jit_unget_reg(reg);
1761}
1762
1763static void
1764_sti_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
1765{
1766 jit_int32_t reg;
1767 reg = jit_get_reg(jit_class_gpr);
1768 movi(rn(reg), i0);
1769 str_l(rn(reg), r0);
1770 jit_unget_reg(reg);
1771}
1772
1773static void
1774_stxi_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1775{
1776 jit_int32_t reg;
1777 if (i0 >= 0 && i0 <= 4095)
1778 STRBI(r1, r0, i0);
1779 else if (i0 > -256 && i0 < 0)
1780 STURB(r1, r0, i0 & 0x1ff);
1781 else {
1782 reg = jit_get_reg(jit_class_gpr);
1783 addi(rn(reg), r0, i0);
1784 str_c(rn(reg), r1);
1785 jit_unget_reg(reg);
1786 }
1787}
1788
1789static void
1790_stxi_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1791{
1792 jit_int32_t reg;
519a9ea1 1793 if (i0 >= 0 && i0 <= 8191 && !(i0 & 1))
4a71579b
PC
1794 STRHI(r1, r0, i0 >> 1);
1795 else if (i0 > -256 && i0 < 0)
1796 STURH(r1, r0, i0 & 0x1ff);
1797 else {
1798 reg = jit_get_reg(jit_class_gpr);
1799 addi(rn(reg), r0, i0);
1800 str_s(rn(reg), r1);
1801 jit_unget_reg(reg);
1802 }
1803}
1804
1805static void
1806_stxi_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1807{
1808 jit_int32_t reg;
519a9ea1 1809 if (i0 >= 0 && i0 <= 16383 && !(i0 & 3))
4a71579b
PC
1810 STRWI(r1, r0, i0 >> 2);
1811 else if (i0 > -256 && i0 < 0)
1812 STURW(r1, r0, i0 & 0x1ff);
1813 else {
1814 reg = jit_get_reg(jit_class_gpr);
1815 addi(rn(reg), r0, i0);
1816 str_i(rn(reg), r1);
1817 jit_unget_reg(reg);
1818 }
1819}
1820
1821static void
1822_stxi_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1823{
1824 jit_int32_t reg;
519a9ea1 1825 if (i0 >= 0 && i0 <= 32767 && !(i0 & 7))
4a71579b
PC
1826 STRI(r1, r0, i0 >> 3);
1827 else if (i0 > -256 && i0 < 0)
1828 STUR(r1, r0, i0 & 0x1ff);
1829 else {
1830 reg = jit_get_reg(jit_class_gpr);
1831 addi(rn(reg), r0, i0);
1832 str_l(rn(reg), r1);
1833 jit_unget_reg(reg);
1834 }
1835}
1836
1837static void
1838_movr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1839{
1840 if (r0 != r1)
1841 MOV(r0, r1);
1842}
1843
1844static void
1845_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1846{
1847 jit_word_t n0, ibit, nbit;
1848 n0 = ~i0;
1849 ibit = nbit = 0;
1850 if (i0 & 0x000000000000ffffL) ibit |= 1;
1851 if (i0 & 0x00000000ffff0000L) ibit |= 2;
1852 if (i0 & 0x0000ffff00000000L) ibit |= 4;
1853 if (i0 & 0xffff000000000000L) ibit |= 8;
1854 if (n0 & 0x000000000000ffffL) nbit |= 1;
1855 if (n0 & 0x00000000ffff0000L) nbit |= 2;
1856 if (n0 & 0x0000ffff00000000L) nbit |= 4;
1857 if (n0 & 0xffff000000000000L) nbit |= 8;
1858 switch (ibit) {
1859 case 0:
1860 MOVZ (r0, 0);
1861 break;
1862 case 1:
1863 MOVZ (r0, i0 & 0xffff);
1864 break;
1865 case 2:
1866 MOVZ_16(r0, (i0 >> 16) & 0xffff);
1867 break;
1868 case 3:
1869 MOVZ (r0, i0 & 0xffff);
1870 MOVK_16(r0, (i0 >> 16) & 0xffff);
1871 break;
1872 case 4:
1873 MOVZ_32(r0, (i0 >> 32) & 0xffff);
1874 break;
1875 case 5:
1876 MOVZ (r0, i0 & 0xffff);
1877 MOVK_32(r0, (i0 >> 32) & 0xffff);
1878 break;
1879 case 6:
1880 MOVZ_16(r0, (i0 >> 16) & 0xffff);
1881 MOVK_32(r0, (i0 >> 32) & 0xffff);
1882 break;
1883 case 7:
1884 if (nbit == 8)
1885 MOVN_48(r0, (n0 >> 48) & 0xffff);
1886 else {
1887 MOVZ (r0, i0 & 0xffff);
1888 MOVK_16(r0, (i0 >> 16) & 0xffff);
1889 MOVK_32(r0, (i0 >> 32) & 0xffff);
1890 }
1891 break;
1892 case 8:
1893 MOVZ_48(r0, (i0 >> 48) & 0xffff);
1894 break;
1895 case 9:
1896 MOVZ (r0, i0 & 0xffff);
1897 MOVK_48(r0, (i0 >> 48) & 0xffff);
1898 break;
1899 case 10:
1900 MOVZ_16(r0, (i0 >> 16) & 0xffff);
1901 MOVK_48(r0, (i0 >> 48) & 0xffff);
1902 break;
1903 case 11:
1904 if (nbit == 4)
1905 MOVN_32(r0, (n0 >> 32) & 0xffff);
1906 else {
1907 MOVZ (r0, i0 & 0xffff);
1908 MOVK_16(r0, (i0 >> 16) & 0xffff);
1909 MOVK_48(r0, (i0 >> 48) & 0xffff);
1910 }
1911 break;
1912 case 12:
1913 MOVZ_32(r0, (i0 >> 32) & 0xffff);
1914 MOVK_48(r0, (i0 >> 48) & 0xffff);
1915 break;
1916 case 13:
1917 if (nbit == 2)
1918 MOVN_16(r0, (n0 >> 16) & 0xffff);
1919 else {
1920 MOVZ (r0, i0 & 0xffff);
1921 MOVK_32(r0, (i0 >> 32) & 0xffff);
1922 MOVK_48(r0, (i0 >> 48) & 0xffff);
1923 }
1924 break;
1925 case 14:
1926 if (nbit == 1)
1927 MOVN (r0, (n0) & 0xffff);
1928 else {
1929 MOVZ_16(r0, (i0 >> 16) & 0xffff);
1930 MOVK_32(r0, (i0 >> 32) & 0xffff);
1931 MOVK_48(r0, (i0 >> 48) & 0xffff);
1932 }
1933 break;
1934 case 15:
1935 if (nbit == 0)
1936 MOVN (r0, 0);
1937 else if (nbit == 1)
1938 MOVN (r0, n0 & 0xffff);
1939 else if (nbit == 8)
1940 MOVN_48(r0, (n0 >> 48) & 0xffff);
1941 else {
1942 MOVZ (r0, i0 & 0xffff);
1943 MOVK_16(r0, (i0 >> 16) & 0xffff);
1944 MOVK_32(r0, (i0 >> 32) & 0xffff);
1945 MOVK_48(r0, (i0 >> 48) & 0xffff);
1946 }
1947 break;
1948 default:
1949 abort();
1950 }
1951}
1952
1953static jit_word_t
1954_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1955{
1956 jit_word_t w;
1957 w = _jit->pc.w;
1958 MOVZ (r0, i0 & 0xffff);
1959 MOVK_16(r0, (i0 >> 16) & 0xffff);
1960 MOVK_32(r0, (i0 >> 32) & 0xffff);
1961 MOVK_48(r0, (i0 >> 48) & 0xffff);
1962 return (w);
1963}
1964
1965static void
1966_ccr(jit_state_t *_jit, jit_int32_t cc,
1967 jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1968{
1969 CMP(r1, r2);
1970 CSET(r0, cc);
1971}
1972
1973static void
1974_cci(jit_state_t *_jit, jit_int32_t cc,
1975 jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1976{
1977 jit_int32_t reg;
1978 jit_word_t is = i0 >> 12;
1979 jit_word_t in = -i0;
1980 jit_word_t iS = in >> 12;
1981 if ( i0 >= 0 && i0 <= 0xfff)
1982 CMPI (r1, i0);
1983 else if ((is << 12) == i0 && is >= 0 && is <= 0xfff)
1984 CMPI_12(r1, is);
1985 else if ( in >= 0 && in <= 0xfff)
1986 CMNI (r1, in);
1987 else if ((iS << 12) == is && iS >= 0 && iS <= 0xfff)
1988 CMNI_12(r1, iS);
1989 else {
1990 reg = jit_get_reg(jit_class_gpr);
1991 movi(rn(reg), i0);
1992 CMP(r1, rn(reg));
1993 jit_unget_reg(reg);
1994 }
1995 CSET(r0, cc);
1996}
1997
1998static jit_word_t
1999_bccr(jit_state_t *_jit, jit_int32_t cc,
2000 jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2001{
2002 jit_word_t w, d;
2003 CMP(r0, r1);
2004 w = _jit->pc.w;
2005 d = (i0 - w) >> 2;
2006 B_C(cc, d);
2007 return (w);
2008}
2009
2010static jit_word_t
2011_bcci(jit_state_t *_jit, jit_int32_t cc,
2012 jit_word_t i0, jit_int32_t r0, jit_word_t i1)
2013{
2014 jit_int32_t reg;
2015 jit_word_t w, d;
2016 jit_word_t is = i1 >> 12;
2017 jit_word_t in = -i1;
2018 jit_word_t iS = in >> 12;
2019 if ( i1 >= 0 && i1 <= 0xfff)
2020 CMPI (r0, i1);
2021 else if ((is << 12) == i1 && is >= 0 && is <= 0xfff)
2022 CMPI_12(r0, is);
2023 else if ( in >= 0 && in <= 0xfff)
2024 CMNI (r0, in);
2025 else if ((iS << 12) == is && iS >= 0 && iS <= 0xfff)
2026 CMNI_12(r0, iS);
2027 else {
2028 reg = jit_get_reg(jit_class_gpr);
2029 movi(rn(reg), i1);
2030 CMP(r0, rn(reg));
2031 jit_unget_reg(reg);
2032 }
2033 w = _jit->pc.w;
2034 d = (i0 - w) >> 2;
2035 B_C(cc, d);
2036 return (w);
2037}
2038
2039static jit_word_t
2040_beqi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
2041{
2042 jit_word_t w;
2043 if (i1 == 0) {
2044 w = _jit->pc.w;
2045 CBZ(r0, (i0 - w) >> 2);
2046 }
2047 else
2048 w = bcci(BCC_EQ, i0, r0, i1);
2049 return (w);
2050}
2051
2052static jit_word_t
2053_bnei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
2054{
2055 jit_word_t w;
2056 if (i1 == 0) {
2057 w = _jit->pc.w;
2058 CBNZ(r0, (i0 - w) >> 2);
2059 }
2060 else
2061 w = bcci(BCC_NE, i0, r0, i1);
2062 return (w);
2063}
2064
2065static jit_word_t
2066_baddr(jit_state_t *_jit, jit_int32_t cc,
2067 jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2068{
2069 jit_word_t w;
2070 addcr(r0, r0, r1);
2071 w = _jit->pc.w;
2072 B_C(cc, (i0 - w) >> 2);
2073 return (w);
2074}
2075
2076static jit_word_t
2077_baddi(jit_state_t *_jit, jit_int32_t cc,
2078 jit_word_t i0, jit_int32_t r0, jit_word_t i1)
2079{
2080 jit_word_t w;
2081 addci(r0, r0, i1);
2082 w = _jit->pc.w;
2083 B_C(cc, (i0 - w) >> 2);
2084 return (w);
2085}
2086
2087static jit_word_t
2088_bsubr(jit_state_t *_jit, jit_int32_t cc,
2089 jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2090{
2091 jit_word_t w;
2092 subcr(r0, r0, r1);
2093 w = _jit->pc.w;
2094 B_C(cc, (i0 - w) >> 2);
2095 return (w);
2096}
2097
2098static jit_word_t
2099_bsubi(jit_state_t *_jit, jit_int32_t cc,
2100 jit_word_t i0, jit_int32_t r0, jit_word_t i1)
2101{
2102 jit_word_t w;
2103 subci(r0, r0, i1);
2104 w = _jit->pc.w;
2105 B_C(cc, (i0 - w) >> 2);
2106 return (w);
2107}
2108
2109static jit_word_t
2110_bmxr(jit_state_t *_jit, jit_int32_t cc,
2111 jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2112{
2113 jit_word_t w;
2114 TST(r0, r1);
2115 w = _jit->pc.w;
2116 B_C(cc, (i0 - w) >> 2);
2117 return (w);
2118}
2119
2120static jit_word_t
2121_bmxi(jit_state_t *_jit, jit_int32_t cc,
2122 jit_word_t i0, jit_int32_t r0, jit_word_t i1)
2123{
2124 jit_word_t w;
2125 jit_int32_t reg;
2126 jit_int32_t imm;
2127 imm = logical_immediate(i1);
2128 if (imm != -1)
2129 TSTI(r0, imm);
2130 else {
2131 reg = jit_get_reg(jit_class_gpr);
2132 movi(rn(reg), i1);
2133 TST(r0, rn(reg));
2134 jit_unget_reg(reg);
2135 }
2136 w = _jit->pc.w;
2137 B_C(cc, (i0 - w) >> 2);
2138 return (w);
2139}
2140
2141static void
2142_jmpi(jit_state_t *_jit, jit_word_t i0)
2143{
2144 jit_word_t w;
2145 jit_int32_t reg;
2146 w = (i0 - _jit->pc.w) >> 2;
2147 if (w >= -33554432 && w <= 33554431)
2148 B(w);
2149 else {
2150 reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
2151 movi(rn(reg), i0);
2152 jmpr(rn(reg));
2153 jit_unget_reg(reg);
2154 }
2155}
2156
2157static jit_word_t
2158_jmpi_p(jit_state_t *_jit, jit_word_t i0)
2159{
2160 jit_word_t w;
2161 jit_int32_t reg;
2162 reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
2163 w = movi_p(rn(reg), i0);
2164 jmpr(rn(reg));
2165 jit_unget_reg(reg);
2166 return (w);
2167}
2168
2169static void
2170_calli(jit_state_t *_jit, jit_word_t i0)
2171{
2172 jit_word_t w;
2173 jit_int32_t reg;
2174 w = (i0 - _jit->pc.w) >> 2;
2175 if (w >= -33554432 && w <= 33554431)
2176 BL(w);
2177 else {
2178 reg = jit_get_reg(jit_class_gpr);
2179 movi(rn(reg), i0);
2180 callr(rn(reg));
2181 jit_unget_reg(reg);
2182 }
2183}
2184
2185static jit_word_t
2186_calli_p(jit_state_t *_jit, jit_word_t i0)
2187{
2188 jit_word_t w;
2189 jit_int32_t reg;
2190 reg = jit_get_reg(jit_class_gpr);
2191 w = movi_p(rn(reg), i0);
2192 callr(rn(reg));
2193 jit_unget_reg(reg);
2194 return (w);
2195}
2196
2197/*
2198 * prolog and epilog not as "optimized" as one would like, but the
2199 * problem of overallocating stack space to save callee save registers
2200 * exists on all ports, and is still a todo to use a variable
2201 * stack_framesize
2202 * value, what would cause needing to patch some calls, most likely
2203 * the offset of jit_arg* of stack arguments.
2204 */
2205static void
2206_prolog(jit_state_t *_jit, jit_node_t *node)
2207{
2208 jit_int32_t reg;
2209 if (_jitc->function->define_frame || _jitc->function->assume_frame) {
2210 jit_int32_t frame = -_jitc->function->frame;
2211 assert(_jitc->function->self.aoff >= frame);
2212 if (_jitc->function->assume_frame)
2213 return;
2214 _jitc->function->self.aoff = frame;
2215 }
2216 if (_jitc->function->allocar)
2217 _jitc->function->self.aoff &= -16;
2218 _jitc->function->stack = ((_jitc->function->self.alen -
2219 /* align stack at 16 bytes */
2220 _jitc->function->self.aoff) + 15) & -16;
2221 STPI_POS(FP_REGNO, LR_REGNO, SP_REGNO, -(stack_framesize >> 3));
2222 MOV_XSP(FP_REGNO, SP_REGNO);
2223#define SPILL(L, R, O) \
2224 do { \
2225 if (jit_regset_tstbit(&_jitc->function->regset, _R##L)) { \
2226 if (jit_regset_tstbit(&_jitc->function->regset, _R##R)) \
2227 STPI(L, R, SP_REGNO, O); \
2228 else \
2229 STRI(L, SP_REGNO, O); \
2230 } \
2231 else if (jit_regset_tstbit(&_jitc->function->regset, _R##R)) \
2232 STRI(R, SP_REGNO, O + 1); \
2233 } while (0)
2234 SPILL(19, 20, 2);
2235 SPILL(21, 22, 4);
2236 SPILL(23, 24, 6);
2237 SPILL(25, 26, 8);
2238 SPILL(27, 28, 10);
2239#undef SPILL
2240#define SPILL(R, O) \
2241 do { \
2242 if (jit_regset_tstbit(&_jitc->function->regset, _V##R)) \
2243 stxi_d(O, SP_REGNO, R); \
2244 } while (0)
2245 SPILL( 8, 96);
2246 SPILL( 9, 104);
2247 SPILL(10, 112);
2248 SPILL(11, 120);
2249 SPILL(12, 128);
2250 SPILL(13, 136);
2251 SPILL(14, 144);
2252 SPILL(15, 152);
2253#undef SPILL
2254 if (_jitc->function->stack)
2255 subi(SP_REGNO, SP_REGNO, _jitc->function->stack);
2256 if (_jitc->function->allocar) {
2257 reg = jit_get_reg(jit_class_gpr);
2258 movi(rn(reg), _jitc->function->self.aoff);
2259 stxi_i(_jitc->function->aoffoff, FP_REGNO, rn(reg));
2260 jit_unget_reg(reg);
2261 }
2262
2263 if (_jitc->function->self.call & jit_call_varargs) {
2264 /* Save gp registers in the save area, if any is a vararg */
2265 for (reg = 8 - _jitc->function->vagp / -8;
2266 jit_arg_reg_p(reg); ++reg)
2267 stxi(_jitc->function->vaoff + offsetof(jit_va_list_t, x0) +
2268 reg * 8, FP_REGNO, rn(JIT_RA0 - reg));
2269
2270 for (reg = 8 - _jitc->function->vafp / -16;
2271 jit_arg_f_reg_p(reg); ++reg)
2272 /* Save fp registers in the save area, if any is a vararg */
2273 /* Note that the full 16 byte register is not saved, because
2274 * lightning only handles float and double, and, while
2275 * attempting to provide a va_list compatible pointer as
2276 * jit_va_start return, does not guarantee it (on all ports). */
2277 stxi_d(_jitc->function->vaoff + offsetof(jit_va_list_t, q0) +
2278 reg * 16 + offsetof(jit_qreg_t, l), FP_REGNO, rn(_V0 - reg));
2279 }
2280}
2281
2282static void
2283_epilog(jit_state_t *_jit, jit_node_t *node)
2284{
2285 if (_jitc->function->assume_frame)
2286 return;
2287 if (_jitc->function->stack)
2288 MOV_XSP(SP_REGNO, FP_REGNO);
2289#define LOAD(L, R, O) \
2290 do { \
2291 if (jit_regset_tstbit(&_jitc->function->regset, _R##L)) { \
2292 if (jit_regset_tstbit(&_jitc->function->regset, _R##R)) \
2293 LDPI(L, R, SP_REGNO, O); \
2294 else \
2295 LDRI(L, SP_REGNO, O); \
2296 } \
2297 else if (jit_regset_tstbit(&_jitc->function->regset, _R##R)) \
2298 LDRI(R, SP_REGNO, O + 1); \
2299 } while (0)
2300 LOAD(19, 20, 2);
2301 LOAD(21, 22, 4);
2302 LOAD(23, 24, 6);
2303 LOAD(25, 26, 8);
2304 LOAD(27, 28, 10);
2305#undef LOAD
2306#define LOAD(R, O) \
2307 do { \
2308 if (jit_regset_tstbit(&_jitc->function->regset, _V##R)) \
2309 ldxi_d(R, SP_REGNO, O); \
2310 } while (0)
2311 LOAD( 8, 96);
2312 LOAD( 9, 104);
2313 LOAD(10, 112);
2314 LOAD(11, 120);
2315 LOAD(12, 128);
2316 LOAD(13, 136);
2317 LOAD(14, 144);
2318 LOAD(15, 152);
2319#undef LOAD
2320 LDPI_PRE(FP_REGNO, LR_REGNO, SP_REGNO, stack_framesize >> 3);
2321 RET();
2322}
2323
2324static void
2325_vastart(jit_state_t *_jit, jit_int32_t r0)
2326{
2327 jit_int32_t reg;
2328
2329 assert(_jitc->function->self.call & jit_call_varargs);
2330
2331 /* Return jit_va_list_t in the register argument */
2332 addi(r0, FP_REGNO, _jitc->function->vaoff);
2333
2334 reg = jit_get_reg(jit_class_gpr);
2335
2336 /* Initialize stack pointer to the first stack argument. */
2337 addi(rn(reg), FP_REGNO, _jitc->function->self.size);
2338 stxi(offsetof(jit_va_list_t, stack), r0, rn(reg));
2339
2340 /* Initialize gp top pointer to the first stack argument. */
2341 addi(rn(reg), r0, va_gp_top_offset);
2342 stxi(offsetof(jit_va_list_t, gptop), r0, rn(reg));
2343
2344 /* Initialize fp top pointer to the first stack argument. */
2345 addi(rn(reg), r0, va_fp_top_offset);
2346 stxi(offsetof(jit_va_list_t, fptop), r0, rn(reg));
2347
2348 /* Initialize gp offset in the save area. */
2349 movi(rn(reg), _jitc->function->vagp);
2350 stxi_i(offsetof(jit_va_list_t, gpoff), r0, rn(reg));
2351
2352 /* Initialize fp offset in the save area. */
2353 movi(rn(reg), _jitc->function->vafp);
2354 stxi_i(offsetof(jit_va_list_t, fpoff), r0, rn(reg));
2355
2356 jit_unget_reg(reg);
2357}
2358
2359static void
2360_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
2361{
2362 jit_word_t ge_code;
2363 jit_word_t lt_code;
2364 jit_int32_t rg0, rg1;
2365
2366 assert(_jitc->function->self.call & jit_call_varargs);
2367
2368 rg0 = jit_get_reg(jit_class_gpr);
2369 rg1 = jit_get_reg(jit_class_gpr);
2370
2371 /* Load the gp offset in save area in the first temporary. */
2372 ldxi_i(rn(rg0), r1, offsetof(jit_va_list_t, gpoff));
2373
2374 /* Jump over if there are no remaining arguments in the save area. */
2375 ge_code = bgei(_jit->pc.w, rn(rg0), 0);
2376
2377 /* Load the gp save pointer in the second temporary. */
2378 ldxi(rn(rg1), r1, offsetof(jit_va_list_t, gptop));
2379
2380 /* Load the vararg argument in the first argument. */
2381 ldxr(r0, rn(rg1), rn(rg0));
2382
2383 /* Update the gp offset. */
2384 addi(rn(rg0), rn(rg0), 8);
2385 stxi_i(offsetof(jit_va_list_t, gpoff), r1, rn(rg0));
2386
2387 /* Will only need one temporary register below. */
2388 jit_unget_reg(rg1);
2389
2390 /* Jump over overflow code. */
2391 lt_code = jmpi_p(_jit->pc.w);
2392
2393 /* Where to land if argument is in overflow area. */
2394 patch_at(ge_code, _jit->pc.w);
2395
2396 /* Load stack pointer. */
2397 ldxi(rn(rg0), r1, offsetof(jit_va_list_t, stack));
2398
2399 /* Load argument. */
2400 ldr(r0, rn(rg0));
2401
2402 /* Update stack pointer. */
2403 addi(rn(rg0), rn(rg0), 8);
2404 stxi(offsetof(jit_va_list_t, stack), r1, rn(rg0));
2405
2406 /* Where to land if argument is in gp save area. */
2407 patch_at(lt_code, _jit->pc.w);
2408
2409 jit_unget_reg(rg0);
2410}
2411
2412static void
2413_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label)
2414{
2415 instr_t i;
2416 jit_word_t d;
2417 jit_int32_t fc, ff, ffc;
2418 union {
2419 jit_int32_t *i;
2420 jit_word_t w;
2421 } u;
2422 u.w = instr;
2423 i.w = u.i[0];
2424 fc = i.w & 0xfc000000;
2425 ff = i.w & 0xff000000;
2426 ffc = i.w & 0xffc00000;
2427 if (fc == A64_B || fc == A64_BL) {
2428 d = (label - instr) >> 2;
2429 assert(d >= -33554432 && d <= 33554431);
2430 i.imm26.b = d;
2431 u.i[0] = i.w;
2432 }
2433 else if (ff == A64_B_C || ff == (A64_CBZ|XS) || ff == (A64_CBNZ|XS)) {
2434 d = (label - instr) >> 2;
2435 assert(d >= -262148 && d <= 262143);
2436 i.imm19.b = d;
2437 u.i[0] = i.w;
2438 }
2439 else if (ffc == (A64_MOVZ|XS)) {
2440 i.imm16.b = label;
2441 u.i[0] = i.w;
2442 i.w = u.i[1];
2443 assert((i.w & 0xffe00000) == (A64_MOVK|XS|MOVI_LSL_16));
2444 i.imm16.b = label >> 16;
2445 u.i[1] = i.w;
2446 i.w = u.i[2];
2447 assert((i.w & 0xffe00000) == (A64_MOVK|XS|MOVI_LSL_32));
2448 i.imm16.b = label >> 32;
2449 u.i[2] = i.w;
2450 i.w = u.i[3];
2451 assert((i.w & 0xffe00000) == (A64_MOVK|XS|MOVI_LSL_48));
2452 i.imm16.b = label >> 48;
2453 u.i[3] = i.w;
2454 }
2455 else
2456 abort();
2457}
2458#endif