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