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