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