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