]> git.proxmox.com Git - qemu.git/blame - tcg/tcg.c
tcg: Simplify logic using TCG_OPF_NOT_PRESENT
[qemu.git] / tcg / tcg.c
CommitLineData
c896fe29
FB
1/*
2 * Tiny Code Generator for QEMU
3 *
4 * Copyright (c) 2008 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
c896fe29
FB
25/* define it to use liveness analysis (better code) */
26#define USE_LIVENESS_ANALYSIS
8f2e8c07 27#define USE_TCG_OPTIMIZATIONS
c896fe29 28
cca82982
AJ
29#include "config.h"
30
813da627
RH
31/* Define to jump the ELF file used to communicate with GDB. */
32#undef DEBUG_JIT
33
a6c6f76c 34#if !defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG)
cca82982
AJ
35/* define it to suppress various consistency checks (faster) */
36#define NDEBUG
37#endif
38
ca10f867 39#include "qemu-common.h"
1de7afc9
PB
40#include "qemu/cache-utils.h"
41#include "qemu/host-utils.h"
42#include "qemu/timer.h"
c896fe29
FB
43
44/* Note: the long term plan is to reduce the dependancies on the QEMU
45 CPU definitions. Currently they are used for qemu_ld/st
46 instructions */
47#define NO_CPU_IO_DEFS
48#include "cpu.h"
c896fe29
FB
49
50#include "tcg-op.h"
813da627
RH
51
52#if TCG_TARGET_REG_BITS == 64
53# define ELF_CLASS ELFCLASS64
54#else
55# define ELF_CLASS ELFCLASS32
56#endif
57#ifdef HOST_WORDS_BIGENDIAN
58# define ELF_DATA ELFDATA2MSB
59#else
60# define ELF_DATA ELFDATA2LSB
61#endif
62
c896fe29
FB
63#include "elf.h"
64
c0ad3001 65/* Forward declarations for functions declared in tcg-target.c and used here. */
e4d58b41
RH
66static void tcg_target_init(TCGContext *s);
67static void tcg_target_qemu_prologue(TCGContext *s);
c896fe29 68static void patch_reloc(uint8_t *code_ptr, int type,
f54b3f92 69 tcg_target_long value, tcg_target_long addend);
c896fe29 70
813da627
RH
71static void tcg_register_jit_int(void *buf, size_t size,
72 void *debug_frame, size_t debug_frame_size)
73 __attribute__((unused));
74
c0ad3001
SW
75/* Forward declarations for functions declared and used in tcg-target.c. */
76static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str);
2a534aff 77static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
c0ad3001 78 tcg_target_long arg2);
2a534aff 79static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
c0ad3001 80static void tcg_out_movi(TCGContext *s, TCGType type,
2a534aff 81 TCGReg ret, tcg_target_long arg);
c0ad3001
SW
82static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
83 const int *const_args);
2a534aff 84static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
c0ad3001
SW
85 tcg_target_long arg2);
86static int tcg_target_const_match(tcg_target_long val,
87 const TCGArgConstraint *arg_ct);
c0ad3001 88
8399ad59 89TCGOpDef tcg_op_defs[] = {
0e2029a0 90#define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags },
c896fe29
FB
91#include "tcg-opc.h"
92#undef DEF
c896fe29 93};
2a24374a 94const size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs);
c896fe29 95
b1d8e52e
BS
96static TCGRegSet tcg_target_available_regs[2];
97static TCGRegSet tcg_target_call_clobber_regs;
c896fe29 98
c896fe29
FB
99static inline void tcg_out8(TCGContext *s, uint8_t v)
100{
101 *s->code_ptr++ = v;
102}
103
104static inline void tcg_out16(TCGContext *s, uint16_t v)
105{
106 *(uint16_t *)s->code_ptr = v;
107 s->code_ptr += 2;
108}
109
110static inline void tcg_out32(TCGContext *s, uint32_t v)
111{
112 *(uint32_t *)s->code_ptr = v;
113 s->code_ptr += 4;
114}
115
116/* label relocation processing */
117
a5ad5916
SW
118static void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
119 int label_index, long addend)
c896fe29
FB
120{
121 TCGLabel *l;
122 TCGRelocation *r;
123
124 l = &s->labels[label_index];
125 if (l->has_value) {
623e265c
PB
126 /* FIXME: This may break relocations on RISC targets that
127 modify instruction fields in place. The caller may not have
128 written the initial value. */
f54b3f92 129 patch_reloc(code_ptr, type, l->u.value, addend);
c896fe29
FB
130 } else {
131 /* add a new relocation entry */
132 r = tcg_malloc(sizeof(TCGRelocation));
133 r->type = type;
134 r->ptr = code_ptr;
135 r->addend = addend;
136 r->next = l->u.first_reloc;
137 l->u.first_reloc = r;
138 }
139}
140
9d6fca70 141static void tcg_out_label(TCGContext *s, int label_index, void *ptr)
c896fe29
FB
142{
143 TCGLabel *l;
144 TCGRelocation *r;
9d6fca70 145 tcg_target_long value = (tcg_target_long)ptr;
c896fe29
FB
146
147 l = &s->labels[label_index];
148 if (l->has_value)
149 tcg_abort();
150 r = l->u.first_reloc;
151 while (r != NULL) {
f54b3f92 152 patch_reloc(r->ptr, r->type, value, r->addend);
c896fe29
FB
153 r = r->next;
154 }
155 l->has_value = 1;
156 l->u.value = value;
157}
158
159int gen_new_label(void)
160{
161 TCGContext *s = &tcg_ctx;
162 int idx;
163 TCGLabel *l;
164
165 if (s->nb_labels >= TCG_MAX_LABELS)
166 tcg_abort();
167 idx = s->nb_labels++;
168 l = &s->labels[idx];
169 l->has_value = 0;
170 l->u.first_reloc = NULL;
171 return idx;
172}
173
174#include "tcg-target.c"
175
c896fe29
FB
176/* pool based memory allocation */
177void *tcg_malloc_internal(TCGContext *s, int size)
178{
179 TCGPool *p;
180 int pool_size;
181
182 if (size > TCG_POOL_CHUNK_SIZE) {
183 /* big malloc: insert a new pool (XXX: could optimize) */
7267c094 184 p = g_malloc(sizeof(TCGPool) + size);
c896fe29 185 p->size = size;
4055299e
KB
186 p->next = s->pool_first_large;
187 s->pool_first_large = p;
188 return p->data;
c896fe29
FB
189 } else {
190 p = s->pool_current;
191 if (!p) {
192 p = s->pool_first;
193 if (!p)
194 goto new_pool;
195 } else {
196 if (!p->next) {
197 new_pool:
198 pool_size = TCG_POOL_CHUNK_SIZE;
7267c094 199 p = g_malloc(sizeof(TCGPool) + pool_size);
c896fe29
FB
200 p->size = pool_size;
201 p->next = NULL;
202 if (s->pool_current)
203 s->pool_current->next = p;
204 else
205 s->pool_first = p;
206 } else {
207 p = p->next;
208 }
209 }
210 }
211 s->pool_current = p;
212 s->pool_cur = p->data + size;
213 s->pool_end = p->data + p->size;
214 return p->data;
215}
216
217void tcg_pool_reset(TCGContext *s)
218{
4055299e
KB
219 TCGPool *p, *t;
220 for (p = s->pool_first_large; p; p = t) {
221 t = p->next;
222 g_free(p);
223 }
224 s->pool_first_large = NULL;
c896fe29
FB
225 s->pool_cur = s->pool_end = NULL;
226 s->pool_current = NULL;
227}
228
c896fe29
FB
229void tcg_context_init(TCGContext *s)
230{
231 int op, total_args, n;
232 TCGOpDef *def;
233 TCGArgConstraint *args_ct;
234 int *sorted_args;
235
236 memset(s, 0, sizeof(*s));
c896fe29
FB
237 s->nb_globals = 0;
238
239 /* Count total number of arguments and allocate the corresponding
240 space */
241 total_args = 0;
242 for(op = 0; op < NB_OPS; op++) {
243 def = &tcg_op_defs[op];
244 n = def->nb_iargs + def->nb_oargs;
245 total_args += n;
246 }
247
7267c094
AL
248 args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args);
249 sorted_args = g_malloc(sizeof(int) * total_args);
c896fe29
FB
250
251 for(op = 0; op < NB_OPS; op++) {
252 def = &tcg_op_defs[op];
253 def->args_ct = args_ct;
254 def->sorted_args = sorted_args;
255 n = def->nb_iargs + def->nb_oargs;
256 sorted_args += n;
257 args_ct += n;
258 }
259
260 tcg_target_init(s);
9002ec79 261}
b03cce8e 262
9002ec79
RH
263void tcg_prologue_init(TCGContext *s)
264{
b03cce8e 265 /* init global prologue and epilogue */
0b0d3320 266 s->code_buf = s->code_gen_prologue;
b03cce8e
FB
267 s->code_ptr = s->code_buf;
268 tcg_target_qemu_prologue(s);
2aeabc08
SW
269 flush_icache_range((tcg_target_ulong)s->code_buf,
270 (tcg_target_ulong)s->code_ptr);
d6b64b2b
RH
271
272#ifdef DEBUG_DISAS
273 if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
274 size_t size = s->code_ptr - s->code_buf;
275 qemu_log("PROLOGUE: [size=%zu]\n", size);
276 log_disas(s->code_buf, size);
277 qemu_log("\n");
278 qemu_log_flush();
279 }
280#endif
c896fe29
FB
281}
282
283void tcg_set_frame(TCGContext *s, int reg,
284 tcg_target_long start, tcg_target_long size)
285{
286 s->frame_start = start;
287 s->frame_end = start + size;
288 s->frame_reg = reg;
289}
290
c896fe29
FB
291void tcg_func_start(TCGContext *s)
292{
e8996ee0 293 int i;
c896fe29
FB
294 tcg_pool_reset(s);
295 s->nb_temps = s->nb_globals;
641d5fbe 296 for(i = 0; i < (TCG_TYPE_COUNT * 2); i++)
e8996ee0 297 s->first_free_temp[i] = -1;
c896fe29
FB
298 s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
299 s->nb_labels = 0;
300 s->current_frame_offset = s->frame_start;
301
0a209d4b
RH
302#ifdef CONFIG_DEBUG_TCG
303 s->goto_tb_issue_mask = 0;
304#endif
305
92414b31 306 s->gen_opc_ptr = s->gen_opc_buf;
1ff0a2c5 307 s->gen_opparam_ptr = s->gen_opparam_buf;
b76f0d8c
YL
308
309#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU)
310 /* Initialize qemu_ld/st labels to assist code generation at the end of TB
311 for TLB miss cases at the end of TB */
312 s->qemu_ldst_labels = tcg_malloc(sizeof(TCGLabelQemuLdst) *
313 TCG_MAX_QEMU_LDST);
314 s->nb_qemu_ldst_labels = 0;
315#endif
c896fe29
FB
316}
317
318static inline void tcg_temp_alloc(TCGContext *s, int n)
319{
320 if (n > TCG_MAX_TEMPS)
321 tcg_abort();
322}
323
a7812ae4
PB
324static inline int tcg_global_reg_new_internal(TCGType type, int reg,
325 const char *name)
c896fe29
FB
326{
327 TCGContext *s = &tcg_ctx;
328 TCGTemp *ts;
329 int idx;
330
331#if TCG_TARGET_REG_BITS == 32
332 if (type != TCG_TYPE_I32)
333 tcg_abort();
334#endif
335 if (tcg_regset_test_reg(s->reserved_regs, reg))
336 tcg_abort();
337 idx = s->nb_globals;
338 tcg_temp_alloc(s, s->nb_globals + 1);
339 ts = &s->temps[s->nb_globals];
340 ts->base_type = type;
341 ts->type = type;
342 ts->fixed_reg = 1;
343 ts->reg = reg;
c896fe29
FB
344 ts->name = name;
345 s->nb_globals++;
346 tcg_regset_set_reg(s->reserved_regs, reg);
a7812ae4
PB
347 return idx;
348}
349
350TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
351{
352 int idx;
353
354 idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name);
355 return MAKE_TCGV_I32(idx);
356}
357
358TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
359{
360 int idx;
361
362 idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);
363 return MAKE_TCGV_I64(idx);
c896fe29
FB
364}
365
a7812ae4
PB
366static inline int tcg_global_mem_new_internal(TCGType type, int reg,
367 tcg_target_long offset,
368 const char *name)
c896fe29
FB
369{
370 TCGContext *s = &tcg_ctx;
371 TCGTemp *ts;
372 int idx;
373
374 idx = s->nb_globals;
375#if TCG_TARGET_REG_BITS == 32
376 if (type == TCG_TYPE_I64) {
377 char buf[64];
c588979b 378 tcg_temp_alloc(s, s->nb_globals + 2);
c896fe29
FB
379 ts = &s->temps[s->nb_globals];
380 ts->base_type = type;
381 ts->type = TCG_TYPE_I32;
382 ts->fixed_reg = 0;
383 ts->mem_allocated = 1;
384 ts->mem_reg = reg;
385#ifdef TCG_TARGET_WORDS_BIGENDIAN
386 ts->mem_offset = offset + 4;
387#else
388 ts->mem_offset = offset;
389#endif
c896fe29
FB
390 pstrcpy(buf, sizeof(buf), name);
391 pstrcat(buf, sizeof(buf), "_0");
392 ts->name = strdup(buf);
393 ts++;
394
395 ts->base_type = type;
396 ts->type = TCG_TYPE_I32;
397 ts->fixed_reg = 0;
398 ts->mem_allocated = 1;
399 ts->mem_reg = reg;
400#ifdef TCG_TARGET_WORDS_BIGENDIAN
401 ts->mem_offset = offset;
402#else
403 ts->mem_offset = offset + 4;
404#endif
c896fe29
FB
405 pstrcpy(buf, sizeof(buf), name);
406 pstrcat(buf, sizeof(buf), "_1");
407 ts->name = strdup(buf);
408
409 s->nb_globals += 2;
410 } else
411#endif
412 {
413 tcg_temp_alloc(s, s->nb_globals + 1);
414 ts = &s->temps[s->nb_globals];
415 ts->base_type = type;
416 ts->type = type;
417 ts->fixed_reg = 0;
418 ts->mem_allocated = 1;
419 ts->mem_reg = reg;
420 ts->mem_offset = offset;
c896fe29
FB
421 ts->name = name;
422 s->nb_globals++;
423 }
a7812ae4
PB
424 return idx;
425}
426
427TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
428 const char *name)
429{
430 int idx;
431
432 idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
433 return MAKE_TCGV_I32(idx);
434}
435
436TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
437 const char *name)
438{
439 int idx;
440
441 idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
442 return MAKE_TCGV_I64(idx);
c896fe29
FB
443}
444
a7812ae4 445static inline int tcg_temp_new_internal(TCGType type, int temp_local)
c896fe29
FB
446{
447 TCGContext *s = &tcg_ctx;
448 TCGTemp *ts;
641d5fbe 449 int idx, k;
c896fe29 450
641d5fbe
FB
451 k = type;
452 if (temp_local)
453 k += TCG_TYPE_COUNT;
454 idx = s->first_free_temp[k];
e8996ee0
FB
455 if (idx != -1) {
456 /* There is already an available temp with the
457 right type */
458 ts = &s->temps[idx];
641d5fbe 459 s->first_free_temp[k] = ts->next_free_temp;
e8996ee0 460 ts->temp_allocated = 1;
641d5fbe 461 assert(ts->temp_local == temp_local);
e8996ee0
FB
462 } else {
463 idx = s->nb_temps;
c896fe29 464#if TCG_TARGET_REG_BITS == 32
e8996ee0 465 if (type == TCG_TYPE_I64) {
8df1ca4b 466 tcg_temp_alloc(s, s->nb_temps + 2);
e8996ee0
FB
467 ts = &s->temps[s->nb_temps];
468 ts->base_type = type;
469 ts->type = TCG_TYPE_I32;
470 ts->temp_allocated = 1;
641d5fbe 471 ts->temp_local = temp_local;
e8996ee0
FB
472 ts->name = NULL;
473 ts++;
474 ts->base_type = TCG_TYPE_I32;
475 ts->type = TCG_TYPE_I32;
476 ts->temp_allocated = 1;
641d5fbe 477 ts->temp_local = temp_local;
e8996ee0
FB
478 ts->name = NULL;
479 s->nb_temps += 2;
480 } else
c896fe29 481#endif
e8996ee0
FB
482 {
483 tcg_temp_alloc(s, s->nb_temps + 1);
484 ts = &s->temps[s->nb_temps];
485 ts->base_type = type;
486 ts->type = type;
487 ts->temp_allocated = 1;
641d5fbe 488 ts->temp_local = temp_local;
e8996ee0
FB
489 ts->name = NULL;
490 s->nb_temps++;
491 }
c896fe29 492 }
27bfd83c
PM
493
494#if defined(CONFIG_DEBUG_TCG)
495 s->temps_in_use++;
496#endif
a7812ae4 497 return idx;
c896fe29
FB
498}
499
a7812ae4
PB
500TCGv_i32 tcg_temp_new_internal_i32(int temp_local)
501{
502 int idx;
503
504 idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
505 return MAKE_TCGV_I32(idx);
506}
507
508TCGv_i64 tcg_temp_new_internal_i64(int temp_local)
509{
510 int idx;
511
512 idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
513 return MAKE_TCGV_I64(idx);
514}
515
516static inline void tcg_temp_free_internal(int idx)
c896fe29
FB
517{
518 TCGContext *s = &tcg_ctx;
519 TCGTemp *ts;
641d5fbe 520 int k;
c896fe29 521
27bfd83c
PM
522#if defined(CONFIG_DEBUG_TCG)
523 s->temps_in_use--;
524 if (s->temps_in_use < 0) {
525 fprintf(stderr, "More temporaries freed than allocated!\n");
526 }
527#endif
528
e8996ee0 529 assert(idx >= s->nb_globals && idx < s->nb_temps);
c896fe29 530 ts = &s->temps[idx];
e8996ee0
FB
531 assert(ts->temp_allocated != 0);
532 ts->temp_allocated = 0;
641d5fbe
FB
533 k = ts->base_type;
534 if (ts->temp_local)
535 k += TCG_TYPE_COUNT;
536 ts->next_free_temp = s->first_free_temp[k];
537 s->first_free_temp[k] = idx;
c896fe29
FB
538}
539
a7812ae4
PB
540void tcg_temp_free_i32(TCGv_i32 arg)
541{
542 tcg_temp_free_internal(GET_TCGV_I32(arg));
543}
544
545void tcg_temp_free_i64(TCGv_i64 arg)
546{
547 tcg_temp_free_internal(GET_TCGV_I64(arg));
548}
e8996ee0 549
a7812ae4 550TCGv_i32 tcg_const_i32(int32_t val)
c896fe29 551{
a7812ae4
PB
552 TCGv_i32 t0;
553 t0 = tcg_temp_new_i32();
e8996ee0
FB
554 tcg_gen_movi_i32(t0, val);
555 return t0;
556}
c896fe29 557
a7812ae4 558TCGv_i64 tcg_const_i64(int64_t val)
e8996ee0 559{
a7812ae4
PB
560 TCGv_i64 t0;
561 t0 = tcg_temp_new_i64();
e8996ee0
FB
562 tcg_gen_movi_i64(t0, val);
563 return t0;
c896fe29
FB
564}
565
a7812ae4 566TCGv_i32 tcg_const_local_i32(int32_t val)
bdffd4a9 567{
a7812ae4
PB
568 TCGv_i32 t0;
569 t0 = tcg_temp_local_new_i32();
bdffd4a9
AJ
570 tcg_gen_movi_i32(t0, val);
571 return t0;
572}
573
a7812ae4 574TCGv_i64 tcg_const_local_i64(int64_t val)
bdffd4a9 575{
a7812ae4
PB
576 TCGv_i64 t0;
577 t0 = tcg_temp_local_new_i64();
bdffd4a9
AJ
578 tcg_gen_movi_i64(t0, val);
579 return t0;
580}
581
27bfd83c
PM
582#if defined(CONFIG_DEBUG_TCG)
583void tcg_clear_temp_count(void)
584{
585 TCGContext *s = &tcg_ctx;
586 s->temps_in_use = 0;
587}
588
589int tcg_check_temp_count(void)
590{
591 TCGContext *s = &tcg_ctx;
592 if (s->temps_in_use) {
593 /* Clear the count so that we don't give another
594 * warning immediately next time around.
595 */
596 s->temps_in_use = 0;
597 return 1;
598 }
599 return 0;
600}
601#endif
602
c896fe29
FB
603void tcg_register_helper(void *func, const char *name)
604{
605 TCGContext *s = &tcg_ctx;
606 int n;
607 if ((s->nb_helpers + 1) > s->allocated_helpers) {
608 n = s->allocated_helpers;
609 if (n == 0) {
610 n = 4;
611 } else {
612 n *= 2;
613 }
614 s->helpers = realloc(s->helpers, n * sizeof(TCGHelperInfo));
615 s->allocated_helpers = n;
616 }
4dc81f28 617 s->helpers[s->nb_helpers].func = (tcg_target_ulong)func;
c896fe29
FB
618 s->helpers[s->nb_helpers].name = name;
619 s->nb_helpers++;
620}
621
39cf05d3
FB
622/* Note: we convert the 64 bit args to 32 bit and do some alignment
623 and endian swap. Maybe it would be better to do the alignment
624 and endian swap in tcg_reg_alloc_call(). */
a7812ae4
PB
625void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
626 int sizemask, TCGArg ret, int nargs, TCGArg *args)
c896fe29 627{
a7812ae4
PB
628 int i;
629 int real_args;
630 int nb_rets;
631 TCGArg *nparam;
2bece2c8
RH
632
633#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
634 for (i = 0; i < nargs; ++i) {
635 int is_64bit = sizemask & (1 << (i+1)*2);
636 int is_signed = sizemask & (2 << (i+1)*2);
637 if (!is_64bit) {
638 TCGv_i64 temp = tcg_temp_new_i64();
639 TCGv_i64 orig = MAKE_TCGV_I64(args[i]);
640 if (is_signed) {
641 tcg_gen_ext32s_i64(temp, orig);
642 } else {
643 tcg_gen_ext32u_i64(temp, orig);
644 }
645 args[i] = GET_TCGV_I64(temp);
646 }
647 }
648#endif /* TCG_TARGET_EXTEND_ARGS */
649
efd7f486 650 *s->gen_opc_ptr++ = INDEX_op_call;
c4afe5c4 651 nparam = s->gen_opparam_ptr++;
a7812ae4
PB
652 if (ret != TCG_CALL_DUMMY_ARG) {
653#if TCG_TARGET_REG_BITS < 64
654 if (sizemask & 1) {
39cf05d3 655#ifdef TCG_TARGET_WORDS_BIGENDIAN
c4afe5c4
EV
656 *s->gen_opparam_ptr++ = ret + 1;
657 *s->gen_opparam_ptr++ = ret;
39cf05d3 658#else
c4afe5c4
EV
659 *s->gen_opparam_ptr++ = ret;
660 *s->gen_opparam_ptr++ = ret + 1;
39cf05d3 661#endif
a7812ae4
PB
662 nb_rets = 2;
663 } else
664#endif
665 {
c4afe5c4 666 *s->gen_opparam_ptr++ = ret;
a7812ae4 667 nb_rets = 1;
c896fe29 668 }
a7812ae4
PB
669 } else {
670 nb_rets = 0;
c896fe29 671 }
a7812ae4
PB
672 real_args = 0;
673 for (i = 0; i < nargs; i++) {
674#if TCG_TARGET_REG_BITS < 64
2bece2c8
RH
675 int is_64bit = sizemask & (1 << (i+1)*2);
676 if (is_64bit) {
39cf05d3
FB
677#ifdef TCG_TARGET_CALL_ALIGN_ARGS
678 /* some targets want aligned 64 bit args */
ebd486d5 679 if (real_args & 1) {
c4afe5c4 680 *s->gen_opparam_ptr++ = TCG_CALL_DUMMY_ARG;
ebd486d5 681 real_args++;
39cf05d3
FB
682 }
683#endif
3f90f252
RH
684 /* If stack grows up, then we will be placing successive
685 arguments at lower addresses, which means we need to
686 reverse the order compared to how we would normally
687 treat either big or little-endian. For those arguments
688 that will wind up in registers, this still works for
689 HPPA (the only current STACK_GROWSUP target) since the
690 argument registers are *also* allocated in decreasing
691 order. If another such target is added, this logic may
692 have to get more complicated to differentiate between
693 stack arguments and register arguments. */
694#if defined(TCG_TARGET_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
c4afe5c4
EV
695 *s->gen_opparam_ptr++ = args[i] + 1;
696 *s->gen_opparam_ptr++ = args[i];
c896fe29 697#else
c4afe5c4
EV
698 *s->gen_opparam_ptr++ = args[i];
699 *s->gen_opparam_ptr++ = args[i] + 1;
c896fe29 700#endif
a7812ae4 701 real_args += 2;
2bece2c8 702 continue;
c896fe29 703 }
2bece2c8
RH
704#endif /* TCG_TARGET_REG_BITS < 64 */
705
c4afe5c4 706 *s->gen_opparam_ptr++ = args[i];
2bece2c8 707 real_args++;
c896fe29 708 }
c4afe5c4 709 *s->gen_opparam_ptr++ = GET_TCGV_PTR(func);
a7812ae4 710
c4afe5c4 711 *s->gen_opparam_ptr++ = flags;
a7812ae4
PB
712
713 *nparam = (nb_rets << 16) | (real_args + 1);
714
715 /* total parameters, needed to go backward in the instruction stream */
c4afe5c4 716 *s->gen_opparam_ptr++ = 1 + nb_rets + real_args + 3;
2bece2c8
RH
717
718#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
719 for (i = 0; i < nargs; ++i) {
720 int is_64bit = sizemask & (1 << (i+1)*2);
721 if (!is_64bit) {
722 TCGv_i64 temp = MAKE_TCGV_I64(args[i]);
723 tcg_temp_free_i64(temp);
724 }
725 }
726#endif /* TCG_TARGET_EXTEND_ARGS */
c896fe29 727}
c896fe29 728
ac56dd48 729#if TCG_TARGET_REG_BITS == 32
a7812ae4 730void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
c896fe29
FB
731 int c, int right, int arith)
732{
cf60bce4 733 if (c == 0) {
a7812ae4 734 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
cf60bce4
FB
735 tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
736 } else if (c >= 32) {
c896fe29
FB
737 c -= 32;
738 if (right) {
739 if (arith) {
a7812ae4 740 tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
ac56dd48 741 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
c896fe29 742 } else {
a7812ae4 743 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
ac56dd48 744 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
c896fe29
FB
745 }
746 } else {
a7812ae4
PB
747 tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
748 tcg_gen_movi_i32(TCGV_LOW(ret), 0);
c896fe29
FB
749 }
750 } else {
a7812ae4 751 TCGv_i32 t0, t1;
c896fe29 752
a7812ae4
PB
753 t0 = tcg_temp_new_i32();
754 t1 = tcg_temp_new_i32();
c896fe29 755 if (right) {
ac56dd48 756 tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c);
c896fe29 757 if (arith)
ac56dd48 758 tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c);
a7812ae4 759 else
ac56dd48 760 tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c);
a7812ae4
PB
761 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
762 tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t0);
ac56dd48 763 tcg_gen_mov_i32(TCGV_HIGH(ret), t1);
c896fe29 764 } else {
a7812ae4 765 tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
c896fe29 766 /* Note: ret can be the same as arg1, so we use t1 */
a7812ae4 767 tcg_gen_shli_i32(t1, TCGV_LOW(arg1), c);
ac56dd48
PB
768 tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
769 tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
a7812ae4 770 tcg_gen_mov_i32(TCGV_LOW(ret), t1);
c896fe29 771 }
a7812ae4
PB
772 tcg_temp_free_i32(t0);
773 tcg_temp_free_i32(t1);
c896fe29
FB
774 }
775}
ac56dd48 776#endif
c896fe29 777
be210acb 778
8fcd3692 779static void tcg_reg_alloc_start(TCGContext *s)
c896fe29
FB
780{
781 int i;
782 TCGTemp *ts;
783 for(i = 0; i < s->nb_globals; i++) {
784 ts = &s->temps[i];
785 if (ts->fixed_reg) {
786 ts->val_type = TEMP_VAL_REG;
787 } else {
788 ts->val_type = TEMP_VAL_MEM;
789 }
790 }
e8996ee0
FB
791 for(i = s->nb_globals; i < s->nb_temps; i++) {
792 ts = &s->temps[i];
7dfd8c6a
AJ
793 if (ts->temp_local) {
794 ts->val_type = TEMP_VAL_MEM;
795 } else {
796 ts->val_type = TEMP_VAL_DEAD;
797 }
e8996ee0
FB
798 ts->mem_allocated = 0;
799 ts->fixed_reg = 0;
800 }
c896fe29
FB
801 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
802 s->reg_to_temp[i] = -1;
803 }
804}
805
ac56dd48
PB
806static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
807 int idx)
c896fe29
FB
808{
809 TCGTemp *ts;
ac56dd48 810
7f6f0ae5 811 assert(idx >= 0 && idx < s->nb_temps);
ac56dd48
PB
812 ts = &s->temps[idx];
813 if (idx < s->nb_globals) {
814 pstrcpy(buf, buf_size, ts->name);
c896fe29 815 } else {
641d5fbe
FB
816 if (ts->temp_local)
817 snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
818 else
819 snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
c896fe29
FB
820 }
821 return buf;
822}
823
a7812ae4
PB
824char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg)
825{
826 return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg));
827}
828
829char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg)
ac56dd48 830{
a810a2de 831 return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg));
ac56dd48
PB
832}
833
e8996ee0 834static int helper_cmp(const void *p1, const void *p2)
4dc81f28 835{
e8996ee0
FB
836 const TCGHelperInfo *th1 = p1;
837 const TCGHelperInfo *th2 = p2;
838 if (th1->func < th2->func)
839 return -1;
840 else if (th1->func == th2->func)
841 return 0;
842 else
843 return 1;
4dc81f28
FB
844}
845
e8996ee0
FB
846/* find helper definition (Note: A hash table would be better) */
847static TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val)
4dc81f28 848{
e8996ee0 849 int m, m_min, m_max;
4dc81f28 850 TCGHelperInfo *th;
e8996ee0 851 tcg_target_ulong v;
4dc81f28 852
e8996ee0
FB
853 if (unlikely(!s->helpers_sorted)) {
854 qsort(s->helpers, s->nb_helpers, sizeof(TCGHelperInfo),
855 helper_cmp);
856 s->helpers_sorted = 1;
857 }
858
859 /* binary search */
860 m_min = 0;
861 m_max = s->nb_helpers - 1;
862 while (m_min <= m_max) {
863 m = (m_min + m_max) >> 1;
864 th = &s->helpers[m];
865 v = th->func;
866 if (v == val)
867 return th;
868 else if (val < v) {
869 m_max = m - 1;
870 } else {
871 m_min = m + 1;
4dc81f28
FB
872 }
873 }
e8996ee0 874 return NULL;
4dc81f28
FB
875}
876
f48f3ede
BS
877static const char * const cond_name[] =
878{
0aed257f
RH
879 [TCG_COND_NEVER] = "never",
880 [TCG_COND_ALWAYS] = "always",
f48f3ede
BS
881 [TCG_COND_EQ] = "eq",
882 [TCG_COND_NE] = "ne",
883 [TCG_COND_LT] = "lt",
884 [TCG_COND_GE] = "ge",
885 [TCG_COND_LE] = "le",
886 [TCG_COND_GT] = "gt",
887 [TCG_COND_LTU] = "ltu",
888 [TCG_COND_GEU] = "geu",
889 [TCG_COND_LEU] = "leu",
890 [TCG_COND_GTU] = "gtu"
891};
892
eeacee4d 893void tcg_dump_ops(TCGContext *s)
c896fe29
FB
894{
895 const uint16_t *opc_ptr;
896 const TCGArg *args;
897 TCGArg arg;
a9751609
RH
898 TCGOpcode c;
899 int i, k, nb_oargs, nb_iargs, nb_cargs, first_insn;
c896fe29
FB
900 const TCGOpDef *def;
901 char buf[128];
902
7e4597d7 903 first_insn = 1;
92414b31 904 opc_ptr = s->gen_opc_buf;
1ff0a2c5 905 args = s->gen_opparam_buf;
efd7f486 906 while (opc_ptr < s->gen_opc_ptr) {
c896fe29
FB
907 c = *opc_ptr++;
908 def = &tcg_op_defs[c];
7e4597d7
FB
909 if (c == INDEX_op_debug_insn_start) {
910 uint64_t pc;
911#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
912 pc = ((uint64_t)args[1] << 32) | args[0];
913#else
914 pc = args[0];
915#endif
eeacee4d
BS
916 if (!first_insn) {
917 qemu_log("\n");
918 }
919 qemu_log(" ---- 0x%" PRIx64, pc);
7e4597d7
FB
920 first_insn = 0;
921 nb_oargs = def->nb_oargs;
922 nb_iargs = def->nb_iargs;
923 nb_cargs = def->nb_cargs;
924 } else if (c == INDEX_op_call) {
c896fe29 925 TCGArg arg;
4dc81f28 926
c896fe29
FB
927 /* variable number of arguments */
928 arg = *args++;
929 nb_oargs = arg >> 16;
930 nb_iargs = arg & 0xffff;
931 nb_cargs = def->nb_cargs;
c896fe29 932
eeacee4d 933 qemu_log(" %s ", def->name);
7e4597d7 934
b03cce8e 935 /* function name */
eeacee4d
BS
936 qemu_log("%s",
937 tcg_get_arg_str_idx(s, buf, sizeof(buf),
938 args[nb_oargs + nb_iargs - 1]));
b03cce8e 939 /* flags */
eeacee4d 940 qemu_log(",$0x%" TCG_PRIlx, args[nb_oargs + nb_iargs]);
b03cce8e 941 /* nb out args */
eeacee4d 942 qemu_log(",$%d", nb_oargs);
b03cce8e 943 for(i = 0; i < nb_oargs; i++) {
eeacee4d
BS
944 qemu_log(",");
945 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
946 args[i]));
b03cce8e
FB
947 }
948 for(i = 0; i < (nb_iargs - 1); i++) {
eeacee4d 949 qemu_log(",");
39cf05d3 950 if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) {
eeacee4d 951 qemu_log("<dummy>");
39cf05d3 952 } else {
eeacee4d
BS
953 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
954 args[nb_oargs + i]));
39cf05d3 955 }
b03cce8e 956 }
fba3161f 957 } else if (c == INDEX_op_movi_i32 || c == INDEX_op_movi_i64) {
e8996ee0
FB
958 tcg_target_ulong val;
959 TCGHelperInfo *th;
960
961 nb_oargs = def->nb_oargs;
962 nb_iargs = def->nb_iargs;
963 nb_cargs = def->nb_cargs;
eeacee4d
BS
964 qemu_log(" %s %s,$", def->name,
965 tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
e8996ee0
FB
966 val = args[1];
967 th = tcg_find_helper(s, val);
968 if (th) {
eeacee4d 969 qemu_log("%s", th->name);
e8996ee0 970 } else {
eeacee4d
BS
971 if (c == INDEX_op_movi_i32) {
972 qemu_log("0x%x", (uint32_t)val);
973 } else {
974 qemu_log("0x%" PRIx64 , (uint64_t)val);
975 }
e8996ee0 976 }
b03cce8e 977 } else {
eeacee4d 978 qemu_log(" %s ", def->name);
b03cce8e
FB
979 if (c == INDEX_op_nopn) {
980 /* variable number of arguments */
981 nb_cargs = *args;
982 nb_oargs = 0;
983 nb_iargs = 0;
984 } else {
985 nb_oargs = def->nb_oargs;
986 nb_iargs = def->nb_iargs;
987 nb_cargs = def->nb_cargs;
988 }
989
990 k = 0;
991 for(i = 0; i < nb_oargs; i++) {
eeacee4d
BS
992 if (k != 0) {
993 qemu_log(",");
994 }
995 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
996 args[k++]));
b03cce8e
FB
997 }
998 for(i = 0; i < nb_iargs; i++) {
eeacee4d
BS
999 if (k != 0) {
1000 qemu_log(",");
1001 }
1002 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
1003 args[k++]));
b03cce8e 1004 }
be210acb
RH
1005 switch (c) {
1006 case INDEX_op_brcond_i32:
be210acb 1007 case INDEX_op_setcond_i32:
ffc5ea09 1008 case INDEX_op_movcond_i32:
ffc5ea09 1009 case INDEX_op_brcond2_i32:
be210acb 1010 case INDEX_op_setcond2_i32:
ffc5ea09 1011 case INDEX_op_brcond_i64:
be210acb 1012 case INDEX_op_setcond_i64:
ffc5ea09 1013 case INDEX_op_movcond_i64:
eeacee4d
BS
1014 if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) {
1015 qemu_log(",%s", cond_name[args[k++]]);
1016 } else {
1017 qemu_log(",$0x%" TCG_PRIlx, args[k++]);
1018 }
f48f3ede 1019 i = 1;
be210acb
RH
1020 break;
1021 default:
f48f3ede 1022 i = 0;
be210acb
RH
1023 break;
1024 }
f48f3ede 1025 for(; i < nb_cargs; i++) {
eeacee4d
BS
1026 if (k != 0) {
1027 qemu_log(",");
1028 }
b03cce8e 1029 arg = args[k++];
eeacee4d 1030 qemu_log("$0x%" TCG_PRIlx, arg);
b03cce8e 1031 }
c896fe29 1032 }
eeacee4d 1033 qemu_log("\n");
c896fe29
FB
1034 args += nb_iargs + nb_oargs + nb_cargs;
1035 }
1036}
1037
1038/* we give more priority to constraints with less registers */
1039static int get_constraint_priority(const TCGOpDef *def, int k)
1040{
1041 const TCGArgConstraint *arg_ct;
1042
1043 int i, n;
1044 arg_ct = &def->args_ct[k];
1045 if (arg_ct->ct & TCG_CT_ALIAS) {
1046 /* an alias is equivalent to a single register */
1047 n = 1;
1048 } else {
1049 if (!(arg_ct->ct & TCG_CT_REG))
1050 return 0;
1051 n = 0;
1052 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1053 if (tcg_regset_test_reg(arg_ct->u.regs, i))
1054 n++;
1055 }
1056 }
1057 return TCG_TARGET_NB_REGS - n + 1;
1058}
1059
1060/* sort from highest priority to lowest */
1061static void sort_constraints(TCGOpDef *def, int start, int n)
1062{
1063 int i, j, p1, p2, tmp;
1064
1065 for(i = 0; i < n; i++)
1066 def->sorted_args[start + i] = start + i;
1067 if (n <= 1)
1068 return;
1069 for(i = 0; i < n - 1; i++) {
1070 for(j = i + 1; j < n; j++) {
1071 p1 = get_constraint_priority(def, def->sorted_args[start + i]);
1072 p2 = get_constraint_priority(def, def->sorted_args[start + j]);
1073 if (p1 < p2) {
1074 tmp = def->sorted_args[start + i];
1075 def->sorted_args[start + i] = def->sorted_args[start + j];
1076 def->sorted_args[start + j] = tmp;
1077 }
1078 }
1079 }
1080}
1081
1082void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
1083{
a9751609 1084 TCGOpcode op;
c896fe29
FB
1085 TCGOpDef *def;
1086 const char *ct_str;
1087 int i, nb_args;
1088
1089 for(;;) {
a9751609 1090 if (tdefs->op == (TCGOpcode)-1)
c896fe29
FB
1091 break;
1092 op = tdefs->op;
c3b08d0e 1093 assert((unsigned)op < NB_OPS);
c896fe29 1094 def = &tcg_op_defs[op];
c68aaa18
SW
1095#if defined(CONFIG_DEBUG_TCG)
1096 /* Duplicate entry in op definitions? */
1097 assert(!def->used);
1098 def->used = 1;
1099#endif
c896fe29
FB
1100 nb_args = def->nb_iargs + def->nb_oargs;
1101 for(i = 0; i < nb_args; i++) {
1102 ct_str = tdefs->args_ct_str[i];
c68aaa18
SW
1103 /* Incomplete TCGTargetOpDef entry? */
1104 assert(ct_str != NULL);
c896fe29
FB
1105 tcg_regset_clear(def->args_ct[i].u.regs);
1106 def->args_ct[i].ct = 0;
1107 if (ct_str[0] >= '0' && ct_str[0] <= '9') {
1108 int oarg;
1109 oarg = ct_str[0] - '0';
1110 assert(oarg < def->nb_oargs);
1111 assert(def->args_ct[oarg].ct & TCG_CT_REG);
1112 /* TCG_CT_ALIAS is for the output arguments. The input
5ff9d6a4 1113 argument is tagged with TCG_CT_IALIAS. */
c896fe29 1114 def->args_ct[i] = def->args_ct[oarg];
5ff9d6a4
FB
1115 def->args_ct[oarg].ct = TCG_CT_ALIAS;
1116 def->args_ct[oarg].alias_index = i;
c896fe29 1117 def->args_ct[i].ct |= TCG_CT_IALIAS;
5ff9d6a4 1118 def->args_ct[i].alias_index = oarg;
c896fe29
FB
1119 } else {
1120 for(;;) {
1121 if (*ct_str == '\0')
1122 break;
1123 switch(*ct_str) {
1124 case 'i':
1125 def->args_ct[i].ct |= TCG_CT_CONST;
1126 ct_str++;
1127 break;
1128 default:
1129 if (target_parse_constraint(&def->args_ct[i], &ct_str) < 0) {
1130 fprintf(stderr, "Invalid constraint '%s' for arg %d of operation '%s'\n",
1131 ct_str, i, def->name);
1132 exit(1);
1133 }
1134 }
1135 }
1136 }
1137 }
1138
c68aaa18
SW
1139 /* TCGTargetOpDef entry with too much information? */
1140 assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL);
1141
c896fe29
FB
1142 /* sort the constraints (XXX: this is just an heuristic) */
1143 sort_constraints(def, 0, def->nb_oargs);
1144 sort_constraints(def, def->nb_oargs, def->nb_iargs);
1145
1146#if 0
1147 {
1148 int i;
1149
1150 printf("%s: sorted=", def->name);
1151 for(i = 0; i < def->nb_oargs + def->nb_iargs; i++)
1152 printf(" %d", def->sorted_args[i]);
1153 printf("\n");
1154 }
1155#endif
1156 tdefs++;
1157 }
1158
c68aaa18 1159#if defined(CONFIG_DEBUG_TCG)
a9751609 1160 i = 0;
c68aaa18 1161 for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) {
f412c762 1162 const TCGOpDef *def = &tcg_op_defs[op];
c1a61f6c 1163 if (def->flags & TCG_OPF_NOT_PRESENT) {
c68aaa18 1164 /* Wrong entry in op definitions? */
f412c762
RH
1165 if (def->used) {
1166 fprintf(stderr, "Invalid op definition for %s\n", def->name);
a9751609
RH
1167 i = 1;
1168 }
c68aaa18
SW
1169 } else {
1170 /* Missing entry in op definitions? */
f412c762
RH
1171 if (!def->used) {
1172 fprintf(stderr, "Missing op definition for %s\n", def->name);
a9751609
RH
1173 i = 1;
1174 }
c68aaa18
SW
1175 }
1176 }
a9751609
RH
1177 if (i == 1) {
1178 tcg_abort();
1179 }
c68aaa18 1180#endif
c896fe29
FB
1181}
1182
1183#ifdef USE_LIVENESS_ANALYSIS
1184
1185/* set a nop for an operation using 'nb_args' */
1186static inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr,
1187 TCGArg *args, int nb_args)
1188{
1189 if (nb_args == 0) {
1190 *opc_ptr = INDEX_op_nop;
1191 } else {
1192 *opc_ptr = INDEX_op_nopn;
1193 args[0] = nb_args;
1194 args[nb_args - 1] = nb_args;
1195 }
1196}
1197
9c43b68d
AJ
1198/* liveness analysis: end of function: all temps are dead, and globals
1199 should be in memory. */
1200static inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps,
1201 uint8_t *mem_temps)
c896fe29 1202{
9c43b68d
AJ
1203 memset(dead_temps, 1, s->nb_temps);
1204 memset(mem_temps, 1, s->nb_globals);
1205 memset(mem_temps + s->nb_globals, 0, s->nb_temps - s->nb_globals);
c896fe29
FB
1206}
1207
9c43b68d
AJ
1208/* liveness analysis: end of basic block: all temps are dead, globals
1209 and local temps should be in memory. */
1210static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps,
1211 uint8_t *mem_temps)
641d5fbe
FB
1212{
1213 int i;
641d5fbe 1214
9c43b68d
AJ
1215 memset(dead_temps, 1, s->nb_temps);
1216 memset(mem_temps, 1, s->nb_globals);
641d5fbe 1217 for(i = s->nb_globals; i < s->nb_temps; i++) {
9c43b68d 1218 mem_temps[i] = s->temps[i].temp_local;
641d5fbe
FB
1219 }
1220}
1221
866cb6cb 1222/* Liveness analysis : update the opc_dead_args array to tell if a
c896fe29
FB
1223 given input arguments is dead. Instructions updating dead
1224 temporaries are removed. */
8fcd3692 1225static void tcg_liveness_analysis(TCGContext *s)
c896fe29 1226{
a9751609 1227 int i, op_index, nb_args, nb_iargs, nb_oargs, arg, nb_ops;
f1fae40c 1228 TCGOpcode op, op_new;
c896fe29
FB
1229 TCGArg *args;
1230 const TCGOpDef *def;
9c43b68d 1231 uint8_t *dead_temps, *mem_temps;
ec7a869d
AJ
1232 uint16_t dead_args;
1233 uint8_t sync_args;
c896fe29 1234
efd7f486 1235 s->gen_opc_ptr++; /* skip end */
c896fe29 1236
92414b31 1237 nb_ops = s->gen_opc_ptr - s->gen_opc_buf;
c896fe29 1238
866cb6cb 1239 s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
ec7a869d 1240 s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
c896fe29
FB
1241
1242 dead_temps = tcg_malloc(s->nb_temps);
9c43b68d
AJ
1243 mem_temps = tcg_malloc(s->nb_temps);
1244 tcg_la_func_end(s, dead_temps, mem_temps);
c896fe29 1245
c4afe5c4 1246 args = s->gen_opparam_ptr;
c896fe29
FB
1247 op_index = nb_ops - 1;
1248 while (op_index >= 0) {
92414b31 1249 op = s->gen_opc_buf[op_index];
c896fe29
FB
1250 def = &tcg_op_defs[op];
1251 switch(op) {
1252 case INDEX_op_call:
c6e113f5
FB
1253 {
1254 int call_flags;
c896fe29 1255
c6e113f5
FB
1256 nb_args = args[-1];
1257 args -= nb_args;
1258 nb_iargs = args[0] & 0xffff;
1259 nb_oargs = args[0] >> 16;
1260 args++;
1261 call_flags = args[nb_oargs + nb_iargs];
1262
1263 /* pure functions can be removed if their result is not
1264 used */
78505279 1265 if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
c6e113f5
FB
1266 for(i = 0; i < nb_oargs; i++) {
1267 arg = args[i];
9c43b68d 1268 if (!dead_temps[arg] || mem_temps[arg]) {
c6e113f5 1269 goto do_not_remove_call;
9c43b68d 1270 }
c6e113f5 1271 }
92414b31 1272 tcg_set_nop(s, s->gen_opc_buf + op_index,
c6e113f5
FB
1273 args - 1, nb_args);
1274 } else {
1275 do_not_remove_call:
c896fe29 1276
c6e113f5 1277 /* output args are dead */
6b64b624 1278 dead_args = 0;
ec7a869d 1279 sync_args = 0;
c6e113f5
FB
1280 for(i = 0; i < nb_oargs; i++) {
1281 arg = args[i];
6b64b624
AJ
1282 if (dead_temps[arg]) {
1283 dead_args |= (1 << i);
1284 }
9c43b68d
AJ
1285 if (mem_temps[arg]) {
1286 sync_args |= (1 << i);
1287 }
c6e113f5 1288 dead_temps[arg] = 1;
9c43b68d 1289 mem_temps[arg] = 0;
c6e113f5 1290 }
78505279
AJ
1291
1292 if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
1293 /* globals should be synced to memory */
1294 memset(mem_temps, 1, s->nb_globals);
1295 }
1296 if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
1297 TCG_CALL_NO_READ_GLOBALS))) {
9c43b68d
AJ
1298 /* globals should go back to memory */
1299 memset(dead_temps, 1, s->nb_globals);
b9c18f56
AJ
1300 }
1301
c6e113f5 1302 /* input args are live */
866cb6cb
AJ
1303 for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1304 arg = args[i];
39cf05d3
FB
1305 if (arg != TCG_CALL_DUMMY_ARG) {
1306 if (dead_temps[arg]) {
866cb6cb 1307 dead_args |= (1 << i);
39cf05d3
FB
1308 }
1309 dead_temps[arg] = 0;
c6e113f5 1310 }
c6e113f5 1311 }
866cb6cb 1312 s->op_dead_args[op_index] = dead_args;
ec7a869d 1313 s->op_sync_args[op_index] = sync_args;
c896fe29 1314 }
c6e113f5 1315 args--;
c896fe29 1316 }
c896fe29 1317 break;
7e4597d7
FB
1318 case INDEX_op_debug_insn_start:
1319 args -= def->nb_args;
1320 break;
c896fe29
FB
1321 case INDEX_op_nopn:
1322 nb_args = args[-1];
1323 args -= nb_args;
1324 break;
5ff9d6a4
FB
1325 case INDEX_op_discard:
1326 args--;
1327 /* mark the temporary as dead */
1328 dead_temps[args[0]] = 1;
9c43b68d 1329 mem_temps[args[0]] = 0;
5ff9d6a4 1330 break;
c896fe29
FB
1331 case INDEX_op_end:
1332 break;
1305c451
RH
1333
1334 case INDEX_op_add2_i32:
f1fae40c
RH
1335 op_new = INDEX_op_add_i32;
1336 goto do_addsub2;
1305c451 1337 case INDEX_op_sub2_i32:
f1fae40c
RH
1338 op_new = INDEX_op_sub_i32;
1339 goto do_addsub2;
1340 case INDEX_op_add2_i64:
1341 op_new = INDEX_op_add_i64;
1342 goto do_addsub2;
1343 case INDEX_op_sub2_i64:
1344 op_new = INDEX_op_sub_i64;
1345 do_addsub2:
1305c451
RH
1346 args -= 6;
1347 nb_iargs = 4;
1348 nb_oargs = 2;
1349 /* Test if the high part of the operation is dead, but not
1350 the low part. The result can be optimized to a simple
1351 add or sub. This happens often for x86_64 guest when the
1352 cpu mode is set to 32 bit. */
3c5645fa
KB
1353 if (dead_temps[args[1]] && !mem_temps[args[1]]) {
1354 if (dead_temps[args[0]] && !mem_temps[args[0]]) {
1305c451
RH
1355 goto do_remove;
1356 }
1357 /* Create the single operation plus nop. */
f1fae40c 1358 s->gen_opc_buf[op_index] = op = op_new;
1305c451
RH
1359 args[1] = args[2];
1360 args[2] = args[4];
92414b31
EV
1361 assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
1362 tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 3);
1305c451
RH
1363 /* Fall through and mark the single-word operation live. */
1364 nb_iargs = 2;
1365 nb_oargs = 1;
1366 }
1367 goto do_not_remove;
1368
1414968a 1369 case INDEX_op_mulu2_i32:
f1fae40c
RH
1370 case INDEX_op_muls2_i32:
1371 op_new = INDEX_op_mul_i32;
1372 goto do_mul2;
1373 case INDEX_op_mulu2_i64:
1374 case INDEX_op_muls2_i64:
1375 op_new = INDEX_op_mul_i64;
1376 do_mul2:
1414968a
RH
1377 args -= 4;
1378 nb_iargs = 2;
1379 nb_oargs = 2;
1380 /* Likewise, test for the high part of the operation dead. */
3c5645fa
KB
1381 if (dead_temps[args[1]] && !mem_temps[args[1]]) {
1382 if (dead_temps[args[0]] && !mem_temps[args[0]]) {
1414968a
RH
1383 goto do_remove;
1384 }
f1fae40c 1385 s->gen_opc_buf[op_index] = op = op_new;
1414968a
RH
1386 args[1] = args[2];
1387 args[2] = args[3];
92414b31
EV
1388 assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
1389 tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 1);
1414968a
RH
1390 /* Fall through and mark the single-word operation live. */
1391 nb_oargs = 1;
1392 }
1393 goto do_not_remove;
1394
c896fe29 1395 default:
1305c451 1396 /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
49516bc0
AJ
1397 args -= def->nb_args;
1398 nb_iargs = def->nb_iargs;
1399 nb_oargs = def->nb_oargs;
c896fe29 1400
49516bc0
AJ
1401 /* Test if the operation can be removed because all
1402 its outputs are dead. We assume that nb_oargs == 0
1403 implies side effects */
1404 if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
1405 for(i = 0; i < nb_oargs; i++) {
1406 arg = args[i];
9c43b68d 1407 if (!dead_temps[arg] || mem_temps[arg]) {
49516bc0 1408 goto do_not_remove;
9c43b68d 1409 }
49516bc0 1410 }
1305c451 1411 do_remove:
92414b31 1412 tcg_set_nop(s, s->gen_opc_buf + op_index, args, def->nb_args);
c896fe29 1413#ifdef CONFIG_PROFILER
49516bc0 1414 s->del_op_count++;
c896fe29 1415#endif
49516bc0
AJ
1416 } else {
1417 do_not_remove:
c896fe29 1418
49516bc0 1419 /* output args are dead */
6b64b624 1420 dead_args = 0;
ec7a869d 1421 sync_args = 0;
49516bc0
AJ
1422 for(i = 0; i < nb_oargs; i++) {
1423 arg = args[i];
6b64b624
AJ
1424 if (dead_temps[arg]) {
1425 dead_args |= (1 << i);
1426 }
9c43b68d
AJ
1427 if (mem_temps[arg]) {
1428 sync_args |= (1 << i);
1429 }
49516bc0 1430 dead_temps[arg] = 1;
9c43b68d 1431 mem_temps[arg] = 0;
49516bc0
AJ
1432 }
1433
1434 /* if end of basic block, update */
1435 if (def->flags & TCG_OPF_BB_END) {
9c43b68d 1436 tcg_la_bb_end(s, dead_temps, mem_temps);
3d5c5f87
AJ
1437 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
1438 /* globals should be synced to memory */
9c43b68d 1439 memset(mem_temps, 1, s->nb_globals);
49516bc0
AJ
1440 }
1441
1442 /* input args are live */
866cb6cb
AJ
1443 for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1444 arg = args[i];
49516bc0 1445 if (dead_temps[arg]) {
866cb6cb 1446 dead_args |= (1 << i);
c896fe29 1447 }
49516bc0 1448 dead_temps[arg] = 0;
c896fe29 1449 }
866cb6cb 1450 s->op_dead_args[op_index] = dead_args;
ec7a869d 1451 s->op_sync_args[op_index] = sync_args;
c896fe29
FB
1452 }
1453 break;
1454 }
1455 op_index--;
1456 }
1457
1ff0a2c5 1458 if (args != s->gen_opparam_buf) {
c896fe29 1459 tcg_abort();
1ff0a2c5 1460 }
c896fe29
FB
1461}
1462#else
1463/* dummy liveness analysis */
655feed5 1464static void tcg_liveness_analysis(TCGContext *s)
c896fe29
FB
1465{
1466 int nb_ops;
92414b31 1467 nb_ops = s->gen_opc_ptr - s->gen_opc_buf;
c896fe29 1468
866cb6cb
AJ
1469 s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1470 memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
ec7a869d
AJ
1471 s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
1472 memset(s->op_sync_args, 0, nb_ops * sizeof(uint8_t));
c896fe29
FB
1473}
1474#endif
1475
1476#ifndef NDEBUG
1477static void dump_regs(TCGContext *s)
1478{
1479 TCGTemp *ts;
1480 int i;
1481 char buf[64];
1482
1483 for(i = 0; i < s->nb_temps; i++) {
1484 ts = &s->temps[i];
ac56dd48 1485 printf(" %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
c896fe29
FB
1486 switch(ts->val_type) {
1487 case TEMP_VAL_REG:
1488 printf("%s", tcg_target_reg_names[ts->reg]);
1489 break;
1490 case TEMP_VAL_MEM:
1491 printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
1492 break;
1493 case TEMP_VAL_CONST:
1494 printf("$0x%" TCG_PRIlx, ts->val);
1495 break;
1496 case TEMP_VAL_DEAD:
1497 printf("D");
1498 break;
1499 default:
1500 printf("???");
1501 break;
1502 }
1503 printf("\n");
1504 }
1505
1506 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1507 if (s->reg_to_temp[i] >= 0) {
1508 printf("%s: %s\n",
1509 tcg_target_reg_names[i],
ac56dd48 1510 tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
c896fe29
FB
1511 }
1512 }
1513}
1514
1515static void check_regs(TCGContext *s)
1516{
1517 int reg, k;
1518 TCGTemp *ts;
1519 char buf[64];
1520
1521 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1522 k = s->reg_to_temp[reg];
1523 if (k >= 0) {
1524 ts = &s->temps[k];
1525 if (ts->val_type != TEMP_VAL_REG ||
1526 ts->reg != reg) {
1527 printf("Inconsistency for register %s:\n",
1528 tcg_target_reg_names[reg]);
b03cce8e 1529 goto fail;
c896fe29
FB
1530 }
1531 }
1532 }
1533 for(k = 0; k < s->nb_temps; k++) {
1534 ts = &s->temps[k];
1535 if (ts->val_type == TEMP_VAL_REG &&
1536 !ts->fixed_reg &&
1537 s->reg_to_temp[ts->reg] != k) {
1538 printf("Inconsistency for temp %s:\n",
ac56dd48 1539 tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
b03cce8e 1540 fail:
c896fe29
FB
1541 printf("reg state:\n");
1542 dump_regs(s);
1543 tcg_abort();
1544 }
1545 }
1546}
1547#endif
1548
1549static void temp_allocate_frame(TCGContext *s, int temp)
1550{
1551 TCGTemp *ts;
1552 ts = &s->temps[temp];
9b9c37c3
RH
1553#if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64)
1554 /* Sparc64 stack is accessed with offset of 2047 */
b591dc59
BS
1555 s->current_frame_offset = (s->current_frame_offset +
1556 (tcg_target_long)sizeof(tcg_target_long) - 1) &
1557 ~(sizeof(tcg_target_long) - 1);
f44c9960 1558#endif
b591dc59
BS
1559 if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
1560 s->frame_end) {
5ff9d6a4 1561 tcg_abort();
b591dc59 1562 }
c896fe29
FB
1563 ts->mem_offset = s->current_frame_offset;
1564 ts->mem_reg = s->frame_reg;
1565 ts->mem_allocated = 1;
b591dc59 1566 s->current_frame_offset += (tcg_target_long)sizeof(tcg_target_long);
c896fe29
FB
1567}
1568
7f6ceedf
AJ
1569/* sync register 'reg' by saving it to the corresponding temporary */
1570static inline void tcg_reg_sync(TCGContext *s, int reg)
1571{
1572 TCGTemp *ts;
1573 int temp;
1574
1575 temp = s->reg_to_temp[reg];
1576 ts = &s->temps[temp];
1577 assert(ts->val_type == TEMP_VAL_REG);
1578 if (!ts->mem_coherent && !ts->fixed_reg) {
1579 if (!ts->mem_allocated) {
1580 temp_allocate_frame(s, temp);
1581 }
1582 tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1583 }
1584 ts->mem_coherent = 1;
1585}
1586
c896fe29
FB
1587/* free register 'reg' by spilling the corresponding temporary if necessary */
1588static void tcg_reg_free(TCGContext *s, int reg)
1589{
c896fe29
FB
1590 int temp;
1591
1592 temp = s->reg_to_temp[reg];
1593 if (temp != -1) {
7f6ceedf
AJ
1594 tcg_reg_sync(s, reg);
1595 s->temps[temp].val_type = TEMP_VAL_MEM;
c896fe29
FB
1596 s->reg_to_temp[reg] = -1;
1597 }
1598}
1599
1600/* Allocate a register belonging to reg1 & ~reg2 */
1601static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1602{
1603 int i, reg;
1604 TCGRegSet reg_ct;
1605
1606 tcg_regset_andnot(reg_ct, reg1, reg2);
1607
1608 /* first try free registers */
0954d0d9 1609 for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
c896fe29
FB
1610 reg = tcg_target_reg_alloc_order[i];
1611 if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
1612 return reg;
1613 }
1614
1615 /* XXX: do better spill choice */
0954d0d9 1616 for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
c896fe29
FB
1617 reg = tcg_target_reg_alloc_order[i];
1618 if (tcg_regset_test_reg(reg_ct, reg)) {
1619 tcg_reg_free(s, reg);
1620 return reg;
1621 }
1622 }
1623
1624 tcg_abort();
1625}
1626
639368dd
AJ
1627/* mark a temporary as dead. */
1628static inline void temp_dead(TCGContext *s, int temp)
1629{
1630 TCGTemp *ts;
1631
1632 ts = &s->temps[temp];
1633 if (!ts->fixed_reg) {
1634 if (ts->val_type == TEMP_VAL_REG) {
1635 s->reg_to_temp[ts->reg] = -1;
1636 }
e5138db5 1637 if (temp < s->nb_globals || ts->temp_local) {
639368dd
AJ
1638 ts->val_type = TEMP_VAL_MEM;
1639 } else {
1640 ts->val_type = TEMP_VAL_DEAD;
1641 }
1642 }
1643}
1644
1ad80729 1645/* sync a temporary to memory. 'allocated_regs' is used in case a
641d5fbe 1646 temporary registers needs to be allocated to store a constant. */
1ad80729 1647static inline void temp_sync(TCGContext *s, int temp, TCGRegSet allocated_regs)
641d5fbe
FB
1648{
1649 TCGTemp *ts;
641d5fbe
FB
1650
1651 ts = &s->temps[temp];
1652 if (!ts->fixed_reg) {
1653 switch(ts->val_type) {
1ad80729
AJ
1654 case TEMP_VAL_CONST:
1655 ts->reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1656 allocated_regs);
1657 ts->val_type = TEMP_VAL_REG;
1658 s->reg_to_temp[ts->reg] = temp;
1659 ts->mem_coherent = 0;
1660 tcg_out_movi(s, ts->type, ts->reg, ts->val);
1661 /* fallthrough*/
641d5fbe 1662 case TEMP_VAL_REG:
1ad80729 1663 tcg_reg_sync(s, ts->reg);
641d5fbe
FB
1664 break;
1665 case TEMP_VAL_DEAD:
641d5fbe
FB
1666 case TEMP_VAL_MEM:
1667 break;
1668 default:
1669 tcg_abort();
1670 }
1671 }
1672}
1673
1ad80729
AJ
1674/* save a temporary to memory. 'allocated_regs' is used in case a
1675 temporary registers needs to be allocated to store a constant. */
1676static inline void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
1677{
2c0366f0
AJ
1678#ifdef USE_LIVENESS_ANALYSIS
1679 /* The liveness analysis already ensures that globals are back
1680 in memory. Keep an assert for safety. */
1681 assert(s->temps[temp].val_type == TEMP_VAL_MEM || s->temps[temp].fixed_reg);
1682#else
1ad80729
AJ
1683 temp_sync(s, temp, allocated_regs);
1684 temp_dead(s, temp);
2c0366f0 1685#endif
1ad80729
AJ
1686}
1687
9814dd27 1688/* save globals to their canonical location and assume they can be
e8996ee0
FB
1689 modified be the following code. 'allocated_regs' is used in case a
1690 temporary registers needs to be allocated to store a constant. */
1691static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
c896fe29 1692{
641d5fbe 1693 int i;
c896fe29
FB
1694
1695 for(i = 0; i < s->nb_globals; i++) {
641d5fbe 1696 temp_save(s, i, allocated_regs);
c896fe29 1697 }
e5097dc8
FB
1698}
1699
3d5c5f87
AJ
1700/* sync globals to their canonical location and assume they can be
1701 read by the following code. 'allocated_regs' is used in case a
1702 temporary registers needs to be allocated to store a constant. */
1703static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
1704{
1705 int i;
1706
1707 for (i = 0; i < s->nb_globals; i++) {
1708#ifdef USE_LIVENESS_ANALYSIS
1709 assert(s->temps[i].val_type != TEMP_VAL_REG || s->temps[i].fixed_reg ||
1710 s->temps[i].mem_coherent);
1711#else
1712 temp_sync(s, i, allocated_regs);
1713#endif
1714 }
1715}
1716
e5097dc8 1717/* at the end of a basic block, we assume all temporaries are dead and
e8996ee0
FB
1718 all globals are stored at their canonical location. */
1719static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
e5097dc8
FB
1720{
1721 TCGTemp *ts;
1722 int i;
1723
c896fe29
FB
1724 for(i = s->nb_globals; i < s->nb_temps; i++) {
1725 ts = &s->temps[i];
641d5fbe
FB
1726 if (ts->temp_local) {
1727 temp_save(s, i, allocated_regs);
1728 } else {
2c0366f0
AJ
1729#ifdef USE_LIVENESS_ANALYSIS
1730 /* The liveness analysis already ensures that temps are dead.
1731 Keep an assert for safety. */
1732 assert(ts->val_type == TEMP_VAL_DEAD);
1733#else
639368dd 1734 temp_dead(s, i);
2c0366f0 1735#endif
c896fe29
FB
1736 }
1737 }
e8996ee0
FB
1738
1739 save_globals(s, allocated_regs);
c896fe29
FB
1740}
1741
866cb6cb 1742#define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
ec7a869d 1743#define NEED_SYNC_ARG(n) ((sync_args >> (n)) & 1)
c896fe29 1744
ec7a869d
AJ
1745static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
1746 uint16_t dead_args, uint8_t sync_args)
e8996ee0
FB
1747{
1748 TCGTemp *ots;
1749 tcg_target_ulong val;
1750
1751 ots = &s->temps[args[0]];
1752 val = args[1];
1753
1754 if (ots->fixed_reg) {
1755 /* for fixed registers, we do not do any constant
1756 propagation */
1757 tcg_out_movi(s, ots->type, ots->reg, val);
1758 } else {
1235fc06 1759 /* The movi is not explicitly generated here */
e8996ee0
FB
1760 if (ots->val_type == TEMP_VAL_REG)
1761 s->reg_to_temp[ots->reg] = -1;
1762 ots->val_type = TEMP_VAL_CONST;
1763 ots->val = val;
1764 }
ec7a869d
AJ
1765 if (NEED_SYNC_ARG(0)) {
1766 temp_sync(s, args[0], s->reserved_regs);
1767 }
4c4e1ab2
AJ
1768 if (IS_DEAD_ARG(0)) {
1769 temp_dead(s, args[0]);
1770 }
e8996ee0
FB
1771}
1772
c896fe29 1773static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
ec7a869d
AJ
1774 const TCGArg *args, uint16_t dead_args,
1775 uint8_t sync_args)
c896fe29 1776{
c29c1d7e 1777 TCGRegSet allocated_regs;
c896fe29 1778 TCGTemp *ts, *ots;
c29c1d7e 1779 const TCGArgConstraint *arg_ct, *oarg_ct;
c896fe29 1780
c29c1d7e 1781 tcg_regset_set(allocated_regs, s->reserved_regs);
c896fe29
FB
1782 ots = &s->temps[args[0]];
1783 ts = &s->temps[args[1]];
c29c1d7e
AJ
1784 oarg_ct = &def->args_ct[0];
1785 arg_ct = &def->args_ct[1];
1786
1787 /* If the source value is not in a register, and we're going to be
1788 forced to have it in a register in order to perform the copy,
1789 then copy the SOURCE value into its own register first. That way
1790 we don't have to reload SOURCE the next time it is used. */
1791 if (((NEED_SYNC_ARG(0) || ots->fixed_reg) && ts->val_type != TEMP_VAL_REG)
1792 || ts->val_type == TEMP_VAL_MEM) {
1793 ts->reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1794 if (ts->val_type == TEMP_VAL_MEM) {
1795 tcg_out_ld(s, ts->type, ts->reg, ts->mem_reg, ts->mem_offset);
1796 ts->mem_coherent = 1;
1797 } else if (ts->val_type == TEMP_VAL_CONST) {
1798 tcg_out_movi(s, ts->type, ts->reg, ts->val);
1799 }
1800 s->reg_to_temp[ts->reg] = args[1];
1801 ts->val_type = TEMP_VAL_REG;
1802 }
c896fe29 1803
c29c1d7e
AJ
1804 if (IS_DEAD_ARG(0) && !ots->fixed_reg) {
1805 /* mov to a non-saved dead register makes no sense (even with
1806 liveness analysis disabled). */
1807 assert(NEED_SYNC_ARG(0));
1808 /* The code above should have moved the temp to a register. */
1809 assert(ts->val_type == TEMP_VAL_REG);
1810 if (!ots->mem_allocated) {
1811 temp_allocate_frame(s, args[0]);
1812 }
1813 tcg_out_st(s, ots->type, ts->reg, ots->mem_reg, ots->mem_offset);
1814 if (IS_DEAD_ARG(1)) {
1815 temp_dead(s, args[1]);
1816 }
1817 temp_dead(s, args[0]);
1818 } else if (ts->val_type == TEMP_VAL_CONST) {
1819 /* propagate constant */
1820 if (ots->val_type == TEMP_VAL_REG) {
1821 s->reg_to_temp[ots->reg] = -1;
1822 }
1823 ots->val_type = TEMP_VAL_CONST;
1824 ots->val = ts->val;
1825 } else {
1826 /* The code in the first if block should have moved the
1827 temp to a register. */
1828 assert(ts->val_type == TEMP_VAL_REG);
866cb6cb 1829 if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
c896fe29 1830 /* the mov can be suppressed */
c29c1d7e 1831 if (ots->val_type == TEMP_VAL_REG) {
c896fe29 1832 s->reg_to_temp[ots->reg] = -1;
c29c1d7e
AJ
1833 }
1834 ots->reg = ts->reg;
639368dd 1835 temp_dead(s, args[1]);
c896fe29 1836 } else {
c29c1d7e
AJ
1837 if (ots->val_type != TEMP_VAL_REG) {
1838 /* When allocating a new register, make sure to not spill the
1839 input one. */
1840 tcg_regset_set_reg(allocated_regs, ts->reg);
1841 ots->reg = tcg_reg_alloc(s, oarg_ct->u.regs, allocated_regs);
c896fe29 1842 }
c29c1d7e 1843 tcg_out_mov(s, ots->type, ots->reg, ts->reg);
c896fe29 1844 }
c29c1d7e
AJ
1845 ots->val_type = TEMP_VAL_REG;
1846 ots->mem_coherent = 0;
1847 s->reg_to_temp[ots->reg] = args[0];
1848 if (NEED_SYNC_ARG(0)) {
1849 tcg_reg_sync(s, ots->reg);
c896fe29 1850 }
ec7a869d 1851 }
c896fe29
FB
1852}
1853
1854static void tcg_reg_alloc_op(TCGContext *s,
a9751609 1855 const TCGOpDef *def, TCGOpcode opc,
ec7a869d
AJ
1856 const TCGArg *args, uint16_t dead_args,
1857 uint8_t sync_args)
c896fe29
FB
1858{
1859 TCGRegSet allocated_regs;
1860 int i, k, nb_iargs, nb_oargs, reg;
1861 TCGArg arg;
1862 const TCGArgConstraint *arg_ct;
1863 TCGTemp *ts;
1864 TCGArg new_args[TCG_MAX_OP_ARGS];
1865 int const_args[TCG_MAX_OP_ARGS];
1866
1867 nb_oargs = def->nb_oargs;
1868 nb_iargs = def->nb_iargs;
1869
1870 /* copy constants */
1871 memcpy(new_args + nb_oargs + nb_iargs,
1872 args + nb_oargs + nb_iargs,
1873 sizeof(TCGArg) * def->nb_cargs);
1874
1875 /* satisfy input constraints */
1876 tcg_regset_set(allocated_regs, s->reserved_regs);
1877 for(k = 0; k < nb_iargs; k++) {
1878 i = def->sorted_args[nb_oargs + k];
1879 arg = args[i];
1880 arg_ct = &def->args_ct[i];
1881 ts = &s->temps[arg];
1882 if (ts->val_type == TEMP_VAL_MEM) {
1883 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
e4d5434c 1884 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
c896fe29
FB
1885 ts->val_type = TEMP_VAL_REG;
1886 ts->reg = reg;
1887 ts->mem_coherent = 1;
1888 s->reg_to_temp[reg] = arg;
1889 } else if (ts->val_type == TEMP_VAL_CONST) {
1890 if (tcg_target_const_match(ts->val, arg_ct)) {
1891 /* constant is OK for instruction */
1892 const_args[i] = 1;
1893 new_args[i] = ts->val;
1894 goto iarg_end;
1895 } else {
e8996ee0 1896 /* need to move to a register */
c896fe29
FB
1897 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1898 tcg_out_movi(s, ts->type, reg, ts->val);
e8996ee0
FB
1899 ts->val_type = TEMP_VAL_REG;
1900 ts->reg = reg;
1901 ts->mem_coherent = 0;
1902 s->reg_to_temp[reg] = arg;
c896fe29
FB
1903 }
1904 }
1905 assert(ts->val_type == TEMP_VAL_REG);
5ff9d6a4
FB
1906 if (arg_ct->ct & TCG_CT_IALIAS) {
1907 if (ts->fixed_reg) {
1908 /* if fixed register, we must allocate a new register
1909 if the alias is not the same register */
1910 if (arg != args[arg_ct->alias_index])
1911 goto allocate_in_reg;
1912 } else {
1913 /* if the input is aliased to an output and if it is
1914 not dead after the instruction, we must allocate
1915 a new register and move it */
866cb6cb 1916 if (!IS_DEAD_ARG(i)) {
5ff9d6a4 1917 goto allocate_in_reg;
866cb6cb 1918 }
5ff9d6a4 1919 }
c896fe29
FB
1920 }
1921 reg = ts->reg;
1922 if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1923 /* nothing to do : the constraint is satisfied */
1924 } else {
1925 allocate_in_reg:
1926 /* allocate a new register matching the constraint
1927 and move the temporary register into it */
1928 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
3b6dac34 1929 tcg_out_mov(s, ts->type, reg, ts->reg);
c896fe29 1930 }
c896fe29
FB
1931 new_args[i] = reg;
1932 const_args[i] = 0;
1933 tcg_regset_set_reg(allocated_regs, reg);
1934 iarg_end: ;
1935 }
1936
a52ad07e
AJ
1937 /* mark dead temporaries and free the associated registers */
1938 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1939 if (IS_DEAD_ARG(i)) {
1940 temp_dead(s, args[i]);
1941 }
1942 }
1943
e8996ee0
FB
1944 if (def->flags & TCG_OPF_BB_END) {
1945 tcg_reg_alloc_bb_end(s, allocated_regs);
1946 } else {
e8996ee0
FB
1947 if (def->flags & TCG_OPF_CALL_CLOBBER) {
1948 /* XXX: permit generic clobber register list ? */
1949 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1950 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1951 tcg_reg_free(s, reg);
1952 }
c896fe29 1953 }
3d5c5f87
AJ
1954 }
1955 if (def->flags & TCG_OPF_SIDE_EFFECTS) {
1956 /* sync globals if the op has side effects and might trigger
1957 an exception. */
1958 sync_globals(s, allocated_regs);
c896fe29 1959 }
e8996ee0
FB
1960
1961 /* satisfy the output constraints */
1962 tcg_regset_set(allocated_regs, s->reserved_regs);
1963 for(k = 0; k < nb_oargs; k++) {
1964 i = def->sorted_args[k];
1965 arg = args[i];
1966 arg_ct = &def->args_ct[i];
1967 ts = &s->temps[arg];
1968 if (arg_ct->ct & TCG_CT_ALIAS) {
1969 reg = new_args[arg_ct->alias_index];
1970 } else {
1971 /* if fixed register, we try to use it */
1972 reg = ts->reg;
1973 if (ts->fixed_reg &&
1974 tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1975 goto oarg_end;
1976 }
1977 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
c896fe29 1978 }
e8996ee0
FB
1979 tcg_regset_set_reg(allocated_regs, reg);
1980 /* if a fixed register is used, then a move will be done afterwards */
1981 if (!ts->fixed_reg) {
ec7a869d
AJ
1982 if (ts->val_type == TEMP_VAL_REG) {
1983 s->reg_to_temp[ts->reg] = -1;
1984 }
1985 ts->val_type = TEMP_VAL_REG;
1986 ts->reg = reg;
1987 /* temp value is modified, so the value kept in memory is
1988 potentially not the same */
1989 ts->mem_coherent = 0;
1990 s->reg_to_temp[reg] = arg;
e8996ee0
FB
1991 }
1992 oarg_end:
1993 new_args[i] = reg;
c896fe29 1994 }
c896fe29
FB
1995 }
1996
c896fe29
FB
1997 /* emit instruction */
1998 tcg_out_op(s, opc, new_args, const_args);
1999
2000 /* move the outputs in the correct register if needed */
2001 for(i = 0; i < nb_oargs; i++) {
2002 ts = &s->temps[args[i]];
2003 reg = new_args[i];
2004 if (ts->fixed_reg && ts->reg != reg) {
3b6dac34 2005 tcg_out_mov(s, ts->type, ts->reg, reg);
c896fe29 2006 }
ec7a869d
AJ
2007 if (NEED_SYNC_ARG(i)) {
2008 tcg_reg_sync(s, reg);
2009 }
2010 if (IS_DEAD_ARG(i)) {
2011 temp_dead(s, args[i]);
2012 }
c896fe29
FB
2013 }
2014}
2015
b03cce8e
FB
2016#ifdef TCG_TARGET_STACK_GROWSUP
2017#define STACK_DIR(x) (-(x))
2018#else
2019#define STACK_DIR(x) (x)
2020#endif
2021
c896fe29 2022static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
a9751609 2023 TCGOpcode opc, const TCGArg *args,
ec7a869d 2024 uint16_t dead_args, uint8_t sync_args)
c896fe29
FB
2025{
2026 int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
2027 TCGArg arg, func_arg;
2028 TCGTemp *ts;
f54b3f92 2029 tcg_target_long stack_offset, call_stack_size, func_addr;
b03cce8e 2030 int const_func_arg, allocate_args;
c896fe29
FB
2031 TCGRegSet allocated_regs;
2032 const TCGArgConstraint *arg_ct;
2033
2034 arg = *args++;
2035
2036 nb_oargs = arg >> 16;
2037 nb_iargs = arg & 0xffff;
2038 nb_params = nb_iargs - 1;
2039
2040 flags = args[nb_oargs + nb_iargs];
2041
6e17d0c5 2042 nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
c896fe29
FB
2043 if (nb_regs > nb_params)
2044 nb_regs = nb_params;
2045
2046 /* assign stack slots first */
c896fe29
FB
2047 call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
2048 call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) &
2049 ~(TCG_TARGET_STACK_ALIGN - 1);
b03cce8e
FB
2050 allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
2051 if (allocate_args) {
345649c0
BS
2052 /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
2053 preallocate call stack */
2054 tcg_abort();
b03cce8e 2055 }
39cf05d3
FB
2056
2057 stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
c896fe29
FB
2058 for(i = nb_regs; i < nb_params; i++) {
2059 arg = args[nb_oargs + i];
39cf05d3
FB
2060#ifdef TCG_TARGET_STACK_GROWSUP
2061 stack_offset -= sizeof(tcg_target_long);
2062#endif
2063 if (arg != TCG_CALL_DUMMY_ARG) {
2064 ts = &s->temps[arg];
2065 if (ts->val_type == TEMP_VAL_REG) {
2066 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
2067 } else if (ts->val_type == TEMP_VAL_MEM) {
2068 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
2069 s->reserved_regs);
2070 /* XXX: not correct if reading values from the stack */
2071 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2072 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
2073 } else if (ts->val_type == TEMP_VAL_CONST) {
2074 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
2075 s->reserved_regs);
2076 /* XXX: sign extend may be needed on some targets */
2077 tcg_out_movi(s, ts->type, reg, ts->val);
2078 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
2079 } else {
2080 tcg_abort();
2081 }
c896fe29 2082 }
39cf05d3
FB
2083#ifndef TCG_TARGET_STACK_GROWSUP
2084 stack_offset += sizeof(tcg_target_long);
2085#endif
c896fe29
FB
2086 }
2087
2088 /* assign input registers */
2089 tcg_regset_set(allocated_regs, s->reserved_regs);
2090 for(i = 0; i < nb_regs; i++) {
2091 arg = args[nb_oargs + i];
39cf05d3
FB
2092 if (arg != TCG_CALL_DUMMY_ARG) {
2093 ts = &s->temps[arg];
2094 reg = tcg_target_call_iarg_regs[i];
2095 tcg_reg_free(s, reg);
2096 if (ts->val_type == TEMP_VAL_REG) {
2097 if (ts->reg != reg) {
3b6dac34 2098 tcg_out_mov(s, ts->type, reg, ts->reg);
39cf05d3
FB
2099 }
2100 } else if (ts->val_type == TEMP_VAL_MEM) {
2101 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2102 } else if (ts->val_type == TEMP_VAL_CONST) {
2103 /* XXX: sign extend ? */
2104 tcg_out_movi(s, ts->type, reg, ts->val);
2105 } else {
2106 tcg_abort();
c896fe29 2107 }
39cf05d3 2108 tcg_regset_set_reg(allocated_regs, reg);
c896fe29 2109 }
c896fe29
FB
2110 }
2111
2112 /* assign function address */
2113 func_arg = args[nb_oargs + nb_iargs - 1];
2114 arg_ct = &def->args_ct[0];
2115 ts = &s->temps[func_arg];
f54b3f92 2116 func_addr = ts->val;
c896fe29
FB
2117 const_func_arg = 0;
2118 if (ts->val_type == TEMP_VAL_MEM) {
2119 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
e4d5434c 2120 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
c896fe29 2121 func_arg = reg;
e8996ee0 2122 tcg_regset_set_reg(allocated_regs, reg);
c896fe29
FB
2123 } else if (ts->val_type == TEMP_VAL_REG) {
2124 reg = ts->reg;
2125 if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
2126 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
3b6dac34 2127 tcg_out_mov(s, ts->type, reg, ts->reg);
c896fe29
FB
2128 }
2129 func_arg = reg;
e8996ee0 2130 tcg_regset_set_reg(allocated_regs, reg);
c896fe29 2131 } else if (ts->val_type == TEMP_VAL_CONST) {
f54b3f92 2132 if (tcg_target_const_match(func_addr, arg_ct)) {
c896fe29 2133 const_func_arg = 1;
f54b3f92 2134 func_arg = func_addr;
c896fe29
FB
2135 } else {
2136 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
f54b3f92 2137 tcg_out_movi(s, ts->type, reg, func_addr);
c896fe29 2138 func_arg = reg;
e8996ee0 2139 tcg_regset_set_reg(allocated_regs, reg);
c896fe29
FB
2140 }
2141 } else {
2142 tcg_abort();
2143 }
e8996ee0 2144
c896fe29
FB
2145
2146 /* mark dead temporaries and free the associated registers */
866cb6cb 2147 for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
866cb6cb 2148 if (IS_DEAD_ARG(i)) {
639368dd 2149 temp_dead(s, args[i]);
c896fe29
FB
2150 }
2151 }
2152
2153 /* clobber call registers */
2154 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
2155 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
2156 tcg_reg_free(s, reg);
2157 }
2158 }
78505279
AJ
2159
2160 /* Save globals if they might be written by the helper, sync them if
2161 they might be read. */
2162 if (flags & TCG_CALL_NO_READ_GLOBALS) {
2163 /* Nothing to do */
2164 } else if (flags & TCG_CALL_NO_WRITE_GLOBALS) {
2165 sync_globals(s, allocated_regs);
2166 } else {
b9c18f56
AJ
2167 save_globals(s, allocated_regs);
2168 }
c896fe29
FB
2169
2170 tcg_out_op(s, opc, &func_arg, &const_func_arg);
c896fe29
FB
2171
2172 /* assign output registers and emit moves if needed */
2173 for(i = 0; i < nb_oargs; i++) {
2174 arg = args[i];
2175 ts = &s->temps[arg];
2176 reg = tcg_target_call_oarg_regs[i];
e8996ee0 2177 assert(s->reg_to_temp[reg] == -1);
c896fe29
FB
2178 if (ts->fixed_reg) {
2179 if (ts->reg != reg) {
3b6dac34 2180 tcg_out_mov(s, ts->type, ts->reg, reg);
c896fe29
FB
2181 }
2182 } else {
ec7a869d
AJ
2183 if (ts->val_type == TEMP_VAL_REG) {
2184 s->reg_to_temp[ts->reg] = -1;
2185 }
2186 ts->val_type = TEMP_VAL_REG;
2187 ts->reg = reg;
2188 ts->mem_coherent = 0;
2189 s->reg_to_temp[reg] = arg;
2190 if (NEED_SYNC_ARG(i)) {
2191 tcg_reg_sync(s, reg);
2192 }
8c11ad25 2193 if (IS_DEAD_ARG(i)) {
639368dd 2194 temp_dead(s, args[i]);
8c11ad25 2195 }
c896fe29
FB
2196 }
2197 }
2198
2199 return nb_iargs + nb_oargs + def->nb_cargs + 1;
2200}
2201
2202#ifdef CONFIG_PROFILER
2203
54604f74 2204static int64_t tcg_table_op_count[NB_OPS];
c896fe29 2205
871e6c35 2206static void dump_op_count(void)
c896fe29
FB
2207{
2208 int i;
2209 FILE *f;
54604f74 2210 f = fopen("/tmp/op.log", "w");
c896fe29 2211 for(i = INDEX_op_end; i < NB_OPS; i++) {
54604f74 2212 fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
c896fe29
FB
2213 }
2214 fclose(f);
2215}
2216#endif
2217
2218
2219static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
2ba1eeb6 2220 long search_pc)
c896fe29 2221{
a9751609
RH
2222 TCGOpcode opc;
2223 int op_index;
c896fe29 2224 const TCGOpDef *def;
c896fe29
FB
2225 const TCGArg *args;
2226
2227#ifdef DEBUG_DISAS
8fec2b8c 2228 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
93fcfe39 2229 qemu_log("OP:\n");
eeacee4d 2230 tcg_dump_ops(s);
93fcfe39 2231 qemu_log("\n");
c896fe29
FB
2232 }
2233#endif
2234
c5cc28ff
AJ
2235#ifdef CONFIG_PROFILER
2236 s->opt_time -= profile_getclock();
2237#endif
2238
8f2e8c07 2239#ifdef USE_TCG_OPTIMIZATIONS
c4afe5c4 2240 s->gen_opparam_ptr =
1ff0a2c5 2241 tcg_optimize(s, s->gen_opc_ptr, s->gen_opparam_buf, tcg_op_defs);
8f2e8c07
KB
2242#endif
2243
a23a9ec6 2244#ifdef CONFIG_PROFILER
c5cc28ff 2245 s->opt_time += profile_getclock();
a23a9ec6
FB
2246 s->la_time -= profile_getclock();
2247#endif
c5cc28ff 2248
c896fe29 2249 tcg_liveness_analysis(s);
c5cc28ff 2250
a23a9ec6
FB
2251#ifdef CONFIG_PROFILER
2252 s->la_time += profile_getclock();
2253#endif
c896fe29
FB
2254
2255#ifdef DEBUG_DISAS
8fec2b8c 2256 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
c5cc28ff 2257 qemu_log("OP after optimization and liveness analysis:\n");
eeacee4d 2258 tcg_dump_ops(s);
93fcfe39 2259 qemu_log("\n");
c896fe29
FB
2260 }
2261#endif
2262
2263 tcg_reg_alloc_start(s);
2264
2265 s->code_buf = gen_code_buf;
2266 s->code_ptr = gen_code_buf;
2267
1ff0a2c5 2268 args = s->gen_opparam_buf;
c896fe29 2269 op_index = 0;
b3db8758 2270
c896fe29 2271 for(;;) {
92414b31 2272 opc = s->gen_opc_buf[op_index];
c896fe29 2273#ifdef CONFIG_PROFILER
54604f74 2274 tcg_table_op_count[opc]++;
c896fe29
FB
2275#endif
2276 def = &tcg_op_defs[opc];
2277#if 0
2278 printf("%s: %d %d %d\n", def->name,
2279 def->nb_oargs, def->nb_iargs, def->nb_cargs);
2280 // dump_regs(s);
2281#endif
2282 switch(opc) {
2283 case INDEX_op_mov_i32:
c896fe29 2284 case INDEX_op_mov_i64:
ec7a869d
AJ
2285 tcg_reg_alloc_mov(s, def, args, s->op_dead_args[op_index],
2286 s->op_sync_args[op_index]);
c896fe29 2287 break;
e8996ee0 2288 case INDEX_op_movi_i32:
e8996ee0 2289 case INDEX_op_movi_i64:
ec7a869d
AJ
2290 tcg_reg_alloc_movi(s, args, s->op_dead_args[op_index],
2291 s->op_sync_args[op_index]);
e8996ee0 2292 break;
7e4597d7
FB
2293 case INDEX_op_debug_insn_start:
2294 /* debug instruction */
2295 break;
c896fe29
FB
2296 case INDEX_op_nop:
2297 case INDEX_op_nop1:
2298 case INDEX_op_nop2:
2299 case INDEX_op_nop3:
2300 break;
2301 case INDEX_op_nopn:
2302 args += args[0];
2303 goto next;
5ff9d6a4 2304 case INDEX_op_discard:
639368dd 2305 temp_dead(s, args[0]);
5ff9d6a4 2306 break;
c896fe29 2307 case INDEX_op_set_label:
e8996ee0 2308 tcg_reg_alloc_bb_end(s, s->reserved_regs);
9d6fca70 2309 tcg_out_label(s, args[0], s->code_ptr);
c896fe29
FB
2310 break;
2311 case INDEX_op_call:
ec7a869d
AJ
2312 args += tcg_reg_alloc_call(s, def, opc, args,
2313 s->op_dead_args[op_index],
2314 s->op_sync_args[op_index]);
c896fe29
FB
2315 goto next;
2316 case INDEX_op_end:
2317 goto the_end;
c896fe29 2318 default:
25c4d9cc
RH
2319 /* Sanity check that we've not introduced any unhandled opcodes. */
2320 if (def->flags & TCG_OPF_NOT_PRESENT) {
2321 tcg_abort();
2322 }
c896fe29
FB
2323 /* Note: in order to speed up the code, it would be much
2324 faster to have specialized register allocator functions for
2325 some common argument patterns */
ec7a869d
AJ
2326 tcg_reg_alloc_op(s, def, opc, args, s->op_dead_args[op_index],
2327 s->op_sync_args[op_index]);
c896fe29
FB
2328 break;
2329 }
2330 args += def->nb_args;
8df1ca4b 2331 next:
2ba1eeb6 2332 if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
b314f270 2333 return op_index;
c896fe29
FB
2334 }
2335 op_index++;
2336#ifndef NDEBUG
2337 check_regs(s);
2338#endif
2339 }
2340 the_end:
b76f0d8c
YL
2341#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU)
2342 /* Generate TB finalization at the end of block */
2343 tcg_out_tb_finalize(s);
2344#endif
c896fe29
FB
2345 return -1;
2346}
2347
54604f74 2348int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
c896fe29
FB
2349{
2350#ifdef CONFIG_PROFILER
2351 {
c896fe29 2352 int n;
92414b31 2353 n = (s->gen_opc_ptr - s->gen_opc_buf);
a23a9ec6
FB
2354 s->op_count += n;
2355 if (n > s->op_count_max)
2356 s->op_count_max = n;
2357
2358 s->temp_count += s->nb_temps;
2359 if (s->nb_temps > s->temp_count_max)
2360 s->temp_count_max = s->nb_temps;
c896fe29
FB
2361 }
2362#endif
2363
2ba1eeb6 2364 tcg_gen_code_common(s, gen_code_buf, -1);
c896fe29
FB
2365
2366 /* flush instruction cache */
2aeabc08
SW
2367 flush_icache_range((tcg_target_ulong)gen_code_buf,
2368 (tcg_target_ulong)s->code_ptr);
2369
c896fe29
FB
2370 return s->code_ptr - gen_code_buf;
2371}
2372
2ba1eeb6 2373/* Return the index of the micro operation such as the pc after is <
623e265c
PB
2374 offset bytes from the start of the TB. The contents of gen_code_buf must
2375 not be changed, though writing the same values is ok.
2376 Return -1 if not found. */
54604f74 2377int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
c896fe29 2378{
623e265c 2379 return tcg_gen_code_common(s, gen_code_buf, offset);
c896fe29 2380}
a23a9ec6
FB
2381
2382#ifdef CONFIG_PROFILER
405cf9ff 2383void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
a23a9ec6
FB
2384{
2385 TCGContext *s = &tcg_ctx;
2386 int64_t tot;
2387
2388 tot = s->interm_time + s->code_time;
2389 cpu_fprintf(f, "JIT cycles %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2390 tot, tot / 2.4e9);
2391 cpu_fprintf(f, "translated TBs %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n",
2392 s->tb_count,
2393 s->tb_count1 - s->tb_count,
2394 s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
2395 cpu_fprintf(f, "avg ops/TB %0.1f max=%d\n",
2396 s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
a23a9ec6
FB
2397 cpu_fprintf(f, "deleted ops/TB %0.2f\n",
2398 s->tb_count ?
2399 (double)s->del_op_count / s->tb_count : 0);
2400 cpu_fprintf(f, "avg temps/TB %0.2f max=%d\n",
2401 s->tb_count ?
2402 (double)s->temp_count / s->tb_count : 0,
2403 s->temp_count_max);
2404
2405 cpu_fprintf(f, "cycles/op %0.1f\n",
2406 s->op_count ? (double)tot / s->op_count : 0);
2407 cpu_fprintf(f, "cycles/in byte %0.1f\n",
2408 s->code_in_len ? (double)tot / s->code_in_len : 0);
2409 cpu_fprintf(f, "cycles/out byte %0.1f\n",
2410 s->code_out_len ? (double)tot / s->code_out_len : 0);
2411 if (tot == 0)
2412 tot = 1;
2413 cpu_fprintf(f, " gen_interm time %0.1f%%\n",
2414 (double)s->interm_time / tot * 100.0);
2415 cpu_fprintf(f, " gen_code time %0.1f%%\n",
2416 (double)s->code_time / tot * 100.0);
c5cc28ff
AJ
2417 cpu_fprintf(f, "optim./code time %0.1f%%\n",
2418 (double)s->opt_time / (s->code_time ? s->code_time : 1)
2419 * 100.0);
a23a9ec6
FB
2420 cpu_fprintf(f, "liveness/code time %0.1f%%\n",
2421 (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2422 cpu_fprintf(f, "cpu_restore count %" PRId64 "\n",
2423 s->restore_count);
2424 cpu_fprintf(f, " avg cycles %0.1f\n",
2425 s->restore_count ? (double)s->restore_time / s->restore_count : 0);
871e6c35
BS
2426
2427 dump_op_count();
a23a9ec6
FB
2428}
2429#else
405cf9ff 2430void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
a23a9ec6 2431{
24bf7b3a 2432 cpu_fprintf(f, "[TCG profiler not compiled]\n");
a23a9ec6
FB
2433}
2434#endif
813da627
RH
2435
2436#ifdef ELF_HOST_MACHINE
5872bbf2
RH
2437/* In order to use this feature, the backend needs to do three things:
2438
2439 (1) Define ELF_HOST_MACHINE to indicate both what value to
2440 put into the ELF image and to indicate support for the feature.
2441
2442 (2) Define tcg_register_jit. This should create a buffer containing
2443 the contents of a .debug_frame section that describes the post-
2444 prologue unwind info for the tcg machine.
2445
2446 (3) Call tcg_register_jit_int, with the constructed .debug_frame.
2447*/
813da627
RH
2448
2449/* Begin GDB interface. THE FOLLOWING MUST MATCH GDB DOCS. */
2450typedef enum {
2451 JIT_NOACTION = 0,
2452 JIT_REGISTER_FN,
2453 JIT_UNREGISTER_FN
2454} jit_actions_t;
2455
2456struct jit_code_entry {
2457 struct jit_code_entry *next_entry;
2458 struct jit_code_entry *prev_entry;
2459 const void *symfile_addr;
2460 uint64_t symfile_size;
2461};
2462
2463struct jit_descriptor {
2464 uint32_t version;
2465 uint32_t action_flag;
2466 struct jit_code_entry *relevant_entry;
2467 struct jit_code_entry *first_entry;
2468};
2469
2470void __jit_debug_register_code(void) __attribute__((noinline));
2471void __jit_debug_register_code(void)
2472{
2473 asm("");
2474}
2475
2476/* Must statically initialize the version, because GDB may check
2477 the version before we can set it. */
2478struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
2479
2480/* End GDB interface. */
2481
2482static int find_string(const char *strtab, const char *str)
2483{
2484 const char *p = strtab + 1;
2485
2486 while (1) {
2487 if (strcmp(p, str) == 0) {
2488 return p - strtab;
2489 }
2490 p += strlen(p) + 1;
2491 }
2492}
2493
5872bbf2 2494static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
813da627
RH
2495 void *debug_frame, size_t debug_frame_size)
2496{
5872bbf2
RH
2497 struct __attribute__((packed)) DebugInfo {
2498 uint32_t len;
2499 uint16_t version;
2500 uint32_t abbrev;
2501 uint8_t ptr_size;
2502 uint8_t cu_die;
2503 uint16_t cu_lang;
2504 uintptr_t cu_low_pc;
2505 uintptr_t cu_high_pc;
2506 uint8_t fn_die;
2507 char fn_name[16];
2508 uintptr_t fn_low_pc;
2509 uintptr_t fn_high_pc;
2510 uint8_t cu_eoc;
2511 };
813da627
RH
2512
2513 struct ElfImage {
2514 ElfW(Ehdr) ehdr;
2515 ElfW(Phdr) phdr;
5872bbf2
RH
2516 ElfW(Shdr) shdr[7];
2517 ElfW(Sym) sym[2];
2518 struct DebugInfo di;
2519 uint8_t da[24];
2520 char str[80];
2521 };
2522
2523 struct ElfImage *img;
2524
2525 static const struct ElfImage img_template = {
2526 .ehdr = {
2527 .e_ident[EI_MAG0] = ELFMAG0,
2528 .e_ident[EI_MAG1] = ELFMAG1,
2529 .e_ident[EI_MAG2] = ELFMAG2,
2530 .e_ident[EI_MAG3] = ELFMAG3,
2531 .e_ident[EI_CLASS] = ELF_CLASS,
2532 .e_ident[EI_DATA] = ELF_DATA,
2533 .e_ident[EI_VERSION] = EV_CURRENT,
2534 .e_type = ET_EXEC,
2535 .e_machine = ELF_HOST_MACHINE,
2536 .e_version = EV_CURRENT,
2537 .e_phoff = offsetof(struct ElfImage, phdr),
2538 .e_shoff = offsetof(struct ElfImage, shdr),
2539 .e_ehsize = sizeof(ElfW(Shdr)),
2540 .e_phentsize = sizeof(ElfW(Phdr)),
2541 .e_phnum = 1,
2542 .e_shentsize = sizeof(ElfW(Shdr)),
2543 .e_shnum = ARRAY_SIZE(img->shdr),
2544 .e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
abbb3eae
RH
2545#ifdef ELF_HOST_FLAGS
2546 .e_flags = ELF_HOST_FLAGS,
2547#endif
2548#ifdef ELF_OSABI
2549 .e_ident[EI_OSABI] = ELF_OSABI,
2550#endif
5872bbf2
RH
2551 },
2552 .phdr = {
2553 .p_type = PT_LOAD,
2554 .p_flags = PF_X,
2555 },
2556 .shdr = {
2557 [0] = { .sh_type = SHT_NULL },
2558 /* Trick: The contents of code_gen_buffer are not present in
2559 this fake ELF file; that got allocated elsewhere. Therefore
2560 we mark .text as SHT_NOBITS (similar to .bss) so that readers
2561 will not look for contents. We can record any address. */
2562 [1] = { /* .text */
2563 .sh_type = SHT_NOBITS,
2564 .sh_flags = SHF_EXECINSTR | SHF_ALLOC,
2565 },
2566 [2] = { /* .debug_info */
2567 .sh_type = SHT_PROGBITS,
2568 .sh_offset = offsetof(struct ElfImage, di),
2569 .sh_size = sizeof(struct DebugInfo),
2570 },
2571 [3] = { /* .debug_abbrev */
2572 .sh_type = SHT_PROGBITS,
2573 .sh_offset = offsetof(struct ElfImage, da),
2574 .sh_size = sizeof(img->da),
2575 },
2576 [4] = { /* .debug_frame */
2577 .sh_type = SHT_PROGBITS,
2578 .sh_offset = sizeof(struct ElfImage),
2579 },
2580 [5] = { /* .symtab */
2581 .sh_type = SHT_SYMTAB,
2582 .sh_offset = offsetof(struct ElfImage, sym),
2583 .sh_size = sizeof(img->sym),
2584 .sh_info = 1,
2585 .sh_link = ARRAY_SIZE(img->shdr) - 1,
2586 .sh_entsize = sizeof(ElfW(Sym)),
2587 },
2588 [6] = { /* .strtab */
2589 .sh_type = SHT_STRTAB,
2590 .sh_offset = offsetof(struct ElfImage, str),
2591 .sh_size = sizeof(img->str),
2592 }
2593 },
2594 .sym = {
2595 [1] = { /* code_gen_buffer */
2596 .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
2597 .st_shndx = 1,
2598 }
2599 },
2600 .di = {
2601 .len = sizeof(struct DebugInfo) - 4,
2602 .version = 2,
2603 .ptr_size = sizeof(void *),
2604 .cu_die = 1,
2605 .cu_lang = 0x8001, /* DW_LANG_Mips_Assembler */
2606 .fn_die = 2,
2607 .fn_name = "code_gen_buffer"
2608 },
2609 .da = {
2610 1, /* abbrev number (the cu) */
2611 0x11, 1, /* DW_TAG_compile_unit, has children */
2612 0x13, 0x5, /* DW_AT_language, DW_FORM_data2 */
2613 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
2614 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
2615 0, 0, /* end of abbrev */
2616 2, /* abbrev number (the fn) */
2617 0x2e, 0, /* DW_TAG_subprogram, no children */
2618 0x3, 0x8, /* DW_AT_name, DW_FORM_string */
2619 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
2620 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
2621 0, 0, /* end of abbrev */
2622 0 /* no more abbrev */
2623 },
2624 .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
2625 ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
813da627
RH
2626 };
2627
2628 /* We only need a single jit entry; statically allocate it. */
2629 static struct jit_code_entry one_entry;
2630
5872bbf2 2631 uintptr_t buf = (uintptr_t)buf_ptr;
813da627 2632 size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
813da627 2633
5872bbf2
RH
2634 img = g_malloc(img_size);
2635 *img = img_template;
2636 memcpy(img + 1, debug_frame, debug_frame_size);
813da627 2637
5872bbf2
RH
2638 img->phdr.p_vaddr = buf;
2639 img->phdr.p_paddr = buf;
2640 img->phdr.p_memsz = buf_size;
813da627 2641
813da627 2642 img->shdr[1].sh_name = find_string(img->str, ".text");
5872bbf2 2643 img->shdr[1].sh_addr = buf;
813da627
RH
2644 img->shdr[1].sh_size = buf_size;
2645
5872bbf2
RH
2646 img->shdr[2].sh_name = find_string(img->str, ".debug_info");
2647 img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
2648
2649 img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
2650 img->shdr[4].sh_size = debug_frame_size;
2651
2652 img->shdr[5].sh_name = find_string(img->str, ".symtab");
2653 img->shdr[6].sh_name = find_string(img->str, ".strtab");
2654
2655 img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
2656 img->sym[1].st_value = buf;
2657 img->sym[1].st_size = buf_size;
813da627 2658
5872bbf2
RH
2659 img->di.cu_low_pc = buf;
2660 img->di.cu_high_pc = buf_size;
2661 img->di.fn_low_pc = buf;
2662 img->di.fn_high_pc = buf_size;
813da627
RH
2663
2664#ifdef DEBUG_JIT
2665 /* Enable this block to be able to debug the ELF image file creation.
2666 One can use readelf, objdump, or other inspection utilities. */
2667 {
2668 FILE *f = fopen("/tmp/qemu.jit", "w+b");
2669 if (f) {
5872bbf2 2670 if (fwrite(img, img_size, 1, f) != img_size) {
813da627
RH
2671 /* Avoid stupid unused return value warning for fwrite. */
2672 }
2673 fclose(f);
2674 }
2675 }
2676#endif
2677
2678 one_entry.symfile_addr = img;
2679 one_entry.symfile_size = img_size;
2680
2681 __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
2682 __jit_debug_descriptor.relevant_entry = &one_entry;
2683 __jit_debug_descriptor.first_entry = &one_entry;
2684 __jit_debug_register_code();
2685}
2686#else
5872bbf2
RH
2687/* No support for the feature. Provide the entry point expected by exec.c,
2688 and implement the internal function we declared earlier. */
813da627
RH
2689
2690static void tcg_register_jit_int(void *buf, size_t size,
2691 void *debug_frame, size_t debug_frame_size)
2692{
2693}
2694
2695void tcg_register_jit(void *buf, size_t buf_size)
2696{
2697}
2698#endif /* ELF_HOST_MACHINE */