1 /*
2 * Copyright (C) 2012-2019 Free Software Foundation, Inc.
3 *
4 * This file is part of GNU lightning.
5 *
6 * GNU lightning is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 3, or (at your option)
9 * any later version.
10 *
11 * GNU lightning is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 * License for more details.
15 *
16 * Authors:
17 * Paulo Cesar Pereira de Andrade
18 */
19
20 #define jit_arg_reg_p(i) ((i) >= 0 && (i) < 8)
21 #if !_CALL_SYSV
22 # define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 13)
23 #else
24 # define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 8)
25 # if __WORDSIZE == 32
26 # define va_gp_shift 2
27 # else
28 # define va_gp_shift 3
29 # endif
30 # define va_gp_increment sizeof(jit_word_t)
31 # define first_gp_argument r3
32 # define first_gp_offset offsetof(jit_va_list_t, \
33 first_gp_argument)
34 # define va_fp_increment sizeof(jit_float64_t)
35 # define first_fp_argument f1
36 # define first_fp_offset offsetof(jit_va_list_t, \
37 first_fp_argument)
38 #endif
39 #if __BYTE_ORDER == __LITTLE_ENDIAN
40 # define C_DISP 0
41 # define S_DISP 0
42 # define I_DISP 0
43 # define F_DISP 0
44 #else
45 # define C_DISP (__WORDSIZE >> 3) - sizeof(jit_int8_t)
46 # define S_DISP (__WORDSIZE >> 3) - sizeof(jit_int16_t)
47 # define I_DISP (__WORDSIZE >> 3) - sizeof(jit_int32_t)
48 # define F_DISP (__WORDSIZE >> 3) - sizeof(jit_float32_t)
49 #endif
50
51 /*
52 * Types
53 */
54 #if _CALL_SYSV
55 typedef struct jit_va_list {
56 jit_uint8_t ngpr;
57 jit_uint8_t nfpr;
58 jit_uint16_t _pad;
59 # if __WORDSIZE == 64
60 jit_uint32_t _pad2;
61 # endif
62 jit_pointer_t over;
63 jit_pointer_t save;
64 # if __WORDSIZE == 32
65 jit_word_t _pad2;
66 # endif
67 jit_word_t r3;
68 jit_word_t r4;
69 jit_word_t r5;
70 jit_word_t r6;
71 jit_word_t r7;
72 jit_word_t r8;
73 jit_word_t r9;
74 jit_word_t r10;
75 jit_float64_t f1;
76 jit_float64_t f2;
77 jit_float64_t f3;
78 jit_float64_t f4;
79 jit_float64_t f5;
80 jit_float64_t f6;
81 jit_float64_t f7;
82 jit_float64_t f8;
83 } jit_va_list_t;
84 #else
85 typedef jit_pointer_t jit_va_list_t;
86 #endif
87
88 /*
89 * Prototypes
90 */
91 #define patch(instr, node) _patch(_jit, instr, node)
92 static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
93
94 /* libgcc */
95 extern void __clear_cache(void *, void *);
96
97 #define PROTO 1
98 # include "jit_ppc-cpu.c"
99 # include "jit_ppc-fpu.c"
100 #undef PROTO
101
102 /*
103 * Initialization
104 */
105 jit_register_t _rvs[] = {
106 { rc(sav) | 0, "r0" },
107 { rc(sav) | 11, "r11" }, /* env */
108 { rc(sav) | 12, "r12" }, /* exception */
109 { rc(sav) | 13, "r13" }, /* thread */
110 { rc(sav) | 2, "r2" }, /* toc */
111 { rc(sav) | rc(gpr) | 14, "r14" },
112 { rc(sav) | rc(gpr) | 15, "r15" },
113 { rc(sav) | rc(gpr) | 16, "r16" },
114 { rc(sav) | rc(gpr) | 17, "r17" },
115 { rc(sav) | rc(gpr) | 18, "r18" },
116 { rc(sav) | rc(gpr) | 19, "r19" },
117 { rc(sav) | rc(gpr) | 20, "r20" },
118 { rc(sav) | rc(gpr) | 21, "r21" },
119 { rc(sav) | rc(gpr) | 22, "r22" },
120 { rc(sav) | rc(gpr) | 23, "r23" },
121 { rc(sav) | rc(gpr) | 24, "r24" },
122 { rc(sav) | rc(gpr) | 25, "r25" },
123 { rc(sav) | rc(gpr) | 26, "r26" },
124 { rc(sav) | rc(gpr) | 27, "r27" },
125 { rc(sav) | rc(gpr) | 28, "r28" },
126 { rc(sav) | rc(gpr) | 29, "r29" },
127 { rc(sav) | rc(gpr) | 30, "r30" },
128 { rc(sav) | 1, "r1" },
129 { rc(sav) | 31, "r31" },
130 { rc(arg) | rc(gpr) | 10, "r10" },
131 { rc(arg) | rc(gpr) | 9, "r9" },
132 { rc(arg) | rc(gpr) | 8, "r8" },
133 { rc(arg) | rc(gpr) | 7, "r7" },
134 { rc(arg) | rc(gpr) | 6, "r6" },
135 { rc(arg) | rc(gpr) | 5, "r5" },
136 { rc(arg) | rc(gpr) | 4, "r4" },
137 { rc(arg) | rc(gpr) | 3, "r3" },
138 { rc(fpr) | 0, "f0" },
139 { rc(sav) | rc(fpr) | 14, "f14" },
140 { rc(sav) | rc(fpr) | 15, "f15" },
141 { rc(sav) | rc(fpr) | 16, "f16" },
142 { rc(sav) | rc(fpr) | 17, "f17" },
143 { rc(sav) | rc(fpr) | 18, "f18" },
144 { rc(sav) | rc(fpr) | 19, "f19" },
145 { rc(sav) | rc(fpr) | 20, "f20" },
146 { rc(sav) | rc(fpr) | 21, "f21" },
147 { rc(sav) | rc(fpr) | 22, "f22" },
148 { rc(sav) | rc(fpr) | 23, "f23" },
149 { rc(sav) | rc(fpr) | 24, "f24" },
150 { rc(sav) | rc(fpr) | 25, "f25" },
151 { rc(sav) | rc(fpr) | 26, "f26" },
152 { rc(sav) | rc(fpr) | 27, "f27" },
153 { rc(sav) | rc(fpr) | 28, "f28" },
154 { rc(sav) | rc(fpr) | 29, "f29" },
155 { rc(sav) | rc(fpr) | 30, "f30" },
156 { rc(sav) | rc(fpr) | 31, "f31" },
157 #if !_CALL_SYSV
158 { rc(arg) | rc(fpr) | 13, "f13" },
159 { rc(arg) | rc(fpr) | 12, "f12" },
160 { rc(arg) | rc(fpr) | 11, "f11" },
161 { rc(arg) | rc(fpr) | 10, "f10" },
162 { rc(arg) | rc(fpr) | 9, "f9" },
163 #else
164 { rc(fpr) | 13, "f13" },
165 { rc(fpr) | 12, "f12" },
166 { rc(fpr) | 11, "f11" },
167 { rc(fpr) | 10, "f10" },
168 { rc(fpr) | 9, "f9" },
169 #endif
170 { rc(arg) | rc(fpr) | 8, "f8" },
171 { rc(arg) | rc(fpr) | 7, "f7" },
172 { rc(arg) | rc(fpr) | 6, "f6" },
173 { rc(arg) | rc(fpr) | 5, "f5" },
174 { rc(arg) | rc(fpr) | 4, "f4" },
175 { rc(arg) | rc(fpr) | 3, "f3" },
176 { rc(arg) | rc(fpr) | 2, "f2" },
177 { rc(arg) | rc(fpr) | 1, "f1" },
178 { _NOREG, "<none>" },
179 };
180
181 /*
182 * Implementation
183 */
184 void
jit_get_cpu(void)185 jit_get_cpu(void)
186 {
187 }
188
189 void
_jit_init(jit_state_t * _jit)190 _jit_init(jit_state_t *_jit)
191 {
192 _jitc->reglen = jit_size(_rvs) - 1;
193 }
194
195 void
_jit_prolog(jit_state_t * _jit)196 _jit_prolog(jit_state_t *_jit)
197 {
198 jit_int32_t offset;
199
200 if (_jitc->function)
201 jit_epilog();
202 assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0);
203 jit_regset_set_ui(&_jitc->regsav, 0);
204 offset = _jitc->functions.offset;
205 if (offset >= _jitc->functions.length) {
206 jit_realloc((jit_pointer_t *)&_jitc->functions.ptr,
207 _jitc->functions.length * sizeof(jit_function_t),
208 (_jitc->functions.length + 16) * sizeof(jit_function_t));
209 _jitc->functions.length += 16;
210 }
211 _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++;
212 _jitc->function->self.size = params_offset;
213 _jitc->function->self.argi = _jitc->function->self.argf =
214 _jitc->function->self.alen = 0;
215 /* float conversion */
216 _jitc->function->self.aoff = alloca_offset - 8;
217 _jitc->function->self.call = jit_call_default;
218 jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
219 _jitc->reglen * sizeof(jit_int32_t));
220
221 /* _no_link here does not mean the jit_link() call can be removed
222 * by rewriting as:
223 * _jitc->function->prolog = jit_new_node(jit_code_prolog);
224 */
225 _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
226 jit_link(_jitc->function->prolog);
227 _jitc->function->prolog->w.w = offset;
228 _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog);
229 /* u: label value
230 * v: offset in blocks vector
231 * w: offset in functions vector
232 */
233 _jitc->function->epilog->w.w = offset;
234
235 jit_regset_new(&_jitc->function->regset);
236 }
237
238 jit_int32_t
_jit_allocai(jit_state_t * _jit,jit_int32_t length)239 _jit_allocai(jit_state_t *_jit, jit_int32_t length)
240 {
241 assert(_jitc->function);
242 switch (length) {
243 case 0: case 1: break;
244 case 2: _jitc->function->self.aoff &= -2; break;
245 case 3: case 4: _jitc->function->self.aoff &= -4; break;
246 default: _jitc->function->self.aoff &= -8; break;
247 }
248 _jitc->function->self.aoff -= length;
249 if (!_jitc->realize) {
250 jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
251 jit_dec_synth();
252 }
253 return (_jitc->function->self.aoff);
254 }
255
256 void
_jit_allocar(jit_state_t * _jit,jit_int32_t u,jit_int32_t v)257 _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
258 {
259 jit_int32_t r0, r1;
260 assert(_jitc->function);
261 jit_inc_synth_ww(allocar, u, v);
262 if (!_jitc->function->allocar) {
263 _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
264 _jitc->function->allocar = 1;
265 }
266 r0 = jit_get_reg(jit_class_gpr);
267 r1 = jit_get_reg(jit_class_gpr);
268 jit_ldr(r0, JIT_SP);
269 jit_negr(r1, v);
270 jit_andi(r1, r1, -16);
271 jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
272 jit_addr(u, u, r1);
273 jit_addr(JIT_SP, JIT_SP, r1);
274 jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
275 jit_str(JIT_SP, r0);
276 jit_unget_reg(r1);
277 jit_unget_reg(r0);
278 jit_dec_synth();
279 }
280
281 void
_jit_ret(jit_state_t * _jit)282 _jit_ret(jit_state_t *_jit)
283 {
284 jit_node_t *instr;
285 assert(_jitc->function);
286 jit_inc_synth(ret);
287 /* jump to epilog */
288 instr = jit_jmpi();
289 jit_patch_at(instr, _jitc->function->epilog);
290 jit_dec_synth();
291 }
292
293 void
_jit_retr(jit_state_t * _jit,jit_int32_t u)294 _jit_retr(jit_state_t *_jit, jit_int32_t u)
295 {
296 jit_inc_synth_w(retr, u);
297 if (JIT_RET != u)
298 jit_movr(JIT_RET, u);
299 jit_live(JIT_RET);
300 jit_ret();
301 jit_dec_synth();
302 }
303
304 void
_jit_reti(jit_state_t * _jit,jit_word_t u)305 _jit_reti(jit_state_t *_jit, jit_word_t u)
306 {
307 jit_inc_synth_w(reti, u);
308 jit_movi(JIT_RET, u);
309 jit_ret();
310 jit_dec_synth();
311 }
312
313 void
_jit_retr_f(jit_state_t * _jit,jit_int32_t u)314 _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
315 {
316 jit_inc_synth_w(retr_f, u);
317 if (JIT_RET != u)
318 jit_movr_f(JIT_FRET, u);
319 else
320 jit_live(JIT_FRET);
321 jit_ret();
322 jit_dec_synth();
323 }
324
325 void
_jit_reti_f(jit_state_t * _jit,jit_float32_t u)326 _jit_reti_f(jit_state_t *_jit, jit_float32_t u)
327 {
328 jit_inc_synth_f(reti_f, u);
329 jit_movi_f(JIT_FRET, u);
330 jit_ret();
331 jit_dec_synth();
332 }
333
334 void
_jit_retr_d(jit_state_t * _jit,jit_int32_t u)335 _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
336 {
337 jit_inc_synth_w(retr_d, u);
338 if (JIT_FRET != u)
339 jit_movr_d(JIT_FRET, u);
340 else
341 jit_live(JIT_FRET);
342 jit_ret();
343 jit_dec_synth();
344 }
345
346 void
_jit_reti_d(jit_state_t * _jit,jit_float64_t u)347 _jit_reti_d(jit_state_t *_jit, jit_float64_t u)
348 {
349 jit_inc_synth_d(reti_d, u);
350 jit_movi_d(JIT_FRET, u);
351 jit_ret();
352 jit_dec_synth();
353 }
354
355 void
_jit_epilog(jit_state_t * _jit)356 _jit_epilog(jit_state_t *_jit)
357 {
358 assert(_jitc->function);
359 assert(_jitc->function->epilog->next == NULL);
360 jit_link(_jitc->function->epilog);
361 _jitc->function = NULL;
362 }
363
364 jit_bool_t
_jit_arg_register_p(jit_state_t * _jit,jit_node_t * u)365 _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
366 {
367 if (u->code == jit_code_arg)
368 return (jit_arg_reg_p(u->u.w));
369 assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d);
370 return (jit_arg_f_reg_p(u->u.w));
371 }
372
373 void
_jit_ellipsis(jit_state_t * _jit)374 _jit_ellipsis(jit_state_t *_jit)
375 {
376 jit_inc_synth(ellipsis);
377 if (_jitc->prepare) {
378 jit_link_prepare();
379 assert(!(_jitc->function->call.call & jit_call_varargs));
380 _jitc->function->call.call |= jit_call_varargs;
381 }
382 else {
383 jit_link_prolog();
384 assert(!(_jitc->function->self.call & jit_call_varargs));
385 _jitc->function->self.call |= jit_call_varargs;
386 #if _CALL_SYSV
387 /* Allocate va_list like object in the stack.
388 * If applicable, with enough space to save all argument
389 * registers, and use fixed offsets for them. */
390 _jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t));
391 #endif
392 _jitc->function->vagp = _jitc->function->self.argi;
393 _jitc->function->vafp = _jitc->function->self.argf;
394 }
395 jit_dec_synth();
396 }
397
398 void
_jit_va_push(jit_state_t * _jit,jit_int32_t u)399 _jit_va_push(jit_state_t *_jit, jit_int32_t u)
400 {
401 jit_inc_synth_w(va_push, u);
402 jit_pushargr(u);
403 jit_dec_synth();
404 }
405
406 jit_node_t *
_jit_arg(jit_state_t * _jit)407 _jit_arg(jit_state_t *_jit)
408 {
409 jit_node_t *node;
410 jit_int32_t offset;
411 jit_bool_t incr = 1;
412 assert(_jitc->function);
413 if (jit_arg_reg_p(_jitc->function->self.argi)) {
414 offset = _jitc->function->self.argi++;
415 #if _CALL_SYSV
416 incr = 0;
417 #endif
418 }
419 else
420 offset = _jitc->function->self.size;
421 if (incr)
422 _jitc->function->self.size += sizeof(jit_word_t);
423 node = jit_new_node_ww(jit_code_arg, offset,
424 ++_jitc->function->self.argn);
425 jit_link_prolog();
426 return (node);
427 }
428
429 jit_node_t *
_jit_arg_f(jit_state_t * _jit)430 _jit_arg_f(jit_state_t *_jit)
431 {
432 jit_node_t *node;
433 jit_int32_t offset;
434 jit_bool_t incr = 1;
435 assert(_jitc->function);
436 if (jit_arg_f_reg_p(_jitc->function->self.argf)) {
437 offset = _jitc->function->self.argf++;
438 #if _CALL_SYSV
439 incr = 0;
440 #endif
441 }
442 else
443 offset = _jitc->function->self.size + F_DISP;
444 #if !_CALL_SYSV
445 if (jit_arg_reg_p(_jitc->function->self.argi)) {
446 # if __WORDSIZE == 32
447 _jitc->function->self.argi += 2;
448 # else
449 _jitc->function->self.argi++;
450 # endif
451 }
452 #endif
453 if (incr)
454 _jitc->function->self.size += sizeof(jit_word_t);
455 node = jit_new_node_ww(jit_code_arg_f, offset,
456 ++_jitc->function->self.argn);
457 jit_link_prolog();
458 return (node);
459 }
460
461 jit_node_t *
_jit_arg_d(jit_state_t * _jit)462 _jit_arg_d(jit_state_t *_jit)
463 {
464 jit_node_t *node;
465 jit_int32_t offset;
466 jit_bool_t incr = 1;
467 assert(_jitc->function);
468 if (jit_arg_f_reg_p(_jitc->function->self.argf)) {
469 offset = _jitc->function->self.argf++;
470 #if _CALL_SYSV
471 incr = 0;
472 #endif
473 }
474 else {
475 #if _CALL_SYSV
476 if (_jitc->function->self.size & 7)
477 _jitc->function->self.size += 4;
478 #endif
479 offset = _jitc->function->self.size;
480 }
481 #if !_CALL_SYSV
482 if (jit_arg_reg_p(_jitc->function->self.argi)) {
483 # if __WORDSIZE == 32
484 _jitc->function->self.argi += 2;
485 # else
486 _jitc->function->self.argi++;
487 # endif
488 }
489 #endif
490 if (incr)
491 _jitc->function->self.size += sizeof(jit_float64_t);
492 node = jit_new_node_ww(jit_code_arg_d, offset,
493 ++_jitc->function->self.argn);
494 jit_link_prolog();
495 return (node);
496 }
497
498 void
_jit_getarg_c(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)499 _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
500 {
501 assert(v->code == jit_code_arg);
502 jit_inc_synth_wp(getarg_c, u, v);
503 if (jit_arg_reg_p(v->u.w))
504 jit_extr_c(u, JIT_RA0 - v->u.w);
505 else
506 jit_ldxi_c(u, JIT_FP, v->u.w + C_DISP);
507 jit_dec_synth();
508 }
509
510 void
_jit_getarg_uc(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)511 _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
512 {
513 assert(v->code == jit_code_arg);
514 jit_inc_synth_wp(getarg_uc, u, v);
515 if (jit_arg_reg_p(v->u.w))
516 jit_extr_uc(u, JIT_RA0 - v->u.w);
517 else
518 jit_ldxi_uc(u, JIT_FP, v->u.w + C_DISP);
519 jit_dec_synth();
520 }
521
522 void
_jit_getarg_s(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)523 _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
524 {
525 assert(v->code == jit_code_arg);
526 jit_inc_synth_wp(getarg_s, u, v);
527 if (jit_arg_reg_p(v->u.w))
528 jit_extr_s(u, JIT_RA0 - v->u.w);
529 else
530 jit_ldxi_s(u, JIT_FP, v->u.w + S_DISP);
531 jit_dec_synth();
532 }
533
534 void
_jit_getarg_us(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)535 _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
536 {
537 assert(v->code == jit_code_arg);
538 jit_inc_synth_wp(getarg_us, u, v);
539 if (jit_arg_reg_p(v->u.w))
540 jit_extr_us(u, JIT_RA0 - v->u.w);
541 else
542 jit_ldxi_us(u, JIT_FP, v->u.w + S_DISP);
543 jit_dec_synth();
544 }
545
546 void
_jit_getarg_i(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)547 _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
548 {
549 assert(v->code == jit_code_arg);
550 jit_inc_synth_wp(getarg_i, u, v);
551 if (jit_arg_reg_p(v->u.w)) {
552 #if __WORDSIZE == 32
553 jit_movr(u, JIT_RA0 - v->u.w);
554 #else
555 jit_extr_i(u, JIT_RA0 - v->u.w);
556 #endif
557 }
558 else
559 jit_ldxi_i(u, JIT_FP, v->u.w + I_DISP);
560 jit_dec_synth();
561 }
562
563 #if __WORDSIZE == 64
564 void
_jit_getarg_ui(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)565 _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
566 {
567 assert(v->code == jit_code_arg);
568 jit_inc_synth_wp(getarg_ui, u, v);
569 if (jit_arg_reg_p(v->u.w))
570 jit_extr_ui(u, JIT_RA0 - v->u.w);
571 else
572 jit_ldxi_ui(u, JIT_FP, v->u.w + I_DISP);
573 jit_dec_synth();
574 }
575
576 void
_jit_getarg_l(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)577 _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
578 {
579 assert(v->code == jit_code_arg);
580 jit_inc_synth_wp(getarg_l, u, v);
581 if (jit_arg_reg_p(v->u.w))
582 jit_movr(u, JIT_RA0 - v->u.w);
583 else
584 jit_ldxi_l(u, JIT_FP, v->u.w);
585 jit_dec_synth();
586 }
587 #endif
588
589 void
_jit_putargr(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)590 _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
591 {
592 assert(v->code == jit_code_arg);
593 jit_inc_synth_wp(putargr, u, v);
594 if (jit_arg_reg_p(v->u.w))
595 jit_movr(JIT_RA0 - v->u.w, u);
596 else
597 jit_stxi(v->u.w, JIT_FP, u);
598 jit_dec_synth();
599 }
600
601 void
_jit_putargi(jit_state_t * _jit,jit_word_t u,jit_node_t * v)602 _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
603 {
604 jit_int32_t regno;
605 jit_inc_synth_wp(putargi, u, v);
606 assert(v->code == jit_code_arg);
607 if (jit_arg_reg_p(v->u.w))
608 jit_movi(JIT_RA0 - v->u.w, u);
609 else {
610 regno = jit_get_reg(jit_class_gpr);
611 jit_movi(regno, u);
612 jit_stxi(v->u.w, JIT_FP, regno);
613 jit_unget_reg(regno);
614 }
615 jit_dec_synth();
616 }
617
618 void
_jit_getarg_f(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)619 _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
620 {
621 assert(v->code == jit_code_arg_f);
622 jit_inc_synth_wp(getarg_f, u, v);
623 if (jit_arg_f_reg_p(v->u.w))
624 jit_movr_d(u, JIT_FA0 - v->u.w);
625 else
626 jit_ldxi_f(u, JIT_FP, v->u.w);
627 jit_dec_synth();
628 }
629
630 void
_jit_putargr_f(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)631 _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
632 {
633 assert(v->code == jit_code_arg_f);
634 jit_inc_synth_wp(putargr_f, u, v);
635 if (jit_arg_f_reg_p(v->u.w))
636 jit_movr_d(JIT_FA0 - v->u.w, u);
637 else
638 jit_stxi_f(v->u.w, JIT_FP, u);
639 jit_dec_synth();
640 }
641
642 void
_jit_putargi_f(jit_state_t * _jit,jit_float32_t u,jit_node_t * v)643 _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
644 {
645 jit_int32_t regno;
646 assert(v->code == jit_code_arg_f);
647 jit_inc_synth_fp(putargi_f, u, v);
648 if (jit_arg_f_reg_p(v->u.w))
649 jit_movi_d(JIT_FA0 - v->u.w, u);
650 else {
651 regno = jit_get_reg(jit_class_fpr);
652 jit_movi_d(regno, u);
653 jit_stxi_f(v->u.w, JIT_FP, regno);
654 jit_unget_reg(regno);
655 }
656 jit_dec_synth();
657 }
658
659 void
_jit_getarg_d(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)660 _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
661 {
662 assert(v->code == jit_code_arg_d);
663 jit_inc_synth_wp(getarg_d, u, v);
664 if (jit_arg_f_reg_p(v->u.w))
665 jit_movr_d(u, JIT_FA0 - v->u.w);
666 else
667 jit_ldxi_d(u, JIT_FP, v->u.w);
668 jit_dec_synth();
669 }
670
671 void
_jit_putargr_d(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)672 _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
673 {
674 assert(v->code == jit_code_arg_d);
675 jit_inc_synth_wp(putargr_d, u, v);
676 if (jit_arg_f_reg_p(v->u.w))
677 jit_movr_d(JIT_FA0 - v->u.w, u);
678 else
679 jit_stxi_d(v->u.w, JIT_FP, u);
680 jit_dec_synth();
681 }
682
683 void
_jit_putargi_d(jit_state_t * _jit,jit_float64_t u,jit_node_t * v)684 _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
685 {
686 jit_int32_t regno;
687 assert(v->code == jit_code_arg_d);
688 jit_inc_synth_dp(putargi_d, u, v);
689 if (jit_arg_f_reg_p(v->u.w))
690 jit_movi_d(JIT_FA0 - v->u.w, u);
691 else {
692 regno = jit_get_reg(jit_class_fpr);
693 jit_movi_d(regno, u);
694 jit_stxi_d(v->u.w, JIT_FP, regno);
695 jit_unget_reg(regno);
696 }
697 jit_dec_synth();
698 }
699
700 void
_jit_pushargr(jit_state_t * _jit,jit_int32_t u)701 _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
702 {
703 jit_bool_t incr = 1;
704 assert(_jitc->function);
705 jit_inc_synth_w(pushargr, u);
706 jit_link_prepare();
707 if (jit_arg_reg_p(_jitc->function->call.argi)) {
708 jit_movr(JIT_RA0 - _jitc->function->call.argi, u);
709 ++_jitc->function->call.argi;
710 #if _CALL_SYSV
711 incr = 0;
712 #endif
713 }
714 else
715 jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, u);
716 if (incr)
717 _jitc->function->call.size += sizeof(jit_word_t);
718 jit_dec_synth();
719 }
720
721 void
_jit_pushargi(jit_state_t * _jit,jit_word_t u)722 _jit_pushargi(jit_state_t *_jit, jit_word_t u)
723 {
724 jit_int32_t regno;
725 jit_bool_t incr = 1;
726 assert(_jitc->function);
727 jit_inc_synth_w(pushargi, u);
728 jit_link_prepare();
729 if (jit_arg_reg_p(_jitc->function->call.argi)) {
730 jit_movi(JIT_RA0 - _jitc->function->call.argi, u);
731 ++_jitc->function->call.argi;
732 #if _CALL_SYSV
733 incr = 0;
734 #endif
735 }
736 else {
737 regno = jit_get_reg(jit_class_gpr);
738 jit_movi(regno, u);
739 jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, regno);
740 jit_unget_reg(regno);
741 }
742 if (incr)
743 _jitc->function->call.size += sizeof(jit_word_t);
744 jit_dec_synth();
745 }
746
747 void
_jit_pushargr_f(jit_state_t * _jit,jit_int32_t u)748 _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
749 {
750 jit_bool_t incr = 1;
751 assert(_jitc->function);
752 jit_inc_synth_w(pushargr_f, u);
753 jit_link_prepare();
754 if (jit_arg_f_reg_p(_jitc->function->call.argf)
755 #if !_CALL_SYSV
756 && !(_jitc->function->call.call & jit_call_varargs)
757 #endif
758 ) {
759 jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u);
760 ++_jitc->function->call.argf;
761 #if !_CALL_SYSV
762 /* in case of excess arguments */
763 if (jit_arg_reg_p(_jitc->function->call.argi)) {
764 # if __WORDSIZE == 32
765 _jitc->function->call.argi += 2;
766 if (!jit_arg_reg_p(_jitc->function->call.argi - 1))
767 --_jitc->function->call.argi;
768 # else
769 _jitc->function->call.argi++;
770 # endif
771 }
772 #elif _CALL_SYSV
773 incr = 0;
774 #endif
775 }
776 #if !_CALL_SYSV
777 else if (jit_arg_reg_p(_jitc->function->call.argi
778 # if __WORDSIZE == 32
779 + 1
780 # endif
781 )) {
782 /* use reserved 8 bytes area */
783 jit_stxi_d(alloca_offset - 8, JIT_FP, u);
784 jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
785 alloca_offset - 8);
786 _jitc->function->call.argi++;
787 # if __WORDSIZE == 32
788 jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
789 alloca_offset - 4);
790 _jitc->function->call.argi++;
791 # endif
792 }
793 #endif
794 else
795 jit_stxi_f(_jitc->function->call.size + params_offset + F_DISP,
796 JIT_SP, u);
797 if (incr)
798 _jitc->function->call.size += sizeof(jit_word_t);
799 jit_dec_synth();
800 }
801
802 void
_jit_pushargi_f(jit_state_t * _jit,jit_float32_t u)803 _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
804 {
805 jit_bool_t incr = 1;
806 jit_int32_t regno;
807 assert(_jitc->function);
808 jit_inc_synth_f(pushargi_f, u);
809 jit_link_prepare();
810 if (jit_arg_f_reg_p(_jitc->function->call.argf)
811 #if !_CALL_SYSV
812 && !(_jitc->function->call.call & jit_call_varargs)
813 #endif
814 ) {
815 jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u);
816 ++_jitc->function->call.argf;
817 #if !_CALL_SYSV
818 /* in case of excess arguments */
819 # if __WORDSIZE == 32
820 _jitc->function->call.argi += 2;
821 if (!jit_arg_reg_p(_jitc->function->call.argi - 1))
822 --_jitc->function->call.argi;
823 # else
824 _jitc->function->call.argi++;
825 # endif
826 #elif _CALL_SYSV
827 incr = 0;
828 #endif
829 }
830 else {
831 regno = jit_get_reg(jit_class_fpr);
832 jit_movi_f(regno, u);
833 #if !_CALL_SYSV
834 if (jit_arg_reg_p(_jitc->function->call.argi
835 # if __WORDSIZE == 32
836 + 1
837 # endif
838 )) {
839 /* use reserved 8 bytes area */
840 jit_stxi_d(alloca_offset - 8, JIT_FP, regno);
841 jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
842 alloca_offset - 8);
843 _jitc->function->call.argi++;
844 # if __WORDSIZE == 32
845 jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
846 alloca_offset - 4);
847 _jitc->function->call.argi++;
848 # endif
849 }
850 else
851 #endif
852 jit_stxi_f(_jitc->function->call.size + params_offset + F_DISP,
853 JIT_SP, regno);
854 jit_unget_reg(regno);
855 }
856 if (incr)
857 _jitc->function->call.size += sizeof(jit_word_t);
858 jit_dec_synth();
859 }
860
861 void
_jit_pushargr_d(jit_state_t * _jit,jit_int32_t u)862 _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
863 {
864 jit_bool_t incr = 1;
865 assert(_jitc->function);
866 jit_inc_synth_w(pushargr_d, u);
867 jit_link_prepare();
868 if (jit_arg_f_reg_p(_jitc->function->call.argf)
869 #if !_CALL_SYSV
870 && !(_jitc->function->call.call & jit_call_varargs)
871 #endif
872 ) {
873 jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u);
874 ++_jitc->function->call.argf;
875 #if !_CALL_SYSV
876 /* in case of excess arguments */
877 # if __WORDSIZE == 32
878 _jitc->function->call.argi += 2;
879 if (!jit_arg_reg_p(_jitc->function->call.argi - 1))
880 --_jitc->function->call.argi;
881 # else
882 _jitc->function->call.argi++;
883 # endif
884 #else /* _CALL_SYSV */
885 incr = 0;
886 #endif
887 }
888 #if !_CALL_SYSV
889 else if (jit_arg_reg_p(_jitc->function->call.argi
890 # if __WORDSIZE == 32
891 + 1
892 # endif
893 )) {
894 /* use reserved 8 bytes area */
895 jit_stxi_d(alloca_offset - 8, JIT_FP, u);
896 jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
897 alloca_offset - 8);
898 _jitc->function->call.argi++;
899 # if __WORDSIZE == 32
900 jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
901 alloca_offset - 4);
902 _jitc->function->call.argi++;
903 # endif
904 }
905 else
906 #endif /* !_CALL_SYSV */
907 {
908 #if _CALL_SYSV
909 if (_jitc->function->call.size & 7)
910 _jitc->function->call.size += 4;
911 #endif
912 jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, u);
913 #if !_CALL_SYSV && __WORDSIZE == 32
914 if (jit_arg_reg_p(_jitc->function->call.argi)) {
915 jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_SP,
916 _jitc->function->call.size + params_offset);
917 _jitc->function->call.argi++;
918 }
919 #endif
920 }
921 if (incr)
922 _jitc->function->call.size += sizeof(jit_float64_t);
923 jit_dec_synth();
924 }
925
926 void
_jit_pushargi_d(jit_state_t * _jit,jit_float64_t u)927 _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
928 {
929 jit_int32_t regno;
930 jit_bool_t incr = 1;
931 assert(_jitc->function);
932 jit_inc_synth_d(pushargi_d, u);
933 jit_link_prepare();
934 if (jit_arg_f_reg_p(_jitc->function->call.argf)
935 #if !_CALL_SYSV
936 && !(_jitc->function->call.call & jit_call_varargs)
937 #endif
938 ) {
939 jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u);
940 ++_jitc->function->call.argf;
941 #if !_CALL_SYSV
942 /* in case of excess arguments */
943 if (jit_arg_reg_p(_jitc->function->call.argi)) {
944 # if __WORDSIZE == 32
945 _jitc->function->call.argi += 2;
946 if (!jit_arg_reg_p(_jitc->function->call.argi - 1))
947 --_jitc->function->call.argi;
948 # else
949 _jitc->function->call.argi++;
950 # endif
951 }
952 #else /* _CALL_SYSV */
953 incr = 0;
954 #endif
955 }
956 else {
957 regno = jit_get_reg(jit_class_fpr);
958 jit_movi_d(regno, u);
959 #if !_CALL_SYSV
960 if (jit_arg_reg_p(_jitc->function->call.argi
961 # if __WORDSIZE == 32
962 + 1
963 # endif
964 )) {
965 /* use reserved 8 bytes area */
966 jit_stxi_d(alloca_offset - 8, JIT_FP, regno);
967 jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
968 alloca_offset - 8);
969 _jitc->function->call.argi++;
970 # if __WORDSIZE == 32
971 jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
972 alloca_offset - 4);
973 _jitc->function->call.argi++;
974 # endif
975 }
976 else
977 #endif /* !_CALL_SYSV */
978 {
979 #if _CALL_SYSV
980 if (_jitc->function->call.size & 7)
981 _jitc->function->call.size += 4;
982 #endif
983 jit_stxi_d(_jitc->function->call.size + params_offset,
984 JIT_SP, regno);
985 #if !_CALL_SYSV && __WORDSIZE == 32
986 if (jit_arg_reg_p(_jitc->function->call.argi)) {
987 jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_SP,
988 _jitc->function->call.size + params_offset);
989 _jitc->function->call.argi++;
990 }
991 #endif
992 }
993 jit_unget_reg(regno);
994 }
995 if (incr)
996 _jitc->function->call.size += sizeof(jit_float64_t);
997 jit_dec_synth();
998 }
999
1000 jit_bool_t
_jit_regarg_p(jit_state_t * _jit,jit_node_t * node,jit_int32_t regno)1001 _jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno)
1002 {
1003 jit_int32_t spec;
1004 spec = jit_class(_rvs[regno].spec);
1005 if (spec & jit_class_arg) {
1006 if (spec & jit_class_gpr) {
1007 regno = JIT_RA0 - regno;
1008 if (regno >= 0 && regno < node->v.w)
1009 return (1);
1010 }
1011 else if (spec & jit_class_fpr) {
1012 regno = JIT_FA0 - regno;
1013 if (regno >= 0 && regno < node->w.w)
1014 return (1);
1015 }
1016 }
1017 return (0);
1018 }
1019
1020 void
_jit_finishr(jit_state_t * _jit,jit_int32_t r0)1021 _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
1022 {
1023 jit_node_t *call;
1024 assert(_jitc->function);
1025 jit_inc_synth_w(finishr, r0);
1026 if (_jitc->function->self.alen < _jitc->function->call.size)
1027 _jitc->function->self.alen = _jitc->function->call.size;
1028 call = jit_callr(r0);
1029 call->v.w = _jitc->function->call.argi;
1030 call->w.w = _jitc->function->call.argf;
1031 #if _CALL_SYSV
1032 /* If passing float arguments in registers */
1033 if ((_jitc->function->call.call & jit_call_varargs) && call->w.w)
1034 call->flag |= jit_flag_varargs;
1035 #endif
1036 _jitc->function->call.argi = _jitc->function->call.argf = 0;
1037 _jitc->prepare = 0;
1038 jit_dec_synth();
1039 }
1040
1041 jit_node_t *
_jit_finishi(jit_state_t * _jit,jit_pointer_t i0)1042 _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
1043 {
1044 jit_node_t *node;
1045 assert(_jitc->function);
1046 jit_inc_synth_w(finishi, (jit_word_t)i0);
1047 if (_jitc->function->self.alen < _jitc->function->call.size)
1048 _jitc->function->self.alen = _jitc->function->call.size;
1049 node = jit_calli(i0);
1050 node->v.w = _jitc->function->call.argi;
1051 node->w.w = _jitc->function->call.argf;
1052 #if _CALL_SYSV
1053 if ((_jitc->function->call.call & jit_call_varargs) && node->w.w)
1054 node->flag |= jit_flag_varargs;
1055 #endif
1056 _jitc->function->call.argi = _jitc->function->call.argf = 0;
1057 _jitc->prepare = 0;
1058 jit_dec_synth();
1059 return (node);
1060 }
1061
1062 void
_jit_retval_c(jit_state_t * _jit,jit_int32_t r0)1063 _jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
1064 {
1065 jit_inc_synth(retval_c);
1066 jit_extr_c(r0, JIT_RET);
1067 jit_dec_synth();
1068 }
1069
1070 void
_jit_retval_uc(jit_state_t * _jit,jit_int32_t r0)1071 _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
1072 {
1073 jit_inc_synth(retval_uc);
1074 jit_extr_uc(r0, JIT_RET);
1075 jit_dec_synth();
1076 }
1077
1078 void
_jit_retval_s(jit_state_t * _jit,jit_int32_t r0)1079 _jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
1080 {
1081 jit_inc_synth(retval_s);
1082 jit_extr_s(r0, JIT_RET);
1083 jit_dec_synth();
1084 }
1085
1086 void
_jit_retval_us(jit_state_t * _jit,jit_int32_t r0)1087 _jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
1088 {
1089 jit_inc_synth(retval_us);
1090 jit_extr_us(r0, JIT_RET);
1091 jit_dec_synth();
1092 }
1093
1094 void
_jit_retval_i(jit_state_t * _jit,jit_int32_t r0)1095 _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
1096 {
1097 jit_inc_synth(retval_i);
1098 #if __WORDSIZE == 32
1099 if (r0 != JIT_RET)
1100 jit_movr(r0, JIT_RET);
1101 #else
1102 jit_extr_i(r0, JIT_RET);
1103 #endif
1104 jit_dec_synth();
1105 }
1106
1107 #if __WORDSIZE == 64
1108 void
_jit_retval_ui(jit_state_t * _jit,jit_int32_t r0)1109 _jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
1110 {
1111 jit_inc_synth(retval_ui);
1112 jit_extr_ui(r0, JIT_RET);
1113 jit_dec_synth();
1114 }
1115
1116 void
_jit_retval_l(jit_state_t * _jit,jit_int32_t r0)1117 _jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
1118 {
1119 jit_inc_synth(retval_l);
1120 if (r0 != JIT_RET)
1121 jit_movr(r0, JIT_RET);
1122 jit_dec_synth();
1123 }
1124 #endif
1125
1126 void
_jit_retval_f(jit_state_t * _jit,jit_int32_t r0)1127 _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
1128 {
1129 jit_inc_synth(retval_f);
1130 jit_retval_d(r0);
1131 jit_dec_synth();
1132 }
1133
1134 void
_jit_retval_d(jit_state_t * _jit,jit_int32_t r0)1135 _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
1136 {
1137 jit_inc_synth(retval_d);
1138 if (r0 != JIT_FRET)
1139 jit_movr_d(r0, JIT_FRET);
1140 jit_dec_synth();
1141 }
1142
1143 jit_pointer_t
_emit_code(jit_state_t * _jit)1144 _emit_code(jit_state_t *_jit)
1145 {
1146 jit_node_t *node;
1147 jit_node_t *temp;
1148 jit_word_t word;
1149 jit_int32_t value;
1150 jit_int32_t offset;
1151 struct {
1152 jit_node_t *node;
1153 jit_word_t word;
1154 #if DEVEL_DISASSEMBLER
1155 jit_word_t prevw;
1156 #endif
1157 jit_word_t patch_offset;
1158 #if _CALL_AIXDESC
1159 jit_word_t prolog_offset;
1160 #endif
1161 } undo;
1162 #if DEVEL_DISASSEMBLER
1163 jit_word_t prevw;
1164 #endif
1165
1166 _jitc->function = NULL;
1167
1168 jit_reglive_setup();
1169
1170 undo.word = 0;
1171 undo.node = NULL;
1172 undo.patch_offset = 0;
1173
1174 #if DEVEL_DISASSEMBLER
1175 prevw = _jit->pc.w;
1176 #endif
1177 #if _CALL_AIXDESC
1178 undo.prolog_offset = 0;
1179 for (node = _jitc->head; node; node = node->next)
1180 if (node->code != jit_code_label &&
1181 node->code != jit_code_note &&
1182 node->code != jit_code_name)
1183 break;
1184 if (node && (node->code != jit_code_prolog ||
1185 !(_jitc->functions.ptr + node->w.w)->assume_frame)) {
1186 /* code may start with a jump so add an initial function descriptor */
1187 word = _jit->pc.w + sizeof(void*) * 3;
1188 iw(word); /* addr */
1189 iw(0); /* toc */
1190 iw(0); /* env */
1191 }
1192 #endif
1193
1194 #define case_rr(name, type) \
1195 case jit_code_##name##r##type: \
1196 name##r##type(rn(node->u.w), rn(node->v.w)); \
1197 break
1198 #define case_rw(name, type) \
1199 case jit_code_##name##i##type: \
1200 name##i##type(rn(node->u.w), node->v.w); \
1201 break
1202 #define case_wr(name, type) \
1203 case jit_code_##name##i##type: \
1204 name##i##type(node->u.w, rn(node->v.w)); \
1205 break
1206 #define case_rrr(name, type) \
1207 case jit_code_##name##r##type: \
1208 name##r##type(rn(node->u.w), \
1209 rn(node->v.w), rn(node->w.w)); \
1210 break
1211 #define case_rrrr(name, type) \
1212 case jit_code_##name##r##type: \
1213 name##r##type(rn(node->u.q.l), rn(node->u.q.h), \
1214 rn(node->v.w), rn(node->w.w)); \
1215 break
1216 #define case_rrw(name, type) \
1217 case jit_code_##name##i##type: \
1218 name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \
1219 break
1220 #define case_rrrw(name, type) \
1221 case jit_code_##name##i##type: \
1222 name##i##type(rn(node->u.q.l), rn(node->u.q.h), \
1223 rn(node->v.w), node->w.w); \
1224 break
1225 #define case_rrf(name, type, size) \
1226 case jit_code_##name##i##type: \
1227 assert(node->flag & jit_flag_data); \
1228 name##i##type(rn(node->u.w), rn(node->v.w), \
1229 (jit_float##size##_t *)node->w.n->u.w); \
1230 break
1231 #define case_wrr(name, type) \
1232 case jit_code_##name##i##type: \
1233 name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \
1234 break
1235 #define case_brr(name, type) \
1236 case jit_code_##name##r##type: \
1237 temp = node->u.n; \
1238 assert(temp->code == jit_code_label || \
1239 temp->code == jit_code_epilog); \
1240 if (temp->flag & jit_flag_patch) \
1241 name##r##type(temp->u.w, rn(node->v.w), \
1242 rn(node->w.w)); \
1243 else { \
1244 word = name##r##type(_jit->pc.w, \
1245 rn(node->v.w), rn(node->w.w)); \
1246 patch(word, node); \
1247 } \
1248 break
1249 #define case_brw(name, type) \
1250 case jit_code_##name##i##type: \
1251 temp = node->u.n; \
1252 assert(temp->code == jit_code_label || \
1253 temp->code == jit_code_epilog); \
1254 if (temp->flag & jit_flag_patch) \
1255 name##i##type(temp->u.w, \
1256 rn(node->v.w), node->w.w); \
1257 else { \
1258 word = name##i##type(_jit->pc.w, \
1259 rn(node->v.w), node->w.w); \
1260 patch(word, node); \
1261 } \
1262 break
1263 #define case_brf(name, type, size) \
1264 case jit_code_##name##i##type: \
1265 temp = node->u.n; \
1266 assert(temp->code == jit_code_label || \
1267 temp->code == jit_code_epilog); \
1268 if (temp->flag & jit_flag_patch) \
1269 name##i##type(temp->u.w, rn(node->v.w), \
1270 (jit_float##size##_t *)node->w.n->u.w); \
1271 else { \
1272 word = name##i##type(_jit->pc.w, rn(node->v.w), \
1273 (jit_float##size##_t *)node->w.n->u.w); \
1274 patch(word, node); \
1275 } \
1276 break
1277 for (node = _jitc->head; node; node = node->next) {
1278 if (_jit->pc.uc >= _jitc->code.end)
1279 return (NULL);
1280
1281 #if DEVEL_DISASSEMBLER
1282 node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
1283 prevw = _jit->pc.w;
1284 #endif
1285 value = jit_classify(node->code);
1286 jit_regarg_set(node, value);
1287 switch (node->code) {
1288 case jit_code_align:
1289 assert(!(node->u.w & (node->u.w - 1)) &&
1290 node->u.w <= sizeof(jit_word_t));
1291 if (node->u.w == sizeof(jit_word_t) &&
1292 (word = _jit->pc.w & (sizeof(jit_word_t) - 1)))
1293 nop(sizeof(jit_word_t) - word);
1294 break;
1295 case jit_code_note: case jit_code_name:
1296 node->u.w = _jit->pc.w;
1297 break;
1298 case jit_code_label:
1299 /* remember label is defined */
1300 node->flag |= jit_flag_patch;
1301 node->u.w = _jit->pc.w;
1302 break;
1303 case_rrr(add,);
1304 case_rrw(add,);
1305 case_rrr(addc,);
1306 case_rrw(addc,);
1307 case_rrr(addx,);
1308 case_rrw(addx,);
1309 case_rrr(sub,);
1310 case_rrw(sub,);
1311 case_rrr(subc,);
1312 case_rrw(subc,);
1313 case_rrr(subx,);
1314 case_rrw(subx,);
1315 case_rrw(rsb,);
1316 case_rrr(mul,);
1317 case_rrw(mul,);
1318 case_rrrr(qmul,);
1319 case_rrrw(qmul,);
1320 case_rrrr(qmul, _u);
1321 case_rrrw(qmul, _u);
1322 case_rrr(div,);
1323 case_rrw(div,);
1324 case_rrr(div, _u);
1325 case_rrw(div, _u);
1326 case_rrrr(qdiv,);
1327 case_rrrw(qdiv,);
1328 case_rrrr(qdiv, _u);
1329 case_rrrw(qdiv, _u);
1330 case_rrr(rem,);
1331 case_rrw(rem,);
1332 case_rrr(rem, _u);
1333 case_rrw(rem, _u);
1334 case_rrr(and,);
1335 case_rrw(and,);
1336 case_rrr(or,);
1337 case_rrw(or,);
1338 case_rrr(xor,);
1339 case_rrw(xor,);
1340 case_rrr(lsh,);
1341 case_rrw(lsh,);
1342 case_rrr(rsh,);
1343 case_rrw(rsh,);
1344 case_rrr(rsh, _u);
1345 case_rrw(rsh, _u);
1346 case_rr(ext, _c);
1347 case_rr(ext, _uc);
1348 case_rr(ext, _s);
1349 case_rr(ext, _us);
1350 # if __WORDSIZE == 64
1351 case_rr(ext, _i);
1352 case_rr(ext, _ui);
1353 # endif
1354 case_rr(hton, _us);
1355 case_rr(hton, _ui);
1356 # if __WORDSIZE == 64
1357 case_rr(hton, _ul);
1358 # endif
1359 case_rr(neg,);
1360 case_rr(com,);
1361 case_rr(mov,);
1362 case jit_code_movi:
1363 if (node->flag & jit_flag_node) {
1364 temp = node->v.n;
1365 if (temp->code == jit_code_data ||
1366 (temp->code == jit_code_label &&
1367 (temp->flag & jit_flag_patch)))
1368 movi(rn(node->u.w), temp->u.w);
1369 else {
1370 assert(temp->code == jit_code_label ||
1371 temp->code == jit_code_epilog);
1372 word = movi_p(rn(node->u.w), node->v.w);
1373 patch(word, node);
1374 }
1375 }
1376 else
1377 movi(rn(node->u.w), node->v.w);
1378 break;
1379 case_rr(trunc, _f_i);
1380 case_rr(trunc, _d_i);
1381 # if __WORDSIZE == 64
1382 case_rr(trunc, _f_l);
1383 case_rr(trunc, _d_l);
1384 # endif
1385 case_rrr(lt,);
1386 case_rrw(lt,);
1387 case_rrr(lt, _u);
1388 case_rrw(lt, _u);
1389 case_rrr(le,);
1390 case_rrw(le,);
1391 case_rrr(le, _u);
1392 case_rrw(le, _u);
1393 case_rrr(eq,);
1394 case_rrw(eq,);
1395 case_rrr(ge,);
1396 case_rrw(ge,);
1397 case_rrr(ge, _u);
1398 case_rrw(ge, _u);
1399 case_rrr(gt,);
1400 case_rrw(gt,);
1401 case_rrr(gt, _u);
1402 case_rrw(gt, _u);
1403 case_rrr(ne,);
1404 case_rrw(ne,);
1405 case_rr(ld, _c);
1406 case_rw(ld, _c);
1407 case_brr(blt,);
1408 case_brw(blt,);
1409 case_brr(blt, _u);
1410 case_brw(blt, _u);
1411 case_brr(ble,);
1412 case_brw(ble,);
1413 case_brr(ble, _u);
1414 case_brw(ble, _u);
1415 case_brr(beq,);
1416 case_brw(beq,);
1417 case_brr(bge,);
1418 case_brw(bge,);
1419 case_brr(bge, _u);
1420 case_brw(bge, _u);
1421 case_brr(bgt,);
1422 case_brw(bgt,);
1423 case_brr(bgt, _u);
1424 case_brw(bgt, _u);
1425 case_brr(bne,);
1426 case_brw(bne,);
1427 case_brr(bms,);
1428 case_brw(bms,);
1429 case_brr(bmc,);
1430 case_brw(bmc,);
1431 case_brr(boadd,);
1432 case_brw(boadd,);
1433 case_brr(boadd, _u);
1434 case_brw(boadd, _u);
1435 case_brr(bxadd,);
1436 case_brw(bxadd,);
1437 case_brr(bxadd, _u);
1438 case_brw(bxadd, _u);
1439 case_brr(bosub,);
1440 case_brw(bosub,);
1441 case_brr(bosub, _u);
1442 case_brw(bosub, _u);
1443 case_brr(bxsub,);
1444 case_brw(bxsub,);
1445 case_brr(bxsub, _u);
1446 case_brw(bxsub, _u);
1447 case_rrr(ldx, _c);
1448 case_rrw(ldx, _c);
1449 case_rr(ld, _uc);
1450 case_rw(ld, _uc);
1451 case_rrr(ldx, _uc);
1452 case_rrw(ldx, _uc);
1453 case_rr(ld, _s);
1454 case_rw(ld, _s);
1455 case_rrr(ldx, _s);
1456 case_rrw(ldx, _s);
1457 case_rr(ld, _us);
1458 case_rw(ld, _us);
1459 case_rrr(ldx, _us);
1460 case_rrw(ldx, _us);
1461 case_rr(ld, _i);
1462 case_rw(ld, _i);
1463 case_rrr(ldx, _i);
1464 case_rrw(ldx, _i);
1465 #if __WORDSIZE == 64
1466 case_rr(ld, _ui);
1467 case_rw(ld, _ui);
1468 case_rrr(ldx, _ui);
1469 case_rrw(ldx, _ui);
1470 case_rr(ld, _l);
1471 case_rw(ld, _l);
1472 case_rrr(ldx, _l);
1473 case_rrw(ldx, _l);
1474 #endif
1475 case_rr(st, _c);
1476 case_wr(st, _c);
1477 case_rrr(stx, _c);
1478 case_wrr(stx, _c);
1479 case_rr(st, _s);
1480 case_wr(st, _s);
1481 case_rrr(stx, _s);
1482 case_wrr(stx, _s);
1483 case_rr(st, _i);
1484 case_wr(st, _i);
1485 case_rrr(stx, _i);
1486 case_wrr(stx, _i);
1487 #if __WORDSIZE == 64
1488 case_rr(st, _l);
1489 case_wr(st, _l);
1490 case_rrr(stx, _l);
1491 case_wrr(stx, _l);
1492 #endif
1493 case_rr(mov, _f);
1494 case jit_code_movi_f:
1495 assert(node->flag & jit_flag_data);
1496 movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w);
1497 break;
1498 case_rr(ext, _f);
1499 case_rr(ext, _d_f);
1500 case_rr(abs, _f);
1501 case_rr(neg, _f);
1502 case_rr(sqrt, _f);
1503 case_rrr(add, _f);
1504 case_rrf(add, _f, 32);
1505 case_rrr(sub, _f);
1506 case_rrf(sub, _f, 32);
1507 case_rrf(rsb, _f, 32);
1508 case_rrr(mul, _f);
1509 case_rrf(mul, _f, 32);
1510 case_rrr(div, _f);
1511 case_rrf(div, _f, 32);
1512 case_rrr(lt, _f);
1513 case_rrf(lt, _f, 32);
1514 case_rrr(le, _f);
1515 case_rrf(le, _f, 32);
1516 case_rrr(eq, _f);
1517 case_rrf(eq, _f, 32);
1518 case_rrr(ge, _f);
1519 case_rrf(ge, _f, 32);
1520 case_rrr(gt, _f);
1521 case_rrf(gt, _f, 32);
1522 case_rrr(ne, _f);
1523 case_rrf(ne, _f, 32);
1524 case_rrr(unlt, _f);
1525 case_rrf(unlt, _f, 32);
1526 case_rrr(unle, _f);
1527 case_rrf(unle, _f, 32);
1528 case_rrr(uneq, _f);
1529 case_rrf(uneq, _f, 32);
1530 case_rrr(unge, _f);
1531 case_rrf(unge, _f, 32);
1532 case_rrr(ungt, _f);
1533 case_rrf(ungt, _f, 32);
1534 case_rrr(ltgt, _f);
1535 case_rrf(ltgt, _f, 32);
1536 case_rrr(ord, _f);
1537 case_rrf(ord, _f, 32);
1538 case_rrr(unord, _f);
1539 case_rrf(unord, _f, 32);
1540 case_brr(blt, _f);
1541 case_brf(blt, _f, 32);
1542 case_brr(ble, _f);
1543 case_brf(ble, _f, 32);
1544 case_brr(beq, _f);
1545 case_brf(beq, _f, 32);
1546 case_brr(bge, _f);
1547 case_brf(bge, _f, 32);
1548 case_brr(bgt, _f);
1549 case_brf(bgt, _f, 32);
1550 case_brr(bne, _f);
1551 case_brf(bne, _f, 32);
1552 case_brr(bunlt, _f);
1553 case_brf(bunlt, _f, 32);
1554 case_brr(bunle, _f);
1555 case_brf(bunle, _f, 32);
1556 case_brr(buneq, _f);
1557 case_brf(buneq, _f, 32);
1558 case_brr(bunge, _f);
1559 case_brf(bunge, _f, 32);
1560 case_brr(bungt, _f);
1561 case_brf(bungt, _f, 32);
1562 case_brr(bltgt, _f);
1563 case_brf(bltgt, _f, 32);
1564 case_brr(bord, _f);
1565 case_brf(bord, _f, 32);
1566 case_brr(bunord, _f);
1567 case_brf(bunord, _f, 32);
1568 case_rr(ld, _f);
1569 case_rw(ld, _f);
1570 case_rrr(ldx, _f);
1571 case_rrw(ldx, _f);
1572 case_rr(st, _f);
1573 case_wr(st, _f);
1574 case_rrr(stx, _f);
1575 case_wrr(stx, _f);
1576 case_rr(mov, _d);
1577 case jit_code_movi_d:
1578 assert(node->flag & jit_flag_data);
1579 movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w);
1580 break;
1581 case_rr(ext, _d);
1582 case_rr(ext, _f_d);
1583 case_rr(abs, _d);
1584 case_rr(neg, _d);
1585 case_rr(sqrt, _d);
1586 case_rrr(add, _d);
1587 case_rrf(add, _d, 64);
1588 case_rrr(sub, _d);
1589 case_rrf(sub, _d, 64);
1590 case_rrf(rsb, _d, 64);
1591 case_rrr(mul, _d);
1592 case_rrf(mul, _d, 64);
1593 case_rrr(div, _d);
1594 case_rrf(div, _d, 64);
1595 case_rrr(lt, _d);
1596 case_rrf(lt, _d, 64);
1597 case_rrr(le, _d);
1598 case_rrf(le, _d, 64);
1599 case_rrr(eq, _d);
1600 case_rrf(eq, _d, 64);
1601 case_rrr(ge, _d);
1602 case_rrf(ge, _d, 64);
1603 case_rrr(gt, _d);
1604 case_rrf(gt, _d, 64);
1605 case_rrr(ne, _d);
1606 case_rrf(ne, _d, 64);
1607 case_rrr(unlt, _d);
1608 case_rrf(unlt, _d, 64);
1609 case_rrr(unle, _d);
1610 case_rrf(unle, _d, 64);
1611 case_rrr(uneq, _d);
1612 case_rrf(uneq, _d, 64);
1613 case_rrr(unge, _d);
1614 case_rrf(unge, _d, 64);
1615 case_rrr(ungt, _d);
1616 case_rrf(ungt, _d, 64);
1617 case_rrr(ltgt, _d);
1618 case_rrf(ltgt, _d, 64);
1619 case_rrr(ord, _d);
1620 case_rrf(ord, _d, 64);
1621 case_rrr(unord, _d);
1622 case_rrf(unord, _d, 64);
1623 case_brr(blt, _d);
1624 case_brf(blt, _d, 64);
1625 case_brr(ble, _d);
1626 case_brf(ble, _d, 64);
1627 case_brr(beq, _d);
1628 case_brf(beq, _d, 64);
1629 case_brr(bge, _d);
1630 case_brf(bge, _d, 64);
1631 case_brr(bgt, _d);
1632 case_brf(bgt, _d, 64);
1633 case_brr(bne, _d);
1634 case_brf(bne, _d, 64);
1635 case_brr(bunlt, _d);
1636 case_brf(bunlt, _d, 64);
1637 case_brr(bunle, _d);
1638 case_brf(bunle, _d, 64);
1639 case_brr(buneq, _d);
1640 case_brf(buneq, _d, 64);
1641 case_brr(bunge, _d);
1642 case_brf(bunge, _d, 64);
1643 case_brr(bungt, _d);
1644 case_brf(bungt, _d, 64);
1645 case_brr(bltgt, _d);
1646 case_brf(bltgt, _d, 64);
1647 case_brr(bord, _d);
1648 case_brf(bord, _d, 64);
1649 case_brr(bunord, _d);
1650 case_brf(bunord, _d, 64);
1651 case_rr(ld, _d);
1652 case_rw(ld, _d);
1653 case_rrr(ldx, _d);
1654 case_rrw(ldx, _d);
1655 case_rr(st, _d);
1656 case_wr(st, _d);
1657 case_rrr(stx, _d);
1658 case_wrr(stx, _d);
1659 case jit_code_jmpr:
1660 jmpr(rn(node->u.w));
1661 break;
1662 case jit_code_jmpi:
1663 if (node->flag & jit_flag_node) {
1664 #if _CALL_AIXDESC
1665 if (_jit->pc.uc == _jit->code.ptr + sizeof(void*) * 3)
1666 _jitc->jump = 1;
1667 #endif
1668 temp = node->u.n;
1669 assert(temp->code == jit_code_label ||
1670 temp->code == jit_code_epilog);
1671 if (temp->flag & jit_flag_patch)
1672 jmpi(temp->u.w);
1673 else {
1674 word = jmpi(_jit->pc.w);
1675 patch(word, node);
1676 }
1677 }
1678 else
1679 (void)jmpi_p(node->u.w);
1680 break;
1681 case jit_code_callr:
1682 callr(rn(node->u.w)
1683 #if _CALL_SYSV
1684 , !!(node->flag & jit_flag_varargs)
1685 #endif
1686 );
1687 break;
1688 case jit_code_calli:
1689 if (node->flag & jit_flag_node) {
1690 temp = node->u.n;
1691 assert(temp->code == jit_code_label ||
1692 temp->code == jit_code_epilog);
1693 word = calli_p(temp->u.w
1694 #if _CALL_SYSV
1695 , !!(node->flag & jit_flag_varargs)
1696 #endif
1697 );
1698 if (!(temp->flag & jit_flag_patch))
1699 patch(word, node);
1700 }
1701 else
1702 calli(node->u.w
1703 #if _CALL_SYSV
1704 , !!(node->flag & jit_flag_varargs)
1705 #endif
1706 );
1707 break;
1708 case jit_code_prolog:
1709 _jitc->function = _jitc->functions.ptr + node->w.w;
1710 undo.node = node;
1711 undo.word = _jit->pc.w;
1712 #if DEVEL_DISASSEMBLER
1713 undo.prevw = prevw;
1714 #endif
1715 undo.patch_offset = _jitc->patches.offset;
1716 #if _CALL_AIXDESC
1717 undo.prolog_offset = _jitc->prolog.offset;
1718 #endif
1719 restart_function:
1720 _jitc->again = 0;
1721 #if _CALL_AIXDESC
1722 if (_jitc->jump && !_jitc->function->assume_frame) {
1723 /* remember prolog to hide offset adjustment for a jump
1724 * to the start of a function, what is expected to be
1725 * a common practice as first jit instruction */
1726 if (_jitc->prolog.offset >= _jitc->prolog.length) {
1727 _jitc->prolog.length += 16;
1728 jit_realloc((jit_pointer_t *)&_jitc->prolog.ptr,
1729 (_jitc->prolog.length - 16) *
1730 sizeof(jit_word_t),
1731 _jitc->prolog.length * sizeof(jit_word_t));
1732 }
1733 _jitc->prolog.ptr[_jitc->prolog.offset++] = _jit->pc.w;
1734 /* function descriptor */
1735 word = _jit->pc.w + sizeof(void*) * 3;
1736 iw(word); /* addr */
1737 iw(0); /* toc */
1738 iw(0); /* env */
1739 }
1740 #endif
1741 prolog(node);
1742 break;
1743 case jit_code_epilog:
1744 assert(_jitc->function == _jitc->functions.ptr + node->w.w);
1745 if (_jitc->again) {
1746 for (temp = undo.node->next;
1747 temp != node; temp = temp->next) {
1748 if (temp->code == jit_code_label ||
1749 temp->code == jit_code_epilog)
1750 temp->flag &= ~jit_flag_patch;
1751 }
1752 temp->flag &= ~jit_flag_patch;
1753 node = undo.node;
1754 _jit->pc.w = undo.word;
1755 #if DEVEL_DISASSEMBLER
1756 prevw = undo.prevw;
1757 #endif
1758 _jitc->patches.offset = undo.patch_offset;
1759 #if _CALL_AIXDESC
1760 _jitc->prolog.offset = undo.prolog_offset;
1761 #endif
1762 goto restart_function;
1763 }
1764 /* remember label is defined */
1765 node->flag |= jit_flag_patch;
1766 node->u.w = _jit->pc.w;
1767 epilog(node);
1768 _jitc->function = NULL;
1769 break;
1770 case jit_code_va_start:
1771 vastart(rn(node->u.w));
1772 break;
1773 case jit_code_va_arg:
1774 vaarg(rn(node->u.w), rn(node->v.w));
1775 break;
1776 case jit_code_va_arg_d:
1777 vaarg_d(rn(node->u.w), rn(node->v.w));
1778 break;
1779 case jit_code_live:
1780 case jit_code_arg: case jit_code_ellipsis:
1781 case jit_code_va_push:
1782 case jit_code_allocai: case jit_code_allocar:
1783 case jit_code_arg_f: case jit_code_arg_d:
1784 case jit_code_va_end:
1785 case jit_code_ret:
1786 case jit_code_retr: case jit_code_reti:
1787 case jit_code_retr_f: case jit_code_reti_f:
1788 case jit_code_retr_d: case jit_code_reti_d:
1789 case jit_code_getarg_c: case jit_code_getarg_uc:
1790 case jit_code_getarg_s: case jit_code_getarg_us:
1791 case jit_code_getarg_i:
1792 #if __WORDSIZE == 64
1793 case jit_code_getarg_ui: case jit_code_getarg_l:
1794 #endif
1795 case jit_code_getarg_f: case jit_code_getarg_d:
1796 case jit_code_putargr: case jit_code_putargi:
1797 case jit_code_putargr_f: case jit_code_putargi_f:
1798 case jit_code_putargr_d: case jit_code_putargi_d:
1799 case jit_code_pushargr: case jit_code_pushargi:
1800 case jit_code_pushargr_f: case jit_code_pushargi_f:
1801 case jit_code_pushargr_d: case jit_code_pushargi_d:
1802 case jit_code_retval_c: case jit_code_retval_uc:
1803 case jit_code_retval_s: case jit_code_retval_us:
1804 case jit_code_retval_i:
1805 #if __WORDSIZE == 64
1806 case jit_code_retval_ui: case jit_code_retval_l:
1807 #endif
1808 case jit_code_retval_f: case jit_code_retval_d:
1809 case jit_code_prepare:
1810 case jit_code_finishr: case jit_code_finishi:
1811 break;
1812 default:
1813 abort();
1814 }
1815 jit_regarg_clr(node, value);
1816 assert(_jitc->regarg == 0 && _jitc->synth == 0);
1817 /* update register live state */
1818 jit_reglive(node);
1819 }
1820 #undef case_brf
1821 #undef case_brw
1822 #undef case_brr
1823 #undef case_wrr
1824 #undef case_rrf
1825 #undef case_rrw
1826 #undef case_rrr
1827 #undef case_wr
1828 #undef case_rw
1829 #undef case_rr
1830
1831 for (offset = 0; offset < _jitc->patches.offset; offset++) {
1832 node = _jitc->patches.ptr[offset].node;
1833 word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
1834 patch_at(_jitc->patches.ptr[offset].inst, word);
1835 }
1836
1837 jit_flush(_jit->code.ptr, _jit->pc.uc);
1838
1839 return (_jit->code.ptr);
1840 }
1841
1842 #define CODE 1
1843 # include "jit_ppc-cpu.c"
1844 # include "jit_ppc-fpu.c"
1845 #undef CODE
1846
1847 void
jit_flush(void * fptr,void * tptr)1848 jit_flush(void *fptr, void *tptr)
1849 {
1850 #if defined(__GNUC__)
1851 jit_word_t f, t, s;
1852
1853 s = sysconf(_SC_PAGE_SIZE);
1854 f = (jit_word_t)fptr & -s;
1855 t = (((jit_word_t)tptr) + s - 1) & -s;
1856 __clear_cache((void *)f, (void *)t);
1857 #endif
1858 }
1859
1860 void
_emit_ldxi(jit_state_t * _jit,jit_int32_t r0,jit_int32_t r1,jit_word_t i0)1861 _emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1862 {
1863 #if __WORDSIZE == 32
1864 ldxi_i(rn(r0), rn(r1), i0);
1865 #else
1866 ldxi_l(rn(r0), rn(r1), i0);
1867 #endif
1868 }
1869
1870 void
_emit_stxi(jit_state_t * _jit,jit_word_t i0,jit_int32_t r0,jit_int32_t r1)1871 _emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1872 {
1873 #if __WORDSIZE == 32
1874 stxi_i(i0, rn(r0), rn(r1));
1875 #else
1876 stxi_l(i0, rn(r0), rn(r1));
1877 #endif
1878 }
1879
1880 void
_emit_ldxi_d(jit_state_t * _jit,jit_int32_t r0,jit_int32_t r1,jit_word_t i0)1881 _emit_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1882 {
1883 ldxi_d(rn(r0), rn(r1), i0);
1884 }
1885
1886 void
_emit_stxi_d(jit_state_t * _jit,jit_word_t i0,jit_int32_t r0,jit_int32_t r1)1887 _emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1888 {
1889 stxi_d(i0, rn(r0), rn(r1));
1890 }
1891
1892 static void
_patch(jit_state_t * _jit,jit_word_t instr,jit_node_t * node)1893 _patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
1894 {
1895 jit_int32_t flag;
1896
1897 assert(node->flag & jit_flag_node);
1898 if (node->code == jit_code_movi)
1899 flag = node->v.n->flag;
1900 else
1901 flag = node->u.n->flag;
1902 assert(!(flag & jit_flag_patch));
1903 if (_jitc->patches.offset >= _jitc->patches.length) {
1904 jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
1905 _jitc->patches.length * sizeof(jit_patch_t),
1906 (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
1907 _jitc->patches.length += 1024;
1908 }
1909 _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
1910 _jitc->patches.ptr[_jitc->patches.offset].node = node;
1911 ++_jitc->patches.offset;
1912 }
1913