1 /******************************** -*- C -*- ****************************
2  *
3  *	Platform-independent layer (arm version)
4  *
5  ***********************************************************************/
6 
7 /***********************************************************************
8  *
9  * Copyright 2011 Free Software Foundation, Inc.
10  *
11  * This file is part of GNU lightning.
12  *
13  * GNU lightning is free software; you can redistribute it and/or modify it
14  * under the terms of the GNU Lesser General Public License as published
15  * by the Free Software Foundation; either version 3, or (at your option)
16  * any later version.
17  *
18  * GNU lightning is distributed in the hope that it will be useful, but
19  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20  * or  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
21  * License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public License
24  * along with GNU lightning; see the file COPYING.LESSER; if not, write to the
25  * Free Software Foundation, 59 Temple Place - Suite 330, Boston,
26  * MA 02111-1307, USA.
27  *
28  * Authors:
29  *	Paulo Cesar Pereira de Andrade
30  ***********************************************************************/
31 
32 #ifndef __lightning_core_arm_h
33 #define __lightning_core_arm_h
34 
35 #define _jitl		_jitp->jitl
36 
37 #define JIT_R_NUM			4
38 #define JIT_R(i) i
39 
40 #define JIT_V_NUM			4
41 static const jit_gpr_t
42 jit_v_order[JIT_V_NUM] = {
43   _R4, _R5, _R6, _R7
44 };
45 #define JIT_V(i)			jit_v_order[i]
46 
47 #define JIT_R0				_R0
48 #define JIT_R1				_R1
49 #define JIT_R2				_R2
50 #define JIT_V0				_R4
51 #define JIT_V1				_R5
52 #define JIT_V2				_R6
53 
54 #define jit_no_set_flags()		jit_flags.no_set_flags
55 
56 #if TARGET_OS_IPHONE
57 # define USE_SEPARATE_DIV_AND_MOD
58 #endif
59 
60 #ifdef USE_SEPARATE_DIV_AND_MOD
61 extern int __divsi3(int, int);
62 extern int __udivsi3(int, int);
63 extern int __modsi3(int, int);
64 extern int __umodsi3(int, int);
65 #else
66 extern int	__aeabi_idivmod(int, int);
67 extern unsigned	__aeabi_uidivmod(unsigned, unsigned);
68 #endif
69 
70 #define jit_nop(n)			arm_nop(_jitp, n)
71 __jit_inline void
arm_nop(jit_state_t _jitp,int n)72 arm_nop(jit_state_t _jitp, int n)
73 {
74   jit_assert(n >= 0);
75   if (jit_thumb_p()) {
76     for (; n > 0; n -= 2)
77       T1_NOP();
78   }
79   else {
80     for (; n > 0; n -= 4)
81       _NOP();
82   }
83 }
84 
85 #define jit_movr_i(r0, r1)		arm_movr_i(_jitp, r0, r1)
86 __jit_inline void
arm_movr_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1)87 arm_movr_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1)
88 {
89   if (r0 != r1) {
90     if (jit_thumb_p())
91       T1_MOV(r0, r1);
92     else
93       _MOV(r0, r1);
94   }
95 }
96 
97 #define jit_movi_i(r0, i0)		arm_movi_i(_jitp, r0, i0)
98 __jit_inline void
arm_movi_i(jit_state_t _jitp,jit_gpr_t r0,int i0)99 arm_movi_i(jit_state_t _jitp, jit_gpr_t r0, int i0)
100 {
101   int		i;
102   if (jit_thumb_p()) {
103     if (!jit_no_set_flags() && r0 < 8 && !(i0 & 0xffffff80))
104       T1_MOVI(r0, i0);
105     else if ((i = encode_thumb_immediate(i0)) != -1)
106       T2_MOVI(r0, i);
107     else if ((i = encode_thumb_immediate(~i0)) != -1)
108       T2_MVNI(r0, i);
109     else {
110       T2_MOVWI(r0, _jit_US(i0));
111       if (i0 & 0xffff0000)
112         T2_MOVTI(r0, _jit_US((unsigned)i0 >> 16));
113     }
114   }
115   else {
116     if (jit_armv6t_p() && !(i0 & 0xffff0000))
117       _MOVWI(r0, i0);
118     else if ((i = encode_arm_immediate(i0)) != -1)
119       _MOVI(r0, i);
120     else if ((i = encode_arm_immediate(~i0)) != -1)
121       _MVNI(r0, i);
122     else if (jit_armv6t_p()) {
123       _MOVWI(r0, _jit_US(i0));
124       if ((i0 & 0xffff0000))
125         _MOVTI(r0, _jit_US((unsigned)i0 >> 16));
126     }
127     else {
128       int     p0, p1, p2, p3, q0, q1, q2, q3;
129       p0 = i0 & 0x000000ff;   p1 = i0 & 0x0000ff00;
130       p2 = i0 & 0x00ff0000;   p3 = i0 & 0xff000000;
131       i0 = ~i0;
132       q0 = i0 & 0x000000ff;   q1 = i0 & 0x0000ff00;
133       q2 = i0 & 0x00ff0000;   q3 = i0 & 0xff000000;
134       if (!!p0 + !!p1 + !!p2 + !!p3 <= !!q0 + !!q1 + !!q2 + !!q3) {
135         /* prefer no inversion on tie */
136         if (p3) {
137           _MOVI(r0, encode_arm_immediate(p3));
138           if (p2) _ORRI(r0, r0, encode_arm_immediate(p2));
139           if (p1) _ORRI(r0, r0, encode_arm_immediate(p1));
140           if (p0) _ORRI(r0, r0, p0);
141         }
142         else if (p2) {
143           _MOVI(r0, encode_arm_immediate(p2));
144           if (p1) _ORRI(r0, r0, encode_arm_immediate(p1));
145           if (p0) _ORRI(r0, r0, p0);
146         }
147         else {
148           _MOVI(r0, encode_arm_immediate(p1));
149           _ORRI(r0, r0, p0);
150         }
151       }
152       else {
153         if (q3) {
154           _MVNI(r0, encode_arm_immediate(q3));
155           if (q2) _EORI(r0, r0, encode_arm_immediate(q2));
156           if (q1) _EORI(r0, r0, encode_arm_immediate(q1));
157           if (q0) _EORI(r0, r0, q0);
158         }
159         else if (q2) {
160           _MVNI(r0, encode_arm_immediate(q2));
161           if (q1) _EORI(r0, r0, encode_arm_immediate(q1));
162           if (q0) _EORI(r0, r0, q0);
163         }
164         else {
165           _MVNI(r0, encode_arm_immediate(q1));
166           _EORI(r0, r0, q0);
167         }
168       }
169     }
170   }
171 }
172 
173 #define jit_movi_p(r0, i0)		arm_movi_p(_jitp, r0, i0)
174 __jit_inline jit_insn *
arm_movi_p(jit_state_t _jitp,jit_gpr_t r0,void * i0)175 arm_movi_p(jit_state_t _jitp, jit_gpr_t r0, void *i0)
176 {
177   jit_insn	*l;
178   int		 im, q0, q1, q2, q3;
179   im = (int)i0;
180   if (jit_thumb_p()) {
181     l = _jitp->x.pc+1;
182     T2_MOVWI(r0, _jit_US((int)i0));
183     T2_MOVTI(r0, _jit_US((int)i0 >> 16));
184   }
185   else {
186     l = _jitp->x.pc;
187     if (jit_armv6t_p()) {
188       _MOVWI(r0, _jit_US((unsigned)i0));
189       _MOVTI(r0, _jit_US((unsigned)i0 >> 16));
190     }
191     else {
192       q0 = im & 0x000000ff;	q1 = im & 0x0000ff00;
193       q2 = im & 0x00ff0000;	q3 = im & 0xff000000;
194       _MOVI(r0, encode_arm_immediate(q3));
195       _ORRI(r0, r0, encode_arm_immediate(q2));
196       _ORRI(r0, r0, encode_arm_immediate(q1));
197       _ORRI(r0, r0, q0);
198     }
199   }
200   return (l);
201 }
202 
203 #define jit_patchable_movi_p(i0, i1) jit_movi_p(i0, i1)
204 
205 #define jit_patch_movi(i0, i1)		arm_patch_movi(i0, i1)
206 __jit_inline void
arm_patch_movi(jit_insn * i0,void * i1)207 arm_patch_movi(jit_insn *i0, void *i1)
208 {
209   union {
210     short		*s;
211     int		*i;
212     void		*v;
213   } u;
214   jit_thumb_t		 thumb;
215   unsigned int	 im;
216   int			 q0, q1, q2, q3;
217   im = (unsigned int)i1;
218   if (jit_thumb_p()) {
219     jit_assert((long)i0 & 0x1);
220     u.v = i0 - 1;
221     q0 = (im & 0xf000) << 4;
222     q1 = (im & 0x0800) << 15;
223     q2 = (im & 0x0700) << 4;
224     q3 =  im & 0x00ff;
225     code2thumb(thumb.s[0], thumb.s[1], u.s[0], u.s[1]);
226     jit_assert(   (thumb.i & 0xfbf00000) == THUMB2_MOVWI);
227     thumb.i = (thumb.i & 0xfbf00f00) | q0 | q1 | q2 | q3;
228     thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]);
229     im >>= 16;
230     q0 = (im & 0xf000) << 4;
231     q1 = (im & 0x0800) << 15;
232     q2 = (im & 0x0700) << 4;
233     q3 =  im & 0x00ff;
234     code2thumb(thumb.s[0], thumb.s[1], u.s[2], u.s[3]);
235     jit_assert(   (thumb.i & 0xfbf00000) == THUMB2_MOVTI);
236     thumb.i = (thumb.i & 0xfbf00f00) | q0 | q1 | q2 | q3;
237     thumb2code(thumb.s[0], thumb.s[1], u.s[2], u.s[3]);
238   }
239   else {
240     u.v = i0;
241     if (jit_armv6t_p()) {
242       q0 =  im &      0xfff;
243       q1 = (im &     0xf000) <<  4;
244       q2 = (im &  0xfff0000) >> 16;
245       q3 = (im & 0xf0000000) >> 12;
246       jit_assert(  (u.i[0] & 0x0ff00000) == (ARM_MOVWI));
247       jit_assert(  (u.i[1] & 0x0ff00000) == (ARM_MOVTI));
248       u.i[0] = (u.i[0] & 0xfff0f000) | q1 | q0;
249       u.i[1] = (u.i[1] & 0xfff0f000) | q3 | q2;
250     }
251     else {
252       q0 = im & 0x000000ff;	q1 = im & 0x0000ff00;
253       q2 = im & 0x00ff0000;	q3 = im & 0xff000000;
254       jit_assert(  (u.i[0] & 0x0ff00000) == (ARM_MOV|ARM_I));
255       u.i[0] = (u.i[0] & 0xfffff000) | encode_arm_immediate(q3);
256       jit_assert(  (u.i[1] & 0x0ff00000) == (ARM_ORR|ARM_I));
257       u.i[1] = (u.i[1] & 0xfffff000) | encode_arm_immediate(q2);
258       jit_assert(  (u.i[2] & 0x0ff00000) == (ARM_ORR|ARM_I));
259       u.i[2] = (u.i[2] & 0xfffff000) | encode_arm_immediate(q1);
260       jit_assert(  (u.i[3] & 0x0ff00000) == (ARM_ORR|ARM_I));
261       u.i[3] = (u.i[3] & 0xfffff000) | encode_arm_immediate(q0);
262     }
263   }
264 }
265 
266 #define jit_patch_calli(i0, i1)		arm_patch_at(_jitp, i0, i1)
267 #define jit_patch_at(jump, label)	arm_patch_at(_jitp, jump, label)
268 __jit_inline void
arm_patch_at(jit_state_t _jitp,jit_insn * jump,jit_insn * label)269 arm_patch_at(jit_state_t _jitp, jit_insn *jump, jit_insn *label)
270 {
271   long		 d;
272   union {
273     short		*s;
274     int		*i;
275     void		*v;
276   } u;
277   jit_thumb_t		 thumb;
278   u.v = jump;
279   if (jit_thumb_p()) {
280     jit_assert((long)u.v & 0x1);
281     jit_assert((long)label & 0x1);
282     u.v = ((char *)u.v - 1);
283 #if 0
284     /* this actually matches other patterns, so cannot patch
285      * automatically short jumps */
286     if ((u.s[0] & THUMB_CC_B) == THUMB_CC_B) {
287       jit_assert(_s8P(d));
288       u.s[0] = (u.s[0] & 0xff00) | (d & 0xff);
289     }
290     else if ((u.s[0] & THUMB_B) == THUMB_B) {
291       jit_assert(_s11P(d));
292       u.s[0] = (u.s[0] & 0xf800) | (d & 0x7ff);
293     }
294     else
295 #endif
296       {
297         code2thumb(thumb.s[0], thumb.s[1], u.s[0], u.s[1]);
298         if ((thumb.i & THUMB2_B) == THUMB2_B) {
299           d = (((long)label - (long)jump) >> 1) - 2;
300           jit_assert(_s24P(d));
301           thumb.i = THUMB2_B | encode_thumb_jump(d);
302           thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]);
303         }
304         else if ((thumb.i & THUMB2_B) == THUMB2_CC_B) {
305           d = (((long)label - (long)jump) >> 1) - 2;
306           jit_assert(_s20P(d));
307           thumb.i = THUMB2_CC_B | (thumb.i & 0x3c00000) |
308             encode_thumb_cc_jump(d);
309           thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]);
310         }
311         else if ((thumb.i & 0xfbf08000) == THUMB2_MOVWI)
312           jit_patch_movi(jump, label);
313         else
314           jit_assert(!"handled branch opcode");
315       }
316   }
317   else {
318     /* 0x0e000000 because 0x01000000 is (branch&) link modifier */
319     if ((u.i[0] & 0x0e000000) == ARM_B) {
320       d = (((long)label - (long)jump) >> 2) - 2;
321       jit_assert(_s24P(d));
322       u.i[0] = (u.i[0] & 0xff000000) | (d & 0x00ffffff);
323     }
324     else if (( jit_armv6t_p() && (u.i[0] & 0x0ff00000) == ARM_MOVWI) ||
325              (!jit_armv6t_p() && (u.i[0] & 0x0ff00000) == (ARM_MOV|ARM_I)))
326       jit_patch_movi(jump, label);
327     else
328       jit_assert(!"handled branch opcode");
329   }
330 }
331 
332 #define jit_notr_i(r0, r1)		arm_notr_i(_jitp, r0, r1)
333 __jit_inline void
arm_notr_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1)334 arm_notr_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1)
335 {
336   if (jit_thumb_p()) {
337     if (!jit_no_set_flags() && (r0|r1) < 8)
338       T1_NOT(r0, r1);
339     else
340       T2_NOT(r0, r1);
341   }
342   else
343     _NOT(r0, r1);
344 }
345 
346 #define jit_negr_i(r0, r1)		arm_negr_i(_jitp, r0, r1)
347 __jit_inline void
arm_negr_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1)348 arm_negr_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1)
349 {
350   if (jit_thumb_p()) {
351     if (!jit_no_set_flags() && (r0|r1) < 8)
352       T1_RSBI(r0, r1);
353     else
354       T2_RSBI(r0, r1, 0);
355   }
356   else
357     _RSBI(r0, r1, 0);
358 }
359 
360 #define jit_addr_i(r0, r1, r2)		arm_addr_i(_jitp, r0, r1, r2)
361 __jit_inline void
arm_addr_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)362 arm_addr_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
363 {
364   if (jit_thumb_p()) {
365     if (!jit_no_set_flags() && (r0|r1|r2) < 8)
366       T1_ADD(r0, r1, r2);
367     else if (r0 == r1 || r0 == r2)
368       T1_ADDX(r0, r0 == r1 ? r2 : r1);
369     else
370       T2_ADD(r0, r1, r2);
371   }
372   else
373     _ADD(r0, r1, r2);
374 }
375 
376 #define jit_addi_i(r0, r1, i0)		arm_addi_i(_jitp, r0, r1, i0)
377 __jit_inline void
arm_addi_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)378 arm_addi_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
379 {
380   int		i;
381   jit_gpr_t	reg;
382   if (jit_thumb_p()) {
383     if (!jit_no_set_flags() && (r0|r1) < 8 && !(i0 & ~7))
384       T1_ADDI3(r0, r1, i0);
385     else if (!jit_no_set_flags() && (r0|r1) < 8 && !(-i0 & ~7))
386       T1_SUBI3(r0, r1, -i0);
387     else if (!jit_no_set_flags() && r0 < 8 && r0 == r1 && !(i0 & ~0xff))
388       T1_ADDI8(r0, i0);
389     else if (!jit_no_set_flags() && r0 < 8 && r0 == r1 && !(-i0 & ~0xff))
390       T1_SUBI8(r0, -i0);
391     else if ((i = encode_thumb_immediate(i0)) != -1)
392       T2_ADDI(r0, r1, i);
393     else if ((i = encode_thumb_immediate(-i0)) != -1)
394       T2_SUBI(r0, r1, i);
395     else if ((i = encode_thumb_word_immediate(i0)) != -1)
396       T2_ADDWI(r0, r1, i);
397     else if ((i = encode_thumb_word_immediate(-i0)) != -1)
398       T2_SUBWI(r0, r1, i);
399     else {
400       reg = r0 != r1 ? r0 : JIT_TMP;
401       jit_movi_i(reg, i0);
402       T2_ADD(r0, r1, reg);
403     }
404   }
405   else {
406     if ((i = encode_arm_immediate(i0)) != -1)
407       _ADDI(r0, r1, i);
408     else if ((i = encode_arm_immediate(-i0)) != -1)
409       _SUBI(r0, r1, i);
410     else {
411       reg = r0 != r1 ? r0 : JIT_TMP;
412       jit_movi_i(reg, i0);
413       _ADD(r0, r1, reg);
414     }
415   }
416 }
417 
418 #define jit_addcr_ui(r0, r1, r2)	arm_addcr_ui(_jitp, r0, r1, r2)
419 __jit_inline void
arm_addcr_ui(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)420 arm_addcr_ui(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
421 {
422   if (jit_thumb_p()) {
423     /* thumb auto set carry if not inside IT block */
424     if ((r0|r1|r2) < 8)
425       T1_ADD(r0, r1, r2);
426     else
427       T2_ADDS(r0, r1, r2);
428   }
429   else
430     _ADDS(r0, r1, r2);
431 }
432 
433 #define jit_addci_ui(r0, r1, i0)	arm_addci_ui(_jitp, r0, r1, i0)
434 __jit_inline void
arm_addci_ui(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)435 arm_addci_ui(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
436 {
437   int		i;
438   jit_gpr_t	reg;
439   if (jit_thumb_p()) {
440     if ((r0|r1) < 8 && !(i0 & ~7))
441       T1_ADDI3(r0, r1, i0);
442     else if ((r0|r1) < 8 && !(-i0 & ~7))
443       T1_SUBI3(r0, r1, -i0);
444     else if (r0 < 8 && r0 == r1 && !(i0 & ~0xff))
445       T1_ADDI8(r0, i0);
446     else if (r0 < 8 && r0 == r1 && !(-i0 & ~0xff))
447       T1_SUBI8(r0, -i0);
448     else if ((i = encode_thumb_immediate(i0)) != -1)
449       T2_ADDSI(r0, r1, i);
450     else if ((i = encode_thumb_immediate(-i0)) != -1)
451       T2_SUBSI(r0, r1, i);
452     else {
453       reg = r0 != r1 ? r0 : JIT_TMP;
454       jit_movi_i(reg, i0);
455       T2_ADDS(r0, r1, reg);
456     }
457   }
458   else {
459     if ((i = encode_arm_immediate(i0)) != -1)
460       _ADDSI(r0, r1, i);
461     else if ((i = encode_arm_immediate(-i0)) != -1)
462       _SUBSI(r0, r1, i);
463     else {
464       reg = r0 != r1 ? r0 : JIT_TMP;
465       jit_movi_i(reg, i0);
466       _ADDS(r0, r1, reg);
467     }
468   }
469 }
470 
471 #define jit_addxr_ui(r0, r1, r2)	arm_addxr_ui(_jitp, r0, r1, r2)
472 __jit_inline void
arm_addxr_ui(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)473 arm_addxr_ui(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
474 {
475   /* keep setting carry because don't know last ADC */
476   if (jit_thumb_p()) {
477     /* thumb auto set carry if not inside IT block */
478     if ((r0|r1|r2) < 8 && (r0 == r1 || r0 == r2))
479       T1_ADC(r0, r0 == r1 ? r2 : r1);
480     else
481       T2_ADCS(r0, r1, r2);
482   }
483   else
484     _ADCS(r0, r1, r2);
485 }
486 
487 #define jit_addxi_ui(r0, r1, i0)	arm_addxi_ui(_jitp, r0, r1, i0)
488 __jit_inline void
arm_addxi_ui(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)489 arm_addxi_ui(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
490 {
491   int		i;
492   jit_gpr_t	reg;
493   if (jit_thumb_p()) {
494     if ((i = encode_thumb_immediate(i0)) != -1)
495       T2_ADCSI(r0, r1, i);
496     else if ((i = encode_thumb_immediate(-i0)) != -1)
497       T2_SBCSI(r0, r1, i);
498     else {
499       int		no_set_flags = jit_no_set_flags();
500       reg = r0 != r1 ? r0 : JIT_TMP;
501       jit_no_set_flags() = 1;
502       jit_movi_i(reg, i0);
503       jit_no_set_flags() = no_set_flags;
504       T2_ADCS(r0, r1, reg);
505     }
506   }
507   else {
508     if ((i = encode_arm_immediate(i0)) != -1)
509       _ADCSI(r0, r1, i);
510     else if ((i = encode_arm_immediate(-i0)) != -1)
511       _SBCSI(r0, r1, i);
512     else {
513       reg = r0 != r1 ? r0 : JIT_TMP;
514       jit_movi_i(reg, i0);
515       _ADCS(r0, r1, reg);
516     }
517   }
518 }
519 
520 #define jit_subr_i(r0, r1, r2)		arm_subr_i(_jitp, r0, r1, r2)
521 __jit_inline void
arm_subr_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)522 arm_subr_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
523 {
524   if (jit_thumb_p()) {
525     if (!jit_no_set_flags() && (r0|r1|r2) < 8)
526       T1_SUB(r0, r1, r2);
527     else
528       T2_SUB(r0, r1, r2);
529   }
530   else
531     _SUB(r0, r1, r2);
532 }
533 
534 #define jit_subi_i(r0, r1, i0)		arm_subi_i(_jitp, r0, r1, i0)
535 __jit_inline void
arm_subi_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)536 arm_subi_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
537 {
538   int		i;
539   jit_gpr_t	reg;
540   if (jit_thumb_p()) {
541     if (!jit_no_set_flags() && (r0|r1) < 8 && !(i0 & ~7))
542       T1_SUBI3(r0, r1, i0);
543     else if (!jit_no_set_flags() && (r0|r1) < 8 && !(-i0 & ~7))
544       T1_ADDI3(r0, r1, -i0);
545     else if (!jit_no_set_flags() && r0 < 8 && r0 == r1 && !(i0 & ~0xff))
546       T1_SUBI8(r0, i0);
547     else if (!jit_no_set_flags() && r0 < 8 && r0 == r1 && !(-i0 & ~0xff))
548       T1_ADDI8(r0, -i0);
549     else if ((i = encode_thumb_immediate(i0)) != -1)
550       T2_SUBI(r0, r1, i);
551     else if ((i = encode_thumb_immediate(-i0)) != -1)
552       T2_ADDI(r0, r1, i);
553     else if ((i = encode_thumb_word_immediate(i0)) != -1)
554       T2_SUBWI(r0, r1, i);
555     else if ((i = encode_thumb_word_immediate(-i0)) != -1)
556       T2_ADDWI(r0, r1, i);
557     else {
558       reg = r0 != r1 ? r0 : JIT_TMP;
559       jit_movi_i(reg, i0);
560       T2_SUB(r0, r1, reg);
561     }
562   }
563   else {
564     if ((i = encode_arm_immediate(i0)) != -1)
565       _SUBI(r0, r1, i);
566     else if ((i = encode_arm_immediate(-i0)) != -1)
567       _ADDI(r0, r1, i);
568     else {
569       reg = r0 != r1 ? r0 : JIT_TMP;
570       jit_movi_i(reg, i0);
571       _SUB(r0, r1, reg);
572     }
573   }
574 }
575 
576 #define jit_subcr_ui(r0, r1, r2)	arm_subcr_ui(_jitp, r0, r1, r2)
577 __jit_inline void
arm_subcr_ui(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)578 arm_subcr_ui(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
579 {
580   if (jit_thumb_p()) {
581     /* thumb auto set carry if not inside IT block */
582     if ((r0|r1|r2) < 8)
583       T1_SUB(r0, r1, r2);
584     else
585       T2_SUBS(r0, r1, r2);
586   }
587   else
588     _SUBS(r0, r1, r2);
589 }
590 
591 #define jit_subci_ui(r0, r1, i0)	arm_subci_ui(_jitp, r0, r1, i0)
592 __jit_inline void
arm_subci_ui(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)593 arm_subci_ui(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
594 {
595   int		i;
596   jit_gpr_t	reg;
597   if (jit_thumb_p()) {
598     if ((r0|r1) < 8 && !(i0 & ~7))
599       T1_SUBI3(r0, r1, i0);
600     else if ((r0|r1) < 8 && !(-i0 & ~7))
601       T1_ADDI3(r0, r1, -i0);
602     else if (r0 < 8 && r0 == r1 && !(i0 & ~0xff))
603       T1_SUBI8(r0, i0);
604     else if (r0 < 8 && r0 == r1 && !(-i0 & ~0xff))
605       T1_ADDI8(r0, -i0);
606     else if ((i = encode_thumb_immediate(i0)) != -1)
607       T2_SUBSI(r0, r1, i);
608     else if ((i = encode_thumb_immediate(-i0)) != -1)
609       T2_ADDSI(r0, r1, i);
610     else {
611       reg = r0 != r1 ? r0 : JIT_TMP;
612       jit_movi_i(reg, i0);
613       T2_SUBS(r0, r1, reg);
614     }
615   }
616   else {
617     if ((i = encode_arm_immediate(i0)) != -1)
618       _SUBSI(r0, r1, i);
619     else if ((i = encode_arm_immediate(-i0)) != -1)
620       _ADDSI(r0, r1, i);
621     else {
622       reg = r0 != r1 ? r0 : JIT_TMP;
623       jit_movi_i(reg, i0);
624       _SUBS(r0, r1, reg);
625     }
626   }
627 }
628 
629 #define jit_subxr_ui(r0, r1, r2)	arm_subxr_ui(_jitp, r0, r1, r2)
630 __jit_inline void
arm_subxr_ui(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)631 arm_subxr_ui(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
632 {
633   /* keep setting carry because don't know last ADC */
634   if (jit_thumb_p()) {
635     /* thumb auto set carry if not inside IT block */
636     if ((r0|r1|r2) < 8 && r0 == r1)
637       T1_SBC(r0, r2);
638     else
639       T2_SBCS(r0, r1, r2);
640   }
641   else
642     _SBCS(r0, r1, r2);
643 }
644 
645 #define jit_subxi_ui(r0, r1, i0)	arm_subxi_ui(_jitp, r0, r1, i0)
646 __jit_inline void
arm_subxi_ui(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)647 arm_subxi_ui(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
648 {
649   int		i;
650   jit_gpr_t	reg;
651   if (jit_thumb_p()) {
652     if ((i = encode_thumb_immediate(i0)) != -1)
653       T2_SBCSI(r0, r1, i);
654     else if ((i = encode_thumb_immediate(-i0)) != -1)
655       T2_ADCSI(r0, r1, i);
656     else {
657       int		no_set_flags = jit_no_set_flags();
658       reg = r0 != r1 ? r0 : JIT_TMP;
659       jit_no_set_flags() = 1;
660       jit_movi_i(reg, i0);
661       jit_no_set_flags() = no_set_flags;
662       T2_SBCS(r0, r1, reg);
663     }
664   }
665   else {
666     if ((i = encode_arm_immediate(i0)) != -1)
667       _SBCSI(r0, r1, i);
668     else if ((i = encode_arm_immediate(-i0)) != -1)
669       _ADCSI(r0, r1, i);
670     else {
671       reg = r0 != r1 ? r0 : JIT_TMP;
672       jit_movi_i(reg, i0);
673       _SBCS(r0, r1, reg);
674     }
675   }
676 }
677 
678 #define jit_rsbr_i(r0, r1, r2)		arm_rsbr_i(_jitp, r0, r1, r2)
679 __jit_inline void
arm_rsbr_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)680 arm_rsbr_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
681 {
682   if (jit_thumb_p())
683     T2_RSB(r0, r1, r2);
684   else
685     _RSB(r0, r1, r2);
686 }
687 
688 #define jit_rsbi_i(r0, r1, i0)		arm_rsbi_i(_jitp, r0, r1, i0)
689 __jit_inline void
arm_rsbi_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)690 arm_rsbi_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
691 {
692   int		i;
693   jit_gpr_t	reg;
694   if (jit_thumb_p()) {
695     if (i0 == 0)
696       arm_negr_i(_jitp, r0, r1);
697     else if ((i = encode_thumb_immediate(i0)) != -1)
698       T2_RSBI(r0, r1, i);
699     else {
700       reg = r0 != r1 ? r0 : JIT_TMP;
701       jit_movi_i(reg, i0);
702       T2_RSB(r0, r1, reg);
703     }
704   }
705   else {
706     if ((i = encode_arm_immediate(i0)) != -1)
707       _RSBI(r0, r1, i);
708     else {
709       reg = r0 != r1 ? r0 : JIT_TMP;
710       jit_movi_i(reg, i0);
711       _RSB(r0, r1, reg);
712     }
713   }
714 }
715 
716 #define jit_mulr_i(r0, r1, r2)		arm_mulr_i(_jitp, r0, r1, r2)
717 #define jit_mulr_ui(r0, r1, r2)		arm_mulr_i(_jitp, r0, r1, r2)
718 __jit_inline void
arm_mulr_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)719 arm_mulr_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
720 {
721   if (jit_thumb_p()) {
722     if (!jit_no_set_flags() && r0 == r2 && (r0|r1) < 8)
723       T1_MUL(r0, r1);
724     else if (!jit_no_set_flags() && r0 == r1 && (r0|r2) < 8)
725       T1_MUL(r0, r2);
726     else
727       T2_MUL(r0, r1, r2);
728   }
729   else {
730     if (r0 == r1 && !jit_armv6_p()) {
731       if (r0 != r2)
732         _MUL(r0, r2, r1);
733       else {
734         _MOV(JIT_TMP, r1);
735         _MUL(r0, JIT_TMP, r2);
736       }
737     }
738     else
739       _MUL(r0, r1, r2);
740   }
741 }
742 
743 #define jit_muli_i(r0, r1, i0)		arm_muli_i(_jitp, r0, r1, i0)
744 #define jit_muli_ui(r0, r1, i0)		arm_muli_i(_jitp, r0, r1, i0)
745 __jit_inline void
arm_muli_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)746 arm_muli_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
747 {
748   jit_gpr_t	reg;
749   reg = r0 != r1 ? r0 : JIT_TMP;
750   jit_movi_i(reg, i0);
751   arm_mulr_i(_jitp, r0, r1, reg);
752 }
753 
754 #define jit_hmulr_i(r0, r1, r2)		arm_hmulr_i(_jitp, r0, r1, r2)
755 __jit_inline void
arm_hmulr_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)756 arm_hmulr_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
757 {
758   if (jit_thumb_p())
759     T2_SMULL(JIT_TMP, r0, r1, r2);
760   else {
761     if (r0 == r1 && !jit_armv6_p()) {
762       jit_assert(r2 != JIT_TMP);
763       _SMULL(JIT_TMP, r0, r2, r1);
764     }
765     else
766       _SMULL(JIT_TMP, r0, r1, r2);
767   }
768 }
769 
770 #define jit_hmuli_i(r0, r1, i0)		arm_hmuli_i(_jitp, r0, r1, i0)
771 __jit_inline void
arm_hmuli_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)772 arm_hmuli_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
773 {
774   jit_gpr_t	reg;
775   if (jit_thumb_p()) {
776     jit_assert(r0 != JIT_TMP);
777     jit_movi_i(JIT_TMP, i0);
778     T2_SMULL(JIT_TMP, r0, r1, JIT_TMP);
779   }
780   else {
781     if (r0 != r1 || jit_armv6_p()) {
782       jit_movi_i(JIT_TMP, i0);
783       _SMULL(JIT_TMP, r0, r1, JIT_TMP);
784     }
785     else {
786       if (r0 != _R0)	    reg = _R0;
787       else if (r0 != _R1)     reg = _R1;
788       else if (r0 != _R2)     reg = _R2;
789       else		    reg = _R3;
790       _PUSH(1<<reg);
791       jit_movi_i(reg, i0);
792       _SMULL(JIT_TMP, r0, r1, reg);
793       _POP(1<<reg);
794     }
795   }
796 }
797 
798 #define jit_hmulr_ui(r0, r1, r2)	arm_hmulr_ui(_jitp, r0, r1, r2)
799 __jit_inline void
arm_hmulr_ui(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)800 arm_hmulr_ui(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
801 {
802   if (jit_thumb_p())
803     T2_UMULL(JIT_TMP, r0, r1, r2);
804   else {
805     if (r0 == r1 && !jit_armv6_p()) {
806       jit_assert(r2 != JIT_TMP);
807       _UMULL(JIT_TMP, r0, r2, r1);
808     }
809     else
810       _UMULL(JIT_TMP, r0, r1, r2);
811   }
812 }
813 
814 #define jit_hmuli_ui(r0, r1, i0)	arm_hmuli_ui(_jitp, r0, r1, i0)
815 __jit_inline void
arm_hmuli_ui(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)816 arm_hmuli_ui(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
817 {
818   jit_gpr_t	reg;
819   if (jit_thumb_p()) {
820     jit_assert(r0 != JIT_TMP);
821     jit_movi_i(JIT_TMP, i0);
822     T2_UMULL(JIT_TMP, r0, r1, JIT_TMP);
823   }
824   else {
825     if (r0 != r1 || jit_armv6_p()) {
826       jit_movi_i(JIT_TMP, i0);
827       _UMULL(JIT_TMP, r0, r1, JIT_TMP);
828     }
829     else {
830       if (r0 != _R0)	    reg = _R0;
831       else if (r0 != _R1)     reg = _R1;
832       else if (r0 != _R2)     reg = _R2;
833       else		    reg = _R3;
834       _PUSH(1<<reg);
835       jit_movi_i(reg, i0);
836       _UMULL(JIT_TMP, r0, r1, reg);
837       _POP(1<<reg);
838     }
839   }
840 }
841 
842 static void
arm_divmod(jit_state_t _jitp,int div,int sign,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)843 arm_divmod(jit_state_t _jitp, int div, int sign,
844 	   jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
845 {
846   int			 l;
847   void		*p;
848   l = 0xf;
849   if ((int)r0 < 4)
850     /* bogus extra push to align at 8 bytes */
851     l = (l & ~(1 << r0)) | 0x10;
852   if (jit_thumb_p())
853     T1_PUSH(l);
854   else
855     _PUSH(l);
856   if (r1 == _R1 && r2 == _R0) {
857     jit_movr_i(JIT_FTMP, _R0);
858     jit_movr_i(_R0, _R1);
859     jit_movr_i(_R1, JIT_FTMP);
860   }
861   else if (r2 == _R0) {
862     jit_movr_i(_R1, r2);
863     jit_movr_i(_R0, r1);
864   }
865   else {
866     jit_movr_i(_R0, r1);
867     jit_movr_i(_R1, r2);
868   }
869 #ifdef USE_SEPARATE_DIV_AND_MOD
870   if (div) {
871     if (sign) p = __divsi3;
872     else p = __udivsi3;
873   } else {
874     if (sign) p = __modsi3;
875     else p = __umodsi3;
876   }
877 #else
878   if (sign)		p = __aeabi_idivmod;
879   else		p = __aeabi_uidivmod;
880 #endif
881   {
882     jit_movi_i(JIT_FTMP, (int)p);
883     if (jit_thumb_p())
884       T1_BLX(JIT_FTMP);
885     else
886       _BLX(JIT_FTMP);
887   }
888 #ifdef USE_SEPARATE_DIV_AND_MOD
889   jit_movr_i(r0, _R0);
890 #else
891   if (div)
892     jit_movr_i(r0, _R0);
893   else
894     jit_movr_i(r0, _R1);
895 #endif
896   if (jit_thumb_p())
897     T1_POP(l);
898   else
899     _POP(l);
900 }
901 
902 #define jit_divr_i(r0, r1, r2)		arm_divr_i(_jitp, r0, r1, r2)
903 __jit_inline void
arm_divr_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)904 arm_divr_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
905 {
906   if (jit_armv7r_p() && jit_thumb_p())
907     T2_SDIV(r0, r1, r2);
908   else
909     arm_divmod(_jitp, 1, 1, r0, r1, r2);
910 }
911 
912 #define jit_divi_i(r0, r1, i0)		arm_divi_i(_jitp, r0, r1, i0)
913 __jit_inline void
arm_divi_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)914 arm_divi_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
915 {
916   jit_movi_i(JIT_TMP, i0);
917   arm_divr_i(_jitp, r0, r1, JIT_TMP);
918 }
919 
920 #define jit_divr_ui(r0, r1, r2)		arm_divr_ui(_jitp, r0, r1, r2)
921 __jit_inline void
arm_divr_ui(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)922 arm_divr_ui(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
923 {
924   if (jit_armv7r_p() && jit_thumb_p())
925     T2_UDIV(r0, r1, r2);
926   else
927     arm_divmod(_jitp, 1, 0, r0, r1, r2);
928 }
929 
930 #define jit_divi_ui(r0, r1, i0)		arm_divi_ui(_jitp, r0, r1, i0)
931 __jit_inline void
arm_divi_ui(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,unsigned int i0)932 arm_divi_ui(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, unsigned int i0)
933 {
934   jit_movi_i(JIT_TMP, i0);
935   arm_divr_ui(_jitp, r0, r1, JIT_TMP);
936 }
937 
938 #define jit_modr_i(r0, r1, r2)		arm_modr_i(_jitp, r0, r1, r2)
939 __jit_inline void
arm_modr_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)940 arm_modr_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
941 {
942   arm_divmod(_jitp, 0, 1, r0, r1, r2);
943 }
944 
945 #define jit_modi_i(r0, r1, i0)		arm_modi_i(_jitp, r0, r1, i0)
946 __jit_inline void
arm_modi_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)947 arm_modi_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
948 {
949   jit_movi_i(JIT_TMP, i0);
950   arm_modr_i(_jitp, r0, r1, JIT_TMP);
951 }
952 
953 #define jit_modr_ui(r0, r1, r2)		arm_modr_ui(_jitp, r0, r1, r2)
954 __jit_inline void
arm_modr_ui(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)955 arm_modr_ui(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
956 {
957   arm_divmod(_jitp, 0, 0, r0, r1, r2);
958 }
959 
960 #define jit_modi_ui(r0, r1, i0)		arm_modi_ui(_jitp, r0, r1, i0)
961 __jit_inline void
arm_modi_ui(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)962 arm_modi_ui(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
963 {
964   jit_movi_i(JIT_TMP, i0);
965   arm_modr_ui(_jitp, r0, r1, JIT_TMP);
966 }
967 
968 #define jit_andr_i(r0, r1, r2)		arm_andr_i(_jitp, r0, r1, r2)
969 __jit_inline void
arm_andr_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)970 arm_andr_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
971 {
972   if (jit_thumb_p()) {
973     if (!jit_no_set_flags() && (r0|r1|r2) < 8 && (r0 == r1 || r0 == r2))
974       T1_AND(r0, r0 == r1 ? r2 : r1);
975     else
976       T2_AND(r0, r1, r2);
977   }
978   else
979     _AND(r0, r1, r2);
980 }
981 
982 #define jit_andi_i(r0, r1, i0)		arm_andi_i(_jitp, r0, r1, i0)
983 __jit_inline void
arm_andi_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)984 arm_andi_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
985 {
986   int		i;
987   jit_gpr_t	reg;
988   if (jit_thumb_p()) {
989     if ((i = encode_thumb_immediate(i0)) != -1)
990       T2_ANDI(r0, r1, i);
991     else if ((i = encode_thumb_immediate(~i0)) != -1)
992       T2_BICI(r0, r1, i);
993     else {
994       reg = r0 != r1 ? r0 : JIT_TMP;
995       jit_movi_i(reg, i0);
996       T2_AND(r0, r1, reg);
997     }
998   }
999   else {
1000     if ((i = encode_arm_immediate(i0)) != -1)
1001       _ANDI(r0, r1, i);
1002     else if ((i = encode_arm_immediate(~i0)) != -1)
1003       _BICI(r0, r1, i);
1004     else {
1005       reg = r0 != r1 ? r0 : JIT_TMP;
1006       jit_movi_i(reg, i0);
1007       _AND(r0, r1, reg);
1008     }
1009   }
1010 }
1011 
1012 #define jit_orr_i(r0, r1, r2)		arm_orr_i(_jitp, r0, r1, r2)
1013 __jit_inline void
arm_orr_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)1014 arm_orr_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
1015 {
1016   if (jit_thumb_p()) {
1017     if (!jit_no_set_flags() && (r0|r1|r2) < 8 && (r0 == r1 || r0 == r2))
1018       T1_ORR(r0, r0 == r1 ? r2 : r1);
1019     else
1020       T2_ORR(r0, r1, r2);
1021   }
1022   else
1023     _ORR(r0, r1, r2);
1024 }
1025 
1026 #define jit_ori_i(r0, r1, i0)		arm_ori_i(_jitp, r0, r1, i0)
1027 __jit_inline void
arm_ori_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)1028 arm_ori_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
1029 {
1030   int		i;
1031   jit_gpr_t	reg;
1032   if (jit_thumb_p()) {
1033     if ((i = encode_thumb_immediate(i0)) != -1)
1034       T2_ORRI(r0, r1, i);
1035     else {
1036       reg = r0 != r1 ? r0 : JIT_TMP;
1037       jit_movi_i(reg, i0);
1038       T2_ORR(r0, r1, reg);
1039     }
1040   }
1041   else {
1042     if ((i = encode_arm_immediate(i0)) != -1)
1043       _ORRI(r0, r1, i);
1044     else {
1045       reg = r0 != r1 ? r0 : JIT_TMP;
1046       jit_movi_i(reg, i0);
1047       _ORR(r0, r1, reg);
1048     }
1049   }
1050 }
1051 
1052 #define jit_xorr_i(r0, r1, r2)		arm_xorr_i(_jitp, r0, r1, r2)
1053 __jit_inline void
arm_xorr_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)1054 arm_xorr_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
1055 {
1056   if (jit_thumb_p()) {
1057     if (!jit_no_set_flags() && (r0|r1|r2) < 8 && (r0 == r1 || r0 == r2))
1058       T1_EOR(r0, r0 == r1 ? r2 : r1);
1059     else
1060       T2_EOR(r0, r1, r2);
1061   }
1062   else
1063     _EOR(r0, r1, r2);
1064 }
1065 
1066 #define jit_xori_i(r0, r1, i0)		arm_xori_i(_jitp, r0, r1, i0)
1067 __jit_inline void
arm_xori_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)1068 arm_xori_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
1069 {
1070   int		i;
1071   jit_gpr_t	reg;
1072   if (jit_thumb_p()) {
1073     if ((i = encode_thumb_immediate(i0)) != -1)
1074       T2_EORI(r0, r1, i);
1075     else {
1076       reg = r0 != r1 ? r0 : JIT_TMP;
1077       jit_movi_i(reg, i0);
1078       T2_EOR(r0, r1, reg);
1079     }
1080   }
1081   else {
1082     if ((i = encode_arm_immediate(i0)) != -1)
1083       _EORI(r0, r1, i);
1084     else {
1085       reg = r0 != r1 ? r0 : JIT_TMP;
1086       jit_movi_i(reg, i0);
1087       _EOR(r0, r1, reg);
1088     }
1089   }
1090 }
1091 
1092 #define jit_lshr_i(r0, r1, r2)		arm_lshr_i(_jitp, r0, r1, r2)
1093 __jit_inline void
arm_lshr_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)1094 arm_lshr_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
1095 {
1096   if (jit_thumb_p()) {
1097     if (!jit_no_set_flags() && (r0|r1|r2) < 8 && r0 == r1)
1098       T1_LSL(r0, r2);
1099     else
1100       T2_LSL(r0, r1, r2);
1101   }
1102   else
1103     _LSL(r0, r1, r2);
1104 }
1105 
1106 #define jit_lshi_i(r0, r1, i0)		arm_lshi_i(_jitp, r0, r1, i0)
1107 __jit_inline void
arm_lshi_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)1108 arm_lshi_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
1109 {
1110   jit_assert(i0 >= 0 && i0 <= 31);
1111   if (i0 == 0)
1112     jit_movr_i(r0, r1);
1113   else if (jit_thumb_p()) {
1114     if (!jit_no_set_flags() && (r0|r1) < 8)
1115       T1_LSLI(r0, r1, i0);
1116     else
1117       T2_LSLI(r0, r1, i0);
1118   }
1119   else
1120     _LSLI(r0, r1, i0);
1121 }
1122 
1123 #define jit_rshr_i(r0, r1, r2)		arm_rshr_i(_jitp, r0, r1, r2)
1124 __jit_inline void
arm_rshr_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)1125 arm_rshr_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
1126 {
1127   if (jit_thumb_p()) {
1128     if (!jit_no_set_flags() && (r0|r1|r2) < 8 && r0 == r1)
1129       T1_ASR(r0, r2);
1130     else
1131       T2_ASR(r0, r1, r2);
1132   }
1133   else
1134     _ASR(r0, r1, r2);
1135 }
1136 
1137 #define jit_rshi_i(r0, r1, i0)		arm_rshi_i(_jitp, r0, r1, i0)
1138 __jit_inline void
arm_rshi_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)1139 arm_rshi_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
1140 {
1141   jit_assert(i0 >= 0 && i0 <= 31);
1142   if (i0 == 0)
1143     jit_movr_i(r0, r1);
1144   else if (jit_thumb_p()) {
1145     if (!jit_no_set_flags() && (r0|r1) < 8)
1146       T1_ASRI(r0, r1, i0);
1147     else
1148       T2_ASRI(r0, r1, i0);
1149   }
1150   else
1151     _ASRI(r0, r1, i0);
1152 }
1153 
1154 #define jit_rshr_ui(r0, r1, r2)		arm_rshr_ui(_jitp, r0, r1, r2)
1155 __jit_inline void
arm_rshr_ui(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)1156 arm_rshr_ui(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
1157 {
1158   if (jit_thumb_p()) {
1159     if (!jit_no_set_flags() && (r0|r1|r2) < 8 && r0 == r1)
1160       T1_LSR(r0, r2);
1161     else
1162       T2_LSR(r0, r1, r2);
1163   }
1164   else
1165     _LSR(r0, r1, r2);
1166 }
1167 
1168 #define jit_rshi_ui(r0, r1, i0)		arm_rshi_ui(_jitp, r0, r1, i0)
1169 __jit_inline void
arm_rshi_ui(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)1170 arm_rshi_ui(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
1171 {
1172   jit_assert(i0 >= 0 && i0 <= 31);
1173   if (i0 == 0)
1174     jit_movr_i(r0, r1);
1175   else if (jit_thumb_p()) {
1176     if (!jit_no_set_flags() && (r0|r1) < 8)
1177       T1_LSRI(r0, r1, i0);
1178     else
1179       T2_LSRI(r0, r1, i0);
1180   }
1181   else
1182     _LSRI(r0, r1, i0);
1183 }
1184 
1185 __jit_inline void
arm_ccr(jit_state_t _jitp,int ct,int cf,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)1186 arm_ccr(jit_state_t _jitp, int ct, int cf,
1187 	jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
1188 {
1189   if (jit_thumb_p()) {
1190     jit_assert((ct ^ cf) >> 28 == 1);
1191     if ((r1|r2) < 8)
1192       T1_CMP(r1, r2);
1193     else if ((r1&r2) & 8)
1194       T1_CMPX(r1, r2);
1195     else
1196       T2_CMP(r1, r2);
1197     _ITE(ct);
1198     if (r0 < 8) {
1199       T1_MOVI(r0, 1);
1200       T1_MOVI(r0, 0);
1201     }
1202     else {
1203       T2_MOVI(r0, 1);
1204       T2_MOVI(r0, 0);
1205     }
1206   }
1207   else {
1208     _CMP(r1, r2);
1209     _CC_MOVI(ct, r0, 1);
1210     _CC_MOVI(cf, r0, 0);
1211   }
1212 }
1213 __jit_inline void
arm_cci(jit_state_t _jitp,int ct,int cf,jit_gpr_t r0,jit_gpr_t r1,int i0)1214 arm_cci(jit_state_t _jitp, int ct, int cf,
1215 	jit_gpr_t r0, jit_gpr_t r1, int i0)
1216 {
1217   int		i;
1218   jit_gpr_t	reg;
1219   if (jit_thumb_p()) {
1220     if (r1 < 7 && !(i0 & 0xffffff00))
1221       T1_CMPI(r1, i0);
1222     else if ((i = encode_thumb_immediate(i0)) != -1)
1223       T2_CMPI(r1, i);
1224     else if ((i = encode_thumb_immediate(-i0)) != -1)
1225       T2_CMNI(r1, i);
1226     else {
1227       reg = r0 != r1 ? r0 : JIT_TMP;
1228       jit_movi_i(reg, i0);
1229       arm_ccr(_jitp, ct, cf, r0, r1, reg);
1230       return;
1231     }
1232     _ITE(ct);
1233     if (r0 < 8) {
1234       T1_MOVI(r0, 1);
1235       T1_MOVI(r0, 0);
1236     }
1237     else {
1238       T2_MOVI(r0, 1);
1239       T2_MOVI(r0, 0);
1240     }
1241   }
1242   else {
1243     if ((i = encode_arm_immediate(i0)) != -1)
1244       _CMPI(r1, i);
1245     else if ((i = encode_arm_immediate(-i0)) != -1)
1246       _CMNI(r1, i);
1247     else {
1248       reg = r0 != r1 ? r0 : JIT_TMP;
1249       jit_movi_i(reg, i0);
1250       _CMP(r1, reg);
1251     }
1252     _CC_MOVI(ct, r0, 1);
1253     _CC_MOVI(cf, r0, 0);
1254   }
1255 }
1256 #define jit_ltr_i(r0, r1, r2)	arm_ccr(_jitp,ARM_CC_LT,ARM_CC_GE,r0,r1,r2)
1257 #define jit_lti_i(r0, r1, i0)	arm_cci(_jitp,ARM_CC_LT,ARM_CC_GE,r0,r1,i0)
1258 #define jit_ltr_ui(r0, r1, r2)	arm_ccr(_jitp,ARM_CC_LO,ARM_CC_HS,r0,r1,r2)
1259 #define jit_lti_ui(r0, r1, i0)	arm_cci(_jitp,ARM_CC_LO,ARM_CC_HS,r0,r1,i0)
1260 #define jit_ler_i(r0, r1, r2)	arm_ccr(_jitp,ARM_CC_LE,ARM_CC_GT,r0,r1,r2)
1261 #define jit_lei_i(r0, r1, i0)	arm_cci(_jitp,ARM_CC_LE,ARM_CC_GT,r0,r1,i0)
1262 #define jit_ler_ui(r0, r1, r2)	arm_ccr(_jitp,ARM_CC_LS,ARM_CC_HI,r0,r1,r2)
1263 #define jit_lei_ui(r0, r1, i0)	arm_cci(_jitp,ARM_CC_LS,ARM_CC_HI,r0,r1,i0)
1264 #define jit_eqr_i(r0, r1, r2)	arm_ccr(_jitp,ARM_CC_EQ,ARM_CC_NE,r0,r1,r2)
1265 #define jit_eqi_i(r0, r1, i0)	arm_cci(_jitp,ARM_CC_EQ,ARM_CC_NE,r0,r1,i0)
1266 #define jit_ger_i(r0, r1, r2)	arm_ccr(_jitp,ARM_CC_GE,ARM_CC_LT,r0,r1,r2)
1267 #define jit_gei_i(r0, r1, i0)	arm_cci(_jitp,ARM_CC_GE,ARM_CC_LT,r0,r1,i0)
1268 #define jit_ger_ui(r0, r1, r2)	arm_ccr(_jitp,ARM_CC_HS,ARM_CC_LO,r0,r1,r2)
1269 #define jit_gei_ui(r0, r1, i0)	arm_cci(_jitp,ARM_CC_HS,ARM_CC_LO,r0,r1,i0)
1270 #define jit_gtr_i(r0, r1, r2)	arm_ccr(_jitp,ARM_CC_GT,ARM_CC_LE,r0,r1,r2)
1271 #define jit_gti_i(r0, r1, i0)	arm_cci(_jitp,ARM_CC_GT,ARM_CC_LE,r0,r1,i0)
1272 #define jit_gtr_ui(r0, r1, r2)	arm_ccr(_jitp,ARM_CC_HI,ARM_CC_LS,r0,r1,r2)
1273 #define jit_gti_ui(r0, r1, i0)	arm_cci(_jitp,ARM_CC_HI,ARM_CC_LS,r0,r1,i0)
1274 
1275 #define jit_ner_i(r0, r1, r2)		arm_ner_i(_jitp, r0, r1, r2)
1276 __jit_inline void
arm_ner_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)1277 arm_ner_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
1278 {
1279   if (jit_thumb_p())
1280     arm_ccr(_jitp, ARM_CC_NE, ARM_CC_EQ, r0, r1, r2);
1281   else {
1282     _SUBS(r0, r1, r2);
1283     _CC_MOVI(ARM_CC_NE, r0, 1);
1284   }
1285 }
1286 
1287 #define jit_nei_i(r0, r1, i0)		arm_nei_i(_jitp, r0, r1, i0)
1288 __jit_inline void
arm_nei_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)1289 arm_nei_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
1290 {
1291   int		i;
1292   jit_gpr_t	reg;
1293   if (jit_thumb_p())
1294     arm_cci(_jitp, ARM_CC_NE, ARM_CC_EQ, r0, r1, i0);
1295   else {
1296     if ((i = encode_arm_immediate(i0)) != -1)
1297       _SUBSI(r0, r1, i);
1298     else if ((i = encode_arm_immediate(-i0)) != -1)
1299       _ADDSI(r0, r1, i);
1300     else {
1301       reg = r0 != r1 ? r0 : JIT_TMP;
1302       jit_movi_i(reg, i0);
1303       _SUBS(r0, r1, reg);
1304     }
1305     _CC_MOVI(ARM_CC_NE, r0, 1);
1306   }
1307 }
1308 
1309 #define jit_jmpr(r0)			arm_jmpr(_jitp, r0)
1310 __jit_inline void
arm_jmpr(jit_state_t _jitp,jit_gpr_t r0)1311 arm_jmpr(jit_state_t _jitp, jit_gpr_t r0)
1312 {
1313   if (jit_thumb_p())
1314     T1_BX(r0);
1315   else
1316     _BX(r0);
1317 }
1318 
1319 __jit_inline jit_insn *
arm_branch(jit_state_t _jitp,int cc,jit_insn * i0)1320 arm_branch(jit_state_t _jitp, int cc, jit_insn *i0)
1321 {
1322   jit_insn	*l;
1323   long	 d;
1324 
1325   l = _jitp->x.pc;
1326   d = (((long)i0 - (long)l) >> 2) - 2;
1327 
1328   if (!_jitl.long_jumps && _s24P(d)) {
1329     _CC_B(cc, d & 0x00ffffff);
1330   } else {
1331     int im = (int)i0;
1332     jit_assert(_jitl.long_jumps);
1333     if (jit_armv6t_p()) {
1334       _CC_MOVWI(cc, JIT_TMP, _jit_US(im));
1335       _CC_MOVTI(cc, JIT_TMP, _jit_US((unsigned)im >> 16));
1336     } else {
1337       int     q0, q1, q2, q3;
1338 
1339       q0 = im & 0x000000ff;	q1 = im & 0x0000ff00;
1340       q2 = im & 0x00ff0000;	q3 = im & 0xff000000;
1341       _CC_MOVI(cc, JIT_TMP, encode_arm_immediate(q3));
1342       _CC_ORRI(cc, JIT_TMP, JIT_TMP, encode_arm_immediate(q2));
1343       _CC_ORRI(cc, JIT_TMP, JIT_TMP, encode_arm_immediate(q1));
1344       _CC_ORRI(cc, JIT_TMP, JIT_TMP, q0);
1345     }
1346     _CC_MOV(cc, _R15, JIT_TMP);
1347   }
1348 
1349   return l;
1350 }
1351 
invert_cc(int cc)1352 __jit_inline int invert_cc(int cc)
1353 {
1354   return cc ^ ARM_CC_NE;
1355 }
1356 
1357 __jit_inline jit_insn *
thumb_branch(jit_state_t _jitp,int cc,jit_insn * i0)1358 thumb_branch(jit_state_t _jitp, int cc, jit_insn *i0)
1359 {
1360   jit_insn	*l;
1361   long	 d;
1362 
1363   jit_assert((long)i0 & 0x1);
1364 
1365   /* use only thumb2 conditional as does not know if will be patched */
1366   l = _jitp->x.pc+1;
1367   d = (((long)i0 - (long)l) >> 1) - 2;
1368   if (!_jitl.long_jumps && _s20P(d)) {
1369     if (cc == ARM_CC_AL)
1370       T2_B(encode_thumb_jump(d));
1371     else
1372       T2_CC_B(cc, encode_thumb_cc_jump(d));
1373   } else {
1374     jit_assert(_jitl.long_jumps);
1375     jit_movi_p(JIT_TMP, i0);
1376     if (cc != ARM_CC_AL) {
1377       cc = invert_cc(cc);
1378       T2_CC_B(cc, 1);
1379     }
1380     T1_MOV(_R15, JIT_TMP);
1381   }
1382 
1383   return l;
1384 }
1385 
1386 #define jit_jmpi(i0)			arm_jmpi(_jitp, i0)
1387 __jit_inline jit_insn *
arm_jmpi(jit_state_t _jitp,void * i0)1388 arm_jmpi(jit_state_t _jitp, void *i0)
1389 {
1390   jit_insn	*l;
1391   if (jit_thumb_p()) {
1392     l = thumb_branch(_jitp, ARM_CC_AL, i0);
1393   }
1394   else {
1395     l = arm_branch(_jitp, ARM_CC_AL, i0);
1396   }
1397   return (l);
1398 }
1399 
1400 __jit_inline jit_insn *
arm_bccr(jit_state_t _jitp,int cc,jit_insn * i0,jit_gpr_t r0,jit_gpr_t r1)1401 arm_bccr(jit_state_t _jitp, int cc, jit_insn *i0, jit_gpr_t r0, jit_gpr_t r1)
1402 {
1403   jit_insn *l;
1404 
1405   if (jit_thumb_p()) {
1406     if ((r0|r1) < 8)
1407       T1_CMP(r0, r1);
1408     else if ((r0&r1) & 8)
1409       T1_CMPX(r0, r1);
1410     else
1411       T2_CMP(r0, r1);
1412     l = thumb_branch(_jitp, cc, i0);
1413   }
1414   else {
1415     _CMP(r0, r1);
1416     l = arm_branch(_jitp, cc, i0);
1417   }
1418   return (l);
1419 }
1420 __jit_inline jit_insn *
arm_bcci(jit_state_t _jitp,int cc,jit_insn * i0,jit_gpr_t r0,int i1)1421 arm_bcci(jit_state_t _jitp, int cc, jit_insn *i0, jit_gpr_t r0, int i1)
1422 {
1423   jit_insn	*l;
1424   int		 i;
1425   if (jit_thumb_p()) {
1426     if (r0 < 7 && !(i1 & 0xffffff00))
1427       T1_CMPI(r0, i1);
1428     else if ((i = encode_thumb_immediate(i1)) != -1)
1429       T2_CMPI(r0, i);
1430     else if ((i = encode_thumb_immediate(-i1)) != -1)
1431       T2_CMNI(r0, i);
1432     else {
1433       jit_movi_i(JIT_TMP, i1);
1434       T2_CMP(r0, JIT_TMP);
1435     }
1436     l = thumb_branch(_jitp, cc, i0);
1437   }
1438   else {
1439     if ((i = encode_arm_immediate(i1)) != -1)
1440       _CMPI(r0, i);
1441     else if ((i = encode_arm_immediate(-i1)) != -1)
1442       _CMNI(r0, i);
1443     else {
1444       jit_movi_i(JIT_TMP, i1);
1445       _CMP(r0, JIT_TMP);
1446     }
1447     l = arm_branch(_jitp, cc, i0);
1448   }
1449   return (l);
1450 }
1451 #define jit_bltr_i(i0, r0, r1)		arm_bccr(_jitp, ARM_CC_LT, i0, r0, r1)
1452 #define jit_blti_i(i0, r0, i1)		arm_bcci(_jitp, ARM_CC_LT, i0, r0, i1)
1453 #define jit_bltr_ui(i0, r0, r1) 	arm_bccr(_jitp, ARM_CC_LO, i0, r0, r1)
1454 #define jit_blti_ui(i0, r0, i1) 	arm_bcci(_jitp, ARM_CC_LO, i0, r0, i1)
1455 #define jit_bler_i(i0, r0, r1)		arm_bccr(_jitp, ARM_CC_LE, i0, r0, r1)
1456 #define jit_blei_i(i0, r0, i1)		arm_bcci(_jitp, ARM_CC_LE, i0, r0, i1)
1457 #define jit_bler_ui(i0, r0, r1) 	arm_bccr(_jitp, ARM_CC_LS, i0, r0, r1)
1458 #define jit_blei_ui(i0, r0, i1) 	arm_bcci(_jitp, ARM_CC_LS, i0, r0, i1)
1459 #define jit_beqr_i(i0, r0, r1)		arm_bccr(_jitp, ARM_CC_EQ, i0, r0, r1)
1460 #define jit_beqi_i(i0, r0, i1)		arm_bcci(_jitp, ARM_CC_EQ, i0, r0, i1)
1461 #define jit_bger_i(i0, r0, r1)		arm_bccr(_jitp, ARM_CC_GE, i0, r0, r1)
1462 #define jit_bgei_i(i0, r0, i1)		arm_bcci(_jitp, ARM_CC_GE, i0, r0, i1)
1463 #define jit_bger_ui(i0, r0, r1) 	arm_bccr(_jitp, ARM_CC_HS, i0, r0, r1)
1464 #define jit_bgei_ui(i0, r0, i1) 	arm_bcci(_jitp, ARM_CC_HS, i0, r0, i1)
1465 #define jit_bgtr_i(i0, r0, r1)		arm_bccr(_jitp, ARM_CC_GT, i0, r0, r1)
1466 #define jit_bgti_i(i0, r0, i1)		arm_bcci(_jitp, ARM_CC_GT, i0, r0, i1)
1467 #define jit_bgtr_ui(i0, r0, r1) 	arm_bccr(_jitp, ARM_CC_HI, i0, r0, r1)
1468 #define jit_bgti_ui(i0, r0, i1) 	arm_bcci(_jitp, ARM_CC_HI, i0, r0, i1)
1469 #define jit_bner_i(i0, r0, r1)		arm_bccr(_jitp, ARM_CC_NE, i0, r0, r1)
1470 #define jit_bnei_i(i0, r0, i1)		arm_bcci(_jitp, ARM_CC_NE, i0, r0, i1)
1471 
1472 __jit_inline jit_insn *
arm_baddr(jit_state_t _jitp,int cc,jit_insn * i0,jit_gpr_t r0,jit_gpr_t r1)1473 arm_baddr(jit_state_t _jitp, int cc, jit_insn *i0, jit_gpr_t r0, jit_gpr_t r1)
1474 {
1475   jit_insn	*l;
1476 
1477   if (jit_thumb_p()) {
1478     if ((r0|r1) < 8)
1479       T1_ADD(r0, r0, r1);
1480     else
1481       T2_ADDS(r0, r0, r1);
1482     l = thumb_branch(_jitp, cc, i0);
1483   }
1484   else {
1485     _ADDS(r0, r0, r1);
1486     l = arm_branch(_jitp, cc, i0);
1487   }
1488   return (l);
1489 }
1490 __jit_inline jit_insn *
arm_baddi(jit_state_t _jitp,int cc,jit_insn * i0,jit_gpr_t r0,int i1)1491 arm_baddi(jit_state_t _jitp, int cc, jit_insn *i0, jit_gpr_t r0, int i1)
1492 {
1493   jit_insn	*l;
1494   int		 i;
1495   if (jit_thumb_p()) {
1496     if (r0 < 8 && !(i1 & ~7))
1497       T1_ADDI3(r0, r0, i1);
1498     else if (r0 < 8 && !(-i1 & ~7))
1499       T1_SUBI3(r0, r0, -i1);
1500     else if (r0 < 8 && !(i1 & ~0xff))
1501       T1_ADDI8(r0, i1);
1502     else if (r0 < 8 && !(-i1 & ~0xff))
1503       T1_SUBI8(r0, -i1);
1504     else if ((i = encode_thumb_immediate(i1)) != -1)
1505       T2_ADDSI(r0, r0, i);
1506     else if ((i = encode_thumb_immediate(-i1)) != -1)
1507       T2_SUBSI(r0, r0, i);
1508     else {
1509       jit_movi_i(JIT_TMP, i1);
1510       T2_ADDS(r0, r0, JIT_TMP);
1511     }
1512     l = thumb_branch(_jitp, cc, i0);
1513   }
1514   else {
1515     if ((i = encode_arm_immediate(i1)) != -1)
1516       _ADDSI(r0, r0, i);
1517     else if ((i = encode_arm_immediate(-i1)) != -1)
1518       _SUBSI(r0, r0, i);
1519     else {
1520       jit_movi_i(JIT_TMP, i1);
1521       _ADDS(r0, r0, JIT_TMP);
1522     }
1523     l = arm_branch(_jitp, cc, i0);
1524   }
1525   return (l);
1526 }
1527 #define jit_boaddr_i(i0, r0, r1)	arm_baddr(_jitp, ARM_CC_VS, i0, r0, r1)
1528 #define jit_boaddi_i(i0, r0, i1)	arm_baddi(_jitp, ARM_CC_VS, i0, r0, i1)
1529 #define jit_boaddr_ui(i0, r0, r1)	arm_baddr(_jitp, ARM_CC_HS, i0, r0, r1)
1530 #define jit_boaddi_ui(i0, r0, i1)	arm_baddi(_jitp, ARM_CC_HS, i0, r0, i1)
1531 
1532 __jit_inline jit_insn *
arm_bsubr(jit_state_t _jitp,int cc,jit_insn * i0,jit_gpr_t r0,jit_gpr_t r1)1533 arm_bsubr(jit_state_t _jitp, int cc, jit_insn *i0, jit_gpr_t r0, jit_gpr_t r1)
1534 {
1535   jit_insn	*l;
1536   if (jit_thumb_p()) {
1537     if ((r0|r1) < 8)
1538       T1_SUB(r0, r0, r1);
1539     else
1540       T2_SUBS(r0, r0, r1);
1541     l = thumb_branch(_jitp, cc, i0);
1542   }
1543   else {
1544     _SUBS(r0, r0, r1);
1545     l = arm_branch(_jitp, cc, i0);
1546   }
1547   return (l);
1548 }
1549 
1550 __jit_inline jit_insn *
arm_bsubi(jit_state_t _jitp,int cc,jit_insn * i0,jit_gpr_t r0,int i1)1551 arm_bsubi(jit_state_t _jitp, int cc, jit_insn *i0, jit_gpr_t r0, int i1)
1552 {
1553   jit_insn	*l;
1554   int		 i;
1555   if (jit_thumb_p()) {
1556     if (r0 < 8 && !(i1 & ~7))
1557       T1_SUBI3(r0, r0, i1);
1558     else if (r0 < 8 && !(-i1 & ~7))
1559       T1_ADDI3(r0, r0, -i1);
1560     else if (r0 < 8 && !(i1 & ~0xff))
1561       T1_SUBI8(r0, i1);
1562     else if (r0 < 8 && !(-i1 & ~0xff))
1563       T1_ADDI8(r0, -i1);
1564     else if ((i = encode_thumb_immediate(i1)) != -1)
1565       T2_SUBSI(r0, r0, i);
1566     else if ((i = encode_thumb_immediate(-i1)) != -1)
1567       T2_ADDSI(r0, r0, i);
1568     else {
1569       jit_movi_i(JIT_TMP, i1);
1570       T2_SUBS(r0, r0, JIT_TMP);
1571     }
1572     l = thumb_branch(_jitp, cc, i0);
1573   }
1574   else {
1575     if ((i = encode_arm_immediate(i1)) != -1)
1576       _SUBSI(r0, r0, i);
1577     else if ((i = encode_arm_immediate(-i1)) != -1)
1578       _ADDSI(r0, r0, i);
1579     else {
1580       jit_movi_i(JIT_TMP, i1);
1581       _SUBS(r0, r0, JIT_TMP);
1582     }
1583     l = arm_branch(_jitp, cc, i0);
1584   }
1585   return (l);
1586 }
1587 #define jit_bosubr_i(i0, r0, r1)	arm_bsubr(_jitp, ARM_CC_VS, i0, r0, r1)
1588 #define jit_bosubi_i(i0, r0, i1)	arm_bsubi(_jitp, ARM_CC_VS, i0, r0, i1)
1589 #define jit_bosubr_ui(i0, r0, r1)	arm_bsubr(_jitp, ARM_CC_LO, i0, r0, r1)
1590 #define jit_bosubi_ui(i0, r0, i1)	arm_bsubi(_jitp, ARM_CC_LO, i0, r0, i1)
1591 
1592 #define jit_bomulr_i(a, r0, r1)		arm_bomulr_i(_jitp, a, r0, r0, r1)
1593 #define jit_bomulr_ui(a, r0, r1)		arm_bomulr_i(_jitp, a, r0, r0, r1)
1594 __jit_inline jit_insn *
arm_bomulr_i(jit_state_t _jitp,jit_insn * i0,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)1595 arm_bomulr_i(jit_state_t _jitp, jit_insn *i0, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
1596 {
1597   jit_insn	*l;
1598 
1599   if (jit_thumb_p()) {
1600     T2_SMULL(r0, JIT_TMP, r1, r2);
1601     T1_ASRI(JIT_TMP2, r0, 31);
1602     T1_CMP(JIT_TMP, JIT_TMP2);
1603     l = thumb_branch(_jitp, ARM_CC_NE, i0);
1604   } else {
1605     if (r0 == r1 && !jit_armv6_p()) {
1606       jit_assert(r2 != JIT_TMP);
1607       _SMULL(r0, JIT_TMP, r2, r1);
1608     }
1609     else
1610       _SMULL(r0, JIT_TMP, r1, r2);
1611     _CC_CMPSH(ARM_CC_AL, JIT_TMP, r0, ARM_ASR, 31);
1612     l = arm_branch(_jitp, ARM_CC_NE, i0);
1613   }
1614 
1615   return l;
1616 }
1617 
1618 __jit_inline jit_insn *
arm_bmxr(jit_state_t _jitp,int cc,jit_insn * i0,jit_gpr_t r0,jit_gpr_t r1)1619 arm_bmxr(jit_state_t _jitp, int cc, jit_insn *i0, jit_gpr_t r0, jit_gpr_t r1)
1620 {
1621   jit_insn	*l;
1622   if (jit_thumb_p()) {
1623     if ((r0|r1) < 8)
1624       T1_TST(r0, r1);
1625     else
1626       T2_TST(r0, r1);
1627     l = thumb_branch(_jitp, cc, i0);
1628   }
1629   else {
1630     if (jit_armv5_p())
1631       _TST(r0, r1);
1632     else
1633       _ANDS(JIT_TMP, r0, r1);
1634     l = arm_branch(_jitp, cc, i0);
1635   }
1636   return (l);
1637 }
1638 __jit_inline jit_insn *
arm_bmxi(jit_state_t _jitp,int cc,jit_insn * i0,jit_gpr_t r0,int i1)1639 arm_bmxi(jit_state_t _jitp, int cc, jit_insn *i0, jit_gpr_t r0, int i1)
1640 {
1641   jit_insn	*l;
1642   int		 i;
1643   if (jit_thumb_p()) {
1644     if ((i = encode_thumb_immediate(i1)) != -1)
1645       T2_TSTI(r0, i);
1646     else {
1647       jit_movi_i(JIT_TMP, i1);
1648       T2_TST(r0, JIT_TMP);
1649     }
1650     l = thumb_branch(_jitp, cc, i0);
1651   }
1652   else {
1653     if (jit_armv5_p()) {
1654       if ((i = encode_arm_immediate(i1)) != -1)
1655         _TSTI(r0, i);
1656       else {
1657         jit_movi_i(JIT_TMP, i1);
1658         _TST(r0, JIT_TMP);
1659       }
1660     }
1661     else {
1662       if ((i = encode_arm_immediate(i1)) != -1)
1663         _ANDSI(JIT_TMP, r0, i);
1664       else if ((i = encode_arm_immediate(~i1)) != -1)
1665         _BICSI(JIT_TMP, r0, i);
1666       else {
1667         jit_movi_i(JIT_TMP, i1);
1668         _ANDS(JIT_TMP, r0, JIT_TMP);
1669       }
1670     }
1671     l = arm_branch(_jitp, cc, i0);
1672   }
1673   return (l);
1674 }
1675 #define jit_bmsr_i(i0, r0, r1)		arm_bmxr(_jitp, ARM_CC_NE, i0, r0, r1)
1676 #define jit_bmsi_i(i0, r0, i1)		arm_bmxi(_jitp, ARM_CC_NE, i0, r0, i1)
1677 #define jit_bmcr_i(i0, r0, r1)		arm_bmxr(_jitp, ARM_CC_EQ, i0, r0, r1)
1678 #define jit_bmci_i(i0, r0, i1)		arm_bmxi(_jitp, ARM_CC_EQ, i0, r0, i1)
1679 
1680 #define jit_ldr_c(r0, r1)		arm_ldr_c(_jitp, r0, r1)
1681 __jit_inline void
arm_ldr_c(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1)1682 arm_ldr_c(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1)
1683 {
1684   if (jit_thumb_p())
1685     T2_LDRSBI(r0, r1, 0);
1686   else
1687     _LDRSBI(r0, r1, 0);
1688 }
1689 
1690 #define jit_ldi_c(r0, i0)		arm_ldi_c(_jitp, r0, i0)
1691 __jit_inline void
arm_ldi_c(jit_state_t _jitp,jit_gpr_t r0,void * i0)1692 arm_ldi_c(jit_state_t _jitp, jit_gpr_t r0, void *i0)
1693 {
1694   jit_movi_i(JIT_TMP, (int)i0);
1695   if (jit_thumb_p())
1696     T2_LDRSBI(r0, JIT_TMP, 0);
1697   else
1698     _LDRSBI(r0, JIT_TMP, 0);
1699 }
1700 
1701 #define jit_ldxr_c(r0, r1, r2)		arm_ldxr_c(_jitp, r0, r1, r2)
1702 __jit_inline void
arm_ldxr_c(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)1703 arm_ldxr_c(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
1704 {
1705   if (jit_thumb_p()) {
1706     if ((r0|r1|r2) < 8)
1707       T1_LDRSB(r0, r1, r2);
1708     else
1709       T2_LDRSB(r0, r1, r2);
1710   }
1711   else
1712     _LDRSB(r0, r1, r2);
1713 }
1714 
1715 #define jit_ldxi_c(r0, r1, i0)		arm_ldxi_c(_jitp, r0, r1, i0)
1716 __jit_inline void
arm_ldxi_c(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)1717 arm_ldxi_c(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
1718 {
1719   jit_gpr_t		reg;
1720   if (jit_thumb_p()) {
1721     if (i0 >= 0 && i0 <= 255)
1722       T2_LDRSBI(r0, r1, i0);
1723     else if (i0 < 0 && i0 >= -255)
1724       T2_LDRSBIN(r0, r1, -i0);
1725     else if (i0 >= 0 && i0 <= 4095)
1726       T2_LDRSBWI(r0, r1, i0);
1727     else {
1728       reg = r0 != r1 ? r0 : JIT_TMP;
1729       jit_movi_i(reg, i0);
1730       if ((r0|r1|reg) < 8)
1731         T1_LDRSB(r0, r1, reg);
1732       else
1733         T2_LDRSB(r0, r1, reg);
1734     }
1735   }
1736   else {
1737     if (i0 >= 0 && i0 <= 255)
1738       _LDRSBI(r0, r1, i0);
1739     else if (i0 < 0 && i0 >= -255)
1740       _LDRSBIN(r0, r1, -i0);
1741     else {
1742       reg = r0 != r1 ? r0 : JIT_TMP;
1743       jit_movi_i(reg, i0);
1744       _LDRSB(r0, r1, reg);
1745     }
1746   }
1747 }
1748 
1749 #define jit_ldr_uc(r0, r1)		arm_ldr_uc(_jitp, r0, r1)
1750 __jit_inline void
arm_ldr_uc(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1)1751 arm_ldr_uc(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1)
1752 {
1753   if (jit_thumb_p())
1754     T2_LDRBI(r0, r1, 0);
1755   else
1756     _LDRBI(r0, r1, 0);
1757 }
1758 
1759 #define jit_ldi_uc(r0, i0)		arm_ldi_uc(_jitp, r0, i0)
1760 __jit_inline void
arm_ldi_uc(jit_state_t _jitp,jit_gpr_t r0,void * i0)1761 arm_ldi_uc(jit_state_t _jitp, jit_gpr_t r0, void *i0)
1762 {
1763   jit_movi_i(JIT_TMP, (int)i0);
1764   if (jit_thumb_p())
1765     T2_LDRBI(r0, JIT_TMP, 0);
1766   else
1767     _LDRBI(r0, JIT_TMP, 0);
1768 }
1769 
1770 #define jit_ldxr_uc(r0, r1, r2)		arm_ldxr_uc(_jitp, r0, r1, r2)
1771 __jit_inline void
arm_ldxr_uc(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)1772 arm_ldxr_uc(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
1773 {
1774   if (jit_thumb_p()) {
1775     if ((r0|r1|r2) < 8)
1776       T1_LDRB(r0, r1, r2);
1777     else
1778       T2_LDRB(r0, r1, r2);
1779   }
1780   else
1781     _LDRB(r0, r1, r2);
1782 }
1783 
1784 #define jit_ldxi_uc(r0, r1, i0)		arm_ldxi_uc(_jitp, r0, r1, i0)
1785 __jit_inline void
arm_ldxi_uc(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)1786 arm_ldxi_uc(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
1787 {
1788   jit_gpr_t		reg;
1789   if (jit_thumb_p()) {
1790     if ((r0|r1) < 8 && i0 >= 0 && i0 < 0x20)
1791       T1_LDRBI(r0, r1, i0);
1792     else if (i0 >= 0 && i0 <= 255)
1793       T2_LDRBI(r0, r1, i0);
1794     else if (i0 < 0 && i0 >= -255)
1795       T2_LDRBIN(r0, r1, -i0);
1796     else if (i0 >= 0 && i0 <= 4095)
1797       T2_LDRBWI(r0, r1, i0);
1798     else {
1799       reg = r0 != r1 ? r0 : JIT_TMP;
1800       jit_movi_i(reg, i0);
1801       if ((r0|r1|reg) < 8)
1802         T1_LDRB(r0, r1, reg);
1803       else
1804         T2_LDRB(r0, r1, reg);
1805     }
1806   }
1807   else {
1808     if (i0 >= 0 && i0 <= 4095)
1809       _LDRBI(r0, r1, i0);
1810     else if (i0 < 0 && i0 >= -4095)
1811       _LDRBIN(r0, r1, -i0);
1812     else {
1813       reg = r0 != r1 ? r0 : JIT_TMP;
1814       jit_movi_i(reg, i0);
1815       _LDRB(r0, r1, reg);
1816     }
1817   }
1818 }
1819 
1820 #define jit_ldr_s(r0, r1)		arm_ldr_s(_jitp, r0, r1)
1821 __jit_inline void
arm_ldr_s(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1)1822 arm_ldr_s(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1)
1823 {
1824   if (jit_thumb_p())
1825     T2_LDRSHI(r0, r1, 0);
1826   else
1827     _LDRSHI(r0, r1, 0);
1828 }
1829 
1830 #define jit_ldi_s(r0, i0)		arm_ldi_s(_jitp, r0, i0)
1831 __jit_inline void
arm_ldi_s(jit_state_t _jitp,jit_gpr_t r0,void * i0)1832 arm_ldi_s(jit_state_t _jitp, jit_gpr_t r0, void *i0)
1833 {
1834   jit_movi_i(JIT_TMP, (int)i0);
1835   if (jit_thumb_p())
1836     T2_LDRSHI(r0, JIT_TMP, 0);
1837   else
1838     _LDRSHI(r0, JIT_TMP, 0);
1839 }
1840 
1841 #define jit_ldxr_s(r0, r1, r2)		arm_ldxr_s(_jitp, r0, r1, r2)
1842 __jit_inline void
arm_ldxr_s(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)1843 arm_ldxr_s(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
1844 {
1845   if (jit_thumb_p()) {
1846     if ((r0|r1|r2) < 8)
1847       T1_LDRSH(r0, r1, r2);
1848     else
1849       T2_LDRSH(r0, r1, r2);
1850   }
1851   else
1852     _LDRSH(r0, r1, r2);
1853 }
1854 
1855 #define jit_ldxi_s(r0, r1, i0)		arm_ldxi_s(_jitp, r0, r1, (int)i0)
1856 __jit_inline void
arm_ldxi_s(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)1857 arm_ldxi_s(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
1858 {
1859   jit_gpr_t		reg;
1860   if (jit_thumb_p()) {
1861     if (i0 >= 0 && i0 <= 255)
1862       T2_LDRSHI(r0, r1, i0);
1863     else if (i0 < 0 && i0 >= -255)
1864       T2_LDRSHIN(r0, r1, -i0);
1865     else if (i0 >= 0 && i0 <= 4095)
1866       T2_LDRSHWI(r0, r1, i0);
1867     else {
1868       reg = r0 != r1 ? r0 : JIT_TMP;
1869       jit_movi_i(reg, i0);
1870       if ((r0|r1|reg) < 8)
1871         T1_LDRSH(r0, r1, reg);
1872       else
1873         T2_LDRSH(r0, r1, reg);
1874     }
1875   }
1876   else {
1877     if (i0 >= 0 && i0 <= 255)
1878       _LDRSHI(r0, r1, i0);
1879     else if (i0 < 0 && i0 >= -255)
1880       _LDRSHIN(r0, r1, -i0);
1881     else {
1882       reg = r0 != r1 ? r0 : JIT_TMP;
1883       jit_movi_i(reg, i0);
1884       _LDRSH(r0, r1, reg);
1885     }
1886   }
1887 
1888 }
1889 #define jit_ldr_us(r0, r1)		arm_ldr_us(_jitp, r0, r1)
1890 __jit_inline void
arm_ldr_us(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1)1891 arm_ldr_us(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1)
1892 {
1893   if (jit_thumb_p())
1894     T2_LDRHI(r0, r1, 0);
1895   else
1896     _LDRHI(r0, r1, 0);
1897 }
1898 
1899 #define jit_ldi_us(r0, i0)		arm_ldi_us(_jitp, r0, i0)
1900 __jit_inline void
arm_ldi_us(jit_state_t _jitp,jit_gpr_t r0,void * i0)1901 arm_ldi_us(jit_state_t _jitp, jit_gpr_t r0, void *i0)
1902 {
1903   jit_movi_i(JIT_TMP, (int)i0);
1904   if (jit_thumb_p())
1905     T2_LDRHI(r0, JIT_TMP, 0);
1906   else
1907     _LDRHI(r0, JIT_TMP, 0);
1908 }
1909 
1910 #define jit_ldxr_us(r0, r1, r2)		arm_ldxr_us(_jitp, r0, r1, r2)
1911 __jit_inline void
arm_ldxr_us(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)1912 arm_ldxr_us(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
1913 {
1914   if (jit_thumb_p()) {
1915     if ((r0|r1|r2) < 8)
1916       T1_LDRH(r0, r1, r2);
1917     else
1918       T2_LDRH(r0, r1, r2);
1919   }
1920   else
1921     _LDRH(r0, r1, r2);
1922 }
1923 
1924 #define jit_ldxi_us(r0, r1, i0)		arm_ldxi_us(_jitp, r0, r1, i0)
1925 __jit_inline void
arm_ldxi_us(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)1926 arm_ldxi_us(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
1927 {
1928   jit_gpr_t		reg;
1929   if (jit_thumb_p()) {
1930     if ((r0|r1) < 8 && i0 >= 0 && !(i0 & 1) && (i0 >> 1) < 0x20)
1931       T1_LDRHI(r0, r1, i0 >> 1);
1932     else if (i0 >= 0 && i0 <= 255)
1933       T2_LDRHI(r0, r1, i0);
1934     else if (i0 < 0 && i0 >= -255)
1935       T2_LDRHIN(r0, r1, -i0);
1936     else if (i0 >= 0 && i0 <= 4095)
1937       T2_LDRHWI(r0, r1, i0);
1938     else {
1939       reg = r0 != r1 ? r0 : JIT_TMP;
1940       jit_movi_i(reg, i0);
1941       if ((r0|r1|reg) < 8)
1942         T1_LDRH(r0, r1, reg);
1943       else
1944         T2_LDRH(r0, r1, reg);
1945     }
1946   }
1947   else {
1948     if (i0 >= 0 && i0 <= 255)
1949       _LDRHI(r0, r1, i0);
1950     else if (i0 < 0 && i0 >= -255)
1951       _LDRHIN(r0, r1, -i0);
1952     else {
1953       reg = r0 != r1 ? r0 : JIT_TMP;
1954       jit_movi_i(reg, i0);
1955       _LDRH(r0, r1, reg);
1956     }
1957   }
1958 }
1959 
1960 #define jit_ldr_i(r0, r1)		arm_ldr_i(_jitp, r0, r1)
1961 __jit_inline void
arm_ldr_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1)1962 arm_ldr_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1)
1963 {
1964   if (jit_thumb_p())
1965     T2_LDRI(r0, r1, 0);
1966   else
1967     _LDRI(r0, r1, 0);
1968 }
1969 
1970 #define jit_ldi_i(r0, i0)		arm_ldi_i(_jitp, r0, i0)
1971 __jit_inline void
arm_ldi_i(jit_state_t _jitp,jit_gpr_t r0,void * i0)1972 arm_ldi_i(jit_state_t _jitp, jit_gpr_t r0, void *i0)
1973 {
1974   jit_movi_i(JIT_TMP, (int)i0);
1975   if (jit_thumb_p())
1976     T2_LDRI(r0, JIT_TMP, 0);
1977   else
1978     _LDRI(r0, JIT_TMP, 0);
1979 }
1980 
1981 #define jit_ldxr_i(r0, r1, r2)		arm_ldxr_i(_jitp, r0, r1, r2)
1982 __jit_inline void
arm_ldxr_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)1983 arm_ldxr_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
1984 {
1985   if (jit_thumb_p()) {
1986     if ((r0|r1|r2) < 8)
1987       T1_LDR(r0, r1, r2);
1988     else
1989       T2_LDR(r0, r1, r2);
1990   }
1991   else
1992     _LDR(r0, r1, r2);
1993 }
1994 
1995 #define jit_ldxi_i(r0, r1, i0)		arm_ldxi_i(_jitp, r0, r1, (int)i0)
1996 __jit_inline void
arm_ldxi_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,int i0)1997 arm_ldxi_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, int i0)
1998 {
1999   jit_gpr_t		reg;
2000   if (jit_thumb_p()) {
2001     if ((r0|r1) < 8 && i0 >= 0 && !(i0 & 3) && (i0 >> 2) < 0x20)
2002       T1_LDRI(r0, r1, i0 >> 2);
2003     else if (r1 == _R13 && r0 < 8 &&
2004              i0 >= 0 && !(i0 & 3) && (i0 >> 2) <= 255)
2005       T1_LDRISP(r0, i0 >> 2);
2006     else if (i0 >= 0 && i0 <= 255)
2007       T2_LDRI(r0, r1, i0);
2008     else if (i0 < 0 && i0 >= -255)
2009       T2_LDRIN(r0, r1, -i0);
2010     else if (i0 >= 0 && i0 <= 4095)
2011       T2_LDRWI(r0, r1, i0);
2012     else {
2013       reg = r0 != r1 ? r0 : JIT_TMP;
2014       jit_movi_i(reg, i0);
2015       if ((r0|r1|reg) < 8)
2016         T1_LDR(r0, r1, reg);
2017       else
2018         T2_LDR(r0, r1, reg);
2019     }
2020   }
2021   else {
2022     if (i0 >= 0 && i0 <= 4095)
2023       _LDRI(r0, r1, i0);
2024     else if (i0 < 0 && i0 >= -4095)
2025       _LDRIN(r0, r1, -i0);
2026     else {
2027       reg = r0 != r1 ? r0 : JIT_TMP;
2028       jit_movi_i(reg, i0);
2029       _LDR(r0, r1, reg);
2030     }
2031   }
2032 }
2033 
2034 #define jit_str_c(r0, r1)		arm_str_c(_jitp, r0, r1)
2035 __jit_inline void
arm_str_c(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1)2036 arm_str_c(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1)
2037 {
2038   if (jit_thumb_p())
2039     T2_STRBI(r1, r0, 0);
2040   else
2041     _STRBI(r1, r0, 0);
2042 }
2043 
2044 #define jit_sti_c(r0, i0)		arm_sti_c(_jitp, r0, i0)
2045 __jit_inline void
arm_sti_c(jit_state_t _jitp,void * i0,jit_gpr_t r0)2046 arm_sti_c(jit_state_t _jitp, void *i0, jit_gpr_t r0)
2047 {
2048   jit_movi_i(JIT_TMP, (int)i0);
2049   if (jit_thumb_p())
2050     T2_STRBI(r0, JIT_TMP, 0);
2051   else
2052     _STRBI(r0, JIT_TMP, 0);
2053 }
2054 
2055 #define jit_stxr_c(r0, r1, r2)		arm_stxr_c(_jitp, r0, r1, r2)
2056 __jit_inline void
arm_stxr_c(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)2057 arm_stxr_c(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
2058 {
2059   if (jit_thumb_p()) {
2060     if ((r0|r1|r2) < 8)
2061       T1_STRB(r2, r1, r0);
2062     else
2063       T2_STRB(r2, r1, r0);
2064   }
2065   else
2066     _STRB(r2, r1, r0);
2067 }
2068 
2069 #define jit_stxi_c(r0, r1, i0)		arm_stxi_c(_jitp, r0, r1, i0)
2070 __jit_inline void
arm_stxi_c(jit_state_t _jitp,int i0,jit_gpr_t r0,jit_gpr_t r1)2071 arm_stxi_c(jit_state_t _jitp, int i0, jit_gpr_t r0, jit_gpr_t r1)
2072 {
2073   if (jit_thumb_p()) {
2074     if ((r0|r1) < 8 && i0 >= 0 && i0 < 0x20)
2075       T1_STRBI(r1, r0, i0);
2076     else if (i0 >= 0 && i0 <= 255)
2077       T2_STRBI(r1, r0, i0);
2078     else if (i0 < 0 && i0 >= -255)
2079       T2_STRBIN(r1, r0, -i0);
2080     else if (i0 >= 0 && i0 <= 4095)
2081       T2_STRBWI(r1, r0, i0);
2082     else {
2083       jit_movi_i(JIT_TMP, (int)i0);
2084       if ((r0|r1|JIT_TMP) < 8)
2085         T1_STRB(r1, r0, JIT_TMP);
2086       else
2087         T2_STRB(r1, r0, JIT_TMP);
2088     }
2089   }
2090   else {
2091     if (i0 >= 0 && i0 <= 4095)
2092       _STRBI(r1, r0, i0);
2093     else if (i0 < 0 && i0 >= -4095)
2094       _STRBIN(r1, r0, -i0);
2095     else {
2096       jit_movi_i(JIT_TMP, i0);
2097       _STRB(r1, r0, JIT_TMP);
2098     }
2099   }
2100 }
2101 
2102 #define jit_str_s(r0, r1)		arm_str_s(_jitp, r0, r1)
2103 __jit_inline void
arm_str_s(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1)2104 arm_str_s(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1)
2105 {
2106   if (jit_thumb_p())
2107     T2_STRHI(r1, r0, 0);
2108   else
2109     _STRHI(r1, r0, 0);
2110 }
2111 
2112 #define jit_sti_s(r0, i0)		arm_sti_s(_jitp, r0, i0)
2113 __jit_inline void
arm_sti_s(jit_state_t _jitp,void * i0,jit_gpr_t r0)2114 arm_sti_s(jit_state_t _jitp, void *i0, jit_gpr_t r0)
2115 {
2116   jit_movi_i(JIT_TMP, (int)i0);
2117   if (jit_thumb_p())
2118     T2_STRHI(r0, JIT_TMP, 0);
2119   else
2120     _STRHI(r0, JIT_TMP, 0);
2121 }
2122 
2123 #define jit_stxr_s(r0, r1, r2)		arm_stxr_s(_jitp, r0, r1, r2)
2124 __jit_inline void
arm_stxr_s(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)2125 arm_stxr_s(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
2126 {
2127   if (jit_thumb_p()) {
2128     if ((r0|r1|r2) < 8)
2129       T1_STRH(r2, r1, r0);
2130     else
2131       T2_STRH(r2, r1, r0);
2132   }
2133   else
2134     _STRH(r2, r1, r0);
2135 }
2136 
2137 #define jit_stxi_s(r0, r1, i0)		arm_stxi_s(_jitp, (int)r0, r1, i0)
2138 __jit_inline void
arm_stxi_s(jit_state_t _jitp,int i0,jit_gpr_t r0,jit_gpr_t r1)2139 arm_stxi_s(jit_state_t _jitp, int i0, jit_gpr_t r0, jit_gpr_t r1)
2140 {
2141   if (jit_thumb_p()) {
2142     if ((r0|r1) < 8 && i0 >= 0 && !(i0 & 1) && (i0 >> 1) < 0x20)
2143       T1_STRHI(r1, r0, i0 >> 1);
2144     else if (i0 >= 0 && i0 <= 255)
2145       T2_STRHI(r1, r0, i0);
2146     else if (i0 < 0 && i0 >= -255)
2147       T2_STRHIN(r1, r0, -i0);
2148     else if (i0 >= 0 && i0 <= 4095)
2149       T2_STRHWI(r1, r0, i0);
2150     else {
2151       jit_movi_i(JIT_TMP, (int)i0);
2152       if ((r0|r1|JIT_TMP) < 8)
2153         T1_STRH(r1, r0, JIT_TMP);
2154       else
2155         T2_STRH(r1, r0, JIT_TMP);
2156     }
2157   }
2158   else {
2159     if (i0 >= 0 && i0 <= 255)
2160       _STRHI(r1, r0, i0);
2161     else if (i0 < 0 && i0 >= -255)
2162       _STRHIN(r1, r0, -i0);
2163     else {
2164       jit_movi_i(JIT_TMP, i0);
2165       _STRH(r1, r0, JIT_TMP);
2166     }
2167   }
2168 }
2169 
2170 #define jit_str_i(r0, r1)		arm_str_i(_jitp, r0, r1)
2171 __jit_inline void
arm_str_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1)2172 arm_str_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1)
2173 {
2174   if (jit_thumb_p())
2175     T2_STRI(r1, r0, 0);
2176   else
2177     _STRI(r1, r0, 0);
2178 }
2179 
2180 #define jit_sti_i(r0, i0)		arm_sti_i(_jitp, r0, i0)
2181 __jit_inline void
arm_sti_i(jit_state_t _jitp,void * i0,jit_gpr_t r0)2182 arm_sti_i(jit_state_t _jitp, void *i0, jit_gpr_t r0)
2183 {
2184   jit_movi_i(JIT_TMP, (int)i0);
2185   if (jit_thumb_p())
2186     T2_STRI(r0, JIT_TMP, 0);
2187   else
2188     _STRI(r0, JIT_TMP, 0);
2189 }
2190 
2191 #define jit_stxr_i(r0, r1, r2)		arm_stxr_i(_jitp, r0, r1, r2)
2192 __jit_inline void
arm_stxr_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1,jit_gpr_t r2)2193 arm_stxr_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2)
2194 {
2195   if (jit_thumb_p()) {
2196     if ((r0|r1|r2) < 8)
2197       T1_STR(r2, r1, r0);
2198     else
2199       T2_STR(r2, r1, r0);
2200   }
2201   else
2202     _STR(r2, r1, r0);
2203 }
2204 
2205 #define jit_stxi_i(r0, r1, i0)		arm_stxi_i(_jitp, (int)r0, r1, i0)
2206 __jit_inline void
arm_stxi_i(jit_state_t _jitp,int i0,jit_gpr_t r0,jit_gpr_t r1)2207 arm_stxi_i(jit_state_t _jitp, int i0, jit_gpr_t r0, jit_gpr_t r1)
2208 {
2209   if (jit_thumb_p()) {
2210     if ((r0|r1) < 8 && i0 >= 0 && !(i0 & 3) && (i0 >> 2) < 0x20)
2211       T1_STRI(r1, r0, i0 >> 2);
2212     else if (r0 == _R13 && r1 < 8 &&
2213              i0 >= 0 && !(i0 & 3) && (i0 >> 2) <= 255)
2214       T1_STRISP(r1, i0 >> 2);
2215     else if (i0 >= 0 && i0 <= 255)
2216       T2_STRI(r1, r0, i0);
2217     else if (i0 < 0 && i0 >= -255)
2218       T2_STRIN(r1, r0, -i0);
2219     else if (i0 >= 0 && i0 <= 4095)
2220       T2_STRWI(r1, r0, i0);
2221     else {
2222       jit_movi_i(JIT_TMP, (int)i0);
2223       if ((r0|r1|JIT_TMP) < 8)
2224         T1_STR(r1, r0, JIT_TMP);
2225       else
2226         T2_STR(r1, r0, JIT_TMP);
2227     }
2228   }
2229   else {
2230     if (i0 >= 0 && i0 <= 4095)
2231       _STRI(r1, r0, i0);
2232     else if (i0 < 0 && i0 >= -4095)
2233       _STRIN(r1, r0, -i0);
2234     else {
2235       jit_movi_i(JIT_TMP, i0);
2236       _STR(r1, r0, JIT_TMP);
2237     }
2238   }
2239 }
2240 
2241 #if __BYTE_ORDER == __LITTLE_ENDIAN
2242 /* inline glibc htons (without register clobber) */
2243 #define jit_ntoh_us(r0, r1)		arm_ntoh_us(_jitp, r0, r1)
2244 __jit_inline void
arm_ntoh_us(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1)2245 arm_ntoh_us(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1)
2246 {
2247   if (jit_thumb_p()) {
2248     if ((r0|r1) < 8)
2249       T1_REV16(r0, r1);
2250     else
2251       T2_REV16(r0, r1);
2252   }
2253   else {
2254     if (jit_armv6_p())
2255       _REV16(r0, r1);
2256     else {
2257       _LSLI(JIT_TMP, r1, 24);
2258       _LSRI(r0, r1, 8);
2259       _ORR_SI(r0, r0, JIT_TMP, ARM_LSR, 16);
2260     }
2261   }
2262 }
2263 
2264 /* inline glibc htonl (without register clobber) */
2265 #define jit_ntoh_ui(r0, r1)		arm_ntoh_ui(_jitp, r0, r1)
2266 __jit_inline void
arm_ntoh_ui(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1)2267 arm_ntoh_ui(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1)
2268 {
2269   if (jit_thumb_p()) {
2270     if ((r0|r1) < 8)
2271       T1_REV(r0, r1);
2272     else
2273       T2_REV(r0, r1);
2274   }
2275   else {
2276     if (jit_armv6_p())
2277       _REV(r0, r1);
2278     else {
2279       _EOR_SI(JIT_TMP, r1, r1, ARM_ROR, 16);
2280       _LSRI(JIT_TMP, JIT_TMP, 8);
2281       _BICI(JIT_TMP, JIT_TMP, encode_arm_immediate(0xff00));
2282       _EOR_SI(r0, JIT_TMP, r1, ARM_ROR, 8);
2283     }
2284   }
2285 }
2286 #endif
2287 
2288 #define jit_extr_c_i(r0, r1)		arm_extr_c_i(_jitp, r0, r1)
2289 __jit_inline void
arm_extr_c_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1)2290 arm_extr_c_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1)
2291 {
2292   if (jit_thumb_p()) {
2293     if ((r0|r1) < 8)
2294       T1_SXTB(r0, r1);
2295     else
2296       T2_SXTB(r0, r1);
2297   }
2298   else {
2299     if (jit_armv6_p())
2300       _SXTB(r0, r1);
2301     else {
2302       _LSLI(r0, r1, 24);
2303       _ASRI(r0, r0, 24);
2304     }
2305   }
2306 }
2307 
2308 #define jit_extr_c_ui(r0, r1)		arm_extr_c_ui(_jitp, r0, r1)
2309 __jit_inline void
arm_extr_c_ui(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1)2310 arm_extr_c_ui(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1)
2311 {
2312   if (jit_thumb_p()) {
2313     if ((r0|r1) < 8)
2314       T1_UXTB(r0, r1);
2315     else
2316       T2_UXTB(r0, r1);
2317   }
2318   else {
2319     if (jit_armv6_p())
2320       _UXTB(r0, r1);
2321     else
2322       _ANDI(r0, r1, 0xff);
2323   }
2324 }
2325 
2326 #define jit_extr_s_i(r0, r1)		arm_extr_s_i(_jitp, r0, r1)
2327 __jit_inline void
arm_extr_s_i(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1)2328 arm_extr_s_i(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1)
2329 {
2330   if (jit_thumb_p()) {
2331     if ((r0|r1) < 8)
2332       T1_SXTH(r0, r1);
2333     else
2334       T2_SXTH(r0, r1);
2335   }
2336   else {
2337     if (jit_armv6_p())
2338       _SXTH(r0, r1);
2339     else {
2340       _LSLI(r0, r1, 16);
2341       _ASRI(r0, r0, 16);
2342     }
2343   }
2344 }
2345 
2346 #define jit_extr_s_ui(r0, r1)		arm_extr_s_ui(_jitp, r0, r1)
2347 __jit_inline void
arm_extr_s_ui(jit_state_t _jitp,jit_gpr_t r0,jit_gpr_t r1)2348 arm_extr_s_ui(jit_state_t _jitp, jit_gpr_t r0, jit_gpr_t r1)
2349 {
2350   if (jit_thumb_p()) {
2351     if ((r0|r1) < 8)
2352       T1_UXTH(r0, r1);
2353     else
2354       T2_UXTH(r0, r1);
2355   }
2356   else {
2357     if (jit_armv6_p())
2358       _UXTH(r0, r1);
2359     else {
2360       /* _ANDI(r0, r1, 0xffff) needs more instructions */
2361       _LSLI(r0, r1, 16);
2362       _LSRI(r0, r0, 16);
2363     }
2364   }
2365 }
2366 
2367 #define JIT_NEXT_FP_OFFSET              8
2368 #define JIT_FRAME_EXTRA_SPACE           16
2369 #define JIT_FRAME_EXTRA_SPACE_OFFSET    (-JIT_FRAME_EXTRA_SPACE)
2370 #define JIT_ARG_STACK_OFFSET            0
2371 
2372 #define jit_prolog(n)			arm_prolog(_jitp, n)
2373 __jit_inline void
arm_prolog(jit_state_t _jitp,int i0)2374 arm_prolog(jit_state_t _jitp, int i0)
2375 {
2376   if (jit_thumb_p()) {
2377     T2_PUSH(/* arguments (should keep state and only save "i0" registers) */
2378             (1<<_R0)|(1<<_R1)|(1<<_R2)|(1<<_R3)|
2379             (1<<_R4)|(1<<_R5)|(1<<_R6)|(1<<_R7)|
2380             /* previous fp and return address */
2381             (1<<JIT_FP)|(1<<JIT_LR));
2382     T2_MOV(JIT_FP, JIT_SP);
2383   }
2384   else {
2385     _PUSH(/* arguments (should keep state and only save "i0" registers) */
2386           (1<<_R0)|(1<<_R1)|(1<<_R2)|(1<<_R3)|
2387           (1<<_R4)|(1<<_R5)|(1<<_R6)|(1<<_R7)|
2388           /* previous fp and return address */
2389           (1<<JIT_FP)|(1<<JIT_LR));
2390     _MOV(JIT_FP, JIT_SP);
2391   }
2392 
2393   _jitl.nextarg_get = _jitl.nextarg_getf = 0;
2394 
2395   if (jit_swf_p()) {
2396     /* 6 soft double precision float registers */
2397     jit_subi_i(JIT_SP, JIT_SP, JIT_FRAME_EXTRA_SPACE + 48);
2398   } else if (JIT_FRAME_EXTRA_SPACE) {
2399     jit_subi_i(JIT_SP, JIT_SP, JIT_FRAME_EXTRA_SPACE);
2400   }
2401 }
2402 
2403 #define jit_callr(r0)			arm_callr(_jitp, r0)
2404 static void
arm_callr(jit_state_t _jitp,jit_gpr_t r0)2405 arm_callr(jit_state_t _jitp, jit_gpr_t r0)
2406 {
2407   if (jit_thumb_p())
2408     T1_BLX(r0);
2409   else
2410     _BLX(r0);
2411 }
2412 
2413 #define jit_calli(i0)			arm_calli(_jitp, i0)
2414 __jit_inline jit_insn *
arm_calli(jit_state_t _jitp,void * i0)2415 arm_calli(jit_state_t _jitp, void *i0)
2416 {
2417   jit_insn	*l;
2418   l = _jitp->x.pc;
2419   jit_movi_p(JIT_TMP, i0);
2420   if (jit_thumb_p()) {
2421     l++;
2422     T1_BLX(JIT_TMP);
2423   } else
2424     _BLX(JIT_TMP);
2425   return (l);
2426 }
2427 
2428 #define jit_short_calli(i0)			arm_short_calli(_jitp, i0)
2429 __jit_inline jit_insn *
arm_short_calli(jit_state_t _jitp,void * i0)2430 arm_short_calli(jit_state_t _jitp, void *i0)
2431 {
2432   jit_insn	*l;
2433   long	 d;
2434 
2435   if (jit_thumb_p()) {
2436     jit_assert((long)i0 & 0x1);
2437     l = _jitp->x.pc+1;
2438     d = (((long)i0 - (long)l) >> 1) - 2;
2439     T2_BLI(encode_thumb_jump(d));
2440   } else {
2441     l = _jitp->x.pc;
2442     d = (((long)i0 - (long)l) >> 2) - 2;
2443     _BLI(d & 0x00ffffff);
2444   }
2445 
2446   return (l);
2447 }
2448 
2449 #define jit_prepare_i(i0)		arm_prepare_i(_jitp, i0)
2450 __jit_inline void
arm_prepare_i(jit_state_t _jitp,int i0)2451 arm_prepare_i(jit_state_t _jitp, int i0)
2452 {
2453   jit_assert(i0 >= 0 && !_jitl.nextarg_put);
2454 }
2455 
2456 #define jit_arg_c()			arm_arg_i(_jitp)
2457 #define jit_arg_uc()			arm_arg_i(_jitp)
2458 #define jit_arg_s()			arm_arg_i(_jitp)
2459 #define jit_arg_us()			arm_arg_i(_jitp)
2460 #define jit_arg_i()			arm_arg_i(_jitp)
2461 #define jit_arg_ui()			arm_arg_i(_jitp)
2462 #define jit_arg_l()			arm_arg_i(_jitp)
2463 #define jit_arg_ul()			arm_arg_i(_jitp)
2464 #define jit_arg_p()			arm_arg_i(_jitp)
2465 __jit_inline int
arm_arg_i(jit_state_t _jitp)2466 arm_arg_i(jit_state_t _jitp)
2467 {
2468   int		ofs = _jitl.nextarg_get++;
2469   return (ofs);
2470 }
2471 
2472 #define jit_getarg_c(r0, i0)		arm_getarg_c(_jitp, r0, i0)
2473 __jit_inline void
arm_getarg_c(jit_state_t _jitp,jit_gpr_t r0,int i0)2474 arm_getarg_c(jit_state_t _jitp, jit_gpr_t r0, int i0)
2475 {
2476   if (i0 < 4)
2477     i0 <<= 2;
2478 #if __BYTE_ORDER == __BIG_ENDIAN
2479   i0 += sizeof(int) - sizeof(char);
2480 #endif
2481   jit_ldxi_c(r0, JIT_FP, i0);
2482 }
2483 
2484 #define jit_getarg_uc(r0, i0)		arm_getarg_uc(_jitp, r0, i0)
2485 __jit_inline void
arm_getarg_uc(jit_state_t _jitp,jit_gpr_t r0,int i0)2486 arm_getarg_uc(jit_state_t _jitp, jit_gpr_t r0, int i0)
2487 {
2488   if (i0 < 4)
2489     i0 <<= 2;
2490 #if __BYTE_ORDER == __BIG_ENDIAN
2491   i0 += sizeof(int) - sizeof(char);
2492 #endif
2493   jit_ldxi_uc(r0, JIT_FP, i0);
2494 }
2495 
2496 #define jit_getarg_s(r0, i0)		arm_getarg_s(_jitp, r0, i0)
2497 __jit_inline void
arm_getarg_s(jit_state_t _jitp,jit_gpr_t r0,int i0)2498 arm_getarg_s(jit_state_t _jitp, jit_gpr_t r0, int i0)
2499 {
2500   if (i0 < 4)
2501     i0 <<= 2;
2502 #if __BYTE_ORDER == __BIG_ENDIAN
2503   i0 += sizeof(int) - sizeof(short);
2504 #endif
2505   jit_ldxi_s(r0, JIT_FP, i0);
2506 }
2507 
2508 #define jit_getarg_us(r0, i0)		arm_getarg_us(_jitp, r0, i0)
2509 __jit_inline void
arm_getarg_us(jit_state_t _jitp,jit_gpr_t r0,int i0)2510 arm_getarg_us(jit_state_t _jitp, jit_gpr_t r0, int i0)
2511 {
2512   if (i0 < 4)
2513     i0 <<= 2;
2514 #if __BYTE_ORDER == __BIG_ENDIAN
2515   i0 += sizeof(int) - sizeof(short);
2516 #endif
2517   jit_ldxi_us(r0, JIT_FP, i0);
2518 }
2519 
2520 #define jit_getarg_i(r0, i0)		arm_getarg_i(_jitp, r0, i0)
2521 #define jit_getarg_ui(r0, i0)		arm_getarg_i(_jitp, r0, i0)
2522 #define jit_getarg_l(r0, i0)		arm_getarg_i(_jitp, r0, i0)
2523 #define jit_getarg_ul(r0, i0)		arm_getarg_i(_jitp, r0, i0)
2524 #define jit_getarg_p(r0, i0)		arm_getarg_i(_jitp, r0, i0)
2525 __jit_inline void
arm_getarg_i(jit_state_t _jitp,jit_gpr_t r0,int i0)2526 arm_getarg_i(jit_state_t _jitp, jit_gpr_t r0, int i0)
2527 {
2528   /* arguments are saved in prolog */
2529   if (i0 < 4)
2530     i0 <<= 2;
2531   jit_ldxi_i(r0, JIT_FP, i0);
2532 }
2533 
2534 #define jit_pusharg_i(r0)		arm_pusharg_i(_jitp, r0)
2535 __jit_inline void
arm_pusharg_i(jit_state_t _jitp,jit_gpr_t r0)2536 arm_pusharg_i(jit_state_t _jitp, jit_gpr_t r0)
2537 {
2538   int		ofs = _jitl.nextarg_put++;
2539   jit_stxi_i((ofs <<2) + JIT_ARG_STACK_OFFSET, JIT_FP, r0);
2540 }
2541 
2542 #define jit_normal_pushonlyarg_i(r0)  arm_normal_pushonlyarg_i(_jitp, r0)
2543 __jit_inline void
arm_normal_pushonlyarg_i(jit_state_t _jitp,jit_gpr_t r0)2544 arm_normal_pushonlyarg_i(jit_state_t _jitp, jit_gpr_t r0)
2545 {
2546   jit_movr_i(JIT_R0, r0);
2547 }
2548 
2549 static void
arm_patch_arguments(jit_state_t _jitp)2550 arm_patch_arguments(jit_state_t _jitp)
2551 {
2552   int ofs = _jitl.nextarg_put;
2553   int reg = 0;
2554   _jitl.nextarg_put = 0;
2555   while (ofs) {
2556     --ofs;
2557     jit_ldxi_i(JIT_R(reg), JIT_FP, (ofs <<2) + JIT_ARG_STACK_OFFSET);
2558     reg++;
2559   }
2560 }
2561 
2562 #define jit_finishr(rs)			arm_finishr(_jitp, rs)
2563 __jit_inline void
arm_finishr(jit_state_t _jitp,jit_gpr_t r0)2564 arm_finishr(jit_state_t _jitp, jit_gpr_t r0)
2565 {
2566   if (r0 < 4) {
2567     jit_movr_i(JIT_TMP, r0);
2568     r0 = JIT_TMP;
2569   }
2570   arm_patch_arguments(_jitp);
2571   jit_callr(r0);
2572 }
2573 
2574 #define jit_finish(i0)			arm_finishi(_jitp, i0)
2575 __jit_inline jit_insn *
arm_finishi(jit_state_t _jitp,void * i0)2576 arm_finishi(jit_state_t _jitp, void *i0)
2577 {
2578   arm_patch_arguments(_jitp);
2579   return (jit_calli(i0));
2580 }
2581 
2582 #define jit_normal_finish(i0)		arm_normal_finishi(_jitp, i0)
2583 __jit_inline jit_insn *
arm_normal_finishi(jit_state_t _jitp,void * i0)2584 arm_normal_finishi(jit_state_t _jitp, void *i0)
2585 {
2586   return (jit_calli(i0));
2587 }
2588 
2589 #define jit_retval_i(r0)		jit_movr_i(r0, JIT_RET)
2590 #define jit_ret()			arm_ret(_jitp)
2591 __jit_inline void
arm_ret(jit_state_t _jitp)2592 arm_ret(jit_state_t _jitp)
2593 {
2594   /* do not restore arguments */
2595   jit_addi_i(JIT_SP, JIT_FP, 16);
2596   if (jit_thumb_p())
2597     T2_POP(/* callee save */
2598            (1<<_R4)|(1<<_R5)|(1<<_R6)|(1<<_R7)|
2599            /* previous fp and return address */
2600            (1<<JIT_FP)|(1<<JIT_PC));
2601   else
2602     _POP(/* callee save */
2603          (1<<_R4)|(1<<_R5)|(1<<_R6)|(1<<_R7)|
2604          /* previous fp and return address */
2605          (1<<JIT_FP)|(1<<JIT_PC));
2606   if (jit_thumb_p() && ((int)_jitp->x.pc & 2))
2607     T1_NOP();
2608 }
2609 
2610 # define jit_pushr_i(r0)		arm_pushr_i(_jitp, r0)
2611 __jit_inline void
arm_pushr_i(jit_state_t _jitp,jit_gpr_t r0)2612 arm_pushr_i(jit_state_t _jitp, jit_gpr_t r0)
2613 {
2614   _PUSH(1<<r0);
2615 }
2616 
2617 # define jit_popr_i(r0)			arm_popr_i(_jitp, r0)
2618 __jit_inline void
arm_popr_i(jit_state_t _jitp,jit_gpr_t r0)2619 arm_popr_i(jit_state_t _jitp, jit_gpr_t r0)
2620 {
2621   _POP(1<<r0);
2622 }
2623 
2624 #define jit_stixi_l(id, rd, is) (jit_movi_l(JIT_TMP, is), jit_stxi_l(id, rd, JIT_TMP))
2625 #define jit_stixi_p(id, rd, is) jit_stixi_l(id, rd, (long)is)
2626 
2627 #define jit_stir_l(rd, is) (jit_movi_l(JIT_TMP, (intptr_t)(is)), jit_str_l(rd, JIT_TMP))
2628 #define jit_stir_p(rd, is) jit_stir_l(rd, is)
2629 
2630 #endif /* __lightning_core_arm_h */
2631