1 /*
2 * Copyright (C) 2012-2017,2019-2020 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 #define _s20P(d) ((d) >= -(int)0x80000 && d <= 0x7ffff)
21 #define _s24P(d) ((d) >= -(int)0x800000 && d <= 0x7fffff)
22 #define _u3(v) ((v) & 0x7)
23 #define _u4(v) ((v) & 0xf)
24 #define _u5(v) ((v) & 0x1f)
25 #define _u8(v) ((v) & 0xff)
26 #define _u12(v) ((v) & 0xfff)
27 #define _u13(v) ((v) & 0x1fff)
28 #define _u16(v) ((v) & 0xffff)
29 #define _u24(v) ((v) & 0xffffff)
30
31 #define ARM_CC_EQ 0x00000000 /* Z=1 */
32 #define ARM_CC_NE 0x10000000 /* Z=0 */
33 #define ARM_CC_HS 0x20000000 /* C=1 */
34 #define ARM_CC_LO 0x30000000 /* C=0 */
35 #define ARM_CC_MI 0x40000000 /* N=1 */
36 #define ARM_CC_VS 0x60000000 /* V=1 */
37 #define ARM_CC_VC 0x70000000 /* V=0 */
38 #define ARM_CC_HI 0x80000000 /* C=1 && Z=0 */
39 #define ARM_CC_LS 0x90000000 /* C=0 || Z=1 */
40 #define ARM_CC_GE 0xa0000000 /* N=V */
41 #define ARM_CC_LT 0xb0000000 /* N!=V */
42 #define ARM_CC_GT 0xc0000000 /* Z=0 && N=V */
43 #define ARM_CC_LE 0xd0000000 /* Z=1 || N!=V */
44 #define ARM_CC_AL 0xe0000000 /* always */
45 #define ARM_CC_NV 0xf0000000 /* reserved */
46 #define THUMB_MOV 0x4600
47 #define THUMB_MOVI 0x2000
48 #define THUMB2_MOVI 0xf0400000
49 #define THUMB2_MOVWI 0xf2400000
50 #define THUMB2_MOVTI 0xf2c00000
51 #define THUMB_MVN 0x43c0
52 #define THUMB2_MVN 0xea600000
53 #define THUMB2_MVNI 0xf0600000
54 #define ARM_S 0x00100000 /* set flags */
55 #define THUMB_ADD 0x1800
56 #define THUMB_ADDX 0x4400
57 #define THUMB2_ADD 0xeb000000
58 #define THUMB_ADDI3 0x1c00
59 #define THUMB_ADDI8 0x3000
60 #define THUMB2_ADDI 0xf1000000
61 #define THUMB2_ADDWI 0xf2000000
62 #define THUMB_ADC 0x4140
63 #define THUMB2_ADC 0xeb400000
64 #define THUMB2_ADCI 0xf1400000
65 #define THUMB_SUB 0x1a00
66 #define THUMB2_SUB 0xeba00000
67 #define THUMB_SUBI3 0x1e00
68 #define THUMB_SUBI8 0x3800
69 #define THUMB2_SUBI 0xf1a00000
70 #define THUMB2_SUBWI 0xf2a00000
71 #define THUMB_SBC 0x4180
72 #define THUMB2_SBC 0xeb600000
73 #define THUMB2_SBCI 0xf1600000
74 #define THUMB_RSBI 0x4240
75 #define THUMB2_RSBI 0xf1c00000
76 #define THUMB_MUL 0x4340
77 #define THUMB2_MUL 0xfb00f000
78 #define THUMB2_UMULL 0xfba00000
79 #define THUMB2_SMULL 0xfb800000
80 #define THUMB_MLS 0xfb000010
81 #define THUMB2_SDIV 0xfb90f0f0
82 #define THUMB2_UDIV 0xfbb0f0f0
83 #define THUMB_AND 0x4000
84 #define THUMB2_AND 0xea000000
85 #define THUMB2_ANDI 0xf0000000
86 #define THUMB2_BIC 0xea200000
87 #define THUMB2_BICI 0xf0200000
88 #define THUMB_ORR 0x4300
89 #define THUMB2_ORR 0xea400000
90 #define THUMB2_ORRI 0xf0400000
91 #define THUMB_EOR 0x4040
92 #define THUMB2_EOR 0xea800000
93 #define THUMB2_EORI 0xf0800000
94 #define THUMB_REV 0xba00
95 #define THUMB2_REV 0xfa90f080
96 #define THUMB_SXTB 0xb240
97 #define THUMB2_SXTB 0xfa40f080
98 #define THUMB_UXTB 0xb2c0
99 #define THUMB2_UXTB 0xfa50f080
100 #define THUMB_SXTH 0xb200
101 #define THUMB2_SXTH 0xfa00f080
102 #define THUMB_UXTH 0xb280
103 #define THUMB2_UXTH 0xfa10f080
104 #define ARM_LSL 0x00000000
105 #define THUMB_LSL 0x4080
106 #define THUMB2_LSL 0xfa00f000
107 #define THUMB_LSLI 0x0000
108 #define THUMB2_LSLI 0xea4f0000
109 #define ARM_LSR 0x00000020
110 #define THUMB_LSR 0x40c0
111 #define THUMB2_LSR 0xfa20f000
112 #define THUMB_LSRI 0x0800
113 #define THUMB2_LSRI 0xea4f0010
114 #define ARM_ASR 0x00000040
115 #define THUMB_ASR 0x4100
116 #define THUMB2_ASR 0xfa40f000
117 #define THUMB_ASRI 0x1000
118 #define THUMB2_ASRI 0xea4f0020
119 #define THUMB_CMP 0x4280
120 #define THUMB_CMPX 0x4500
121 #define THUMB2_CMP 0xebb00000
122 #define THUMB_CMPI 0x2800
123 #define THUMB2_CMPI 0xf1b00000
124 #define THUMB2_CMN 0xeb100000
125 #define THUMB2_CMNI 0xf1100000
126 #define THUMB_TST 0x4200
127 #define THUMB2_TST 0xea100000
128 #define THUMB2_TSTI 0xf0100000
129 #define THUMB_BLX 0x4780
130 #define THUMB_BX 0x4700
131 #define THUMB_CC_B 0xd000
132 #define THUMB_B 0xe000
133 #define THUMB2_CC_B 0xf0008000
134 #define THUMB2_B 0xf0009000
135 #define THUMB2_BLI 0xf000d000
136 #define THUMB2_BLXI 0xf000c000
137 #define THUMB2_P 0x00000400
138 #define THUMB2_U 0x00000200
139 #define THUMB_LDRSB 0x5600
140 #define THUMB2_LDRSB 0xf9100000
141 #define THUMB2_LDRSBI 0xf9100c00
142 #define THUMB2_LDRSBWI 0xf9900000
143 #define THUMB_LDRB 0x5c00
144 #define THUMB2_LDRB 0xf8100000
145 #define THUMB_LDRBI 0x7800
146 #define THUMB2_LDRBI 0xf8100c00
147 #define THUMB2_LDRBWI 0xf8900000
148 #define THUMB_LDRSH 0x5e00
149 #define THUMB2_LDRSH 0xf9300000
150 #define THUMB2_LDRSHI 0xf9300c00
151 #define THUMB2_LDRSHWI 0xf9b00000
152 #define THUMB_LDRH 0x5a00
153 #define THUMB2_LDRH 0xf8300000
154 #define THUMB_LDRHI 0x8800
155 #define THUMB2_LDRHI 0xf8300c00
156 #define THUMB2_LDRHWI 0xf8b00000
157 #define THUMB_LDR 0x5800
158 #define THUMB2_LDR 0xf8500000
159 #define THUMB2_LDRP 0xf85f0000
160 #define THUMB_LDRI 0x6800
161 #define THUMB_LDRISP 0x9800
162 #define THUMB2_LDRI 0xf8500c00
163 #define THUMB2_LDRWI 0xf8d00000
164 #define THUMB_STRB 0x5400
165 #define THUMB2_STRB 0xf8000000
166 #define THUMB_STRBI 0x7000
167 #define THUMB2_STRBI 0xf8000c00
168 #define THUMB2_STRBWI 0xf8800000
169 #define THUMB_STRH 0x5200
170 #define THUMB2_STRH 0xf8200000
171 #define THUMB_STRHI 0x8000
172 #define THUMB2_STRHI 0xf8200c00
173 #define THUMB2_STRHWI 0xf8a00000
174 #define THUMB_STR 0x5000
175 #define THUMB2_STR 0xf8400000
176 #define THUMB_STRI 0x6000
177 #define THUMB2_STRWI 0xf8c00000
178 #define THUMB_STRISP 0x9000
179 #define THUMB2_STRI 0xf8400c00
180 #define THUMB2_LDM_W 0x00200000
181 #define THUMB2_PUSH 0xe92d0000
182 #define THUMB_DMB 0xf3bf8f50
183 #define THUMB_LDREX 0xe8500f00
184 #define THUMB_STREX 0xe8400000
185 #define THUMB_BRK 0xbe00
186
187 #define _NOREG (jit_gpr_regno(_PC))
188
189 #define JIT_RELOC_B JIT_RELOC_FLAG_0
190
191 static void
emit_wide_thumb(jit_state_t * _jit,uint32_t inst)192 emit_wide_thumb(jit_state_t *_jit, uint32_t inst)
193 {
194 emit_u16(_jit, inst >> 16);
195 emit_u16_with_pool(_jit, inst & 0xffff);
196 }
197
198 static uint32_t
rotate_left(uint32_t v,uint32_t n)199 rotate_left(uint32_t v, uint32_t n) {
200 if (n == 0) {
201 return v;
202 }
203 ASSERT(n < 32);
204 return (v << n | v >> (32 - n));
205 }
206
207 static int
encode_arm_immediate(unsigned int v)208 encode_arm_immediate(unsigned int v)
209 {
210 unsigned int a, i;
211
212 for (i = 0; i < 32; i += 2)
213 if ((a = rotate_left(v, i)) <= 0xff)
214 return (a | (i << 7));
215
216 return (-1);
217 }
218
219 static int
encode_thumb_immediate(unsigned int v)220 encode_thumb_immediate(unsigned int v)
221 {
222 int i;
223 unsigned int m;
224 unsigned int n;
225 /* 00000000 00000000 00000000 abcdefgh */
226 if ((v & 0xff) == v)
227 return (v);
228 /* 00000000 abcdefgh 00000000 abcdefgh */
229 if ((v & 0xff00ff) == v && ((v & 0xff0000) >> 16) == (v & 0xff))
230 return ((v & 0xff) | (1 << 12));
231 /* abcdefgh 00000000 abcdefgh 00000000 */
232 if (((v & 0xffff0000) >> 16) == (v & 0xffff) && (v & 0xff) == 0)
233 return (((v & 0x0000ff00) >> 8) | (2 << 12));
234 /* abcdefgh abcdefgh abcdefgh abcdefgh */
235 if ( (v & 0xff) == ((v & 0xff00) >> 8) &&
236 ((v & 0xff00) >> 8) == ((v & 0xff0000) >> 16) &&
237 ((v & 0xff0000) << 8) == (v & 0xff000000))
238 return ((v & 0xff) | (3 << 12));
239 /* 1bcdefgh << 24 ... 1bcdefgh << 1 */
240 for (i = 8, m = 0xff000000, n = 0x80000000;
241 i < 23; i++, m >>= 1, n >>= 1) {
242 if ((v & m) == v && (v & n)) {
243 v >>= 32 - i;
244 if (!(i & 1))
245 v &= 0x7f;
246 i >>= 1;
247 return (((i & 7) << 12) | ((i & 8) << 23) | v);
248 }
249 }
250 return (-1);
251 }
252
253 static int
encode_thumb_word_immediate(unsigned int v)254 encode_thumb_word_immediate(unsigned int v)
255 {
256 if ((v & 0xfffff000) == 0)
257 return (((v & 0x800) << 15) | ((v & 0x700) << 4) | (v & 0xff));
258 return (-1);
259 }
260
261 static uint32_t
read_wide_thumb(uint32_t * loc)262 read_wide_thumb(uint32_t *loc)
263 {
264 uint16_t *sloc = (uint16_t*)loc;
265 return (sloc[0] << 16) | sloc[1];
266 }
267
268 static void
write_wide_thumb(uint32_t * loc,uint32_t v)269 write_wide_thumb(uint32_t *loc, uint32_t v)
270 {
271 uint16_t *sloc = (uint16_t *)loc;
272 sloc[0] = v >> 16;
273 sloc[1] = v & 0xffff;
274 }
275
276 static int
offset_in_jmp_range(int32_t offset,int flags)277 offset_in_jmp_range(int32_t offset, int flags)
278 {
279 if (!(offset & 1) && flags | JIT_RELOC_B)
280 return 0;
281 else
282 return -0x1000000 <= offset && offset <= 0xffffff;
283 }
284
285 static int32_t
decode_thumb_jump(uint32_t v)286 decode_thumb_jump(uint32_t v)
287 {
288 uint32_t s = (v >> 26) & 1;
289 uint32_t j1 = (v >> 13) & 1;
290 uint32_t j2 = (v >> 11) & 1;
291 uint32_t i1 = s ? j1 : !j1;
292 uint32_t i2 = s ? j2 : !j2;
293 uint32_t hi = (v >> 16) & 0x3ff;
294 uint32_t lo = v & 0x7ff;
295
296 int32_t ret = s << 31;
297 ret >>= 8;
298 ret |= i1 << 22;
299 ret |= i2 << 21;
300 ret |= hi << 11;
301 ret |= lo;
302 return ret << 1;
303 }
304
305 static const uint32_t thumb_jump_mask = 0xf800d000;
306
307 static uint32_t
encode_thumb_jump(int32_t v)308 encode_thumb_jump(int32_t v)
309 {
310 ASSERT(offset_in_jmp_range(v, 0));
311 v >>= 1;
312 uint32_t s = !!(v & 0x800000);
313 uint32_t i1 = !!(v & 0x400000);
314 uint32_t i2 = !!(v & 0x200000);
315 uint32_t j1 = s ? i1 : !i1;
316 uint32_t j2 = s ? i2 : !i2;
317 uint32_t ret = (s<<26)|((v&0x1ff800)<<5)|(j1<<13)|(j2<<11)|(v&0x7ff);
318 ASSERT(decode_thumb_jump(ret) == v << 1);
319 ASSERT((ret & thumb_jump_mask) == 0);
320 return ret;
321 }
322
323 static uint32_t
patch_thumb_jump(uint32_t inst,int32_t v)324 patch_thumb_jump(uint32_t inst, int32_t v)
325 {
326 inst &= thumb_jump_mask;
327 if (!(v & 1)) {
328 ASSERT(inst == THUMB2_BLI || inst == THUMB2_BLXI);
329 v = (v + 2) & ~2;
330 inst = THUMB2_BLXI;
331 }
332 return inst | encode_thumb_jump(v);
333 }
334
335 static int32_t
read_jmp_offset(uint32_t * loc)336 read_jmp_offset(uint32_t *loc)
337 {
338 return decode_thumb_jump(read_wide_thumb(loc));
339 }
340
341 static void
patch_jmp_offset(uint32_t * loc,int32_t v)342 patch_jmp_offset(uint32_t *loc, int32_t v)
343 {
344 write_wide_thumb(loc, patch_thumb_jump(read_wide_thumb(loc), v));
345 }
346
347 static void
patch_veneer_jmp_offset(uint32_t * loc,int32_t v)348 patch_veneer_jmp_offset(uint32_t *loc, int32_t v)
349 {
350 ASSERT(!(v & 1));
351 patch_jmp_offset(loc, v | 1);
352 }
353
354 static jit_reloc_t
emit_thumb_jump(jit_state_t * _jit,uint32_t inst)355 emit_thumb_jump(jit_state_t *_jit, uint32_t inst)
356 {
357 while (1) {
358 uint8_t *pc_base = _jit->pc.uc + 4;
359 int32_t off = (uint8_t*)jit_address(_jit) - pc_base;
360 enum jit_reloc_kind kind = JIT_RELOC_JMP_WITH_VENEER;
361 if (inst == THUMB2_B)
362 kind |= JIT_RELOC_B;
363 jit_reloc_t ret = jit_reloc (_jit, kind, 0, _jit->pc.uc, pc_base, 0);
364 uint8_t thumb_jump_width = 24;
365 if (add_pending_literal(_jit, ret, thumb_jump_width - 1)) {
366 emit_wide_thumb(_jit, patch_thumb_jump(inst, off));
367 return ret;
368 }
369 }
370 }
371
372 static int
offset_in_jcc_range(int32_t v,int flags)373 offset_in_jcc_range(int32_t v, int flags)
374 {
375 if (!(v & 1))
376 return 0;
377 else
378 return -0x100000 <= v && v <= 0xfffff;
379 }
380
381 static int32_t
decode_thumb_cc_jump(uint32_t v)382 decode_thumb_cc_jump(uint32_t v)
383 {
384 uint32_t s = (v >> 26) & 1;
385 uint32_t j1 = (v >> 13) & 1;
386 uint32_t j2 = (v >> 11) & 1;
387 uint32_t hi = (v >> 16) & 0x3f;
388 uint32_t lo = v & 0x7ff;
389
390 int32_t ret = s << 31;
391 ret >>= 12;
392 ret |= j2 << 18;
393 ret |= j1 << 17;
394 ret |= hi << 11;
395 ret |= lo;
396 return ret << 1;
397 }
398
399 static const uint32_t thumb_cc_jump_mask = 0xfbc0d000;
400
401 static uint32_t
encode_thumb_cc_jump(int32_t v)402 encode_thumb_cc_jump(int32_t v)
403 {
404 ASSERT(offset_in_jcc_range(v, 0));
405 v >>= 1;
406 uint32_t s = !!(v & 0x80000);
407 uint32_t j2 = !!(v & 0x40000);
408 uint32_t j1 = !!(v & 0x20000);
409 uint32_t hi = (v >> 11) & 0x3f;
410 uint32_t lo = v & 0x7ff;
411 uint32_t ret = (s<<26)|(hi << 16)|(j1<<13)|(j2<<11)|lo;
412 ASSERT(decode_thumb_cc_jump(ret) == v << 1);
413 ASSERT((ret & thumb_cc_jump_mask) == 0);
414 return ret;
415 }
416
417 static uint32_t
patch_thumb_cc_jump(uint32_t inst,int32_t v)418 patch_thumb_cc_jump(uint32_t inst, int32_t v)
419 {
420 return (inst & thumb_cc_jump_mask) | encode_thumb_cc_jump(v);
421 }
422
423 static int32_t
read_jcc_offset(uint32_t * loc)424 read_jcc_offset(uint32_t *loc)
425 {
426 return decode_thumb_cc_jump(read_wide_thumb(loc));
427 }
428
429 static void
patch_jcc_offset(uint32_t * loc,int32_t v)430 patch_jcc_offset(uint32_t *loc, int32_t v)
431 {
432 write_wide_thumb(loc, patch_thumb_cc_jump(read_wide_thumb(loc), v));
433 }
434
435 static void
patch_veneer_jcc_offset(uint32_t * loc,int32_t v)436 patch_veneer_jcc_offset(uint32_t *loc, int32_t v)
437 {
438 ASSERT(!(v & 1));
439 patch_jcc_offset(loc, v | 1);
440 }
441
442 static jit_reloc_t
emit_thumb_cc_jump(jit_state_t * _jit,uint32_t inst)443 emit_thumb_cc_jump(jit_state_t *_jit, uint32_t inst)
444 {
445 while (1) {
446 uint8_t *pc_base = _jit->pc.uc + 4;
447 int32_t off = (uint8_t*)jit_address(_jit) - pc_base;
448 jit_reloc_t ret =
449 jit_reloc (_jit, JIT_RELOC_JCC_WITH_VENEER, 0, _jit->pc.uc, pc_base, 0);
450 uint8_t thumb_cc_jump_width = 20;
451 if (add_pending_literal(_jit, ret, thumb_cc_jump_width - 1)) {
452 emit_wide_thumb(_jit, patch_thumb_cc_jump(inst, off));
453 return ret;
454 }
455 }
456 }
457
458 static void
torrr(jit_state_t * _jit,int o,int rn,int rd,int rm)459 torrr(jit_state_t *_jit, int o, int rn, int rd, int rm)
460 {
461 ASSERT(!(o & 0xf0f0f));
462 emit_wide_thumb(_jit, o|(_u4(rn)<<16)|(_u4(rd)<<8)|_u4(rm));
463 }
464
465 static void
torxr(jit_state_t * _jit,int o,int rn,int rt,int rm)466 torxr(jit_state_t *_jit, int o, int rn, int rt, int rm)
467 {
468 ASSERT(!(o & 0xf0f0f));
469 emit_wide_thumb(_jit, o|(_u4(rn)<<16)|(_u4(rt)<<12)|_u4(rm));
470 }
471
472 static void
torrrr(jit_state_t * _jit,int o,int rn,int rl,int rh,int rm)473 torrrr(jit_state_t *_jit, int o, int rn, int rl, int rh, int rm)
474 {
475 ASSERT(!(o & 0x000fff0f));
476 emit_wide_thumb(_jit, o|(_u4(rn)<<16)|(_u4(rl)<<12)|(_u4(rh)<<8)|_u4(rm));
477 }
478
479 static void
torri(jit_state_t * _jit,int o,int rn,int rd,int im)480 torri(jit_state_t *_jit, int o, int rn, int rd, int im)
481 {
482 ASSERT(!(o & 0x0c0f7fff));
483 ASSERT(!(im & 0xfbff8f00));
484 emit_wide_thumb(_jit, o|(_u4(rn)<<16)|(_u4(rd)<<8)|im);
485 }
486
487 static void
torri8(jit_state_t * _jit,int o,int rn,int rt,int im)488 torri8(jit_state_t *_jit, int o, int rn, int rt, int im)
489 {
490 ASSERT(!(o & 0x000ff0ff));
491 ASSERT(!(im & 0xffffff00));
492 emit_wide_thumb(_jit, o|(_u4(rn)<<16)|(_u4(rt)<<12)|im);
493 }
494
495 static void
torri12(jit_state_t * _jit,int o,int rn,int rt,int im)496 torri12(jit_state_t *_jit, int o, int rn, int rt, int im)
497 {
498 ASSERT(!(o & 0x000fffff));
499 ASSERT(!(im & 0xfffff000));
500 emit_wide_thumb(_jit, o|(_u4(rn)<<16)|(_u4(rt)<<12)|im);
501 }
502
503 static void
tshift(jit_state_t * _jit,int o,int rd,int rm,int im)504 tshift(jit_state_t *_jit, int o, int rd, int rm, int im)
505 {
506 ASSERT(!(o & 0x7fcf));
507 ASSERT(im >= 0 && im < 32);
508 emit_wide_thumb(_jit, o|((im&0x1c)<<10)|(_u4(rd)<<8)|((im&3)<<6)|_u4(rm));
509 }
510
511 static void
toriw(jit_state_t * _jit,int o,int rd,int im)512 toriw(jit_state_t *_jit, int o, int rd, int im)
513 {
514 ASSERT(!(im & 0xffff0000));
515 emit_wide_thumb(_jit, o|((im&0xf000)<<4)|((im&0x800)<<15)|((im&0x700)<<4)|(_u4(rd)<<8)|(im&0xff));
516 }
517
518 static jit_reloc_t
tcb(jit_state_t * _jit,int cc)519 tcb(jit_state_t *_jit, int cc)
520 {
521 ASSERT(!(cc & 0xfffffff));
522 ASSERT(cc != ARM_CC_AL && cc != ARM_CC_NV);
523 cc = ((uint32_t)cc) >> 6;
524 return emit_thumb_cc_jump(_jit, THUMB2_CC_B|cc);
525 }
526
527 static jit_reloc_t
tb(jit_state_t * _jit,int o)528 tb(jit_state_t *_jit, int o)
529 {
530 ASSERT(!(o & 0x07ff2fff));
531 return emit_thumb_jump(_jit, o);
532 }
533
534 static void
T1_ORR(jit_state_t * _jit,int32_t rdn,int32_t rm)535 T1_ORR(jit_state_t *_jit, int32_t rdn, int32_t rm)
536 {
537 emit_u16_with_pool(_jit, THUMB_ORR|(_u3(rm)<<3)|_u3(rdn));
538 }
539
540 static void
T2_ORR(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t rm)541 T2_ORR(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t rm)
542 {
543 return torrr(_jit, THUMB2_ORR,rn,rd,rm);
544 }
545
546 static void
T2_ORRI(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t im)547 T2_ORRI(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t im)
548 {
549 return torri(_jit, THUMB2_ORRI,rn,rd,im);
550 }
551
552 static void
T1_EOR(jit_state_t * _jit,int32_t rdn,int32_t rm)553 T1_EOR(jit_state_t *_jit, int32_t rdn, int32_t rm)
554 {
555 emit_u16_with_pool(_jit, THUMB_EOR|(_u3(rm)<<3)|_u3(rdn));
556 }
557
558 static void
T2_EOR(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t rm)559 T2_EOR(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t rm)
560 {
561 return torrr(_jit, THUMB2_EOR,rn,rd,rm);
562 }
563
564 static void
T2_EORI(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t im)565 T2_EORI(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t im)
566 {
567 return torri(_jit, THUMB2_EORI,rn,rd,im);
568 }
569
570 static void
T1_MOV(jit_state_t * _jit,int32_t rd,int32_t rm)571 T1_MOV(jit_state_t *_jit, int32_t rd, int32_t rm)
572 {
573 emit_u16_with_pool(_jit, THUMB_MOV|((_u4(rd)&8)<<4)|(_u4(rm)<<3)|(rd&7));
574 }
575
576 static void
T1_MOVI(jit_state_t * _jit,int32_t rd,int32_t im)577 T1_MOVI(jit_state_t *_jit, int32_t rd, int32_t im)
578 {
579 emit_u16_with_pool(_jit, THUMB_MOVI|(_u3(rd)<<8)|_u8(im));
580 }
581
582 static void
T2_MOVI(jit_state_t * _jit,int32_t rd,int32_t im)583 T2_MOVI(jit_state_t *_jit, int32_t rd, int32_t im)
584 {
585 return torri(_jit, THUMB2_MOVI,_NOREG,rd,im);
586 }
587
588 static void
T2_MOVWI(jit_state_t * _jit,int32_t rd,int32_t im)589 T2_MOVWI(jit_state_t *_jit, int32_t rd, int32_t im)
590 {
591 return toriw(_jit, THUMB2_MOVWI,rd,im);
592 }
593
594 static void
T2_MOVTI(jit_state_t * _jit,int32_t rd,int32_t im)595 T2_MOVTI(jit_state_t *_jit, int32_t rd, int32_t im)
596 {
597 return toriw(_jit, THUMB2_MOVTI,rd,im);
598 }
599
600 static void
T1_MVN(jit_state_t * _jit,int32_t rd,int32_t rm)601 T1_MVN(jit_state_t *_jit, int32_t rd, int32_t rm)
602 {
603 emit_u16_with_pool(_jit, THUMB_MVN|(_u3(rm)<<3)|_u3(rd));
604 }
605
606 static void
T2_MVN(jit_state_t * _jit,int32_t rd,int32_t rm)607 T2_MVN(jit_state_t *_jit, int32_t rd, int32_t rm)
608 {
609 return torrr(_jit, THUMB2_MVN,_NOREG,rd,rm);
610 }
611
612 static void
T2_MVNI(jit_state_t * _jit,int32_t rd,int32_t im)613 T2_MVNI(jit_state_t *_jit, int32_t rd, int32_t im)
614 {
615 return torri(_jit, THUMB2_MVNI,_NOREG,rd,im);
616 }
617
618 static void
T1_NOT(jit_state_t * _jit,int32_t rd,int32_t rm)619 T1_NOT(jit_state_t *_jit, int32_t rd, int32_t rm)
620 {
621 return T1_MVN(_jit, rd,rm);
622 }
623
624 static void
T2_NOT(jit_state_t * _jit,int32_t rd,int32_t rm)625 T2_NOT(jit_state_t *_jit, int32_t rd, int32_t rm)
626 {
627 return T2_MVN(_jit, rd,rm);
628 }
629
630 static void
T1_NOP(jit_state_t * _jit)631 T1_NOP(jit_state_t *_jit)
632 {
633 emit_u16_with_pool(_jit, 0xbf00);
634 }
635
636 static void
T1_ADD(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t rm)637 T1_ADD(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t rm)
638 {
639 emit_u16_with_pool(_jit, THUMB_ADD|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rd));
640 }
641
642 static void
T1_ADDX(jit_state_t * _jit,int32_t rdn,int32_t rm)643 T1_ADDX(jit_state_t *_jit, int32_t rdn, int32_t rm)
644 {
645 emit_u16_with_pool(_jit, THUMB_ADDX|((_u4(rdn)&8)<<4)|(_u4(rm)<<3)|(rdn&7));
646 }
647
648 static void
T2_ADD(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t rm)649 T2_ADD(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t rm)
650 {
651 return torrr(_jit, THUMB2_ADD,rn,rd,rm);
652 }
653
654 static void
T1_ADDI3(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t im)655 T1_ADDI3(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t im)
656 {
657 emit_u16_with_pool(_jit, THUMB_ADDI3|(_u3(im)<<6)|(_u3(rn)<<3)|_u3(rd));
658 }
659
660 static void
T1_ADDI8(jit_state_t * _jit,int32_t rdn,int32_t im)661 T1_ADDI8(jit_state_t *_jit, int32_t rdn, int32_t im)
662 {
663 emit_u16_with_pool(_jit, THUMB_ADDI8|(_u3(rdn)<<8)|_u8(im));
664 }
665
666 static void
T2_ADDI(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t im)667 T2_ADDI(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t im)
668 {
669 return torri(_jit, THUMB2_ADDI,rn,rd,im);
670 }
671
672 static void
T2_ADDWI(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t im)673 T2_ADDWI(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t im)
674 {
675 return torri(_jit, THUMB2_ADDWI,rn,rd,im);
676 }
677
678 static void
T2_ADDS(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t rm)679 T2_ADDS(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t rm)
680 {
681 return torrr(_jit, THUMB2_ADD|ARM_S,rn,rd,rm);
682 }
683
684 static void
T2_ADDSI(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t im)685 T2_ADDSI(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t im)
686 {
687 return torri(_jit, THUMB2_ADDI|ARM_S,rn,rd,im);
688 }
689
690 static void
T1_ADC(jit_state_t * _jit,int32_t rdn,int32_t rm)691 T1_ADC(jit_state_t *_jit, int32_t rdn, int32_t rm)
692 {
693 emit_u16_with_pool(_jit, THUMB_ADC|(_u3(rm)<<3)|_u3(rdn));
694 }
695
696 static void
T2_ADCS(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t rm)697 T2_ADCS(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t rm)
698 {
699 return torrr(_jit, THUMB2_ADC|ARM_S,rn,rd,rm);
700 }
701
702 static void
T2_ADCSI(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t im)703 T2_ADCSI(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t im)
704 {
705 return torri(_jit, THUMB2_ADCI|ARM_S,rn,rd,im);
706 }
707
708 static void
T1_SUB(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t rm)709 T1_SUB(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t rm)
710 {
711 emit_u16_with_pool(_jit, THUMB_SUB|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rd));
712 }
713
714 static void
T2_SUB(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t rm)715 T2_SUB(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t rm)
716 {
717 return torrr(_jit, THUMB2_SUB,rn,rd,rm);
718 }
719
720 static void
T1_SUBI3(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t im)721 T1_SUBI3(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t im)
722 {
723 emit_u16_with_pool(_jit, THUMB_SUBI3|(_u3(im)<<6)|(_u3(rn)<<3)|_u3(rd));
724 }
725
726 static void
T1_SUBI8(jit_state_t * _jit,int32_t rdn,int32_t im)727 T1_SUBI8(jit_state_t *_jit, int32_t rdn, int32_t im)
728 {
729 emit_u16_with_pool(_jit, THUMB_SUBI8|(_u3(rdn)<<8)|_u8(im));
730 }
731
732 static void
T2_SUBI(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t im)733 T2_SUBI(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t im)
734 {
735 return torri(_jit, THUMB2_SUBI,rn,rd,im);
736 }
737
738 static void
T2_SUBWI(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t im)739 T2_SUBWI(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t im)
740 {
741 return torri(_jit, THUMB2_SUBWI,rn,rd,im);
742 }
743
744 static void
T2_SUBS(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t rm)745 T2_SUBS(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t rm)
746 {
747 return torrr(_jit, THUMB2_SUB|ARM_S,rn,rd,rm);
748 }
749
750 static void
T2_SUBSI(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t im)751 T2_SUBSI(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t im)
752 {
753 return torri(_jit, THUMB2_SUBI|ARM_S,rn,rd,im);
754 }
755
756 static void
T1_SBC(jit_state_t * _jit,int32_t rdn,int32_t rm)757 T1_SBC(jit_state_t *_jit, int32_t rdn, int32_t rm)
758 {
759 emit_u16_with_pool(_jit, THUMB_SBC|(_u3(rm)<<3)|_u3(rdn));
760 }
761
762 static void
T2_SBCS(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t rm)763 T2_SBCS(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t rm)
764 {
765 return torrr(_jit, THUMB2_SBC|ARM_S,rn,rd,rm);
766 }
767
768 static void
T2_SBCSI(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t im)769 T2_SBCSI(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t im)
770 {
771 return torri(_jit, THUMB2_SBCI|ARM_S,rn,rd,im);
772 }
773
774 static void
T1_RSBI(jit_state_t * _jit,int32_t rd,int32_t rn)775 T1_RSBI(jit_state_t *_jit, int32_t rd, int32_t rn)
776 {
777 emit_u16_with_pool(_jit, THUMB_RSBI|(_u3(rn)<<3)|_u3(rd));
778 }
779
780 static void
T2_RSBI(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t im)781 T2_RSBI(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t im)
782 {
783 return torri(_jit, THUMB2_RSBI,rn,rd,im);
784 }
785
786 static void
T1_MUL(jit_state_t * _jit,int32_t rdm,int32_t rn)787 T1_MUL(jit_state_t *_jit, int32_t rdm, int32_t rn)
788 {
789 emit_u16_with_pool(_jit, THUMB_MUL|(_u3(rn)<<3)|_u3(rdm));
790 }
791
792 static void
T2_MUL(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t rm)793 T2_MUL(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t rm)
794 {
795 return torrr(_jit, THUMB2_MUL,rn,rd,rm);
796 }
797
798 static void
T2_SMULL(jit_state_t * _jit,int32_t rl,int32_t rh,int32_t rn,int32_t rm)799 T2_SMULL(jit_state_t *_jit, int32_t rl, int32_t rh, int32_t rn, int32_t rm)
800 {
801 return torrrr(_jit, THUMB2_SMULL,rn,rl,rh,rm);
802 }
803
804 static void
T2_UMULL(jit_state_t * _jit,int32_t rl,int32_t rh,int32_t rn,int32_t rm)805 T2_UMULL(jit_state_t *_jit, int32_t rl, int32_t rh, int32_t rn, int32_t rm)
806 {
807 return torrrr(_jit, THUMB2_UMULL,rn,rl,rh,rm);
808 }
809
810 static void
T2_SDIV(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t rm)811 T2_SDIV(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t rm)
812 {
813 return torrr(_jit, THUMB2_SDIV,rn,rd,rm);
814 }
815
816 static void
T2_UDIV(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t rm)817 T2_UDIV(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t rm)
818 {
819 return torrr(_jit, THUMB2_UDIV,rn,rd,rm);
820 }
821
822 static void
T1_MLS(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t rm,int32_t ra)823 T1_MLS(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t rm, int32_t ra)
824 {
825 return torrrr(_jit, THUMB_MLS, rn, ra, rd, rm);
826 }
827
828 static void
T1_AND(jit_state_t * _jit,int32_t rdn,int32_t rm)829 T1_AND(jit_state_t *_jit, int32_t rdn, int32_t rm)
830 {
831 emit_u16_with_pool(_jit, THUMB_AND|(_u3(rm)<<3)|_u3(rdn));
832 }
833
834 static void
T2_AND(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t rm)835 T2_AND(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t rm)
836 {
837 return torrr(_jit, THUMB2_AND,rn,rd,rm);
838 }
839
840 static void
T2_ANDI(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t im)841 T2_ANDI(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t im)
842 {
843 return torri(_jit, THUMB2_ANDI,rn,rd,im);
844 }
845
846 static void
T2_BICI(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t im)847 T2_BICI(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t im)
848 {
849 return torri(_jit, THUMB2_BICI,rn,rd,im);
850 }
851
852 static void
T1_REV(jit_state_t * _jit,int32_t rd,int32_t rm)853 T1_REV(jit_state_t *_jit, int32_t rd, int32_t rm)
854 {
855 emit_u16_with_pool(_jit, THUMB_REV|(_u3(rm)<<3)|_u3(rd));
856 }
857
858 static void
T2_REV(jit_state_t * _jit,int32_t rd,int32_t rm)859 T2_REV(jit_state_t *_jit, int32_t rd, int32_t rm)
860 {
861 return torrr(_jit, THUMB2_REV,rm,rd,rm);
862 }
863
864 static void
T1_SXTB(jit_state_t * _jit,int32_t rd,int32_t rm)865 T1_SXTB(jit_state_t *_jit, int32_t rd, int32_t rm)
866 {
867 emit_u16_with_pool(_jit, THUMB_SXTB|(_u3(rm)<<3)|_u3(rd));
868 }
869
870 static void
T2_SXTB(jit_state_t * _jit,int32_t rd,int32_t rm)871 T2_SXTB(jit_state_t *_jit, int32_t rd, int32_t rm)
872 {
873 return torrr(_jit, THUMB2_SXTB,_NOREG,rd,rm);
874 }
875
876 static void
T1_UXTB(jit_state_t * _jit,int32_t rd,int32_t rm)877 T1_UXTB(jit_state_t *_jit, int32_t rd, int32_t rm)
878 {
879 emit_u16_with_pool(_jit, THUMB_UXTB|(_u3(rm)<<3)|_u3(rd));
880 }
881
882 static void
T2_UXTB(jit_state_t * _jit,int32_t rd,int32_t rm)883 T2_UXTB(jit_state_t *_jit, int32_t rd, int32_t rm)
884 {
885 return torrr(_jit, THUMB2_UXTB,_NOREG,rd,rm);
886 }
887
888 static void
T1_SXTH(jit_state_t * _jit,int32_t rd,int32_t rm)889 T1_SXTH(jit_state_t *_jit, int32_t rd, int32_t rm)
890 {
891 emit_u16_with_pool(_jit, THUMB_SXTH|(_u3(rm)<<3)|_u3(rd));
892 }
893
894 static void
T2_SXTH(jit_state_t * _jit,int32_t rd,int32_t rm)895 T2_SXTH(jit_state_t *_jit, int32_t rd, int32_t rm)
896 {
897 return torrr(_jit, THUMB2_SXTH,_NOREG,rd,rm);
898 }
899
900 static void
T1_UXTH(jit_state_t * _jit,int32_t rd,int32_t rm)901 T1_UXTH(jit_state_t *_jit, int32_t rd, int32_t rm)
902 {
903 emit_u16_with_pool(_jit, THUMB_UXTH|(_u3(rm)<<3)|_u3(rd));
904 }
905
906 static void
T2_UXTH(jit_state_t * _jit,int32_t rd,int32_t rm)907 T2_UXTH(jit_state_t *_jit, int32_t rd, int32_t rm)
908 {
909 return torrr(_jit, THUMB2_UXTH,_NOREG,rd,rm);
910 }
911
912 static void
T1_LSL(jit_state_t * _jit,int32_t rdn,int32_t rm)913 T1_LSL(jit_state_t *_jit, int32_t rdn, int32_t rm)
914 {
915 emit_u16_with_pool(_jit, THUMB_LSL|(_u3(rm)<<3)|_u3(rdn));
916 }
917
918 static void
T2_LSL(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t rm)919 T2_LSL(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t rm)
920 {
921 return torrr(_jit, THUMB2_LSL,rn,rd,rm);
922 }
923
924 static void
T1_LSLI(jit_state_t * _jit,int32_t rd,int32_t rm,int32_t im)925 T1_LSLI(jit_state_t *_jit, int32_t rd, int32_t rm, int32_t im)
926 {
927 emit_u16_with_pool(_jit, THUMB_LSLI|(_u5(im)<<6)|(_u3(rm)<<3)|_u3(rd));
928 }
929
930 static void
T2_LSLI(jit_state_t * _jit,int32_t rd,int32_t rm,int32_t im)931 T2_LSLI(jit_state_t *_jit, int32_t rd, int32_t rm, int32_t im)
932 {
933 return tshift(_jit, THUMB2_LSLI,rd,rm,im);
934 }
935
936 static void
T1_LSR(jit_state_t * _jit,int32_t rdn,int32_t rm)937 T1_LSR(jit_state_t *_jit, int32_t rdn, int32_t rm)
938 {
939 emit_u16_with_pool(_jit, THUMB_LSR|(_u3(rm)<<3)|_u3(rdn));
940 }
941
942 static void
T2_LSR(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t rm)943 T2_LSR(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t rm)
944 {
945 return torrr(_jit, THUMB2_LSR,rn,rd,rm);
946 }
947
948 static void
T1_LSRI(jit_state_t * _jit,int32_t rd,int32_t rm,int32_t im)949 T1_LSRI(jit_state_t *_jit, int32_t rd, int32_t rm, int32_t im)
950 {
951 emit_u16_with_pool(_jit, THUMB_LSRI|(_u5(im)<<6)|(_u3(rm)<<3)|_u3(rd));
952 }
953
954 static void
T2_LSRI(jit_state_t * _jit,int32_t rd,int32_t rm,int32_t im)955 T2_LSRI(jit_state_t *_jit, int32_t rd, int32_t rm, int32_t im)
956 {
957 return tshift(_jit, THUMB2_LSRI,rd,rm,im);
958 }
959
960 static void
T1_ASR(jit_state_t * _jit,int32_t rdn,int32_t rm)961 T1_ASR(jit_state_t *_jit, int32_t rdn, int32_t rm)
962 {
963 emit_u16_with_pool(_jit, THUMB_ASR|(_u3(rm)<<3)|_u3(rdn));
964 }
965
966 static void
T2_ASR(jit_state_t * _jit,int32_t rd,int32_t rn,int32_t rm)967 T2_ASR(jit_state_t *_jit, int32_t rd, int32_t rn, int32_t rm)
968 {
969 return torrr(_jit, THUMB2_ASR,rn,rd,rm);
970 }
971
972 static void
T1_ASRI(jit_state_t * _jit,int32_t rd,int32_t rm,int32_t im)973 T1_ASRI(jit_state_t *_jit, int32_t rd, int32_t rm, int32_t im)
974 {
975 emit_u16_with_pool(_jit, THUMB_ASRI|(_u5(im)<<6)|(_u3(rm)<<3)|_u3(rd));
976 }
977
978 static void
T2_ASRI(jit_state_t * _jit,int32_t rd,int32_t rm,int32_t im)979 T2_ASRI(jit_state_t *_jit, int32_t rd, int32_t rm, int32_t im)
980 {
981 return tshift(_jit, THUMB2_ASRI,rd,rm,im);
982 }
983
984 static void
T1_CMP(jit_state_t * _jit,int32_t rn,int32_t rm)985 T1_CMP(jit_state_t *_jit, int32_t rn, int32_t rm)
986 {
987 emit_u16_with_pool(_jit, THUMB_CMP|(_u3(rm)<<3)|_u3(rn));
988 }
989
990 static void
T1_CMPX(jit_state_t * _jit,int32_t rn,int32_t rm)991 T1_CMPX(jit_state_t *_jit, int32_t rn, int32_t rm)
992 {
993 emit_u16_with_pool(_jit, THUMB_CMPX|((_u4(rn)&8)<<4)|(_u4(rm)<<3)|(rn&7));
994 }
995
996 static void
T2_CMP(jit_state_t * _jit,int32_t rn,int32_t rm)997 T2_CMP(jit_state_t *_jit, int32_t rn, int32_t rm)
998 {
999 return torrr(_jit, THUMB2_CMP,rn,_NOREG,rm);
1000 }
1001
1002 static void
T1_CMPI(jit_state_t * _jit,int32_t rn,int32_t im)1003 T1_CMPI(jit_state_t *_jit, int32_t rn, int32_t im)
1004 {
1005 emit_u16_with_pool(_jit, THUMB_CMPI|(_u3(rn)<<8)|_u8(im));
1006 }
1007
1008 static void
T2_CMPI(jit_state_t * _jit,int32_t rn,int32_t im)1009 T2_CMPI(jit_state_t *_jit, int32_t rn, int32_t im)
1010 {
1011 return torri(_jit, THUMB2_CMPI,rn,_NOREG,im);
1012 }
1013
1014 static void
T2_CMNI(jit_state_t * _jit,int32_t rn,int32_t im)1015 T2_CMNI(jit_state_t *_jit, int32_t rn, int32_t im)
1016 {
1017 return torri(_jit, THUMB2_CMNI,rn,_NOREG,im);
1018 }
1019
1020 static void
T1_TST(jit_state_t * _jit,int32_t rn,int32_t rm)1021 T1_TST(jit_state_t *_jit, int32_t rn, int32_t rm)
1022 {
1023 emit_u16_with_pool(_jit, THUMB_TST|(_u3(rm)<<3)|_u3(rn));
1024 }
1025
1026 static void
T2_TST(jit_state_t * _jit,int32_t rn,int32_t rm)1027 T2_TST(jit_state_t *_jit, int32_t rn, int32_t rm)
1028 {
1029 return torrr(_jit, THUMB2_TST,rn,_NOREG,rm);
1030 }
1031
1032 static void
T2_TSTI(jit_state_t * _jit,int32_t rn,int32_t im)1033 T2_TSTI(jit_state_t *_jit, int32_t rn, int32_t im)
1034 {
1035 return torri(_jit, THUMB2_TSTI,rn,_NOREG,im);
1036 }
1037
1038 static void
T1_BLX(jit_state_t * _jit,int32_t r0)1039 T1_BLX(jit_state_t *_jit, int32_t r0)
1040 {
1041 emit_u16_with_pool(_jit, THUMB_BLX|(_u4(r0)<<3));
1042 }
1043
1044 static void
T1_BX(jit_state_t * _jit,int32_t r0)1045 T1_BX(jit_state_t *_jit, int32_t r0)
1046 {
1047 emit_u16_with_pool(_jit, THUMB_BX|(_u4(r0)<<3));
1048 }
1049
1050 static jit_reloc_t
T2_CC_B(jit_state_t * _jit,uint32_t cc)1051 T2_CC_B(jit_state_t *_jit, uint32_t cc)
1052 {
1053 return tcb(_jit, cc);
1054 }
1055
1056 static jit_reloc_t
T2_B(jit_state_t * _jit)1057 T2_B(jit_state_t *_jit)
1058 {
1059 return tb(_jit, THUMB2_B);
1060 }
1061
1062 static jit_reloc_t
T2_BLI(jit_state_t * _jit)1063 T2_BLI(jit_state_t *_jit)
1064 {
1065 return tb(_jit, THUMB2_BLI);
1066 }
1067
1068 enum dmb_option { DMB_ISH = 0xb };
1069 static void
T1_DMB(jit_state_t * _jit,enum dmb_option option)1070 T1_DMB(jit_state_t *_jit, enum dmb_option option)
1071 {
1072 emit_wide_thumb(_jit, THUMB_DMB|_u4(option));
1073 }
1074
1075 static void
T1_LDREX(jit_state_t * _jit,int32_t rt,int32_t rn,int8_t offset)1076 T1_LDREX(jit_state_t *_jit, int32_t rt, int32_t rn, int8_t offset)
1077 {
1078 emit_wide_thumb(_jit, THUMB_LDREX|(_u4(rn)<<16)|(_u4(rt)<<12)|_u8(offset));
1079 }
1080
1081 static void
T1_STREX(jit_state_t * _jit,int32_t rd,int32_t rt,int32_t rn,int8_t offset)1082 T1_STREX(jit_state_t *_jit, int32_t rd, int32_t rt, int32_t rn, int8_t offset)
1083 {
1084 emit_wide_thumb
1085 (_jit, THUMB_STREX|(_u4(rn)<<16)|(_u4(rt)<<12)|(_u4(rd)<<8)|_u8(offset));
1086 }
1087
1088 static void
T1_LDRSB(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t rm)1089 T1_LDRSB(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t rm)
1090 {
1091 emit_u16_with_pool(_jit, THUMB_LDRSB|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rt));
1092 }
1093
1094 static void
T2_LDRSB(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t rm)1095 T2_LDRSB(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t rm)
1096 {
1097 return torxr(_jit, THUMB2_LDRSB,rn,rt,rm);
1098 }
1099
1100 static void
T2_LDRSBI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1101 T2_LDRSBI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1102 {
1103 return torri8(_jit, THUMB2_LDRSBI|THUMB2_U,rn,rt,im);
1104 }
1105
1106 static void
T2_LDRSBWI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1107 T2_LDRSBWI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1108 {
1109 return torri12(_jit, THUMB2_LDRSBWI,rn,rt,im);
1110 }
1111
1112 static void
T2_LDRSBIN(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1113 T2_LDRSBIN(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1114 {
1115 return torri8(_jit, THUMB2_LDRSBI,rn,rt,im);
1116 }
1117
1118 static void
T1_LDRB(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t rm)1119 T1_LDRB(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t rm)
1120 {
1121 emit_u16_with_pool(_jit, THUMB_LDRB|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rt));
1122 }
1123
1124 static void
T2_LDRB(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t rm)1125 T2_LDRB(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t rm)
1126 {
1127 return torxr(_jit, THUMB2_LDRB,rn,rt,rm);
1128 }
1129
1130 static void
T1_LDRBI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1131 T1_LDRBI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1132 {
1133 emit_u16_with_pool(_jit, THUMB_LDRBI|(_u5(im)<<6)|(_u3(rn)<<3)|_u3(rt));
1134 }
1135
1136 static void
T2_LDRBI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1137 T2_LDRBI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1138 {
1139 return torri8(_jit, THUMB2_LDRBI|THUMB2_U,rn,rt,im);
1140 }
1141
1142 static void
T2_LDRBWI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1143 T2_LDRBWI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1144 {
1145 return torri12(_jit, THUMB2_LDRBWI,rn,rt,im);
1146 }
1147
1148 static void
T2_LDRBIN(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1149 T2_LDRBIN(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1150 {
1151 return torri8(_jit, THUMB2_LDRBI,rn,rt,im);
1152 }
1153
1154 static void
T1_LDRSH(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t rm)1155 T1_LDRSH(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t rm)
1156 {
1157 emit_u16_with_pool(_jit, THUMB_LDRSH|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rt));
1158 }
1159
1160 static void
T2_LDRSH(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t rm)1161 T2_LDRSH(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t rm)
1162 {
1163 return torxr(_jit, THUMB2_LDRSH,rn,rt,rm);
1164 }
1165
1166 static void
T2_LDRSHI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1167 T2_LDRSHI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1168 {
1169 return torri8(_jit, THUMB2_LDRSHI|THUMB2_U,rn,rt,im);
1170 }
1171
1172 static void
T2_LDRSHWI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1173 T2_LDRSHWI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1174 {
1175 return torri12(_jit, THUMB2_LDRSHWI,rn,rt,im);
1176 }
1177
1178 static void
T2_LDRSHIN(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1179 T2_LDRSHIN(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1180 {
1181 return torri8(_jit, THUMB2_LDRSHI,rn,rt,im);
1182 }
1183
1184 static void
T1_LDRH(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t rm)1185 T1_LDRH(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t rm)
1186 {
1187 emit_u16_with_pool(_jit, THUMB_LDRH|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rt));
1188 }
1189
1190 static void
T2_LDRH(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t rm)1191 T2_LDRH(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t rm)
1192 {
1193 return torxr(_jit, THUMB2_LDRH,rn,rt,rm);
1194 }
1195
1196 static void
T1_LDRHI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1197 T1_LDRHI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1198 {
1199 emit_u16_with_pool(_jit, THUMB_LDRHI|(_u5(im)<<6)|(_u3(rn)<<3)|_u3(rt));
1200 }
1201
1202 static void
T2_LDRHI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1203 T2_LDRHI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1204 {
1205 return torri8(_jit, THUMB2_LDRHI|THUMB2_U,rn,rt,im);
1206 }
1207
1208 static void
T2_LDRHWI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1209 T2_LDRHWI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1210 {
1211 return torri12(_jit, THUMB2_LDRHWI,rn,rt,im);
1212 }
1213
1214 static void
T2_LDRHIN(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1215 T2_LDRHIN(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1216 {
1217 return torri8(_jit, THUMB2_LDRHI,rn,rt,im);
1218 }
1219
1220 static void
T1_LDR(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t rm)1221 T1_LDR(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t rm)
1222 {
1223 emit_u16_with_pool(_jit, THUMB_LDR|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rt));
1224 }
1225
1226 static void
T2_LDR(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t rm)1227 T2_LDR(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t rm)
1228 {
1229 return torxr(_jit, THUMB2_LDR,rn,rt,rm);
1230 }
1231
1232 static void
T1_LDRI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1233 T1_LDRI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1234 {
1235 emit_u16_with_pool(_jit, THUMB_LDRI|(_u5(im)<<6)|(_u3(rn)<<3)|_u3(rt));
1236 }
1237
1238 static void
T1_LDRISP(jit_state_t * _jit,int32_t rt,int32_t im)1239 T1_LDRISP(jit_state_t *_jit, int32_t rt, int32_t im)
1240 {
1241 emit_u16_with_pool(_jit, THUMB_LDRISP|(_u3(rt)<<8)|_u8(im));
1242 }
1243
1244 static void
T2_LDRI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1245 T2_LDRI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1246 {
1247 return torri8(_jit, THUMB2_LDRI|THUMB2_U,rn,rt,im);
1248 }
1249
1250 static void
T2_LDRWI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1251 T2_LDRWI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1252 {
1253 return torri12(_jit, THUMB2_LDRWI,rn,rt,im);
1254 }
1255
1256 static void
T2_LDRIN(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1257 T2_LDRIN(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1258 {
1259 return torri8(_jit, THUMB2_LDRI,rn,rt,im);
1260 }
1261
1262 static void
T1_STRB(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t rm)1263 T1_STRB(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t rm)
1264 {
1265 emit_u16_with_pool(_jit, THUMB_STRB|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rt));
1266 }
1267
1268 static void
T2_STRB(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t rm)1269 T2_STRB(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t rm)
1270 {
1271 return torxr(_jit, THUMB2_STRB,rn,rt,rm);
1272 }
1273
1274 static void
T1_STRBI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1275 T1_STRBI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1276 {
1277 emit_u16_with_pool(_jit, THUMB_STRBI | (_u5(im) << 6) | (_u3(rn) << 3) | _u3(rt));
1278 }
1279
1280 static void
T2_STRBI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1281 T2_STRBI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1282 {
1283 return torri8(_jit, THUMB2_STRBI|THUMB2_U,rn,rt,im);
1284 }
1285
1286 static void
T2_STRBWI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1287 T2_STRBWI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1288 {
1289 return torri12(_jit, THUMB2_STRBWI,rn,rt,im);
1290 }
1291
1292 static void
T2_STRBIN(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1293 T2_STRBIN(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1294 {
1295 return torri8(_jit, THUMB2_STRBI,rn,rt,im);
1296 }
1297
1298 static void
T1_STRH(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t rm)1299 T1_STRH(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t rm)
1300 {
1301 emit_u16_with_pool(_jit, THUMB_STRH|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rt));
1302 }
1303
1304 static void
T2_STRH(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t rm)1305 T2_STRH(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t rm)
1306 {
1307 return torxr(_jit, THUMB2_STRH,rn,rt,rm);
1308 }
1309
1310 static void
T1_STRHI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1311 T1_STRHI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1312 {
1313 emit_u16_with_pool(_jit, THUMB_STRHI|(_u5(im)<<6)|(_u3(rn)<<3)|_u3(rt));
1314 }
1315
1316 static void
T2_STRHI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1317 T2_STRHI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1318 {
1319 return torri8(_jit, THUMB2_STRHI|THUMB2_U,rn,rt,im);
1320 }
1321
1322 static void
T2_STRHWI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1323 T2_STRHWI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1324 {
1325 return torri12(_jit, THUMB2_STRHWI,rn,rt,im);
1326 }
1327
1328 static void
T2_STRHIN(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1329 T2_STRHIN(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1330 {
1331 return torri8(_jit, THUMB2_STRHI,rn,rt,im);
1332 }
1333
1334 static void
T1_STR(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t rm)1335 T1_STR(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t rm)
1336 {
1337 emit_u16_with_pool(_jit, THUMB_STR|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rt));
1338 }
1339
1340 static void
T2_STR(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t rm)1341 T2_STR(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t rm)
1342 {
1343 return torxr(_jit, THUMB2_STR,rn,rt,rm);
1344 }
1345
1346 static void
T1_STRI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1347 T1_STRI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1348 {
1349 emit_u16_with_pool(_jit, THUMB_STRI|(_u5(im)<<6)|(_u3(rn)<<3)|_u3(rt));
1350 }
1351
1352 static void
T1_STRISP(jit_state_t * _jit,int32_t rt,int32_t im)1353 T1_STRISP(jit_state_t *_jit, int32_t rt, int32_t im)
1354 {
1355 emit_u16_with_pool(_jit, THUMB_STRISP|(_u3(rt)<<8)|(_u8(im)));
1356 }
1357
1358 static void
T2_STRI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1359 T2_STRI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1360 {
1361 return torri8(_jit, THUMB2_STRI|THUMB2_U,rn,rt,im);
1362 }
1363
1364 static void
T2_STRWI(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1365 T2_STRWI(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1366 {
1367 return torri12(_jit, THUMB2_STRWI,rn,rt,im);
1368 }
1369
1370 static void
T2_STRIN(jit_state_t * _jit,int32_t rt,int32_t rn,int32_t im)1371 T2_STRIN(jit_state_t *_jit, int32_t rt, int32_t rn, int32_t im)
1372 {
1373 return torri8(_jit, THUMB2_STRI,rn,rt,im);
1374 }
1375
1376 static void
T1_BRK(jit_state_t * _jit)1377 T1_BRK(jit_state_t *_jit)
1378 {
1379 emit_u16_with_pool(_jit, THUMB_BRK);
1380 }
1381
1382 static void
nop(jit_state_t * _jit,int32_t i0)1383 nop(jit_state_t *_jit, int32_t i0)
1384 {
1385 for (; i0 > 0; i0 -= 2)
1386 T1_NOP(_jit);
1387
1388 ASSERT(i0 == 0);
1389 }
1390
1391 static void
movr(jit_state_t * _jit,int32_t r0,int32_t r1)1392 movr(jit_state_t *_jit, int32_t r0, int32_t r1)
1393 {
1394 if (r0 != r1) {
1395 T1_MOV(_jit, r0, r1);
1396 }
1397 }
1398
1399 enum preserve_flags { PRESERVE_FLAGS, FLAGS_UNIMPORTANT };
1400
1401 static void
_movi(jit_state_t * _jit,int32_t r0,jit_word_t i0,enum preserve_flags flags)1402 _movi(jit_state_t *_jit, int32_t r0, jit_word_t i0, enum preserve_flags flags)
1403 {
1404 int i;
1405
1406 if (flags == PRESERVE_FLAGS && r0 < 8 && !(i0 & 0xffffff80))
1407 T1_MOVI(_jit, r0, i0);
1408 else if (r0 < 8 && !(i0 & 0xffffff80))
1409 T1_MOVI(_jit, r0, i0);
1410 else if ((i = encode_thumb_immediate(i0)) != -1)
1411 T2_MOVI(_jit, r0, i);
1412 else if ((i = encode_thumb_immediate(~i0)) != -1)
1413 T2_MVNI(_jit, r0, i);
1414 else {
1415 T2_MOVWI(_jit, r0, (uint16_t)i0);
1416 if (i0 & 0xffff0000)
1417 T2_MOVTI(_jit, r0, (uint16_t)((unsigned)i0 >> 16));
1418 }
1419 }
1420
1421 static void
movi(jit_state_t * _jit,int32_t r0,jit_word_t i0)1422 movi(jit_state_t *_jit, int32_t r0, jit_word_t i0)
1423 {
1424 return _movi(_jit, r0, i0, FLAGS_UNIMPORTANT);
1425 }
1426
1427 static int
offset_in_load_from_pool_range(int32_t offset)1428 offset_in_load_from_pool_range(int32_t offset)
1429 {
1430 return -0xfff <= offset && offset <= 0xfff;
1431 }
1432
1433 static int32_t
decode_load_from_pool_offset(uint32_t inst)1434 decode_load_from_pool_offset(uint32_t inst)
1435 {
1436 int32_t ret = inst & 0xfff;
1437 return ((inst >> 23) & 1) ? ret : -ret;
1438 }
1439
1440 static uint32_t
encode_load_from_pool_offset(int32_t off)1441 encode_load_from_pool_offset(int32_t off)
1442 {
1443 ASSERT(offset_in_load_from_pool_range(off));
1444 uint32_t u = off >= 0;
1445 uint32_t ret = ((u ? off : -off) & 0xfff) | (u << 23);
1446 ASSERT(decode_load_from_pool_offset(ret) == off);
1447 return ret;
1448 }
1449
1450 static uint32_t
patch_load_from_pool(uint32_t inst,int32_t off)1451 patch_load_from_pool(uint32_t inst, int32_t off)
1452 {
1453 uint32_t load_from_pool_mask = THUMB2_LDRP | (0xf << 12);
1454 return (inst & load_from_pool_mask) | encode_load_from_pool_offset(off);
1455 }
1456
1457 static int32_t
read_load_from_pool_offset(uint32_t * loc)1458 read_load_from_pool_offset(uint32_t *loc)
1459 {
1460 return decode_load_from_pool_offset(read_wide_thumb(loc));
1461 }
1462
1463 static void
patch_load_from_pool_offset(uint32_t * loc,int32_t v)1464 patch_load_from_pool_offset(uint32_t *loc, int32_t v)
1465 {
1466 write_wide_thumb(loc, patch_load_from_pool(read_wide_thumb(loc), v));
1467 }
1468
1469 static jit_reloc_t
emit_load_from_pool(jit_state_t * _jit,uint32_t inst)1470 emit_load_from_pool(jit_state_t *_jit, uint32_t inst)
1471 {
1472 while (1) {
1473 uint8_t *pc_base = (uint8_t *)((_jit->pc.w + 4) & ~3);
1474 uint8_t rsh = 0;
1475 int32_t off = (_jit->pc.uc - pc_base) >> rsh;
1476 jit_reloc_t ret =
1477 jit_reloc (_jit, JIT_RELOC_LOAD_FROM_POOL, 0, _jit->pc.uc, pc_base, rsh);
1478 uint8_t load_from_pool_width = 12;
1479 if (add_pending_literal(_jit, ret, load_from_pool_width)) {
1480 emit_wide_thumb(_jit, patch_load_from_pool(inst, off));
1481 return ret;
1482 }
1483 }
1484 }
1485
1486 static jit_reloc_t
movi_from_pool(jit_state_t * _jit,int32_t Rt)1487 movi_from_pool(jit_state_t *_jit, int32_t Rt)
1488 {
1489 return emit_load_from_pool(_jit, THUMB2_LDRP | (_u4(Rt) << 12));
1490 }
1491
1492 static jit_reloc_t
mov_addr(jit_state_t * _jit,int32_t r0)1493 mov_addr(jit_state_t *_jit, int32_t r0)
1494 {
1495 return movi_from_pool(_jit, r0);
1496 }
1497
1498 static void
comr(jit_state_t * _jit,int32_t r0,int32_t r1)1499 comr(jit_state_t *_jit, int32_t r0, int32_t r1)
1500 {
1501 if ((r0|r1) < 8)
1502 T1_NOT(_jit, r0, r1);
1503 else
1504 T2_NOT(_jit, r0, r1);
1505 }
1506
1507 static void
negr(jit_state_t * _jit,int32_t r0,int32_t r1)1508 negr(jit_state_t *_jit, int32_t r0, int32_t r1)
1509 {
1510 if ((r0|r1) < 8)
1511 T1_RSBI(_jit, r0, r1);
1512 else
1513 T2_RSBI(_jit, r0, r1, 0);
1514 }
1515
1516 static void
addr(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)1517 addr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
1518 {
1519 if ((r0|r1|r2) < 8)
1520 T1_ADD(_jit, r0, r1, r2);
1521 else if (r0 == r1 || r0 == r2)
1522 T1_ADDX(_jit, r0, r0 == r1 ? r2 : r1);
1523 else
1524 T2_ADD(_jit, r0, r1, r2);
1525 }
1526
1527 static void
addi(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)1528 addi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
1529 {
1530 int i;
1531
1532 if ((r0|r1) < 8 && !(i0 & ~7))
1533 T1_ADDI3(_jit, r0, r1, i0);
1534 else if ((r0|r1) < 8 && !(-i0 & ~7))
1535 T1_SUBI3(_jit, r0, r1, -i0);
1536 else if (r0 < 8 && r0 == r1 && !(i0 & ~0xff))
1537 T1_ADDI8(_jit, r0, i0);
1538 else if (r0 < 8 && r0 == r1 && !(-i0 & ~0xff))
1539 T1_SUBI8(_jit, r0, -i0);
1540 else if ((i = encode_thumb_immediate(i0)) != -1)
1541 T2_ADDI(_jit, r0, r1, i);
1542 else if ((i = encode_thumb_immediate(-i0)) != -1)
1543 T2_SUBI(_jit, r0, r1, i);
1544 else if ((i = encode_thumb_word_immediate(i0)) != -1)
1545 T2_ADDWI(_jit, r0, r1, i);
1546 else if ((i = encode_thumb_word_immediate(-i0)) != -1)
1547 T2_SUBWI(_jit, r0, r1, i);
1548 else {
1549 jit_gpr_t reg = get_temp_gpr(_jit);
1550 movi(_jit, jit_gpr_regno(reg), i0);
1551 T2_ADD(_jit, r0, r1, jit_gpr_regno(reg));
1552 unget_temp_gpr(_jit);
1553 }
1554 }
1555
1556 static void
addcr(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)1557 addcr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
1558 {
1559 /* thumb auto set carry if not inside IT block */
1560 if ((r0|r1|r2) < 8)
1561 T1_ADD(_jit, r0, r1, r2);
1562 else
1563 T2_ADDS(_jit, r0, r1, r2);
1564 }
1565
1566 static void
addci(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)1567 addci(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
1568 {
1569 int i;
1570
1571 if ((r0|r1) < 8 && !(i0 & ~7))
1572 T1_ADDI3(_jit, r0, r1, i0);
1573 else if ((r0|r1) < 8 && !(-i0 & ~7))
1574 T1_SUBI3(_jit, r0, r1, -i0);
1575 else if (r0 < 8 && r0 == r1 && !(i0 & ~0xff))
1576 T1_ADDI8(_jit, r0, i0);
1577 else if (r0 < 8 && r0 == r1 && !(-i0 & ~0xff))
1578 T1_SUBI8(_jit, r0, -i0);
1579 else if ((i = encode_thumb_immediate(i0)) != -1)
1580 T2_ADDSI(_jit, r0, r1, i);
1581 else if ((i = encode_thumb_immediate(-i0)) != -1)
1582 T2_SUBSI(_jit, r0, r1, i);
1583 else {
1584 jit_gpr_t reg = get_temp_gpr(_jit);
1585 movi(_jit, jit_gpr_regno(reg), i0);
1586 T2_ADDS(_jit, r0, r1, jit_gpr_regno(reg));
1587 unget_temp_gpr(_jit);
1588 }
1589 }
1590
1591 static void
addxr(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)1592 addxr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
1593 {
1594 /* keep setting carry because don't know last ADC */
1595
1596 /* thumb auto set carry if not inside IT block */
1597 if ((r0|r1|r2) < 8 && (r0 == r1 || r0 == r2))
1598 T1_ADC(_jit, r0, r0 == r1 ? r2 : r1);
1599 else
1600 T2_ADCS(_jit, r0, r1, r2);
1601 }
1602
1603 static void
addxi(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)1604 addxi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
1605 {
1606 int i;
1607 if ((i = encode_thumb_immediate(i0)) != -1)
1608 T2_ADCSI(_jit, r0, r1, i);
1609 else if ((i = encode_thumb_immediate(-i0)) != -1)
1610 T2_SBCSI(_jit, r0, r1, i);
1611 else if (r0 != r1) {
1612 _movi(_jit, r0, i0, PRESERVE_FLAGS);
1613 T2_ADCS(_jit, r0, r1, r0);
1614 } else {
1615 jit_gpr_t reg = get_temp_gpr(_jit);
1616 _movi(_jit, jit_gpr_regno(reg), i0, PRESERVE_FLAGS);
1617 T2_ADCS(_jit, r0, r1, jit_gpr_regno(reg));
1618 unget_temp_gpr(_jit);
1619 }
1620 }
1621
1622 static void
subr(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)1623 subr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
1624 {
1625 if ((r0|r1|r2) < 8)
1626 T1_SUB(_jit, r0, r1, r2);
1627 else
1628 T2_SUB(_jit, r0, r1, r2);
1629 }
1630
1631 static void
subi(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)1632 subi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
1633 {
1634 int i;
1635
1636 if ((r0|r1) < 8 && !(i0 & ~7))
1637 T1_SUBI3(_jit, r0, r1, i0);
1638 else if ((r0|r1) < 8 && !(-i0 & ~7))
1639 T1_ADDI3(_jit, r0, r1, -i0);
1640 else if (r0 < 8 && r0 == r1 && !(i0 & ~0xff))
1641 T1_SUBI8(_jit, r0, i0);
1642 else if (r0 < 8 && r0 == r1 && !(-i0 & ~0xff))
1643 T1_ADDI8(_jit, r0, -i0);
1644 else if ((i = encode_thumb_immediate(i0)) != -1)
1645 T2_SUBI(_jit, r0, r1, i);
1646 else if ((i = encode_thumb_immediate(-i0)) != -1)
1647 T2_ADDI(_jit, r0, r1, i);
1648 else if ((i = encode_thumb_word_immediate(i0)) != -1)
1649 T2_SUBWI(_jit, r0, r1, i);
1650 else if ((i = encode_thumb_word_immediate(-i0)) != -1)
1651 T2_ADDWI(_jit, r0, r1, i);
1652 else {
1653 jit_gpr_t reg = get_temp_gpr(_jit);
1654 movi(_jit, jit_gpr_regno(reg), i0);
1655 T2_SUB(_jit, r0, r1, jit_gpr_regno(reg));
1656 unget_temp_gpr(_jit);
1657 }
1658 }
1659
1660 static void
subcr(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)1661 subcr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
1662 {
1663 /* thumb auto set carry if not inside IT block */
1664 if ((r0|r1|r2) < 8)
1665 T1_SUB(_jit, r0, r1, r2);
1666 else
1667 T2_SUBS(_jit, r0, r1, r2);
1668 }
1669
1670 static void
subci(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)1671 subci(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
1672 {
1673 int i;
1674
1675 if ((r0|r1) < 8 && !(i0 & ~7))
1676 T1_SUBI3(_jit, r0, r1, i0);
1677 else if ((r0|r1) < 8 && !(-i0 & ~7))
1678 T1_ADDI3(_jit, r0, r1, -i0);
1679 else if (r0 < 8 && r0 == r1 && !(i0 & ~0xff))
1680 T1_SUBI8(_jit, r0, i0);
1681 else if (r0 < 8 && r0 == r1 && !(-i0 & ~0xff))
1682 T1_ADDI8(_jit, r0, -i0);
1683 else if ((i = encode_thumb_immediate(i0)) != -1)
1684 T2_SUBSI(_jit, r0, r1, i);
1685 else if ((i = encode_thumb_immediate(-i0)) != -1)
1686 T2_ADDSI(_jit, r0, r1, i);
1687 else {
1688 jit_gpr_t reg = get_temp_gpr(_jit);
1689 movi(_jit, jit_gpr_regno(reg), i0);
1690 T2_SUBS(_jit, r0, r1, jit_gpr_regno(reg));
1691 unget_temp_gpr(_jit);
1692 }
1693 }
1694
1695 static void
subxr(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)1696 subxr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
1697 {
1698 /* keep setting carry because don't know last SBC */
1699
1700 /* thumb auto set carry if not inside IT block */
1701 if ((r0|r1|r2) < 8 && r0 == r1)
1702 T1_SBC(_jit, r0, r2);
1703 else
1704 T2_SBCS(_jit, r0, r1, r2);
1705 }
1706
1707 static void
subxi(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)1708 subxi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
1709 {
1710 int i;
1711 if ((i = encode_arm_immediate(i0)) != -1)
1712 T2_SBCSI(_jit, r0, r1, i);
1713 else if ((i = encode_arm_immediate(-i0)) != -1)
1714 T2_ADCSI(_jit, r0, r1, i);
1715 else if (r0 != r1) {
1716 _movi(_jit, r0, i0, PRESERVE_FLAGS);
1717 T2_SBCS(_jit, r0, r1, r0);
1718 } else {
1719 jit_gpr_t reg = get_temp_gpr(_jit);
1720 _movi(_jit, jit_gpr_regno(reg), i0, PRESERVE_FLAGS);
1721 T2_SBCS(_jit, r0, r1, jit_gpr_regno(reg));
1722 unget_temp_gpr(_jit);
1723 }
1724 }
1725
1726 static void
mulr(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)1727 mulr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
1728 {
1729 if (r0 == r2 && (r0|r1) < 8)
1730 T1_MUL(_jit, r0, r1);
1731 else if (r0 == r1 && (r0|r2) < 8)
1732 T1_MUL(_jit, r0, r2);
1733 else
1734 T2_MUL(_jit, r0, r1, r2);
1735 }
1736
1737 static void
muli(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)1738 muli(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
1739 {
1740 jit_gpr_t reg = get_temp_gpr(_jit);
1741 movi(_jit, jit_gpr_regno(reg), i0);
1742 mulr(_jit, r0, r1, jit_gpr_regno(reg));
1743 unget_temp_gpr(_jit);
1744 }
1745
1746 static void
iqmulr(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2,int32_t r3,jit_bool_t sign)1747 iqmulr(jit_state_t *_jit, int32_t r0, int32_t r1,
1748 int32_t r2, int32_t r3, jit_bool_t sign)
1749 {
1750 if (r2 == r3) {
1751 jit_gpr_t reg = get_temp_gpr(_jit);
1752 movr(_jit, jit_gpr_regno(reg), r2);
1753 if (sign)
1754 T2_SMULL(_jit, r0, r1, jit_gpr_regno(reg), r2);
1755 else
1756 T2_UMULL(_jit, r0, r1, jit_gpr_regno(reg), r2);
1757 unget_temp_gpr(_jit);
1758 } else if (r0 != r2 && r1 != r2) {
1759 if (sign)
1760 T2_SMULL(_jit, r0, r1, r2, r3);
1761 else
1762 T2_UMULL(_jit, r0, r1, r2, r3);
1763 } else {
1764 if (sign)
1765 T2_SMULL(_jit, r0, r1, r3, r2);
1766 else
1767 T2_UMULL(_jit, r0, r1, r3, r2);
1768 }
1769 }
1770
1771 static void
iqmuli(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2,jit_word_t i0,jit_bool_t sign)1772 iqmuli(jit_state_t *_jit, int32_t r0, int32_t r1,
1773 int32_t r2, jit_word_t i0, jit_bool_t sign)
1774 {
1775 jit_gpr_t reg = get_temp_gpr(_jit);
1776 movi(_jit, jit_gpr_regno(reg), i0);
1777 iqmulr(_jit, r0, r1, r2, jit_gpr_regno(reg), sign);
1778 unget_temp_gpr(_jit);
1779 }
1780
1781 static void
qmulr(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2,int32_t r3)1782 qmulr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2, int32_t r3)
1783 {
1784 return iqmulr(_jit, r0,r1,r2,r3,1);
1785 }
1786
1787 static void
qmulr_u(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2,int32_t r3)1788 qmulr_u(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2, int32_t r3)
1789 {
1790 return iqmulr(_jit, r0,r1,r2,r3,0);
1791 }
1792
1793 static void
qmuli(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2,int32_t i0)1794 qmuli(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2, int32_t i0)
1795 {
1796 return iqmuli(_jit, r0,r1,r2,i0,1);
1797 }
1798
1799 static void
qmuli_u(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2,int32_t i0)1800 qmuli_u(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2, int32_t i0)
1801 {
1802 return iqmuli(_jit, r0,r1,r2,i0,0);
1803 }
1804
1805 static void
divr(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)1806 divr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
1807 {
1808 T2_SDIV(_jit, r0, r1, r2);
1809 }
1810
1811 static void
divi(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)1812 divi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
1813 {
1814 jit_gpr_t reg = get_temp_gpr(_jit);
1815 movi(_jit, jit_gpr_regno(reg), i0);
1816 divr(_jit, r0, r1, jit_gpr_regno(reg));
1817 unget_temp_gpr(_jit);
1818 }
1819
1820 static void
divr_u(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)1821 divr_u(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
1822 {
1823 T2_UDIV(_jit, r0, r1, r2);
1824 }
1825
1826 static void
divi_u(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)1827 divi_u(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
1828 {
1829 jit_gpr_t reg = get_temp_gpr(_jit);
1830 movi(_jit, jit_gpr_regno(reg), i0);
1831 divr_u(_jit, r0, r1, jit_gpr_regno(reg));
1832 unget_temp_gpr(_jit);
1833 }
1834
1835 static void
iqdivr(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2,int32_t r3,jit_bool_t sign)1836 iqdivr(jit_state_t *_jit, int32_t r0, int32_t r1,
1837 int32_t r2, int32_t r3, jit_bool_t sign)
1838 {
1839 int need_tmp = r0 == r2 || r0 == r3;
1840 if (need_tmp) {
1841 int32_t tmp = jit_gpr_regno(get_temp_gpr(_jit));
1842 if (r0 == r2) {
1843 movr(_jit, tmp, r2);
1844 r2 = tmp;
1845 }
1846 if (r0 == r3) {
1847 if (r2 != r3)
1848 movr(_jit, tmp, r3);
1849 r3 = tmp;
1850 }
1851 }
1852 if (sign)
1853 divr(_jit, r0, r2, r3);
1854 else
1855 divr_u(_jit, r0, r2, r3);
1856 T1_MLS(_jit, r1, r3, r0, r2);
1857 if (need_tmp)
1858 unget_temp_gpr(_jit);
1859 }
1860
1861 static void
iqdivi(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2,jit_word_t i0,jit_bool_t sign)1862 iqdivi(jit_state_t *_jit, int32_t r0, int32_t r1,
1863 int32_t r2, jit_word_t i0, jit_bool_t sign)
1864 {
1865 jit_gpr_t reg = get_temp_gpr(_jit);
1866 movi(_jit, jit_gpr_regno(reg), i0);
1867 iqdivr(_jit, r0, r1, r2, jit_gpr_regno(reg), sign);
1868 unget_temp_gpr(_jit);
1869 }
1870
1871 static void
qdivr(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2,int32_t r3)1872 qdivr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2, int32_t r3)
1873 {
1874 return iqdivr(_jit, r0,r1,r2,r3,1);
1875 }
1876
1877 static void
qdivr_u(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2,int32_t r3)1878 qdivr_u(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2, int32_t r3)
1879 {
1880 return iqdivr(_jit, r0,r1,r2,r3,0);
1881 }
1882
1883 static void
qdivi(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2,int32_t i0)1884 qdivi(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2, int32_t i0)
1885 {
1886 return iqdivi(_jit, r0,r1,r2,i0,1);
1887 }
1888
1889 static void
qdivi_u(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2,int32_t i0)1890 qdivi_u(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2, int32_t i0)
1891 {
1892 return iqdivi(_jit, r0,r1,r2,i0,0);
1893 }
1894
1895 static void
iremr(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2,jit_bool_t sign)1896 iremr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2, jit_bool_t sign)
1897 {
1898 return iqdivr(_jit, r0, r0, r1, r2, sign);
1899 }
1900
1901 static void
remr(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)1902 remr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
1903 {
1904 return iremr(_jit, r0, r1, r2, 1);
1905 }
1906
1907 static void
remi(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)1908 remi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
1909 {
1910 jit_gpr_t reg = get_temp_gpr(_jit);
1911 movi(_jit, jit_gpr_regno(reg), i0);
1912 remr(_jit, r0, r1, jit_gpr_regno(reg));
1913 unget_temp_gpr(_jit);
1914 }
1915
1916 static void
remr_u(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)1917 remr_u(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
1918 {
1919 return iremr(_jit, r0, r1, r2, 0);
1920 }
1921
1922 static void
remi_u(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)1923 remi_u(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
1924 {
1925 jit_gpr_t reg = get_temp_gpr(_jit);
1926 movi(_jit, jit_gpr_regno(reg), i0);
1927 remr_u(_jit, r0, r1,jit_gpr_regno(reg));
1928 unget_temp_gpr(_jit);
1929 }
1930
1931 static void
andr(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)1932 andr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
1933 {
1934 if ((r0|r1|r2) < 8 && (r0 == r1 || r0 == r2))
1935 T1_AND(_jit, r0, r0 == r1 ? r2 : r1);
1936 else
1937 T2_AND(_jit, r0, r1, r2);
1938 }
1939
1940 static void
andi(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)1941 andi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
1942 {
1943 int i;
1944
1945 if ((i = encode_thumb_immediate(i0)) != -1)
1946 T2_ANDI(_jit, r0, r1, i);
1947 else if ((i = encode_thumb_immediate(~i0)) != -1)
1948 T2_BICI(_jit, r0, r1, i);
1949 else if (r0 != r1) {
1950 movi(_jit, r0, i0);
1951 T2_AND(_jit, r0, r1, r0);
1952 } else {
1953 jit_gpr_t reg = get_temp_gpr(_jit);
1954 movi(_jit, jit_gpr_regno(reg), i0);
1955 T2_AND(_jit, r0, r1, jit_gpr_regno(reg));
1956 unget_temp_gpr(_jit);
1957 }
1958 }
1959
1960 static void
orr(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)1961 orr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
1962 {
1963 if ((r0|r1|r2) < 8 && (r0 == r1 || r0 == r2))
1964 T1_ORR(_jit, r0, r0 == r1 ? r2 : r1);
1965 else
1966 T2_ORR(_jit, r0, r1, r2);
1967 }
1968
1969 static void
ori(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)1970 ori(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
1971 {
1972 int i;
1973
1974 if ((i = encode_thumb_immediate(i0)) != -1)
1975 T2_ORRI(_jit, r0, r1, i);
1976 else if (r0 != r1) {
1977 movi(_jit, r0, i0);
1978 T2_ORR(_jit, r0, r1, r0);
1979 } else {
1980 jit_gpr_t reg = get_temp_gpr(_jit);
1981 movi(_jit, jit_gpr_regno(reg), i0);
1982 T2_ORR(_jit, r0, r1, jit_gpr_regno(reg));
1983 unget_temp_gpr(_jit);
1984 }
1985 }
1986
1987 static void
xorr(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)1988 xorr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
1989 {
1990 if ((r0|r1|r2) < 8 && (r0 == r1 || r0 == r2))
1991 T1_EOR(_jit, r0, r0 == r1 ? r2 : r1);
1992 else
1993 T2_EOR(_jit, r0, r1, r2);
1994 }
1995
1996 static void
xori(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)1997 xori(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
1998 {
1999 int i;
2000
2001 if ((i = encode_thumb_immediate(i0)) != -1)
2002 T2_EORI(_jit, r0, r1, i);
2003 else if (r0 != r1) {
2004 movi(_jit, r0, i0);
2005 T2_EOR(_jit, r0, r1, r0);
2006 } else {
2007 jit_gpr_t reg = get_temp_gpr(_jit);
2008 movi(_jit, jit_gpr_regno(reg), i0);
2009 T2_EOR(_jit, r0, r1, jit_gpr_regno(reg));
2010 unget_temp_gpr(_jit);
2011 }
2012 }
2013
2014 static void
lshr(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)2015 lshr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
2016 {
2017 if ((r0|r1|r2) < 8 && r0 == r1)
2018 T1_LSL(_jit, r0, r2);
2019 else
2020 T2_LSL(_jit, r0, r1, r2);
2021 }
2022
2023 static void
lshi(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)2024 lshi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
2025 {
2026 ASSERT(i0 >= 0 && i0 <= 31);
2027 if (i0 == 0)
2028 movr(_jit, r0, r1);
2029 else {
2030 if ((r0|r1) < 8)
2031 T1_LSLI(_jit, r0, r1, i0);
2032 else
2033 T2_LSLI(_jit, r0, r1, i0);
2034 }
2035 }
2036
2037 static void
rshr(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)2038 rshr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
2039 {
2040 if ((r0|r1|r2) < 8 && r0 == r1)
2041 T1_ASR(_jit, r0, r2);
2042 else
2043 T2_ASR(_jit, r0, r1, r2);
2044 }
2045
2046 static void
rshi(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)2047 rshi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
2048 {
2049 ASSERT(i0 >= 0 && i0 <= 31);
2050 if (i0 == 0)
2051 movr(_jit, r0, r1);
2052 else {
2053 if ((r0|r1) < 8)
2054 T1_ASRI(_jit, r0, r1, i0);
2055 else
2056 T2_ASRI(_jit, r0, r1, i0);
2057 }
2058 }
2059
2060 static void
rshr_u(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)2061 rshr_u(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
2062 {
2063 if ((r0|r1|r2) < 8 && r0 == r1)
2064 T1_LSR(_jit, r0, r2);
2065 else
2066 T2_LSR(_jit, r0, r1, r2);
2067 }
2068
2069 static void
rshi_u(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)2070 rshi_u(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
2071 {
2072 ASSERT(i0 >= 0 && i0 <= 31);
2073 if (i0 == 0)
2074 movr(_jit, r0, r1);
2075 else {
2076 if ((r0|r1) < 8)
2077 T1_LSRI(_jit, r0, r1, i0);
2078 else
2079 T2_LSRI(_jit, r0, r1, i0);
2080 }
2081 }
2082
2083 static void
jmpr(jit_state_t * _jit,int32_t r0)2084 jmpr(jit_state_t *_jit, int32_t r0)
2085 {
2086 T1_BX(_jit, r0);
2087 }
2088
2089 static jit_reloc_t
jmp(jit_state_t * _jit)2090 jmp(jit_state_t *_jit)
2091 {
2092 return T2_B(_jit);
2093 }
2094
2095 static void
jmpi(jit_state_t * _jit,jit_word_t i0)2096 jmpi(jit_state_t *_jit, jit_word_t i0)
2097 {
2098 return jit_patch_there(_jit, jmp(_jit), (void*)i0);
2099 }
2100
2101 static jit_reloc_t
bccr(jit_state_t * _jit,int cc,int32_t r0,int32_t r1)2102 bccr(jit_state_t *_jit, int cc, int32_t r0, int32_t r1)
2103 {
2104 if ((r0|r1) < 8)
2105 T1_CMP(_jit, r0, r1);
2106 else if ((r0&r1) & 8)
2107 T1_CMPX(_jit, r0, r1);
2108 else
2109 T2_CMP(_jit, r0, r1);
2110 return T2_CC_B(_jit, cc);
2111 }
2112
2113 static jit_reloc_t
bcci(jit_state_t * _jit,int cc,int32_t r0,jit_word_t i1)2114 bcci(jit_state_t *_jit, int cc, int32_t r0, jit_word_t i1)
2115 {
2116 int i;
2117 if (r0 < 7 && !(i1 & 0xffffff00))
2118 T1_CMPI(_jit, r0, i1);
2119 else if ((i = encode_thumb_immediate(i1)) != -1)
2120 T2_CMPI(_jit, r0, i);
2121 else if ((i = encode_thumb_immediate(-i1)) != -1)
2122 T2_CMNI(_jit, r0, i);
2123 else {
2124 jit_gpr_t reg = get_temp_gpr(_jit);
2125 movi(_jit, jit_gpr_regno(reg), i1);
2126 T2_CMP(_jit, r0, jit_gpr_regno(reg));
2127 unget_temp_gpr(_jit);
2128 }
2129 return T2_CC_B(_jit, cc);
2130 }
2131
2132 static jit_reloc_t
bltr(jit_state_t * _jit,int32_t r0,int32_t r1)2133 bltr(jit_state_t *_jit, int32_t r0, int32_t r1)
2134 {
2135 return bccr(_jit, ARM_CC_LT, r0, r1);
2136 }
2137
2138 static jit_reloc_t
blti(jit_state_t * _jit,int32_t r0,int32_t i1)2139 blti(jit_state_t *_jit, int32_t r0, int32_t i1)
2140 {
2141 return bcci(_jit, ARM_CC_LT, r0, i1);
2142 }
2143
2144 static jit_reloc_t
bltr_u(jit_state_t * _jit,int32_t r0,int32_t r1)2145 bltr_u(jit_state_t *_jit, int32_t r0, int32_t r1)
2146 {
2147 return bccr(_jit, ARM_CC_LO, r0, r1);
2148 }
2149
2150 static jit_reloc_t
blti_u(jit_state_t * _jit,int32_t r0,int32_t i1)2151 blti_u(jit_state_t *_jit, int32_t r0, int32_t i1)
2152 {
2153 return bcci(_jit, ARM_CC_LO, r0, i1);
2154 }
2155
2156 static jit_reloc_t
bler(jit_state_t * _jit,int32_t r0,int32_t r1)2157 bler(jit_state_t *_jit, int32_t r0, int32_t r1)
2158 {
2159 return bccr(_jit, ARM_CC_LE, r0, r1);
2160 }
2161
2162 static jit_reloc_t
blei(jit_state_t * _jit,int32_t r0,int32_t i1)2163 blei(jit_state_t *_jit, int32_t r0, int32_t i1)
2164 {
2165 return bcci(_jit, ARM_CC_LE, r0, i1);
2166 }
2167
2168 static jit_reloc_t
bler_u(jit_state_t * _jit,int32_t r0,int32_t r1)2169 bler_u(jit_state_t *_jit, int32_t r0, int32_t r1)
2170 {
2171 return bccr(_jit, ARM_CC_LS, r0, r1);
2172 }
2173
2174 static jit_reloc_t
blei_u(jit_state_t * _jit,int32_t r0,int32_t i1)2175 blei_u(jit_state_t *_jit, int32_t r0, int32_t i1)
2176 {
2177 return bcci(_jit, ARM_CC_LS, r0, i1);
2178 }
2179
2180 static jit_reloc_t
beqr(jit_state_t * _jit,int32_t r0,int32_t r1)2181 beqr(jit_state_t *_jit, int32_t r0, int32_t r1)
2182 {
2183 return bccr(_jit, ARM_CC_EQ, r0, r1);
2184 }
2185
2186 static jit_reloc_t
beqi(jit_state_t * _jit,int32_t r0,int32_t i1)2187 beqi(jit_state_t *_jit, int32_t r0, int32_t i1)
2188 {
2189 return bcci(_jit, ARM_CC_EQ, r0, i1);
2190 }
2191
2192 static jit_reloc_t
bger(jit_state_t * _jit,int32_t r0,int32_t r1)2193 bger(jit_state_t *_jit, int32_t r0, int32_t r1)
2194 {
2195 return bccr(_jit, ARM_CC_GE, r0, r1);
2196 }
2197
2198 static jit_reloc_t
bgei(jit_state_t * _jit,int32_t r0,int32_t i1)2199 bgei(jit_state_t *_jit, int32_t r0, int32_t i1)
2200 {
2201 return bcci(_jit, ARM_CC_GE, r0, i1);
2202 }
2203
2204 static jit_reloc_t
bger_u(jit_state_t * _jit,int32_t r0,int32_t r1)2205 bger_u(jit_state_t *_jit, int32_t r0, int32_t r1)
2206 {
2207 return bccr(_jit, ARM_CC_HS, r0, r1);
2208 }
2209
2210 static jit_reloc_t
bgei_u(jit_state_t * _jit,int32_t r0,int32_t i1)2211 bgei_u(jit_state_t *_jit, int32_t r0, int32_t i1)
2212 {
2213 return bcci(_jit, ARM_CC_HS, r0, i1);
2214 }
2215
2216 static jit_reloc_t
bgtr(jit_state_t * _jit,int32_t r0,int32_t r1)2217 bgtr(jit_state_t *_jit, int32_t r0, int32_t r1)
2218 {
2219 return bccr(_jit, ARM_CC_GT, r0, r1);
2220 }
2221
2222 static jit_reloc_t
bgti(jit_state_t * _jit,int32_t r0,int32_t i1)2223 bgti(jit_state_t *_jit, int32_t r0, int32_t i1)
2224 {
2225 return bcci(_jit, ARM_CC_GT, r0, i1);
2226 }
2227
2228 static jit_reloc_t
bgtr_u(jit_state_t * _jit,int32_t r0,int32_t r1)2229 bgtr_u(jit_state_t *_jit, int32_t r0, int32_t r1)
2230 {
2231 return bccr(_jit, ARM_CC_HI, r0, r1);
2232 }
2233
2234 static jit_reloc_t
bgti_u(jit_state_t * _jit,int32_t r0,int32_t i1)2235 bgti_u(jit_state_t *_jit, int32_t r0, int32_t i1)
2236 {
2237 return bcci(_jit, ARM_CC_HI, r0, i1);
2238 }
2239
2240 static jit_reloc_t
bner(jit_state_t * _jit,int32_t r0,int32_t r1)2241 bner(jit_state_t *_jit, int32_t r0, int32_t r1)
2242 {
2243 return bccr(_jit, ARM_CC_NE, r0, r1);
2244 }
2245
2246 static jit_reloc_t
bnei(jit_state_t * _jit,int32_t r0,int32_t i1)2247 bnei(jit_state_t *_jit, int32_t r0, int32_t i1)
2248 {
2249 return bcci(_jit, ARM_CC_NE, r0, i1);
2250 }
2251
2252 static jit_reloc_t
baddr(jit_state_t * _jit,int cc,int32_t r0,int32_t r1)2253 baddr(jit_state_t *_jit, int cc, int32_t r0, int32_t r1)
2254 {
2255 if ((r0|r1) < 8)
2256 T1_ADD(_jit, r0, r0, r1);
2257 else
2258 T2_ADDS(_jit, r0, r0, r1);
2259 return T2_CC_B(_jit, cc);
2260 }
2261
2262 static jit_reloc_t
baddi(jit_state_t * _jit,int cc,int32_t r0,int i1)2263 baddi(jit_state_t *_jit, int cc, int32_t r0, int i1)
2264 {
2265 int i;
2266 if (r0 < 8 && !(i1 & ~7))
2267 T1_ADDI3(_jit, r0, r0, i1);
2268 else if (r0 < 8 && !(-i1 & ~7))
2269 T1_SUBI3(_jit, r0, r0, -i1);
2270 else if (r0 < 8 && !(i1 & ~0xff))
2271 T1_ADDI8(_jit, r0, i1);
2272 else if (r0 < 8 && !(-i1 & ~0xff))
2273 T1_SUBI8(_jit, r0, -i1);
2274 else if ((i = encode_thumb_immediate(i1)) != -1)
2275 T2_ADDSI(_jit, r0, r0, i);
2276 else if ((i = encode_thumb_immediate(-i1)) != -1)
2277 T2_SUBSI(_jit, r0, r0, i);
2278 else {
2279 jit_gpr_t reg = get_temp_gpr(_jit);
2280 movi(_jit, jit_gpr_regno(reg), i1);
2281 T2_ADDS(_jit, r0, r0, jit_gpr_regno(reg));
2282 unget_temp_gpr(_jit);
2283 }
2284 return T2_CC_B(_jit, cc);
2285 }
2286
2287 static jit_reloc_t
boaddr(jit_state_t * _jit,int32_t r0,int32_t r1)2288 boaddr(jit_state_t *_jit, int32_t r0, int32_t r1)
2289 {
2290 return baddr(_jit, ARM_CC_VS, r0, r1);
2291 }
2292
2293 static jit_reloc_t
boaddi(jit_state_t * _jit,int32_t r0,int32_t i1)2294 boaddi(jit_state_t *_jit, int32_t r0, int32_t i1)
2295 {
2296 return baddi(_jit, ARM_CC_VS, r0, i1);
2297 }
2298
2299 static jit_reloc_t
boaddr_u(jit_state_t * _jit,int32_t r0,int32_t r1)2300 boaddr_u(jit_state_t *_jit, int32_t r0, int32_t r1)
2301 {
2302 return baddr(_jit, ARM_CC_HS, r0, r1);
2303 }
2304
2305 static jit_reloc_t
boaddi_u(jit_state_t * _jit,int32_t r0,int32_t i1)2306 boaddi_u(jit_state_t *_jit, int32_t r0, int32_t i1)
2307 {
2308 return baddi(_jit, ARM_CC_HS, r0, i1);
2309 }
2310
2311 static jit_reloc_t
bxaddr(jit_state_t * _jit,int32_t r0,int32_t r1)2312 bxaddr(jit_state_t *_jit, int32_t r0, int32_t r1)
2313 {
2314 return baddr(_jit, ARM_CC_VC, r0, r1);
2315 }
2316
2317 static jit_reloc_t
bxaddi(jit_state_t * _jit,int32_t r0,int32_t i1)2318 bxaddi(jit_state_t *_jit, int32_t r0, int32_t i1)
2319 {
2320 return baddi(_jit, ARM_CC_VC, r0, i1);
2321 }
2322
2323 static jit_reloc_t
bxaddr_u(jit_state_t * _jit,int32_t r0,int32_t r1)2324 bxaddr_u(jit_state_t *_jit, int32_t r0, int32_t r1)
2325 {
2326 return baddr(_jit, ARM_CC_LO, r0, r1);
2327 }
2328
2329 static jit_reloc_t
bxaddi_u(jit_state_t * _jit,int32_t r0,int32_t i1)2330 bxaddi_u(jit_state_t *_jit, int32_t r0, int32_t i1)
2331 {
2332 return baddi(_jit, ARM_CC_LO, r0, i1);
2333 }
2334
2335 static jit_reloc_t
bsubr(jit_state_t * _jit,int cc,int32_t r0,int32_t r1)2336 bsubr(jit_state_t *_jit, int cc, int32_t r0, int32_t r1)
2337 {
2338 if ((r0|r1) < 8)
2339 T1_SUB(_jit, r0, r0, r1);
2340 else
2341 T2_SUBS(_jit, r0, r0, r1);
2342 return T2_CC_B(_jit, cc);
2343 }
2344
2345 static jit_reloc_t
bsubi(jit_state_t * _jit,int cc,int32_t r0,int i1)2346 bsubi(jit_state_t *_jit, int cc, int32_t r0, int i1)
2347 {
2348 int i;
2349 if (r0 < 8 && !(i1 & ~7))
2350 T1_SUBI3(_jit, r0, r0, i1);
2351 else if (r0 < 8 && !(-i1 & ~7))
2352 T1_ADDI3(_jit, r0, r0, -i1);
2353 else if (r0 < 8 && !(i1 & ~0xff))
2354 T1_SUBI8(_jit, r0, i1);
2355 else if (r0 < 8 && !(-i1 & ~0xff))
2356 T1_ADDI8(_jit, r0, -i1);
2357 else if ((i = encode_thumb_immediate(i1)) != -1)
2358 T2_SUBSI(_jit, r0, r0, i);
2359 else if ((i = encode_thumb_immediate(-i1)) != -1)
2360 T2_SUBSI(_jit, r0, r0, i);
2361 else {
2362 jit_gpr_t reg = get_temp_gpr(_jit);
2363 movi(_jit, jit_gpr_regno(reg), i1);
2364 T2_SUBS(_jit, r0, r0, jit_gpr_regno(reg));
2365 unget_temp_gpr(_jit);
2366 }
2367 return T2_CC_B(_jit, cc);
2368 }
2369
2370 static jit_reloc_t
bosubr(jit_state_t * _jit,int32_t r0,int32_t r1)2371 bosubr(jit_state_t *_jit, int32_t r0, int32_t r1)
2372 {
2373 return bsubr(_jit, ARM_CC_VS, r0, r1);
2374 }
2375
2376 static jit_reloc_t
bosubi(jit_state_t * _jit,int32_t r0,int32_t i1)2377 bosubi(jit_state_t *_jit, int32_t r0, int32_t i1)
2378 {
2379 return bsubi(_jit, ARM_CC_VS, r0, i1);
2380 }
2381
2382 static jit_reloc_t
bosubr_u(jit_state_t * _jit,int32_t r0,int32_t r1)2383 bosubr_u(jit_state_t *_jit, int32_t r0, int32_t r1)
2384 {
2385 return bsubr(_jit, ARM_CC_LO, r0, r1);
2386 }
2387
2388 static jit_reloc_t
bosubi_u(jit_state_t * _jit,int32_t r0,int32_t i1)2389 bosubi_u(jit_state_t *_jit, int32_t r0, int32_t i1)
2390 {
2391 return bsubi(_jit, ARM_CC_LO, r0, i1);
2392 }
2393
2394 static jit_reloc_t
bxsubr(jit_state_t * _jit,int32_t r0,int32_t r1)2395 bxsubr(jit_state_t *_jit, int32_t r0, int32_t r1)
2396 {
2397 return bsubr(_jit, ARM_CC_VC, r0, r1);
2398 }
2399
2400 static jit_reloc_t
bxsubi(jit_state_t * _jit,int32_t r0,int32_t i1)2401 bxsubi(jit_state_t *_jit, int32_t r0, int32_t i1)
2402 {
2403 return bsubi(_jit, ARM_CC_VC, r0, i1);
2404 }
2405
2406 static jit_reloc_t
bxsubr_u(jit_state_t * _jit,int32_t r0,int32_t r1)2407 bxsubr_u(jit_state_t *_jit, int32_t r0, int32_t r1)
2408 {
2409 return bsubr(_jit, ARM_CC_HS, r0, r1);
2410 }
2411
2412 static jit_reloc_t
bxsubi_u(jit_state_t * _jit,int32_t r0,int32_t i1)2413 bxsubi_u(jit_state_t *_jit, int32_t r0, int32_t i1)
2414 {
2415 return bsubi(_jit, ARM_CC_HS, r0, i1);
2416 }
2417
2418 static jit_reloc_t
bmxr(jit_state_t * _jit,int cc,int32_t r0,int32_t r1)2419 bmxr(jit_state_t *_jit, int cc, int32_t r0, int32_t r1)
2420 {
2421 if ((r0|r1) < 8)
2422 T1_TST(_jit, r0, r1);
2423 else
2424 T2_TST(_jit, r0, r1);
2425 return T2_CC_B(_jit, cc);
2426 }
2427
2428 static jit_reloc_t
bmxi(jit_state_t * _jit,int cc,int32_t r0,jit_word_t i1)2429 bmxi(jit_state_t *_jit, int cc, int32_t r0, jit_word_t i1)
2430 {
2431 int i;
2432 if ((i = encode_thumb_immediate(i1)) != -1)
2433 T2_TSTI(_jit, r0, i);
2434 else {
2435 jit_gpr_t reg = get_temp_gpr(_jit);
2436 movi(_jit, jit_gpr_regno(reg), i1);
2437 T2_TST(_jit, r0, jit_gpr_regno(reg));
2438 unget_temp_gpr(_jit);
2439 }
2440 return T2_CC_B(_jit, cc);
2441 }
2442
2443 static jit_reloc_t
bmsr(jit_state_t * _jit,int32_t r0,int32_t r1)2444 bmsr(jit_state_t *_jit, int32_t r0, int32_t r1)
2445 {
2446 return bmxr(_jit, ARM_CC_NE, r0, r1);
2447 }
2448
2449 static jit_reloc_t
bmsi(jit_state_t * _jit,int32_t r0,int32_t i1)2450 bmsi(jit_state_t *_jit, int32_t r0, int32_t i1)
2451 {
2452 return bmxi(_jit, ARM_CC_NE, r0, i1);
2453 }
2454
2455 static jit_reloc_t
bmcr(jit_state_t * _jit,int32_t r0,int32_t r1)2456 bmcr(jit_state_t *_jit, int32_t r0, int32_t r1)
2457 {
2458 return bmxr(_jit, ARM_CC_EQ, r0, r1);
2459 }
2460
2461 static jit_reloc_t
bmci(jit_state_t * _jit,int32_t r0,int32_t i1)2462 bmci(jit_state_t *_jit, int32_t r0, int32_t i1)
2463 {
2464 return bmxi(_jit, ARM_CC_EQ, r0, i1);
2465 }
2466
2467 static void
ldr_c(jit_state_t * _jit,int32_t r0,int32_t r1)2468 ldr_c(jit_state_t *_jit, int32_t r0, int32_t r1)
2469 {
2470 T2_LDRSBI(_jit, r0, r1, 0);
2471 }
2472
2473 static void
ldi_c(jit_state_t * _jit,int32_t r0,jit_word_t i0)2474 ldi_c(jit_state_t *_jit, int32_t r0, jit_word_t i0)
2475 {
2476 jit_gpr_t reg = get_temp_gpr(_jit);
2477 movi(_jit, jit_gpr_regno(reg), i0);
2478 T2_LDRSBI(_jit, r0, jit_gpr_regno(reg), 0);
2479 unget_temp_gpr(_jit);
2480 }
2481
2482 static void
ldxr_c(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)2483 ldxr_c(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
2484 {
2485 if ((r0|r1|r2) < 8)
2486 T1_LDRSB(_jit, r0, r1, r2);
2487 else
2488 T2_LDRSB(_jit, r0, r1, r2);
2489 }
2490
2491 #define jit_ldrt_strt_p() 0
2492
2493 static void
ldxi_c(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)2494 ldxi_c(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
2495 {
2496
2497 if (jit_ldrt_strt_p() && i0 >= 0 && i0 <= 255)
2498 T2_LDRSBI(_jit, r0, r1, i0);
2499 else if (i0 < 0 && i0 >= -255)
2500 T2_LDRSBIN(_jit, r0, r1, -i0);
2501 else if (i0 >= 0 && i0 <= 4095)
2502 T2_LDRSBWI(_jit, r0, r1, i0);
2503 else if (r0 != r1) {
2504 movi(_jit, r0, i0);
2505 if ((r0|r1) < 8)
2506 T1_LDRSB(_jit, r0, r1, r0);
2507 else
2508 T2_LDRSB(_jit, r0, r1, r0);
2509 } else {
2510 jit_gpr_t reg = get_temp_gpr(_jit);
2511 movi(_jit, jit_gpr_regno(reg), i0);
2512 if ((r0|r1|jit_gpr_regno(reg)) < 8)
2513 T1_LDRSB(_jit, r0, r1, jit_gpr_regno(reg));
2514 else
2515 T2_LDRSB(_jit, r0, r1, jit_gpr_regno(reg));
2516 unget_temp_gpr(_jit);
2517 }
2518 }
2519
2520 static void
ldr_uc(jit_state_t * _jit,int32_t r0,int32_t r1)2521 ldr_uc(jit_state_t *_jit, int32_t r0, int32_t r1)
2522 {
2523 T2_LDRBI(_jit, r0, r1, 0);
2524 }
2525
2526 static void
ldi_uc(jit_state_t * _jit,int32_t r0,jit_word_t i0)2527 ldi_uc(jit_state_t *_jit, int32_t r0, jit_word_t i0)
2528 {
2529 jit_gpr_t reg = get_temp_gpr(_jit);
2530 movi(_jit, jit_gpr_regno(reg), i0);
2531 T2_LDRBI(_jit, r0, jit_gpr_regno(reg), 0);
2532 unget_temp_gpr(_jit);
2533 }
2534
2535 static void
ldxr_uc(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)2536 ldxr_uc(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
2537 {
2538 if ((r0|r1|r2) < 8)
2539 T1_LDRB(_jit, r0, r1, r2);
2540 else
2541 T2_LDRB(_jit, r0, r1, r2);
2542 }
2543
2544 static void
ldxi_uc(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)2545 ldxi_uc(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
2546 {
2547 if ((r0|r1) < 8 && i0 >= 0 && i0 < 0x20)
2548 T1_LDRBI(_jit, r0, r1, i0);
2549 else if (jit_ldrt_strt_p() && i0 >= 0 && i0 <= 255)
2550 T2_LDRBI(_jit, r0, r1, i0);
2551 else if (i0 < 0 && i0 >= -255)
2552 T2_LDRBIN(_jit, r0, r1, -i0);
2553 else if (i0 >= 0 && i0 <= 4095)
2554 T2_LDRBWI(_jit, r0, r1, i0);
2555 else if (r0 != r1) {
2556 movi(_jit, r0, i0);
2557 if ((r0|r1) < 8)
2558 T1_LDRB(_jit, r0, r1, r0);
2559 else
2560 T2_LDRB(_jit, r0, r1, r0);
2561 } else {
2562 jit_gpr_t reg = get_temp_gpr(_jit);
2563 movi(_jit, jit_gpr_regno(reg), i0);
2564 if ((r0|r1|jit_gpr_regno(reg)) < 8)
2565 T1_LDRB(_jit, r0, r1, jit_gpr_regno(reg));
2566 else
2567 T2_LDRB(_jit, r0, r1, jit_gpr_regno(reg));
2568 unget_temp_gpr(_jit);
2569 }
2570 }
2571
2572 static void
ldr_s(jit_state_t * _jit,int32_t r0,int32_t r1)2573 ldr_s(jit_state_t *_jit, int32_t r0, int32_t r1)
2574 {
2575 T2_LDRSHI(_jit, r0, r1, 0);
2576 }
2577
2578 static void
ldi_s(jit_state_t * _jit,int32_t r0,jit_word_t i0)2579 ldi_s(jit_state_t *_jit, int32_t r0, jit_word_t i0)
2580 {
2581 jit_gpr_t reg = get_temp_gpr(_jit);
2582 movi(_jit, jit_gpr_regno(reg), i0);
2583 T2_LDRSHI(_jit, r0, jit_gpr_regno(reg), 0);
2584 unget_temp_gpr(_jit);
2585 }
2586
2587 static void
ldxr_s(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)2588 ldxr_s(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
2589 {
2590 if ((r0|r1|r2) < 8)
2591 T1_LDRSH(_jit, r0, r1, r2);
2592 else
2593 T2_LDRSH(_jit, r0, r1, r2);
2594 }
2595
2596 static void
ldxi_s(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)2597 ldxi_s(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
2598 {
2599 if (jit_ldrt_strt_p() && i0 >= 0 && i0 <= 255)
2600 T2_LDRSHI(_jit, r0, r1, i0);
2601 else if (i0 < 0 && i0 >= -255)
2602 T2_LDRSHIN(_jit, r0, r1, -i0);
2603 else if (i0 >= 0 && i0 <= 4095)
2604 T2_LDRSHWI(_jit, r0, r1, i0);
2605 else if (r0 != r1) {
2606 movi(_jit, r0, i0);
2607 if ((r0|r1) < 8)
2608 T1_LDRSH(_jit, r0, r1, r0);
2609 else
2610 T2_LDRSH(_jit, r0, r1, r0);
2611 } else {
2612 jit_gpr_t reg = get_temp_gpr(_jit);
2613 movi(_jit, jit_gpr_regno(reg), i0);
2614 if ((r0|r1|jit_gpr_regno(reg)) < 8)
2615 T1_LDRSH(_jit, r0, r1, jit_gpr_regno(reg));
2616 else
2617 T2_LDRSH(_jit, r0, r1, jit_gpr_regno(reg));
2618 unget_temp_gpr(_jit);
2619 }
2620 }
2621
2622 static void
ldr_us(jit_state_t * _jit,int32_t r0,int32_t r1)2623 ldr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
2624 {
2625 T2_LDRHI(_jit, r0, r1, 0);
2626 }
2627
2628 static void
ldi_us(jit_state_t * _jit,int32_t r0,jit_word_t i0)2629 ldi_us(jit_state_t *_jit, int32_t r0, jit_word_t i0)
2630 {
2631 jit_gpr_t reg = get_temp_gpr(_jit);
2632 movi(_jit, jit_gpr_regno(reg), i0);
2633 T2_LDRHI(_jit, r0, jit_gpr_regno(reg), 0);
2634 unget_temp_gpr(_jit);
2635 }
2636
2637 static void
ldxr_us(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)2638 ldxr_us(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
2639 {
2640
2641 if ((r0|r1|r2) < 8)
2642 T1_LDRH(_jit, r0, r1, r2);
2643 else
2644 T2_LDRH(_jit, r0, r1, r2);
2645 }
2646
2647 static void
ldxi_us(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)2648 ldxi_us(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
2649 {
2650 if ((r0|r1) < 8 && i0 >= 0 && !(i0 & 1) && (i0 >> 1) < 0x20)
2651 T1_LDRHI(_jit, r0, r1, i0 >> 1);
2652 else if (jit_ldrt_strt_p() && i0 >= 0 && i0 <= 255)
2653 T2_LDRHI(_jit, r0, r1, i0);
2654 else if (i0 < 0 && i0 >= -255)
2655 T2_LDRHIN(_jit, r0, r1, -i0);
2656 else if (i0 >= 0 && i0 <= 4095)
2657 T2_LDRHWI(_jit, r0, r1, i0);
2658 else if (r0 != r1) {
2659 movi(_jit, r0, i0);
2660 if ((r0|r1) < 8)
2661 T1_LDRH(_jit, r0, r1, r0);
2662 else
2663 T2_LDRH(_jit, r0, r1, r0);
2664 } else {
2665 jit_gpr_t reg = get_temp_gpr(_jit);
2666 movi(_jit, jit_gpr_regno(reg), i0);
2667 if ((r0|r1|jit_gpr_regno(reg)) < 8)
2668 T1_LDRH(_jit, r0, r1, jit_gpr_regno(reg));
2669 else
2670 T2_LDRH(_jit, r0, r1, jit_gpr_regno(reg));
2671 unget_temp_gpr(_jit);
2672 }
2673 }
2674
2675 static void
ldr_i(jit_state_t * _jit,int32_t r0,int32_t r1)2676 ldr_i(jit_state_t *_jit, int32_t r0, int32_t r1)
2677 {
2678 T2_LDRI(_jit, r0, r1, 0);
2679 }
2680
2681 static void
ldi_i(jit_state_t * _jit,int32_t r0,jit_word_t i0)2682 ldi_i(jit_state_t *_jit, int32_t r0, jit_word_t i0)
2683 {
2684 jit_gpr_t reg = get_temp_gpr(_jit);
2685 movi(_jit, jit_gpr_regno(reg), i0);
2686 T2_LDRI(_jit, r0, jit_gpr_regno(reg), 0);
2687 unget_temp_gpr(_jit);
2688 }
2689
2690 static void
ldxr_i(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)2691 ldxr_i(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
2692 {
2693 if ((r0|r1|r2) < 8)
2694 T1_LDR(_jit, r0, r1, r2);
2695 else
2696 T2_LDR(_jit, r0, r1, r2);
2697 }
2698
2699 static void
ldxi_i(jit_state_t * _jit,int32_t r0,int32_t r1,jit_word_t i0)2700 ldxi_i(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
2701 {
2702 if ((r0|r1) < 8 && i0 >= 0 && !(i0 & 3) && (i0 >> 2) < 0x20)
2703 T1_LDRI(_jit, r0, r1, i0 >> 2);
2704 else if (r1 == jit_gpr_regno(JIT_SP) && r0 < 8 &&
2705 i0 >= 0 && !(i0 & 3) && (i0 >> 2) <= 255)
2706 T1_LDRISP(_jit, r0, i0 >> 2);
2707 else if (jit_ldrt_strt_p() && i0 >= 0 && i0 <= 255)
2708 T2_LDRI(_jit, r0, r1, i0);
2709 else if (i0 < 0 && i0 > -255)
2710 T2_LDRIN(_jit, r0, r1, -i0);
2711 else if (i0 >= 0 && i0 <= 4095)
2712 T2_LDRWI(_jit, r0, r1, i0);
2713 else if (r0 != r1) {
2714 movi(_jit, r0, i0);
2715 if ((r0|r1) < 8)
2716 T1_LDR(_jit, r0, r1, r0);
2717 else
2718 T2_LDR(_jit, r0, r1, r0);
2719 } else {
2720 jit_gpr_t reg = get_temp_gpr(_jit);
2721 movi(_jit, jit_gpr_regno(reg), i0);
2722 if ((r0|r1|jit_gpr_regno(reg)) < 8)
2723 T1_LDR(_jit, r0, r1, jit_gpr_regno(reg));
2724 else
2725 T2_LDR(_jit, r0, r1, jit_gpr_regno(reg));
2726 unget_temp_gpr(_jit);
2727 }
2728 }
2729
2730 static void
str_c(jit_state_t * _jit,int32_t r0,int32_t r1)2731 str_c(jit_state_t *_jit, int32_t r0, int32_t r1)
2732 {
2733 T2_STRBI(_jit, r1, r0, 0);
2734 }
2735
2736 static void
sti_c(jit_state_t * _jit,jit_word_t i0,int32_t r0)2737 sti_c(jit_state_t *_jit, jit_word_t i0, int32_t r0)
2738 {
2739 jit_gpr_t reg = get_temp_gpr(_jit);
2740 movi(_jit, jit_gpr_regno(reg), i0);
2741 T2_STRBI(_jit, r0, jit_gpr_regno(reg), 0);
2742 unget_temp_gpr(_jit);
2743 }
2744
2745 static void
stxr_c(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)2746 stxr_c(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
2747 {
2748 if ((r0|r1|r2) < 8)
2749 T1_STRB(_jit, r2, r1, r0);
2750 else
2751 T2_STRB(_jit, r2, r1, r0);
2752 }
2753
2754 static void
stxi_c(jit_state_t * _jit,jit_word_t i0,int32_t r0,int32_t r1)2755 stxi_c(jit_state_t *_jit, jit_word_t i0, int32_t r0, int32_t r1)
2756 {
2757 if ((r0|r1) < 8 && i0 >= 0 && i0 < 0x20)
2758 T1_STRBI(_jit, r1, r0, i0);
2759 else if (jit_ldrt_strt_p() && i0 >= 0 && i0 <= 255)
2760 T2_STRBI(_jit, r1, r0, i0);
2761 else if (i0 < 0 && i0 >= -255)
2762 T2_STRBIN(_jit, r1, r0, -i0);
2763 else if (i0 >= 0 && i0 <= 4095)
2764 T2_STRBWI(_jit, r1, r0, i0);
2765 else {
2766 jit_gpr_t reg = get_temp_gpr(_jit);
2767 movi(_jit, jit_gpr_regno(reg), i0);
2768 if ((r0|r1|jit_gpr_regno(reg)) < 8)
2769 T1_STRB(_jit, r1, r0, jit_gpr_regno(reg));
2770 else
2771 T2_STRB(_jit, r1, r0, jit_gpr_regno(reg));
2772 unget_temp_gpr(_jit);
2773 }
2774 }
2775
2776 static void
str_s(jit_state_t * _jit,int32_t r0,int32_t r1)2777 str_s(jit_state_t *_jit, int32_t r0, int32_t r1)
2778 {
2779 T2_STRHI(_jit, r1, r0, 0);
2780 }
2781
2782 static void
sti_s(jit_state_t * _jit,jit_word_t i0,int32_t r0)2783 sti_s(jit_state_t *_jit, jit_word_t i0, int32_t r0)
2784 {
2785 jit_gpr_t reg = get_temp_gpr(_jit);
2786 movi(_jit, jit_gpr_regno(reg), i0);
2787 T2_STRHI(_jit, r0, jit_gpr_regno(reg), 0);
2788 unget_temp_gpr(_jit);
2789 }
2790
2791 static void
stxr_s(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)2792 stxr_s(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
2793 {
2794 if ((r0|r1|r2) < 8)
2795 T1_STRH(_jit, r2, r1, r0);
2796 else
2797 T2_STRH(_jit, r2, r1, r0);
2798 }
2799
2800 static void
stxi_s(jit_state_t * _jit,jit_word_t i0,int32_t r0,int32_t r1)2801 stxi_s(jit_state_t *_jit, jit_word_t i0, int32_t r0, int32_t r1)
2802 {
2803 if ((r0|r1) < 8 && i0 >= 0 && !(i0 & 1) && (i0 >> 1) < 0x20)
2804 T1_STRHI(_jit, r1, r0, i0 >> 1);
2805 else if (jit_ldrt_strt_p() && i0 >= 0 && i0 <= 255)
2806 T2_STRHI(_jit, r1, r0, i0);
2807 else if (i0 < 0 && i0 >= -255)
2808 T2_STRHIN(_jit, r1, r0, -i0);
2809 else if (i0 >= 0 && i0 <= 4095)
2810 T2_STRHWI(_jit, r1, r0, i0);
2811 else {
2812 jit_gpr_t reg = get_temp_gpr(_jit);
2813 movi(_jit, jit_gpr_regno(reg), i0);
2814 if ((r0|r1|jit_gpr_regno(reg)) < 8)
2815 T1_STRH(_jit, r1, r0, jit_gpr_regno(reg));
2816 else
2817 T2_STRH(_jit, r1, r0, jit_gpr_regno(reg));
2818 unget_temp_gpr(_jit);
2819 }
2820 }
2821
2822 static void
str_i(jit_state_t * _jit,int32_t r0,int32_t r1)2823 str_i(jit_state_t *_jit, int32_t r0, int32_t r1)
2824 {
2825 T2_STRI(_jit, r1, r0, 0);
2826 }
2827
2828 static void
sti_i(jit_state_t * _jit,jit_word_t i0,int32_t r0)2829 sti_i(jit_state_t *_jit, jit_word_t i0, int32_t r0)
2830 {
2831 jit_gpr_t reg = get_temp_gpr(_jit);
2832 movi(_jit, jit_gpr_regno(reg), i0);
2833 T2_STRI(_jit, r0, jit_gpr_regno(reg), 0);
2834 unget_temp_gpr(_jit);
2835 }
2836
2837 static void
stxr_i(jit_state_t * _jit,int32_t r0,int32_t r1,int32_t r2)2838 stxr_i(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
2839 {
2840 if ((r0|r1|r2) < 8)
2841 T1_STR(_jit, r2, r1, r0);
2842 else
2843 T2_STR(_jit, r2, r1, r0);
2844 }
2845
2846 static void
stxi_i(jit_state_t * _jit,jit_word_t i0,int32_t r0,int32_t r1)2847 stxi_i(jit_state_t *_jit, jit_word_t i0, int32_t r0, int32_t r1)
2848 {
2849 if ((r0|r1) < 8 && i0 >= 0 && !(i0 & 3) && (i0 >> 2) < 0x20)
2850 T1_STRI(_jit, r1, r0, i0 >> 2);
2851 else if (r0 == jit_gpr_regno(JIT_SP) && r1 < 8 &&
2852 i0 >= 0 && !(i0 & 3) && (i0 >> 2) <= 255)
2853 T1_STRISP(_jit, r1, i0 >> 2);
2854 else if (jit_ldrt_strt_p() && i0 >= 0 && i0 <= 255)
2855 T2_STRI(_jit, r1, r0, i0);
2856 else if (i0 < 0 && i0 >= -255)
2857 T2_STRIN(_jit, r1, r0, -i0);
2858 else if (i0 >= 0 && i0 <= 4095)
2859 T2_STRWI(_jit, r1, r0, i0);
2860 else {
2861 jit_gpr_t reg = get_temp_gpr(_jit);
2862 movi(_jit, jit_gpr_regno(reg), i0);
2863 if ((r0|r1|jit_gpr_regno(reg)) < 8)
2864 T1_STR(_jit, r1, r0, jit_gpr_regno(reg));
2865 else
2866 T2_STR(_jit, r1, r0, jit_gpr_regno(reg));
2867 unget_temp_gpr(_jit);
2868 }
2869 }
2870
2871 static void
bswapr_us(jit_state_t * _jit,int32_t r0,int32_t r1)2872 bswapr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
2873 {
2874 if ((r0|r1) < 8)
2875 T1_REV(_jit, r0, r1);
2876 else
2877 T2_REV(_jit, r0, r1);
2878 rshi_u(_jit, r0, r0, 16);
2879 }
2880
2881 /* inline glibc htonl (without register clobber) */
2882 static void
bswapr_ui(jit_state_t * _jit,int32_t r0,int32_t r1)2883 bswapr_ui(jit_state_t *_jit, int32_t r0, int32_t r1)
2884 {
2885 if ((r0|r1) < 8)
2886 T1_REV(_jit, r0, r1);
2887 else
2888 T2_REV(_jit, r0, r1);
2889 }
2890
2891 static void
extr_c(jit_state_t * _jit,int32_t r0,int32_t r1)2892 extr_c(jit_state_t *_jit, int32_t r0, int32_t r1)
2893 {
2894
2895 if ((r0|r1) < 8)
2896 T1_SXTB(_jit, r0, r1);
2897 else
2898 T2_SXTB(_jit, r0, r1);
2899 }
2900
2901 static void
extr_uc(jit_state_t * _jit,int32_t r0,int32_t r1)2902 extr_uc(jit_state_t *_jit, int32_t r0, int32_t r1)
2903 {
2904 if ((r0|r1) < 8)
2905 T1_UXTB(_jit, r0, r1);
2906 else
2907 T2_UXTB(_jit, r0, r1);
2908 }
2909
2910 static void
extr_s(jit_state_t * _jit,int32_t r0,int32_t r1)2911 extr_s(jit_state_t *_jit, int32_t r0, int32_t r1)
2912 {
2913 if ((r0|r1) < 8)
2914 T1_SXTH(_jit, r0, r1);
2915 else
2916 T2_SXTH(_jit, r0, r1);
2917 }
2918
2919 static void
extr_us(jit_state_t * _jit,int32_t r0,int32_t r1)2920 extr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
2921 {
2922 if ((r0|r1) < 8)
2923 T1_UXTH(_jit, r0, r1);
2924 else
2925 T2_UXTH(_jit, r0, r1);
2926 }
2927
2928 static void
callr(jit_state_t * _jit,int32_t r0)2929 callr(jit_state_t *_jit, int32_t r0)
2930 {
2931 T1_BLX(_jit, r0);
2932 }
2933
2934 static void
calli(jit_state_t * _jit,jit_word_t i0)2935 calli(jit_state_t *_jit, jit_word_t i0)
2936 {
2937 jit_patch_there(_jit, T2_BLI(_jit), (void*)i0);
2938 }
2939
2940 static void
jmpi_with_link(jit_state_t * _jit,jit_word_t i0)2941 jmpi_with_link(jit_state_t *_jit, jit_word_t i0)
2942 {
2943 jit_patch_there(_jit, T2_BLI(_jit), (void*)i0);
2944 }
2945
2946 static void
push_link_register(jit_state_t * _jit)2947 push_link_register(jit_state_t *_jit)
2948 {
2949 }
2950
2951 static void
pop_link_register(jit_state_t * _jit)2952 pop_link_register(jit_state_t *_jit)
2953 {
2954 }
2955
2956 static void
ret(jit_state_t * _jit)2957 ret(jit_state_t *_jit)
2958 {
2959 T1_BX(_jit, jit_gpr_regno(_LR));
2960 }
2961
2962 static void
reti(jit_state_t * _jit,int32_t i0)2963 reti(jit_state_t *_jit, int32_t i0)
2964 {
2965 movi(_jit, jit_gpr_regno(_R0), i0);
2966 ret(_jit);
2967 }
2968
2969 static void
retr(jit_state_t * _jit,int32_t r0)2970 retr(jit_state_t *_jit, int32_t r0)
2971 {
2972 movr(_jit, jit_gpr_regno(_R0), r0);
2973 ret(_jit);
2974 }
2975
2976 static void
retval_c(jit_state_t * _jit,int32_t r0)2977 retval_c(jit_state_t *_jit, int32_t r0)
2978 {
2979 extr_c(_jit, r0, jit_gpr_regno(_R0));
2980 }
2981
2982 static void
retval_uc(jit_state_t * _jit,int32_t r0)2983 retval_uc(jit_state_t *_jit, int32_t r0)
2984 {
2985 extr_uc(_jit, r0, jit_gpr_regno(_R0));
2986 }
2987
2988 static void
retval_s(jit_state_t * _jit,int32_t r0)2989 retval_s(jit_state_t *_jit, int32_t r0)
2990 {
2991 extr_s(_jit, r0, jit_gpr_regno(_R0));
2992 }
2993
2994 static void
retval_us(jit_state_t * _jit,int32_t r0)2995 retval_us(jit_state_t *_jit, int32_t r0)
2996 {
2997 extr_us(_jit, r0, jit_gpr_regno(_R0));
2998 }
2999
3000 static void
retval_i(jit_state_t * _jit,int32_t r0)3001 retval_i(jit_state_t *_jit, int32_t r0)
3002 {
3003 movr(_jit, r0, jit_gpr_regno(_R0));
3004 }
3005
3006 static uint32_t*
jmp_without_veneer(jit_state_t * _jit)3007 jmp_without_veneer(jit_state_t *_jit)
3008 {
3009 uint32_t *loc = _jit->pc.ui;
3010 emit_u16(_jit, 0);
3011 emit_u16(_jit, 0);
3012 return loc;
3013 }
3014
3015 static void
patch_jmp_without_veneer(jit_state_t * _jit,uint32_t * loc)3016 patch_jmp_without_veneer(jit_state_t *_jit, uint32_t *loc)
3017 {
3018 uint8_t *pc_base = ((uint8_t *)loc) + 4;
3019 int32_t off = (uint8_t*)jit_address(_jit) - pc_base;
3020 write_wide_thumb(loc, THUMB2_B | encode_thumb_jump(off));
3021 }
3022
3023 struct veneer
3024 {
3025 uint16_t ldr;
3026 uint16_t br;
3027 uint32_t addr;
3028 };
3029
3030 static void
patch_veneer(uint32_t * loc,jit_pointer_t addr)3031 patch_veneer(uint32_t *loc, jit_pointer_t addr)
3032 {
3033 struct veneer *v = (struct veneer*) loc;
3034 v->addr = (uintptr_t) addr;
3035 }
3036
3037 static void
emit_veneer(jit_state_t * _jit,jit_pointer_t target)3038 emit_veneer(jit_state_t *_jit, jit_pointer_t target)
3039 {
3040 uint16_t thumb1_ldr = 0x4800;
3041 int32_t tmp = jit_gpr_regno(JIT_TMP1);
3042 ASSERT(tmp < 8);
3043 // Loaded addr is 4 bytes after the LDR, which is aligned, so offset is 0.
3044 emit_u16(_jit, thumb1_ldr | (tmp << 8));
3045 emit_u16(_jit, THUMB_BX|(_u4(tmp)<<3));
3046 emit_u32(_jit, (uint32_t) target);
3047 }
3048
3049 static void
ldr_atomic(jit_state_t * _jit,int32_t dst,int32_t loc)3050 ldr_atomic(jit_state_t *_jit, int32_t dst, int32_t loc)
3051 {
3052 T1_DMB(_jit, DMB_ISH);
3053 ldr_i(_jit, dst, loc);
3054 T1_DMB(_jit, DMB_ISH);
3055 }
3056
3057 static void
str_atomic(jit_state_t * _jit,int32_t loc,int32_t val)3058 str_atomic(jit_state_t *_jit, int32_t loc, int32_t val)
3059 {
3060 T1_DMB(_jit, DMB_ISH);
3061 str_i(_jit, loc, val);
3062 T1_DMB(_jit, DMB_ISH);
3063 }
3064
3065 static void
swap_atomic(jit_state_t * _jit,int32_t dst,int32_t loc,int32_t val)3066 swap_atomic(jit_state_t *_jit, int32_t dst, int32_t loc, int32_t val)
3067 {
3068 int32_t result = jit_gpr_regno(get_temp_gpr(_jit));
3069 int32_t val_or_tmp = dst == val ? jit_gpr_regno(get_temp_gpr(_jit)) : val;
3070 movr(_jit, val_or_tmp, val);
3071 T1_DMB(_jit, DMB_ISH);
3072 void *retry = jit_address(_jit);
3073 T1_LDREX(_jit, dst, loc, 0);
3074 T1_STREX(_jit, result, val_or_tmp, loc, 0);
3075 jit_patch_there(_jit, bnei(_jit, result, 0), retry);
3076 T1_DMB(_jit, DMB_ISH);
3077 if (dst == val) unget_temp_gpr(_jit);
3078 unget_temp_gpr(_jit);
3079 }
3080
3081 static void
cas_atomic(jit_state_t * _jit,int32_t dst,int32_t loc,int32_t expected,int32_t desired)3082 cas_atomic(jit_state_t *_jit, int32_t dst, int32_t loc, int32_t expected,
3083 int32_t desired)
3084 {
3085 int32_t dst_or_tmp;
3086 if (dst == loc || dst == expected || dst == expected)
3087 dst_or_tmp = jit_gpr_regno(get_temp_gpr(_jit));
3088 else
3089 dst_or_tmp = dst;
3090 T1_DMB(_jit, DMB_ISH);
3091 void *retry = jit_address(_jit);
3092 T1_LDREX(_jit, dst_or_tmp, loc, 0);
3093 jit_reloc_t bad = bner(_jit, dst_or_tmp, expected);
3094 int result = jit_gpr_regno(get_temp_gpr(_jit));
3095 T1_STREX(_jit, result, desired, loc, 0);
3096 jit_patch_there(_jit, bnei(_jit, result, 0), retry);
3097 unget_temp_gpr(_jit);
3098 jit_patch_here(_jit, bad);
3099 T1_DMB(_jit, DMB_ISH);
3100 movr(_jit, dst, dst_or_tmp);
3101 unget_temp_gpr(_jit);
3102 }
3103
3104 static void
breakpoint(jit_state_t * _jit)3105 breakpoint(jit_state_t *_jit)
3106 {
3107 T1_BRK(_jit);
3108 }
3109