1 /*
2  * Copyright (C) 2014-2019  Free Software Foundation, Inc.
3  *
4  * This file is part of GNU lightning.
5  *
6  * GNU lightning is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published
8  * by the Free Software Foundation; either version 3, or (at your option)
9  * any later version.
10  *
11  * GNU lightning is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14  * License for more details.
15  *
16  * Authors:
17  *	Paulo Cesar Pereira de Andrade
18  */
19 
20 #define jit_arg_reg_p(i)		((i) >= 0 && (i) < 6)
21 #define jit_arg_f_reg_p(i)		((i) >= 0 && (i) < 6)
22 #if __BYTE_ORDER == __LITTLE_ENDIAN
23 #  define C_DISP			0
24 #  define S_DISP			0
25 #  define I_DISP			0
26 #  define F_DISP			0
27 #else
28 #  define C_DISP			8 - sizeof(jit_int8_t)
29 #  define S_DISP			8 - sizeof(jit_int16_t)
30 #  define I_DISP			8 - sizeof(jit_int32_t)
31 #  define F_DISP			8 - sizeof(jit_float32_t)
32 #endif
33 
34 /*
35  * Types
36  */
37 /*
38  * What I could understand from gcc/config/alpha/alpha.c:alpha_build_builtin_va_list()
39  * and other helpers, as well as objdump of simple test programs; could not
40  * get gdb working on the test system I had access...
41  *
42  * base-48 to base is where up to 6 float registers are saved.
43  * base to base+48 is where up to 6 integer registers are saved.
44  * base+48... is where varargs arguments are stored.
45  *
46  *	if (offset < 48) {
47  *		if (type == double)
48  *			offset -= 48;
49  *	}
50  *	load(reg, base, offset);
51  *	offset += 8;
52  */
53 typedef struct jit_va_list {
54     jit_pointer_t	base;
55     jit_word_t		offset;
56 } jit_va_list_t;
57 
58 /*
59  * Prototypes
60  */
61 #define patch(instr, node)		_patch(_jit, instr, node)
62 static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
63 
64 #define PROTO				1
65 #  include "jit_alpha-cpu.c"
66 #  include "jit_alpha-fpu.c"
67 #undef PROTO
68 
69 /*
70  * Initialization
71  */
72 jit_register_t		_rvs[] = {
73     { rc(gpr) | 0x1c,			"at" },
74     { rc(gpr) | 0x00,			"v0" },
75     { rc(gpr) | 0x01,			"t0" },
76     { rc(gpr) | 0x02,			"t1" },
77     { rc(gpr) | 0x03,			"t2" },
78     { rc(gpr) | 0x04,			"t3" },
79     { rc(gpr) | 0x05,			"t4" },
80     { rc(gpr) | 0x06,			"t5" },
81     { rc(gpr) | 0x07,			"t6" },
82     { rc(gpr) | 0x08,			"t7" },
83     { rc(gpr) | 0x16,			"t8" },
84     { rc(gpr) | 0x17,			"t9" },
85     { rc(gpr) | 0x18,			"t10" },
86     { rc(gpr) | 0x19,			"t11" },
87     { rc(sav) | rc(gpr) | 0x09,		"s0" },
88     { rc(sav) | rc(gpr) | 0x0a,		"s1" },
89     { rc(sav) | rc(gpr) | 0x0b,		"s2" },
90     { rc(sav) | rc(gpr) | 0x0c,		"s3" },
91     { rc(sav) | rc(gpr) | 0x0d,		"s4" },
92     { rc(sav) | rc(gpr) | 0x0e,		"s5" },
93     { 0x0f,				"fp" },
94     { rc(arg) | rc(gpr) | 0x15,		"a5" },
95     { rc(arg) | rc(gpr) | 0x14,		"a4" },
96     { rc(arg) | rc(gpr) | 0x13,		"a3" },
97     { rc(arg) | rc(gpr) | 0x12,		"a2" },
98     { rc(arg) | rc(gpr) | 0x11,		"a1" },
99     { rc(arg) | rc(gpr) | 0x10,		"a0" },
100     { 0x1a,				"ra" },
101     { 0x1b,				"pv" },
102     { 0x1d,				"gp" },
103     { 0x1e,				"sp" },
104     { 0x1f,				"zero" },
105     { rc(fpr) | 0x00,			"$f0" },
106     { rc(fpr) | 0x01,			"$f1" },
107     { rc(sav) | rc(fpr) | 0x02,		"$f2" },
108     { rc(sav) | rc(fpr) | 0x03,		"$f3" },
109     { rc(sav) | rc(fpr) | 0x04,		"$f4" },
110     { rc(sav) | rc(fpr) | 0x05,		"$f5" },
111     { rc(sav) | rc(fpr) | 0x06,		"$f6" },
112     { rc(sav) | rc(fpr) | 0x07,		"$f7" },
113     { rc(sav) | rc(fpr) | 0x08,		"$f8" },
114     { rc(sav) | rc(fpr) | 0x09,		"$f9" },
115     { rc(fpr) | 0x0a,			"$f10" },
116     { rc(fpr) | 0x0b,			"$f11" },
117     { rc(fpr) | 0x0c,			"$f12" },
118     { rc(fpr) | 0x0d,			"$f13" },
119     { rc(fpr) | 0x0e,			"$f14" },
120     { rc(fpr) | 0x0f,			"$f15" },
121     { rc(arg) | rc(fpr) | 0x15,		"$f21" },
122     { rc(arg) | rc(fpr) | 0x14,		"$f20" },
123     { rc(arg) | rc(fpr) | 0x13,		"$f19" },
124     { rc(arg) | rc(fpr) | 0x12,		"$f18" },
125     { rc(arg) | rc(fpr) | 0x11,		"$f17" },
126     { rc(arg) | rc(fpr) | 0x10,		"$f16" },
127     { rc(fpr) | 0x16,			"$f22" },
128     { rc(fpr) | 0x17,			"$f23" },
129     { rc(fpr) | 0x18,			"$f24" },
130     { rc(fpr) | 0x19,			"$f25" },
131     { rc(fpr) | 0x1a,			"$f26" },
132     { rc(fpr) | 0x1b,			"$f27" },
133     { rc(fpr) | 0x1c,			"$f28" },
134     { rc(fpr) | 0x1d,			"$f29" },
135     { rc(fpr) | 0x1e,			"$f30" },
136     { 0x1f,				"$f31" },
137     { _NOREG,				"<none>" },
138 };
139 
140 /*
141  * Implementation
142  */
143 void
jit_get_cpu(void)144 jit_get_cpu(void)
145 {
146 }
147 
148 void
_jit_init(jit_state_t * _jit)149 _jit_init(jit_state_t *_jit)
150 {
151     _jitc->reglen = jit_size(_rvs) - 1;
152     jit_carry = _NOREG;
153 }
154 
155 void
_jit_prolog(jit_state_t * _jit)156 _jit_prolog(jit_state_t *_jit)
157 {
158     jit_int32_t		 offset;
159 
160     if (_jitc->function)
161 	jit_epilog();
162     assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0);
163     jit_regset_set_ui(&_jitc->regsav, 0);
164     offset = _jitc->functions.offset;
165     if (offset >= _jitc->functions.length) {
166 	jit_realloc((jit_pointer_t *)&_jitc->functions.ptr,
167 		    _jitc->functions.length * sizeof(jit_function_t),
168 		    (_jitc->functions.length + 16) * sizeof(jit_function_t));
169 	_jitc->functions.length += 16;
170     }
171     _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++;
172     _jitc->function->self.size = stack_framesize;
173     _jitc->function->self.argi = _jitc->function->self.alen = 0;
174     /* float conversion */
175     _jitc->function->self.aoff = -8;
176     _jitc->function->self.call = jit_call_default;
177     jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
178 	      _jitc->reglen * sizeof(jit_int32_t));
179 
180     /* _no_link here does not mean the jit_link() call can be removed
181      * by rewriting as:
182      * _jitc->function->prolog = jit_new_node(jit_code_prolog);
183      */
184     _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
185     jit_link(_jitc->function->prolog);
186     _jitc->function->prolog->w.w = offset;
187     _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog);
188     /*	u:	label value
189      *	v:	offset in blocks vector
190      *	w:	offset in functions vector
191      */
192     _jitc->function->epilog->w.w = offset;
193 
194     jit_regset_new(&_jitc->function->regset);
195 }
196 
197 jit_int32_t
_jit_allocai(jit_state_t * _jit,jit_int32_t length)198 _jit_allocai(jit_state_t *_jit, jit_int32_t length)
199 {
200     assert(_jitc->function != NULL);
201     switch (length) {
202 	case 0:	case 1:						break;
203 	case 2:		_jitc->function->self.aoff &= -2;	break;
204 	case 3:	case 4:	_jitc->function->self.aoff &= -4;	break;
205 	default:	_jitc->function->self.aoff &= -8;	break;
206     }
207     _jitc->function->self.aoff -= length;
208     if (!_jitc->realize) {
209 	jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
210 	jit_dec_synth();
211     }
212     return (_jitc->function->self.aoff);
213 }
214 
215 void
_jit_allocar(jit_state_t * _jit,jit_int32_t u,jit_int32_t v)216 _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
217 {
218     jit_int32_t		 reg;
219     assert(_jitc->function != NULL);
220     jit_inc_synth_ww(allocar, u, v);
221     if (!_jitc->function->allocar) {
222 	_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
223 	_jitc->function->allocar = 1;
224     }
225     reg = jit_get_reg(jit_class_gpr);
226     jit_negr(reg, v);
227     jit_andi(reg, reg, -8);
228     jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
229     jit_addr(u, u, reg);
230     jit_addr(JIT_SP, JIT_SP, reg);
231     jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
232     jit_unget_reg(reg);
233     jit_dec_synth();
234 }
235 
236 void
_jit_ret(jit_state_t * _jit)237 _jit_ret(jit_state_t *_jit)
238 {
239     jit_node_t		*instr;
240     assert(_jitc->function != NULL);
241     jit_inc_synth(ret);
242     /* jump to epilog */
243     instr = jit_jmpi();
244     jit_patch_at(instr, _jitc->function->epilog);
245     jit_dec_synth();
246 }
247 
248 void
_jit_retr(jit_state_t * _jit,jit_int32_t u)249 _jit_retr(jit_state_t *_jit, jit_int32_t u)
250 {
251     jit_inc_synth_w(retr, u);
252     if (JIT_RET != u)
253 	jit_movr(JIT_RET, u);
254     jit_live(JIT_RET);
255     jit_ret();
256     jit_dec_synth();
257 }
258 
259 void
_jit_reti(jit_state_t * _jit,jit_word_t u)260 _jit_reti(jit_state_t *_jit, jit_word_t u)
261 {
262     jit_inc_synth_w(reti, u);
263     jit_movi(JIT_RET, u);
264     jit_ret();
265     jit_dec_synth();
266 }
267 
268 void
_jit_retr_f(jit_state_t * _jit,jit_int32_t u)269 _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
270 {
271     jit_inc_synth_w(retr_f, u);
272     if (u != JIT_FRET)
273 	jit_movr_f(JIT_FRET, u);
274     else
275 	jit_live(JIT_FRET);
276     jit_ret();
277     jit_dec_synth();
278 }
279 
280 void
_jit_reti_f(jit_state_t * _jit,jit_float32_t u)281 _jit_reti_f(jit_state_t *_jit, jit_float32_t u)
282 {
283     jit_inc_synth_f(reti_f, u);
284     jit_movi_f(JIT_FRET, u);
285     jit_ret();
286     jit_dec_synth();
287 }
288 
289 void
_jit_retr_d(jit_state_t * _jit,jit_int32_t u)290 _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
291 {
292     jit_inc_synth_w(retr_d, u);
293     if (u != JIT_FRET)
294 	jit_movr_d(JIT_FRET, u);
295     else
296 	jit_live(JIT_FRET);
297     jit_ret();
298     jit_dec_synth();
299 }
300 
301 void
_jit_reti_d(jit_state_t * _jit,jit_float64_t u)302 _jit_reti_d(jit_state_t *_jit, jit_float64_t u)
303 {
304     jit_inc_synth_d(reti_d, u);
305     jit_movi_d(JIT_FRET, u);
306     jit_ret();
307     jit_dec_synth();
308 }
309 
310 void
_jit_epilog(jit_state_t * _jit)311 _jit_epilog(jit_state_t *_jit)
312 {
313     assert(_jitc->function != NULL);
314     assert(_jitc->function->epilog->next == NULL);
315     jit_link(_jitc->function->epilog);
316     _jitc->function = NULL;
317 }
318 
319 jit_bool_t
_jit_arg_register_p(jit_state_t * _jit,jit_node_t * u)320 _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
321 {
322     if (u->code == jit_code_arg)
323 	return (jit_arg_reg_p(u->u.w));
324     assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d);
325     return (jit_arg_f_reg_p(u->u.w));
326 }
327 
328 void
_jit_ellipsis(jit_state_t * _jit)329 _jit_ellipsis(jit_state_t *_jit)
330 {
331     jit_inc_synth(ellipsis);
332     if (_jitc->prepare) {
333 	jit_link_prepare();
334 	assert(!(_jitc->function->call.call & jit_call_varargs));
335 	_jitc->function->call.call |= jit_call_varargs;
336     }
337     else {
338 	jit_link_prolog();
339 	assert(!(_jitc->function->self.call & jit_call_varargs));
340 	_jitc->function->self.call |= jit_call_varargs;
341 
342 	/* Allocate va_list like object in the stack */
343 	_jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t));
344 	_jitc->function->vagp = _jitc->function->self.argi;
345     }
346     jit_dec_synth();
347 }
348 
349 void
_jit_va_push(jit_state_t * _jit,jit_int32_t u)350 _jit_va_push(jit_state_t *_jit, jit_int32_t u)
351 {
352     jit_int32_t		reg;
353     jit_inc_synth_w(va_push, u);
354     reg = jit_get_reg(jit_class_gpr);
355     jit_ldxi(reg, u, offsetof(jit_va_list_t, base));
356     jit_pushargr(reg);
357     jit_ldxi(reg, u, offsetof(jit_va_list_t, offset));
358     jit_pushargr(reg);
359     jit_unget_reg(reg);
360     jit_dec_synth();
361 }
362 
363 jit_node_t *
_jit_arg(jit_state_t * _jit)364 _jit_arg(jit_state_t *_jit)
365 {
366     jit_node_t		*node;
367     jit_int32_t		 offset;
368     assert(_jitc->function != NULL);
369     if (jit_arg_reg_p(_jitc->function->self.argi))
370 	offset = _jitc->function->self.argi++;
371     else {
372 	offset = _jitc->function->self.size;
373 	_jitc->function->self.size += 8;
374     }
375     node = jit_new_node_ww(jit_code_arg, offset,
376 			   ++_jitc->function->self.argn);
377     jit_link_prolog();
378     return (node);
379 }
380 
381 jit_node_t *
_jit_arg_f(jit_state_t * _jit)382 _jit_arg_f(jit_state_t *_jit)
383 {
384     jit_node_t		*node;
385     jit_int32_t		 offset;
386     assert(_jitc->function != NULL);
387     if (jit_arg_f_reg_p(_jitc->function->self.argi))
388 	offset = _jitc->function->self.argi++;
389     else {
390 	offset = _jitc->function->self.size;
391 	_jitc->function->self.size += 8;
392     }
393     node = jit_new_node_ww(jit_code_arg_f, offset,
394 			   ++_jitc->function->self.argn);
395     jit_link_prolog();
396     return (node);
397 }
398 
399 jit_node_t *
_jit_arg_d(jit_state_t * _jit)400 _jit_arg_d(jit_state_t *_jit)
401 {
402     jit_node_t		*node;
403     jit_int32_t		 offset;
404     assert(_jitc->function != NULL);
405     if (jit_arg_f_reg_p(_jitc->function->self.argi))
406 	offset = _jitc->function->self.argi++;
407     else {
408 	offset = _jitc->function->self.size;
409 	_jitc->function->self.size += 8;
410     }
411     node = jit_new_node_ww(jit_code_arg_d, offset,
412 			   ++_jitc->function->self.argn);
413     jit_link_prolog();
414     return (node);
415 }
416 
417 void
_jit_getarg_c(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)418 _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
419 {
420     assert(v->code == jit_code_arg);
421     jit_inc_synth_wp(getarg_c, u, v);
422     if (jit_arg_reg_p(v->u.w))
423 	jit_extr_c(u, _A0 - v->u.w);
424     else
425 	jit_ldxi_c(u, _FP, v->u.w + C_DISP);
426     jit_dec_synth();
427 }
428 
429 void
_jit_getarg_uc(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)430 _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
431 {
432     assert(v->code == jit_code_arg);
433     jit_inc_synth_wp(getarg_uc, u, v);
434     if (jit_arg_reg_p(v->u.w))
435 	jit_extr_uc(u, _A0 - v->u.w);
436     else
437 	jit_ldxi_uc(u, _FP, v->u.w + C_DISP);
438     jit_dec_synth();
439 }
440 
441 void
_jit_getarg_s(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)442 _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
443 {
444     assert(v->code == jit_code_arg);
445     jit_inc_synth_wp(getarg_s, u, v);
446     if (jit_arg_reg_p(v->u.w))
447 	jit_extr_s(u, _A0 - v->u.w);
448     else
449 	jit_ldxi_s(u, _FP, v->u.w + S_DISP);
450     jit_dec_synth();
451 }
452 
453 void
_jit_getarg_us(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)454 _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
455 {
456     assert(v->code == jit_code_arg);
457     jit_inc_synth_wp(getarg_us, u, v);
458     if (jit_arg_reg_p(v->u.w))
459 	jit_extr_us(u, _A0 - v->u.w);
460     else
461 	jit_ldxi_us(u, _FP, v->u.w + S_DISP);
462     jit_dec_synth();
463 }
464 
465 void
_jit_getarg_i(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)466 _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
467 {
468     assert(v->code == jit_code_arg);
469     jit_inc_synth_wp(getarg_i, u, v);
470     if (jit_arg_reg_p(v->u.w))
471 	jit_extr_i(u, _A0 - v->u.w);
472     else
473 	jit_ldxi_i(u, _FP, v->u.w + I_DISP);
474     jit_dec_synth();
475 }
476 
477 void
_jit_getarg_ui(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)478 _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
479 {
480     assert(v->code == jit_code_arg);
481     jit_inc_synth_wp(getarg_ui, u, v);
482     if (jit_arg_reg_p(v->u.w))
483 	jit_extr_ui(u, _A0 - v->u.w);
484     else
485 	jit_ldxi_ui(u, _FP, v->u.w + I_DISP);
486     jit_dec_synth();
487 }
488 
489 void
_jit_getarg_l(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)490 _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
491 {
492     assert(v->code == jit_code_arg);
493     jit_inc_synth_wp(getarg_l, u, v);
494     if (jit_arg_reg_p(v->u.w))
495 	jit_movr(u, _A0 - v->u.w);
496     else
497 	jit_ldxi_l(u, _FP, v->u.w);
498     jit_dec_synth();
499 }
500 
501 void
_jit_putargr(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)502 _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
503 {
504     assert(v->code == jit_code_arg);
505     jit_inc_synth_wp(putargr, u, v);
506     if (jit_arg_reg_p(v->u.w))
507 	jit_movr(_A0 - v->u.w, u);
508     else
509 	jit_stxi(v->u.w, _FP, u);
510     jit_dec_synth();
511 }
512 
513 void
_jit_putargi(jit_state_t * _jit,jit_word_t u,jit_node_t * v)514 _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
515 {
516     jit_int32_t		regno;
517     assert(v->code == jit_code_arg);
518     jit_inc_synth_wp(putargi, u, v);
519     if (jit_arg_reg_p(v->u.w))
520 	jit_movi(_A0 - v->u.w, u);
521     else {
522 	regno = jit_get_reg(jit_class_gpr);
523 	jit_movi(regno, u);
524 	jit_stxi(v->u.w, _FP, regno);
525 	jit_unget_reg(regno);
526     }
527     jit_dec_synth();
528 }
529 
530 void
_jit_getarg_f(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)531 _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
532 {
533     assert(v->code == jit_code_arg_f);
534     jit_inc_synth_wp(getarg_f, u, v);
535     if (jit_arg_f_reg_p(v->u.w))
536 	jit_movr_f(u, _F16 - v->u.w);
537     else
538 	jit_ldxi_f(u, _FP, v->u.w + F_DISP);
539     jit_dec_synth();
540 }
541 
542 void
_jit_putargr_f(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)543 _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
544 {
545     assert(v->code == jit_code_arg_f);
546     jit_inc_synth_wp(putargr_f, u, v);
547     if (jit_arg_f_reg_p(v->u.w))
548 	jit_movr_f(_F16 - v->u.w, u);
549     else
550 	jit_stxi_f(v->u.w, _FP, u + F_DISP);
551     jit_dec_synth();
552 }
553 
554 void
_jit_putargi_f(jit_state_t * _jit,jit_float32_t u,jit_node_t * v)555 _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
556 {
557     jit_int32_t		regno;
558     assert(v->code == jit_code_arg_f);
559     jit_inc_synth_fp(putargi_f, u, v);
560     if (jit_arg_f_reg_p(v->u.w))
561 	jit_movi_f(_F16 - v->u.w, u);
562     else {
563 	regno = jit_get_reg(jit_class_fpr);
564 	jit_movi_f(regno, u);
565 	jit_stxi_f(v->u.w, _FP, regno + F_DISP);
566 	jit_unget_reg(regno);
567     }
568     jit_dec_synth();
569 }
570 
571 void
_jit_getarg_d(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)572 _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
573 {
574     assert(v->code == jit_code_arg_d);
575     jit_inc_synth_wp(getarg_d, u, v);
576     if (jit_arg_f_reg_p(v->u.w))
577 	jit_movr_d(u, _F16 - v->u.w);
578     else
579 	jit_ldxi_d(u, _FP, v->u.w);
580     jit_dec_synth();
581 }
582 
583 void
_jit_putargr_d(jit_state_t * _jit,jit_int32_t u,jit_node_t * v)584 _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
585 {
586     assert(v->code == jit_code_arg_d);
587     jit_inc_synth_wp(putargr_d, u, v);
588     if (jit_arg_f_reg_p(v->u.w))
589 	jit_movr_d(_F16 - v->u.w, u);
590     else
591 	jit_stxi_d(v->u.w, _FP, u);
592     jit_dec_synth();
593 }
594 
595 void
_jit_putargi_d(jit_state_t * _jit,jit_float64_t u,jit_node_t * v)596 _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
597 {
598     jit_int32_t		regno;
599     assert(v->code == jit_code_arg_d);
600     jit_inc_synth_dp(putargi_d, u, v);
601     if (jit_arg_f_reg_p(v->u.w))
602 	jit_movi_d(_F16 - v->u.w, u);
603     else {
604 	regno = jit_get_reg(jit_class_fpr);
605 	jit_movi_d(regno, u);
606 	jit_stxi_d(v->u.w, _FP, regno);
607 	jit_unget_reg(regno);
608     }
609     jit_dec_synth();
610 }
611 
612 void
_jit_pushargr(jit_state_t * _jit,jit_int32_t u)613 _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
614 {
615     assert(_jitc->function != NULL);
616     jit_inc_synth_w(pushargr, u);
617     jit_link_prepare();
618     if (jit_arg_reg_p(_jitc->function->call.argi)) {
619 	jit_movr(_A0 - _jitc->function->call.argi, u);
620 	++_jitc->function->call.argi;
621     }
622     else {
623 	jit_stxi(_jitc->function->call.size, JIT_SP, u);
624 	_jitc->function->call.size += 8;
625     }
626     jit_dec_synth();
627 }
628 
629 void
_jit_pushargi(jit_state_t * _jit,jit_int64_t u)630 _jit_pushargi(jit_state_t *_jit, jit_int64_t u)
631 {
632     jit_int32_t		regno;
633     assert(_jitc->function != NULL);
634     jit_inc_synth_w(pushargi, u);
635     jit_link_prepare();
636     if (jit_arg_reg_p(_jitc->function->call.argi)) {
637 	jit_movi(_A0 - _jitc->function->call.argi, u);
638 	++_jitc->function->call.argi;
639     }
640     else {
641 	regno = jit_get_reg(jit_class_gpr);
642 	jit_movi(regno, u);
643 	jit_stxi(_jitc->function->call.size, JIT_SP, regno);
644 	_jitc->function->call.size += 8;
645 	jit_unget_reg(regno);
646     }
647     jit_dec_synth();
648 }
649 
650 void
_jit_pushargr_f(jit_state_t * _jit,jit_int32_t u)651 _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
652 {
653     assert(_jitc->function != NULL);
654     jit_inc_synth_w(pushargr_f, u);
655     jit_link_prepare();
656     if (jit_arg_f_reg_p(_jitc->function->call.argi)) {
657 	jit_movr_f(_F16 - _jitc->function->call.argi, u);
658 	++_jitc->function->call.argi;
659     }
660     else {
661 	jit_stxi_f(_jitc->function->call.size + F_DISP, JIT_SP, u);
662 	_jitc->function->call.size += 8;
663     }
664     jit_dec_synth();
665 }
666 
667 void
_jit_pushargi_f(jit_state_t * _jit,jit_float32_t u)668 _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
669 {
670     jit_int32_t		regno;
671     assert(_jitc->function != NULL);
672     jit_inc_synth_f(pushargi_f, u);
673     jit_link_prepare();
674     if (jit_arg_f_reg_p(_jitc->function->call.argi)) {
675 	jit_movi_f(_F16 - _jitc->function->call.argi, u);
676 	++_jitc->function->call.argi;
677     }
678     else {
679 	regno = jit_get_reg(jit_class_fpr);
680 	jit_movi_f(regno, u);
681 	jit_stxi_f(_jitc->function->call.size + F_DISP, JIT_SP, regno);
682 	_jitc->function->call.size += 8;
683 	jit_unget_reg(regno);
684     }
685     jit_dec_synth();
686 }
687 
688 void
_jit_pushargr_d(jit_state_t * _jit,jit_int32_t u)689 _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
690 {
691     assert(_jitc->function != NULL);
692     jit_inc_synth_w(pushargr_d, u);
693     jit_link_prepare();
694     if (jit_arg_f_reg_p(_jitc->function->call.argi)) {
695 	jit_movr_d(_F16 - _jitc->function->call.argi, u);
696 	++_jitc->function->call.argi;
697     }
698     else {
699 	jit_stxi_d(_jitc->function->call.size, JIT_SP, u);
700 	_jitc->function->call.size += 8;
701     }
702     jit_dec_synth();
703 }
704 
705 void
_jit_pushargi_d(jit_state_t * _jit,jit_float64_t u)706 _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
707 {
708     jit_int32_t		regno;
709     assert(_jitc->function != NULL);
710     jit_inc_synth_d(pushargi_d, u);
711     jit_link_prepare();
712     if (jit_arg_f_reg_p(_jitc->function->call.argi)) {
713 	jit_movi_d(_F16 - _jitc->function->call.argi, u);
714 	++_jitc->function->call.argi;
715     }
716     else {
717 	regno = jit_get_reg(jit_class_fpr);
718 	jit_movi_d(regno, u);
719 	jit_stxi_d(_jitc->function->call.size, JIT_SP, regno);
720 	_jitc->function->call.size += 8;
721 	jit_unget_reg(regno);
722     }
723     jit_dec_synth();
724 }
725 
726 jit_bool_t
_jit_regarg_p(jit_state_t * _jit,jit_node_t * node,jit_int32_t regno)727 _jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno)
728 {
729     jit_int32_t		spec;
730 
731     spec = jit_class(_rvs[regno].spec);
732     if (spec & jit_class_arg) {
733 	if (spec & jit_class_gpr) {
734 	    regno = _A0 - regno;
735 	    if (regno >= 0 && regno < node->v.w)
736 		return (1);
737 	}
738 	else if (spec & jit_class_fpr) {
739 	    regno = _F16 - regno;
740 	    if (regno >= 0 && regno < node->w.w)
741 		return (1);
742 	}
743     }
744 
745     return (0);
746 }
747 
748 void
_jit_finishr(jit_state_t * _jit,jit_int32_t r0)749 _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
750 {
751     jit_node_t		*call;
752     assert(_jitc->function != NULL);
753     jit_inc_synth_w(finishr, r0);
754     if (_jitc->function->self.alen < _jitc->function->call.size)
755 	_jitc->function->self.alen = _jitc->function->call.size;
756     call = jit_callr(r0);
757     call->v.w = call->w.w = _jitc->function->self.argi;
758     _jitc->function->call.argi = _jitc->function->call.size = 0;
759     _jitc->prepare = 0;
760     jit_dec_synth();
761 }
762 
763 jit_node_t *
_jit_finishi(jit_state_t * _jit,jit_pointer_t i0)764 _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
765 {
766     jit_node_t		*call;
767     assert(_jitc->function != NULL);
768     jit_inc_synth_w(finishi, (jit_word_t)i0);
769     if (_jitc->function->self.alen < _jitc->function->call.size)
770 	_jitc->function->self.alen = _jitc->function->call.size;
771     call = jit_calli(i0);
772     call->v.w = call->w.w = _jitc->function->self.argf;
773     _jitc->function->call.argi = _jitc->function->call.size = 0;
774     _jitc->prepare = 0;
775     jit_dec_synth();
776     return (call);
777 }
778 
779 void
_jit_retval_c(jit_state_t * _jit,jit_int32_t r0)780 _jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
781 {
782     jit_inc_synth_w(retval_c, r0);
783     jit_extr_c(r0, JIT_RET);
784     jit_dec_synth();
785 }
786 
787 void
_jit_retval_uc(jit_state_t * _jit,jit_int32_t r0)788 _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
789 {
790     jit_inc_synth_w(retval_uc, r0);
791     jit_extr_uc(r0, JIT_RET);
792     jit_dec_synth();
793 }
794 
795 void
_jit_retval_s(jit_state_t * _jit,jit_int32_t r0)796 _jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
797 {
798     jit_inc_synth_w(retval_s, r0);
799     jit_extr_s(r0, JIT_RET);
800     jit_dec_synth();
801 }
802 
803 void
_jit_retval_us(jit_state_t * _jit,jit_int32_t r0)804 _jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
805 {
806     jit_inc_synth_w(retval_us, r0);
807     jit_extr_us(r0, JIT_RET);
808     jit_dec_synth();
809 }
810 
811 void
_jit_retval_i(jit_state_t * _jit,jit_int32_t r0)812 _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
813 {
814     jit_inc_synth_w(retval_i, r0);
815     jit_extr_i(r0, JIT_RET);
816     jit_dec_synth();
817 }
818 
819 void
_jit_retval_ui(jit_state_t * _jit,jit_int32_t r0)820 _jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
821 {
822     jit_inc_synth_w(retval_ui, r0);
823     jit_extr_ui(r0, JIT_RET);
824     jit_dec_synth();
825 }
826 
827 void
_jit_retval_l(jit_state_t * _jit,jit_int32_t r0)828 _jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
829 {
830     jit_inc_synth_w(retval_l, r0);
831     if (r0 != JIT_RET)
832 	jit_movr(r0, JIT_RET);
833     jit_dec_synth();
834 }
835 
836 void
_jit_retval_f(jit_state_t * _jit,jit_int32_t r0)837 _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
838 {
839     jit_inc_synth_w(retval_f, r0);
840     if (r0 != JIT_FRET)
841 	jit_movr_f(r0, JIT_FRET);
842     jit_dec_synth();
843 }
844 
845 void
_jit_retval_d(jit_state_t * _jit,jit_int32_t r0)846 _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
847 {
848     jit_inc_synth_w(retval_d, r0);
849     if (r0 != JIT_FRET)
850 	jit_movr_d(r0, JIT_FRET);
851     jit_dec_synth();
852 }
853 
854 jit_pointer_t
_emit_code(jit_state_t * _jit)855 _emit_code(jit_state_t *_jit)
856 {
857     jit_node_t		*node;
858     jit_node_t		*temp;
859     jit_word_t		 word;
860     jit_word_t		 value;
861     jit_int32_t		 offset;
862     struct {
863 	jit_node_t	*node;
864 	jit_uint8_t	*data;
865 	jit_word_t	 word;
866 #if DEVEL_DISASSEMBLER
867 	jit_word_t	 prevw;
868 #endif
869 	jit_int32_t	 const_offset;
870 	jit_int32_t	 patch_offset;
871     } undo;
872 #if DEVEL_DISASSEMBLER
873     jit_word_t		 prevw;
874 #endif
875 
876     _jitc->function = NULL;
877 
878     jit_reglive_setup();
879 
880     undo.word = 0;
881     undo.node = NULL;
882     undo.const_offset = undo.patch_offset = 0;
883 #define case_rr(name, type)						\
884 	    case jit_code_##name##r##type:				\
885 		name##r##type(rn(node->u.w), rn(node->v.w));		\
886 		break
887 #define case_rw(name, type)						\
888 	    case jit_code_##name##i##type:				\
889 		name##i##type(rn(node->u.w), node->v.w);		\
890 		break
891 #define case_wr(name, type)						\
892 	    case jit_code_##name##i##type:				\
893 		name##i##type(node->u.w, rn(node->v.w));		\
894 		break
895 #define case_rrr(name, type)						\
896 	    case jit_code_##name##r##type:				\
897 		name##r##type(rn(node->u.w),				\
898 			      rn(node->v.w), rn(node->w.w));		\
899 		break
900 #define case_rrw(name, type)						\
901 	    case jit_code_##name##i##type:				\
902 		name##i##type(rn(node->u.w), rn(node->v.w), node->w.w);	\
903 		break
904 #define case_rrf(name, type, size)					\
905 	    case jit_code_##name##i##type:				\
906 		assert(node->flag & jit_flag_data);			\
907 		name##i##type(rn(node->u.w), rn(node->v.w),		\
908 			      (jit_float##size##_t *)node->w.n->u.w);	\
909 		break
910 #define case_rrrr(name, type)						\
911 	    case jit_code_##name##r##type:				\
912 		name##r##type(rn(node->u.q.l), rn(node->u.q.h),		\
913 			      rn(node->v.w), rn(node->w.w));		\
914 		break
915 #define case_rrrw(name, type)						\
916 	    case jit_code_##name##i##type:				\
917 		name##i##type(rn(node->u.q.l), rn(node->u.q.h),		\
918 			      rn(node->v.w), node->w.w);		\
919 		break
920 #define case_wrr(name, type)						\
921 	    case jit_code_##name##i##type:				\
922 		name##i##type(node->u.w, rn(node->v.w), rn(node->w.w));	\
923 		break
924 #define case_brr(name, type)						\
925 	    case jit_code_##name##r##type:				\
926 		temp = node->u.n;					\
927 		assert(temp->code == jit_code_label ||			\
928 		       temp->code == jit_code_epilog);			\
929 		if (temp->flag & jit_flag_patch)			\
930 		    name##r##type(temp->u.w, rn(node->v.w),		\
931 				  rn(node->w.w));			\
932 		else {							\
933 		    word = name##r##type(_jit->pc.w,			\
934 					 rn(node->v.w), rn(node->w.w));	\
935 		    patch(word, node);					\
936 		}							\
937 		break
938 #define case_brw(name, type)						\
939 	    case jit_code_##name##i##type:				\
940 		temp = node->u.n;					\
941 		assert(temp->code == jit_code_label ||			\
942 		       temp->code == jit_code_epilog);			\
943 		if (temp->flag & jit_flag_patch)			\
944 		    name##i##type(temp->u.w,				\
945 				  rn(node->v.w), node->w.w);		\
946 		else {							\
947 		    word = name##i##type(_jit->pc.w,			\
948 					 rn(node->v.w), node->w.w);	\
949 		    patch(word, node);					\
950 		}							\
951 		break
952 #define case_brf(name, type, size)					\
953 	    case jit_code_##name##i##type:				\
954 		temp = node->u.n;					\
955 		assert(temp->code == jit_code_label ||			\
956 		       temp->code == jit_code_epilog);			\
957 		if (temp->flag & jit_flag_patch)			\
958 		    name##i##type(temp->u.w, rn(node->v.w),		\
959 				(jit_float##size##_t *)node->w.n->u.w);	\
960 		else {							\
961 		    word = name##i##type(_jit->pc.w, rn(node->v.w),	\
962 				(jit_float##size##_t *)node->w.n->u.w);	\
963 		    patch(word, node);					\
964 		}							\
965 		break
966 #if DEVEL_DISASSEMBLER
967     prevw = _jit->pc.w;
968 #endif
969     for (node = _jitc->head; node; node = node->next) {
970 	if (_jit->pc.uc >= _jitc->code.end)
971 	    return (NULL);
972 
973 #if DEVEL_DISASSEMBLER
974 	node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
975 	prevw = _jit->pc.w;
976 #endif
977 	value = jit_classify(node->code);
978 	jit_regarg_set(node, value);
979 	switch (node->code) {
980 	    case jit_code_align:
981 		assert(!(node->u.w & (node->u.w - 1)) &&
982 		       node->u.w <= sizeof(jit_word_t));
983 		if (node->u.w == sizeof(jit_word_t) &&
984 		    (word = _jit->pc.w & (sizeof(jit_word_t) - 1)))
985 		    nop(sizeof(jit_word_t) - word);
986 		break;
987 	    case jit_code_note:		case jit_code_name:
988 		node->u.w = _jit->pc.w;
989 		break;
990 	    case jit_code_label:
991 		/* remember label is defined */
992 		node->flag |= jit_flag_patch;
993 		node->u.w = _jit->pc.w;
994 		break;
995 		case_rrr(add,);
996 		case_rrw(add,);
997 		case_rrr(addc,);
998 		case_rrw(addc,);
999 		case_rrr(addx,);
1000 		case_rrw(addx,);
1001 		case_rrr(sub,);
1002 		case_rrw(sub,);
1003 		case_rrr(subc,);
1004 		case_rrw(subc,);
1005 		case_rrr(subx,);
1006 		case_rrw(subx,);
1007 		case_rrw(rsb,);
1008 		case_rrr(mul,);
1009 		case_rrw(mul,);
1010 		case_rrrr(qmul,);
1011 		case_rrrw(qmul,);
1012 		case_rrrr(qmul, _u);
1013 		case_rrrw(qmul, _u);
1014 		case_rrr(div,);
1015 		case_rrw(div,);
1016 		case_rrr(div, _u);
1017 		case_rrw(div, _u);
1018 		case_rrrr(qdiv,);
1019 		case_rrrw(qdiv,);
1020 		case_rrrr(qdiv, _u);
1021 		case_rrrw(qdiv, _u);
1022 		case_rrr(rem,);
1023 		case_rrw(rem,);
1024 		case_rrr(rem, _u);
1025 		case_rrw(rem, _u);
1026 		case_rrr(lsh,);
1027 		case_rrw(lsh,);
1028 		case_rrr(rsh,);
1029 		case_rrw(rsh,);
1030 		case_rrr(rsh, _u);
1031 		case_rrw(rsh, _u);
1032 		case_rrr(and,);
1033 		case_rrw(and,);
1034 		case_rrr(or,);
1035 		case_rrw(or,);
1036 		case_rrr(xor,);
1037 		case_rrw(xor,);
1038 		case_rr(trunc, _f_i);
1039 		case_rr(trunc, _d_i);
1040 		case_rr(trunc, _f_l);
1041 		case_rr(trunc, _d_l);
1042 		case_rr(ld, _c);
1043 		case_rw(ld, _c);
1044 		case_rr(ld, _uc);
1045 		case_rw(ld, _uc);
1046 		case_rr(ld, _s);
1047 		case_rw(ld, _s);
1048 		case_rr(ld, _us);
1049 		case_rw(ld, _us);
1050 		case_rr(ld, _i);
1051 		case_rw(ld, _i);
1052 		case_rr(ld, _ui);
1053 		case_rw(ld, _ui);
1054 		case_rr(ld, _l);
1055 		case_rw(ld, _l);
1056 		case_rrr(ldx, _c);
1057 		case_rrw(ldx, _c);
1058 		case_rrr(ldx, _uc);
1059 		case_rrw(ldx, _uc);
1060 		case_rrr(ldx, _s);
1061 		case_rrw(ldx, _s);
1062 		case_rrr(ldx, _us);
1063 		case_rrw(ldx, _us);
1064 		case_rrr(ldx, _i);
1065 		case_rrw(ldx, _i);
1066 		case_rrr(ldx, _ui);
1067 		case_rrw(ldx, _ui);
1068 		case_rrr(ldx, _l);
1069 		case_rrw(ldx, _l);
1070 		case_rr(st, _c);
1071 		case_wr(st, _c);
1072 		case_rr(st, _s);
1073 		case_wr(st, _s);
1074 		case_rr(st, _i);
1075 		case_wr(st, _i);
1076 		case_rr(st, _l);
1077 		case_wr(st, _l);
1078 		case_rrr(stx, _c);
1079 		case_wrr(stx, _c);
1080 		case_rrr(stx, _s);
1081 		case_wrr(stx, _s);
1082 		case_rrr(stx, _i);
1083 		case_wrr(stx, _i);
1084 		case_rrr(stx, _l);
1085 		case_wrr(stx, _l);
1086 		case_rr(hton, _us);
1087 		case_rr(hton, _ui);
1088 		case_rr(hton, _ul);
1089 		case_rr(ext, _c);
1090 		case_rr(ext, _uc);
1091 		case_rr(ext, _s);
1092 		case_rr(ext, _us);
1093 		case_rr(ext, _i);
1094 		case_rr(ext, _ui);
1095 		case_rr(mov,);
1096 	    case jit_code_movi:
1097 		if (node->flag & jit_flag_node) {
1098 		    temp = node->v.n;
1099 		    if (temp->code == jit_code_data ||
1100 			(temp->code == jit_code_label &&
1101 			 (temp->flag & jit_flag_patch)))
1102 			movi(rn(node->u.w), temp->u.w);
1103 		    else {
1104 			assert(temp->code == jit_code_label ||
1105 			       temp->code == jit_code_epilog);
1106 			word = movi_p(rn(node->u.w), node->v.w);
1107 			patch(word, node);
1108 		    }
1109 		}
1110 		else
1111 		    movi(rn(node->u.w), node->v.w);
1112 		break;
1113 		case_rr(neg,);
1114 		case_rr(com,);
1115 		case_rrr(lt,);
1116 		case_rrw(lt,);
1117 		case_rrr(lt, _u);
1118 		case_rrw(lt, _u);
1119 		case_rrr(le,);
1120 		case_rrw(le,);
1121 		case_rrr(le, _u);
1122 		case_rrw(le, _u);
1123 		case_rrr(eq,);
1124 		case_rrw(eq,);
1125 		case_rrr(ge,);
1126 		case_rrw(ge,);
1127 		case_rrr(ge, _u);
1128 		case_rrw(ge, _u);
1129 		case_rrr(gt,);
1130 		case_rrw(gt,);
1131 		case_rrr(gt, _u);
1132 		case_rrw(gt, _u);
1133 		case_rrr(ne,);
1134 		case_rrw(ne,);
1135 		case_brr(blt,);
1136 		case_brw(blt,);
1137 		case_brr(blt, _u);
1138 		case_brw(blt, _u);
1139 		case_brr(ble,);
1140 		case_brw(ble,);
1141 		case_brr(ble, _u);
1142 		case_brw(ble, _u);
1143 		case_brr(beq,);
1144 		case_brw(beq,);
1145 		case_brr(bge,);
1146 		case_brw(bge,);
1147 		case_brr(bge, _u);
1148 		case_brw(bge, _u);
1149 		case_brr(bgt,);
1150 		case_brw(bgt,);
1151 		case_brr(bgt, _u);
1152 		case_brw(bgt, _u);
1153 		case_brr(bne,);
1154 		case_brw(bne,);
1155 		case_brr(boadd,);
1156 		case_brw(boadd,);
1157 		case_brr(boadd, _u);
1158 		case_brw(boadd, _u);
1159 		case_brr(bxadd,);
1160 		case_brw(bxadd,);
1161 		case_brr(bxadd, _u);
1162 		case_brw(bxadd, _u);
1163 		case_brr(bosub,);
1164 		case_brw(bosub,);
1165 		case_brr(bosub, _u);
1166 		case_brw(bosub, _u);
1167 		case_brr(bxsub,);
1168 		case_brw(bxsub,);
1169 		case_brr(bxsub, _u);
1170 		case_brw(bxsub, _u);
1171 		case_brr(bms,);
1172 		case_brw(bms,);
1173 		case_brr(bmc,);
1174 		case_brw(bmc,);
1175 		case_rrr(add, _f);
1176 		case_rrf(add, _f, 32);
1177 		case_rrr(sub, _f);
1178 		case_rrf(sub, _f, 32);
1179 		case_rrf(rsb, _f, 32);
1180 		case_rrr(mul, _f);
1181 		case_rrf(mul, _f, 32);
1182 		case_rrr(div, _f);
1183 		case_rrf(div, _f, 32);
1184 		case_rr(abs, _f);
1185 		case_rr(neg, _f);
1186 		case_rr(sqrt, _f);
1187 		case_rr(ext, _f);
1188 		case_rr(ld, _f);
1189 		case_rw(ld, _f);
1190 		case_rrr(ldx, _f);
1191 		case_rrw(ldx, _f);
1192 		case_rr(st, _f);
1193 		case_wr(st, _f);
1194 		case_rrr(stx, _f);
1195 		case_wrr(stx, _f);
1196 		case_rr(mov, _f);
1197 	    case jit_code_movi_f:
1198 		assert(node->flag & jit_flag_data);
1199 		movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w);
1200 		break;
1201 		case_rr(ext, _d_f);
1202 		case_rrr(lt, _f);
1203 		case_rrf(lt, _f, 32);
1204 		case_rrr(le, _f);
1205 		case_rrf(le, _f, 32);
1206 		case_rrr(eq, _f);
1207 		case_rrf(eq, _f, 32);
1208 		case_rrr(ge, _f);
1209 		case_rrf(ge, _f, 32);
1210 		case_rrr(gt, _f);
1211 		case_rrf(gt, _f, 32);
1212 		case_rrr(ne, _f);
1213 		case_rrf(ne, _f, 32);
1214 		case_rrr(unlt, _f);
1215 		case_rrf(unlt, _f, 32);
1216 		case_rrr(unle, _f);
1217 		case_rrf(unle, _f, 32);
1218 		case_rrr(uneq, _f);
1219 		case_rrf(uneq, _f, 32);
1220 		case_rrr(unge, _f);
1221 		case_rrf(unge, _f, 32);
1222 		case_rrr(ungt, _f);
1223 		case_rrf(ungt, _f, 32);
1224 		case_rrr(ltgt, _f);
1225 		case_rrf(ltgt, _f, 32);
1226 		case_rrr(ord, _f);
1227 		case_rrf(ord, _f, 32);
1228 		case_rrr(unord, _f);
1229 		case_rrf(unord, _f, 32);
1230 		case_brr(blt, _f);
1231 		case_brf(blt, _f, 32);
1232 		case_brr(ble, _f);
1233 		case_brf(ble, _f, 32);
1234 		case_brr(beq, _f);
1235 		case_brf(beq, _f, 32);
1236 		case_brr(bge, _f);
1237 		case_brf(bge, _f, 32);
1238 		case_brr(bgt, _f);
1239 		case_brf(bgt, _f, 32);
1240 		case_brr(bne, _f);
1241 		case_brf(bne, _f, 32);
1242 		case_brr(bunlt, _f);
1243 		case_brf(bunlt, _f, 32);
1244 		case_brr(bunle, _f);
1245 		case_brf(bunle, _f, 32);
1246 		case_brr(buneq, _f);
1247 		case_brf(buneq, _f, 32);
1248 		case_brr(bunge, _f);
1249 		case_brf(bunge, _f, 32);
1250 		case_brr(bungt, _f);
1251 		case_brf(bungt, _f, 32);
1252 		case_brr(bltgt, _f);
1253 		case_brf(bltgt, _f, 32);
1254 		case_brr(bord, _f);
1255 		case_brf(bord, _f, 32);
1256 		case_brr(bunord, _f);
1257 		case_brf(bunord, _f, 32);
1258 		case_rrr(add, _d);
1259 		case_rrf(add, _d, 64);
1260 		case_rrr(sub, _d);
1261 		case_rrf(sub, _d, 64);
1262 		case_rrf(rsb, _d, 64);
1263 		case_rrr(mul, _d);
1264 		case_rrf(mul, _d, 64);
1265 		case_rrr(div, _d);
1266 		case_rrf(div, _d, 64);
1267 		case_rr(abs, _d);
1268 		case_rr(neg, _d);
1269 		case_rr(sqrt, _d);
1270 		case_rr(ext, _d);
1271 		case_rr(ld, _d);
1272 		case_rw(ld, _d);
1273 		case_rrr(ldx, _d);
1274 		case_rrw(ldx, _d);
1275 		case_rr(st, _d);
1276 		case_wr(st, _d);
1277 		case_rrr(stx, _d);
1278 		case_wrr(stx, _d);
1279 		case_rr(mov, _d);
1280 	    case jit_code_movi_d:
1281 		assert(node->flag & jit_flag_data);
1282 		movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w);
1283 		break;
1284 		case_rr(ext, _f_d);
1285 		case_rrr(lt, _d);
1286 		case_rrf(lt, _d, 64);
1287 		case_rrr(le, _d);
1288 		case_rrf(le, _d, 64);
1289 		case_rrr(eq, _d);
1290 		case_rrf(eq, _d, 64);
1291 		case_rrr(ge, _d);
1292 		case_rrf(ge, _d, 64);
1293 		case_rrr(gt, _d);
1294 		case_rrf(gt, _d, 64);
1295 		case_rrr(ne, _d);
1296 		case_rrf(ne, _d, 64);
1297 		case_rrr(unlt, _d);
1298 		case_rrf(unlt, _d, 64);
1299 		case_rrr(unle, _d);
1300 		case_rrf(unle, _d, 64);
1301 		case_rrr(uneq, _d);
1302 		case_rrf(uneq, _d, 64);
1303 		case_rrr(unge, _d);
1304 		case_rrf(unge, _d, 64);
1305 		case_rrr(ungt, _d);
1306 		case_rrf(ungt, _d, 64);
1307 		case_rrr(ltgt, _d);
1308 		case_rrf(ltgt, _d, 64);
1309 		case_rrr(ord, _d);
1310 		case_rrf(ord, _d, 64);
1311 		case_rrr(unord, _d);
1312 		case_rrf(unord, _d, 64);
1313 		case_brr(blt, _d);
1314 		case_brf(blt, _d, 64);
1315 		case_brr(ble, _d);
1316 		case_brf(ble, _d, 64);
1317 		case_brr(beq, _d);
1318 		case_brf(beq, _d, 64);
1319 		case_brr(bge, _d);
1320 		case_brf(bge, _d, 64);
1321 		case_brr(bgt, _d);
1322 		case_brf(bgt, _d, 64);
1323 		case_brr(bne, _d);
1324 		case_brf(bne, _d, 64);
1325 		case_brr(bunlt, _d);
1326 		case_brf(bunlt, _d, 64);
1327 		case_brr(bunle, _d);
1328 		case_brf(bunle, _d, 64);
1329 		case_brr(buneq, _d);
1330 		case_brf(buneq, _d, 64);
1331 		case_brr(bunge, _d);
1332 		case_brf(bunge, _d, 64);
1333 		case_brr(bungt, _d);
1334 		case_brf(bungt, _d, 64);
1335 		case_brr(bltgt, _d);
1336 		case_brf(bltgt, _d, 64);
1337 		case_brr(bord, _d);
1338 		case_brf(bord, _d, 64);
1339 		case_brr(bunord, _d);
1340 		case_brf(bunord, _d, 64);
1341 	    case jit_code_jmpr:
1342 		jmpr(rn(node->u.w));
1343 		break;
1344 	    case jit_code_jmpi:
1345 		if (node->flag & jit_flag_node) {
1346 		    temp = node->u.n;
1347 		    assert(temp->code == jit_code_label ||
1348 			   temp->code == jit_code_epilog);
1349 		    if (temp->flag & jit_flag_patch)
1350 			jmpi(temp->u.w);
1351 		    else {
1352 			word = jmpi_p(_jit->pc.w);
1353 			patch(word, node);
1354 		    }
1355 		}
1356 		else
1357 		    jmpi(node->u.w);
1358 		break;
1359 	    case jit_code_callr:
1360 		callr(rn(node->u.w));
1361 		break;
1362 	    case jit_code_calli:
1363 		if (node->flag & jit_flag_node) {
1364 		    temp = node->u.n;
1365 		    assert(temp->code == jit_code_label ||
1366 			   temp->code == jit_code_epilog);
1367 		    if (!(temp->flag & jit_flag_patch)) {
1368 			word = calli_p(temp->u.w);
1369 			patch(word, node);
1370 		    }
1371 		    else
1372 			calli(temp->u.w);
1373 		}
1374 		else
1375 		    calli(node->u.w);
1376 		break;
1377 	    case jit_code_prolog:
1378 		_jitc->function = _jitc->functions.ptr + node->w.w;
1379 		undo.node = node;
1380 		undo.word = _jit->pc.w;
1381 #if DEVEL_DISASSEMBLER
1382 		undo.prevw = prevw;
1383 #endif
1384 		undo.patch_offset = _jitc->patches.offset;
1385 	    restart_function:
1386 		_jitc->again = 0;
1387 		prolog(node);
1388 		break;
1389 	    case jit_code_epilog:
1390 		assert(_jitc->function == _jitc->functions.ptr + node->w.w);
1391 		if (_jitc->again) {
1392 		    for (temp = undo.node->next;
1393 			 temp != node; temp = temp->next) {
1394 			if (temp->code == jit_code_label ||
1395 			    temp->code == jit_code_epilog)
1396 			    temp->flag &= ~jit_flag_patch;
1397 		    }
1398 		    temp->flag &= ~jit_flag_patch;
1399 		    node = undo.node;
1400 		    _jit->pc.w = undo.word;
1401 #if DEVEL_DISASSEMBLER
1402 		    prevw = undo.prevw;
1403 #endif
1404 		    _jitc->patches.offset = undo.patch_offset;
1405 		    goto restart_function;
1406 		}
1407 		/* remember label is defined */
1408 		node->flag |= jit_flag_patch;
1409 		node->u.w = _jit->pc.w;
1410 		epilog(node);
1411 		_jitc->function = NULL;
1412 		break;
1413 	    case jit_code_va_start:
1414 		vastart(rn(node->u.w));
1415 		break;
1416 	    case jit_code_va_arg:
1417 		vaarg(rn(node->u.w), rn(node->v.w));
1418 		break;
1419 	    case jit_code_va_arg_d:
1420 		vaarg_d(rn(node->u.w), rn(node->v.w));
1421 		break;
1422 	    case jit_code_live:			case jit_code_ellipsis:
1423 	    case jit_code_va_push:
1424 	    case jit_code_allocai:		case jit_code_allocar:
1425 	    case jit_code_arg:
1426 	    case jit_code_arg_f:		case jit_code_arg_d:
1427 	    case jit_code_va_end:
1428 	    case jit_code_ret:
1429 	    case jit_code_retr:			case jit_code_reti:
1430 	    case jit_code_retr_f:		case jit_code_reti_f:
1431 	    case jit_code_retr_d:		case jit_code_reti_d:
1432 	    case jit_code_getarg_c:		case jit_code_getarg_uc:
1433 	    case jit_code_getarg_s:		case jit_code_getarg_us:
1434 	    case jit_code_getarg_i:		case jit_code_getarg_ui:
1435 	    case jit_code_getarg_l:
1436 	    case jit_code_getarg_f:		case jit_code_getarg_d:
1437 	    case jit_code_putargr:		case jit_code_putargi:
1438 	    case jit_code_putargr_f:		case jit_code_putargi_f:
1439 	    case jit_code_putargr_d:		case jit_code_putargi_d:
1440 	    case jit_code_pushargr:		case jit_code_pushargi:
1441 	    case jit_code_pushargr_f:		case jit_code_pushargi_f:
1442 	    case jit_code_pushargr_d:		case jit_code_pushargi_d:
1443 	    case jit_code_retval_c:		case jit_code_retval_uc:
1444 	    case jit_code_retval_s:		case jit_code_retval_us:
1445 	    case jit_code_retval_i:
1446 	    case jit_code_retval_ui:		case jit_code_retval_l:
1447 	    case jit_code_retval_f:		case jit_code_retval_d:
1448 	    case jit_code_prepare:
1449 	    case jit_code_finishr:		case jit_code_finishi:
1450 		break;
1451 	    default:
1452 		abort();
1453 	}
1454 	if (jit_carry != _NOREG) {
1455 	    switch (node->code) {
1456 		case jit_code_note:
1457 		case jit_code_addcr:		case jit_code_addci:
1458 		case jit_code_addxr:		case jit_code_addxi:
1459 		case jit_code_subcr:		case jit_code_subci:
1460 		case jit_code_subxr:		case jit_code_subxi:
1461 		    break;
1462 		default:
1463 		    jit_unget_reg(jit_carry);
1464 		    jit_carry = _NOREG;
1465 		    break;
1466 	    }
1467 	}
1468 	jit_regarg_clr(node, value);
1469 	assert(_jitc->regarg == 0 ||
1470 	       (jit_carry != _NOREG && _jitc->regarg == (1 << jit_carry)));
1471 	assert(_jitc->synth == 0);
1472 	/* update register live state */
1473 	jit_reglive(node);
1474     }
1475 #undef case_brf
1476 #undef case_brw
1477 #undef case_brr
1478 #undef case_wrr
1479 #undef case_rrrw
1480 #undef case_rrrr
1481 #undef case_rrf
1482 #undef case_rrw
1483 #undef case_rrr
1484 #undef case_wr
1485 #undef case_rw
1486 #undef case_rr
1487     for (offset = 0; offset < _jitc->patches.offset; offset++) {
1488 	node = _jitc->patches.ptr[offset].node;
1489 	word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
1490 	patch_at(_jitc->patches.ptr[offset].inst, word);
1491     }
1492 
1493     jit_flush(_jit->code.ptr, _jit->pc.uc);
1494 
1495     return (_jit->code.ptr);
1496 }
1497 
1498 #define CODE				1
1499 #  include "jit_alpha-cpu.c"
1500 #  include "jit_alpha-fpu.c"
1501 #undef CODE
1502 
1503 void
jit_flush(void * fptr,void * tptr)1504 jit_flush(void *fptr, void *tptr)
1505 {
1506 }
1507 
1508 void
_emit_ldxi(jit_state_t * _jit,jit_int32_t r0,jit_int32_t r1,jit_word_t i0)1509 _emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1510 {
1511     ldxi(rn(r0), rn(r1), i0);
1512 }
1513 
1514 void
_emit_stxi(jit_state_t * _jit,jit_word_t i0,jit_int32_t r0,jit_int32_t r1)1515 _emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1516 {
1517     stxi(i0, rn(r0), rn(r1));
1518 }
1519 
1520 void
_emit_ldxi_d(jit_state_t * _jit,jit_int32_t r0,jit_int32_t r1,jit_word_t i0)1521 _emit_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1522 {
1523     ldxi_d(rn(r0), rn(r1), i0);
1524 }
1525 
1526 void
_emit_stxi_d(jit_state_t * _jit,jit_word_t i0,jit_int32_t r0,jit_int32_t r1)1527 _emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1528 {
1529     stxi_d(i0, rn(r0), rn(r1));
1530 }
1531 
1532 static void
_patch(jit_state_t * _jit,jit_word_t instr,jit_node_t * node)1533 _patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
1534 {
1535     jit_int32_t		 flag;
1536 
1537     assert(node->flag & jit_flag_node);
1538     if (node->code == jit_code_movi)
1539 	flag = node->v.n->flag;
1540     else
1541 	flag = node->u.n->flag;
1542      assert(!(flag & jit_flag_patch));
1543     if (_jitc->patches.offset >= _jitc->patches.length) {
1544 	jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
1545 		    _jitc->patches.length * sizeof(jit_patch_t),
1546 		    (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
1547 	_jitc->patches.length += 1024;
1548     }
1549     _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
1550     _jitc->patches.ptr[_jitc->patches.offset].node = node;
1551     ++_jitc->patches.offset;
1552 }
1553