tcg: Introduce tcgv_{i32,i64,ptr}_{arg,temp}
[qemu/kevin.git] / tcg / tcg.c
blobcb985aabdcbf8003bb15f354356ec4762a5fac64
1 /*
2 * Tiny Code Generator for QEMU
4 * Copyright (c) 2008 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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.
25 /* define it to use liveness analysis (better code) */
26 #define USE_TCG_OPTIMIZATIONS
28 #include "qemu/osdep.h"
30 /* Define to jump the ELF file used to communicate with GDB. */
31 #undef DEBUG_JIT
33 #include "qemu/cutils.h"
34 #include "qemu/host-utils.h"
35 #include "qemu/timer.h"
37 /* Note: the long term plan is to reduce the dependencies on the QEMU
38 CPU definitions. Currently they are used for qemu_ld/st
39 instructions */
40 #define NO_CPU_IO_DEFS
41 #include "cpu.h"
43 #include "exec/cpu-common.h"
44 #include "exec/exec-all.h"
46 #include "tcg-op.h"
48 #if UINTPTR_MAX == UINT32_MAX
49 # define ELF_CLASS ELFCLASS32
50 #else
51 # define ELF_CLASS ELFCLASS64
52 #endif
53 #ifdef HOST_WORDS_BIGENDIAN
54 # define ELF_DATA ELFDATA2MSB
55 #else
56 # define ELF_DATA ELFDATA2LSB
57 #endif
59 #include "elf.h"
60 #include "exec/log.h"
62 /* Forward declarations for functions declared in tcg-target.inc.c and
63 used here. */
64 static void tcg_target_init(TCGContext *s);
65 static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode);
66 static void tcg_target_qemu_prologue(TCGContext *s);
67 static void patch_reloc(tcg_insn_unit *code_ptr, int type,
68 intptr_t value, intptr_t addend);
70 /* The CIE and FDE header definitions will be common to all hosts. */
71 typedef struct {
72 uint32_t len __attribute__((aligned((sizeof(void *)))));
73 uint32_t id;
74 uint8_t version;
75 char augmentation[1];
76 uint8_t code_align;
77 uint8_t data_align;
78 uint8_t return_column;
79 } DebugFrameCIE;
81 typedef struct QEMU_PACKED {
82 uint32_t len __attribute__((aligned((sizeof(void *)))));
83 uint32_t cie_offset;
84 uintptr_t func_start;
85 uintptr_t func_len;
86 } DebugFrameFDEHeader;
88 typedef struct QEMU_PACKED {
89 DebugFrameCIE cie;
90 DebugFrameFDEHeader fde;
91 } DebugFrameHeader;
93 static void tcg_register_jit_int(void *buf, size_t size,
94 const void *debug_frame,
95 size_t debug_frame_size)
96 __attribute__((unused));
98 /* Forward declarations for functions declared and used in tcg-target.inc.c. */
99 static const char *target_parse_constraint(TCGArgConstraint *ct,
100 const char *ct_str, TCGType type);
101 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
102 intptr_t arg2);
103 static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
104 static void tcg_out_movi(TCGContext *s, TCGType type,
105 TCGReg ret, tcg_target_long arg);
106 static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
107 const int *const_args);
108 static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
109 intptr_t arg2);
110 static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
111 TCGReg base, intptr_t ofs);
112 static void tcg_out_call(TCGContext *s, tcg_insn_unit *target);
113 static int tcg_target_const_match(tcg_target_long val, TCGType type,
114 const TCGArgConstraint *arg_ct);
115 #ifdef TCG_TARGET_NEED_LDST_LABELS
116 static bool tcg_out_ldst_finalize(TCGContext *s);
117 #endif
119 #define TCG_HIGHWATER 1024
121 static TCGRegSet tcg_target_available_regs[2];
122 static TCGRegSet tcg_target_call_clobber_regs;
124 #if TCG_TARGET_INSN_UNIT_SIZE == 1
125 static __attribute__((unused)) inline void tcg_out8(TCGContext *s, uint8_t v)
127 *s->code_ptr++ = v;
130 static __attribute__((unused)) inline void tcg_patch8(tcg_insn_unit *p,
131 uint8_t v)
133 *p = v;
135 #endif
137 #if TCG_TARGET_INSN_UNIT_SIZE <= 2
138 static __attribute__((unused)) inline void tcg_out16(TCGContext *s, uint16_t v)
140 if (TCG_TARGET_INSN_UNIT_SIZE == 2) {
141 *s->code_ptr++ = v;
142 } else {
143 tcg_insn_unit *p = s->code_ptr;
144 memcpy(p, &v, sizeof(v));
145 s->code_ptr = p + (2 / TCG_TARGET_INSN_UNIT_SIZE);
149 static __attribute__((unused)) inline void tcg_patch16(tcg_insn_unit *p,
150 uint16_t v)
152 if (TCG_TARGET_INSN_UNIT_SIZE == 2) {
153 *p = v;
154 } else {
155 memcpy(p, &v, sizeof(v));
158 #endif
160 #if TCG_TARGET_INSN_UNIT_SIZE <= 4
161 static __attribute__((unused)) inline void tcg_out32(TCGContext *s, uint32_t v)
163 if (TCG_TARGET_INSN_UNIT_SIZE == 4) {
164 *s->code_ptr++ = v;
165 } else {
166 tcg_insn_unit *p = s->code_ptr;
167 memcpy(p, &v, sizeof(v));
168 s->code_ptr = p + (4 / TCG_TARGET_INSN_UNIT_SIZE);
172 static __attribute__((unused)) inline void tcg_patch32(tcg_insn_unit *p,
173 uint32_t v)
175 if (TCG_TARGET_INSN_UNIT_SIZE == 4) {
176 *p = v;
177 } else {
178 memcpy(p, &v, sizeof(v));
181 #endif
183 #if TCG_TARGET_INSN_UNIT_SIZE <= 8
184 static __attribute__((unused)) inline void tcg_out64(TCGContext *s, uint64_t v)
186 if (TCG_TARGET_INSN_UNIT_SIZE == 8) {
187 *s->code_ptr++ = v;
188 } else {
189 tcg_insn_unit *p = s->code_ptr;
190 memcpy(p, &v, sizeof(v));
191 s->code_ptr = p + (8 / TCG_TARGET_INSN_UNIT_SIZE);
195 static __attribute__((unused)) inline void tcg_patch64(tcg_insn_unit *p,
196 uint64_t v)
198 if (TCG_TARGET_INSN_UNIT_SIZE == 8) {
199 *p = v;
200 } else {
201 memcpy(p, &v, sizeof(v));
204 #endif
206 /* label relocation processing */
208 static void tcg_out_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
209 TCGLabel *l, intptr_t addend)
211 TCGRelocation *r;
213 if (l->has_value) {
214 /* FIXME: This may break relocations on RISC targets that
215 modify instruction fields in place. The caller may not have
216 written the initial value. */
217 patch_reloc(code_ptr, type, l->u.value, addend);
218 } else {
219 /* add a new relocation entry */
220 r = tcg_malloc(sizeof(TCGRelocation));
221 r->type = type;
222 r->ptr = code_ptr;
223 r->addend = addend;
224 r->next = l->u.first_reloc;
225 l->u.first_reloc = r;
229 static void tcg_out_label(TCGContext *s, TCGLabel *l, tcg_insn_unit *ptr)
231 intptr_t value = (intptr_t)ptr;
232 TCGRelocation *r;
234 tcg_debug_assert(!l->has_value);
236 for (r = l->u.first_reloc; r != NULL; r = r->next) {
237 patch_reloc(r->ptr, r->type, value, r->addend);
240 l->has_value = 1;
241 l->u.value_ptr = ptr;
244 TCGLabel *gen_new_label(void)
246 TCGContext *s = &tcg_ctx;
247 TCGLabel *l = tcg_malloc(sizeof(TCGLabel));
249 *l = (TCGLabel){
250 .id = s->nb_labels++
253 return l;
256 #include "tcg-target.inc.c"
258 /* pool based memory allocation */
259 void *tcg_malloc_internal(TCGContext *s, int size)
261 TCGPool *p;
262 int pool_size;
264 if (size > TCG_POOL_CHUNK_SIZE) {
265 /* big malloc: insert a new pool (XXX: could optimize) */
266 p = g_malloc(sizeof(TCGPool) + size);
267 p->size = size;
268 p->next = s->pool_first_large;
269 s->pool_first_large = p;
270 return p->data;
271 } else {
272 p = s->pool_current;
273 if (!p) {
274 p = s->pool_first;
275 if (!p)
276 goto new_pool;
277 } else {
278 if (!p->next) {
279 new_pool:
280 pool_size = TCG_POOL_CHUNK_SIZE;
281 p = g_malloc(sizeof(TCGPool) + pool_size);
282 p->size = pool_size;
283 p->next = NULL;
284 if (s->pool_current)
285 s->pool_current->next = p;
286 else
287 s->pool_first = p;
288 } else {
289 p = p->next;
293 s->pool_current = p;
294 s->pool_cur = p->data + size;
295 s->pool_end = p->data + p->size;
296 return p->data;
299 void tcg_pool_reset(TCGContext *s)
301 TCGPool *p, *t;
302 for (p = s->pool_first_large; p; p = t) {
303 t = p->next;
304 g_free(p);
306 s->pool_first_large = NULL;
307 s->pool_cur = s->pool_end = NULL;
308 s->pool_current = NULL;
311 typedef struct TCGHelperInfo {
312 void *func;
313 const char *name;
314 unsigned flags;
315 unsigned sizemask;
316 } TCGHelperInfo;
318 #include "exec/helper-proto.h"
320 static const TCGHelperInfo all_helpers[] = {
321 #include "exec/helper-tcg.h"
323 static GHashTable *helper_table;
325 static int indirect_reg_alloc_order[ARRAY_SIZE(tcg_target_reg_alloc_order)];
326 static void process_op_defs(TCGContext *s);
328 void tcg_context_init(TCGContext *s)
330 int op, total_args, n, i;
331 TCGOpDef *def;
332 TCGArgConstraint *args_ct;
333 int *sorted_args;
335 memset(s, 0, sizeof(*s));
336 s->nb_globals = 0;
338 /* Count total number of arguments and allocate the corresponding
339 space */
340 total_args = 0;
341 for(op = 0; op < NB_OPS; op++) {
342 def = &tcg_op_defs[op];
343 n = def->nb_iargs + def->nb_oargs;
344 total_args += n;
347 args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args);
348 sorted_args = g_malloc(sizeof(int) * total_args);
350 for(op = 0; op < NB_OPS; op++) {
351 def = &tcg_op_defs[op];
352 def->args_ct = args_ct;
353 def->sorted_args = sorted_args;
354 n = def->nb_iargs + def->nb_oargs;
355 sorted_args += n;
356 args_ct += n;
359 /* Register helpers. */
360 /* Use g_direct_hash/equal for direct pointer comparisons on func. */
361 helper_table = g_hash_table_new(NULL, NULL);
363 for (i = 0; i < ARRAY_SIZE(all_helpers); ++i) {
364 g_hash_table_insert(helper_table, (gpointer)all_helpers[i].func,
365 (gpointer)&all_helpers[i]);
368 tcg_target_init(s);
369 process_op_defs(s);
371 /* Reverse the order of the saved registers, assuming they're all at
372 the start of tcg_target_reg_alloc_order. */
373 for (n = 0; n < ARRAY_SIZE(tcg_target_reg_alloc_order); ++n) {
374 int r = tcg_target_reg_alloc_order[n];
375 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, r)) {
376 break;
379 for (i = 0; i < n; ++i) {
380 indirect_reg_alloc_order[i] = tcg_target_reg_alloc_order[n - 1 - i];
382 for (; i < ARRAY_SIZE(tcg_target_reg_alloc_order); ++i) {
383 indirect_reg_alloc_order[i] = tcg_target_reg_alloc_order[i];
388 * Allocate TBs right before their corresponding translated code, making
389 * sure that TBs and code are on different cache lines.
391 TranslationBlock *tcg_tb_alloc(TCGContext *s)
393 uintptr_t align = qemu_icache_linesize;
394 TranslationBlock *tb;
395 void *next;
397 tb = (void *)ROUND_UP((uintptr_t)s->code_gen_ptr, align);
398 next = (void *)ROUND_UP((uintptr_t)(tb + 1), align);
400 if (unlikely(next > s->code_gen_highwater)) {
401 return NULL;
403 s->code_gen_ptr = next;
404 s->data_gen_ptr = NULL;
405 return tb;
408 void tcg_prologue_init(TCGContext *s)
410 size_t prologue_size, total_size;
411 void *buf0, *buf1;
413 /* Put the prologue at the beginning of code_gen_buffer. */
414 buf0 = s->code_gen_buffer;
415 s->code_ptr = buf0;
416 s->code_buf = buf0;
417 s->code_gen_prologue = buf0;
419 /* Generate the prologue. */
420 tcg_target_qemu_prologue(s);
421 buf1 = s->code_ptr;
422 flush_icache_range((uintptr_t)buf0, (uintptr_t)buf1);
424 /* Deduct the prologue from the buffer. */
425 prologue_size = tcg_current_code_size(s);
426 s->code_gen_ptr = buf1;
427 s->code_gen_buffer = buf1;
428 s->code_buf = buf1;
429 total_size = s->code_gen_buffer_size - prologue_size;
430 s->code_gen_buffer_size = total_size;
432 /* Compute a high-water mark, at which we voluntarily flush the buffer
433 and start over. The size here is arbitrary, significantly larger
434 than we expect the code generation for any one opcode to require. */
435 s->code_gen_highwater = s->code_gen_buffer + (total_size - TCG_HIGHWATER);
437 tcg_register_jit(s->code_gen_buffer, total_size);
439 #ifdef DEBUG_DISAS
440 if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
441 qemu_log_lock();
442 qemu_log("PROLOGUE: [size=%zu]\n", prologue_size);
443 log_disas(buf0, prologue_size);
444 qemu_log("\n");
445 qemu_log_flush();
446 qemu_log_unlock();
448 #endif
450 /* Assert that goto_ptr is implemented completely. */
451 if (TCG_TARGET_HAS_goto_ptr) {
452 tcg_debug_assert(s->code_gen_epilogue != NULL);
456 void tcg_func_start(TCGContext *s)
458 tcg_pool_reset(s);
459 s->nb_temps = s->nb_globals;
461 /* No temps have been previously allocated for size or locality. */
462 memset(s->free_temps, 0, sizeof(s->free_temps));
464 s->nb_labels = 0;
465 s->current_frame_offset = s->frame_start;
467 #ifdef CONFIG_DEBUG_TCG
468 s->goto_tb_issue_mask = 0;
469 #endif
471 s->gen_op_buf[0].next = 1;
472 s->gen_op_buf[0].prev = 0;
473 s->gen_next_op_idx = 1;
476 static inline TCGTemp *tcg_temp_alloc(TCGContext *s)
478 int n = s->nb_temps++;
479 tcg_debug_assert(n < TCG_MAX_TEMPS);
480 return memset(&s->temps[n], 0, sizeof(TCGTemp));
483 static inline TCGTemp *tcg_global_alloc(TCGContext *s)
485 TCGTemp *ts;
487 tcg_debug_assert(s->nb_globals == s->nb_temps);
488 s->nb_globals++;
489 ts = tcg_temp_alloc(s);
490 ts->temp_global = 1;
492 return ts;
495 static int tcg_global_reg_new_internal(TCGContext *s, TCGType type,
496 TCGReg reg, const char *name)
498 TCGTemp *ts;
500 if (TCG_TARGET_REG_BITS == 32 && type != TCG_TYPE_I32) {
501 tcg_abort();
504 ts = tcg_global_alloc(s);
505 ts->base_type = type;
506 ts->type = type;
507 ts->fixed_reg = 1;
508 ts->reg = reg;
509 ts->name = name;
510 tcg_regset_set_reg(s->reserved_regs, reg);
512 return temp_idx(ts);
515 void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size)
517 int idx;
518 s->frame_start = start;
519 s->frame_end = start + size;
520 idx = tcg_global_reg_new_internal(s, TCG_TYPE_PTR, reg, "_frame");
521 s->frame_temp = &s->temps[idx];
524 TCGv_i32 tcg_global_reg_new_i32(TCGReg reg, const char *name)
526 TCGContext *s = &tcg_ctx;
527 int idx;
529 if (tcg_regset_test_reg(s->reserved_regs, reg)) {
530 tcg_abort();
532 idx = tcg_global_reg_new_internal(s, TCG_TYPE_I32, reg, name);
533 return MAKE_TCGV_I32(idx);
536 TCGv_i64 tcg_global_reg_new_i64(TCGReg reg, const char *name)
538 TCGContext *s = &tcg_ctx;
539 int idx;
541 if (tcg_regset_test_reg(s->reserved_regs, reg)) {
542 tcg_abort();
544 idx = tcg_global_reg_new_internal(s, TCG_TYPE_I64, reg, name);
545 return MAKE_TCGV_I64(idx);
548 int tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
549 intptr_t offset, const char *name)
551 TCGContext *s = &tcg_ctx;
552 TCGTemp *base_ts = &s->temps[GET_TCGV_PTR(base)];
553 TCGTemp *ts = tcg_global_alloc(s);
554 int indirect_reg = 0, bigendian = 0;
555 #ifdef HOST_WORDS_BIGENDIAN
556 bigendian = 1;
557 #endif
559 if (!base_ts->fixed_reg) {
560 /* We do not support double-indirect registers. */
561 tcg_debug_assert(!base_ts->indirect_reg);
562 base_ts->indirect_base = 1;
563 s->nb_indirects += (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64
564 ? 2 : 1);
565 indirect_reg = 1;
568 if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) {
569 TCGTemp *ts2 = tcg_global_alloc(s);
570 char buf[64];
572 ts->base_type = TCG_TYPE_I64;
573 ts->type = TCG_TYPE_I32;
574 ts->indirect_reg = indirect_reg;
575 ts->mem_allocated = 1;
576 ts->mem_base = base_ts;
577 ts->mem_offset = offset + bigendian * 4;
578 pstrcpy(buf, sizeof(buf), name);
579 pstrcat(buf, sizeof(buf), "_0");
580 ts->name = strdup(buf);
582 tcg_debug_assert(ts2 == ts + 1);
583 ts2->base_type = TCG_TYPE_I64;
584 ts2->type = TCG_TYPE_I32;
585 ts2->indirect_reg = indirect_reg;
586 ts2->mem_allocated = 1;
587 ts2->mem_base = base_ts;
588 ts2->mem_offset = offset + (1 - bigendian) * 4;
589 pstrcpy(buf, sizeof(buf), name);
590 pstrcat(buf, sizeof(buf), "_1");
591 ts2->name = strdup(buf);
592 } else {
593 ts->base_type = type;
594 ts->type = type;
595 ts->indirect_reg = indirect_reg;
596 ts->mem_allocated = 1;
597 ts->mem_base = base_ts;
598 ts->mem_offset = offset;
599 ts->name = name;
601 return temp_idx(ts);
604 static int tcg_temp_new_internal(TCGType type, int temp_local)
606 TCGContext *s = &tcg_ctx;
607 TCGTemp *ts;
608 int idx, k;
610 k = type + (temp_local ? TCG_TYPE_COUNT : 0);
611 idx = find_first_bit(s->free_temps[k].l, TCG_MAX_TEMPS);
612 if (idx < TCG_MAX_TEMPS) {
613 /* There is already an available temp with the right type. */
614 clear_bit(idx, s->free_temps[k].l);
616 ts = &s->temps[idx];
617 ts->temp_allocated = 1;
618 tcg_debug_assert(ts->base_type == type);
619 tcg_debug_assert(ts->temp_local == temp_local);
620 } else {
621 ts = tcg_temp_alloc(s);
622 if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) {
623 TCGTemp *ts2 = tcg_temp_alloc(s);
625 ts->base_type = type;
626 ts->type = TCG_TYPE_I32;
627 ts->temp_allocated = 1;
628 ts->temp_local = temp_local;
630 tcg_debug_assert(ts2 == ts + 1);
631 ts2->base_type = TCG_TYPE_I64;
632 ts2->type = TCG_TYPE_I32;
633 ts2->temp_allocated = 1;
634 ts2->temp_local = temp_local;
635 } else {
636 ts->base_type = type;
637 ts->type = type;
638 ts->temp_allocated = 1;
639 ts->temp_local = temp_local;
641 idx = temp_idx(ts);
644 #if defined(CONFIG_DEBUG_TCG)
645 s->temps_in_use++;
646 #endif
647 return idx;
650 TCGv_i32 tcg_temp_new_internal_i32(int temp_local)
652 int idx;
654 idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
655 return MAKE_TCGV_I32(idx);
658 TCGv_i64 tcg_temp_new_internal_i64(int temp_local)
660 int idx;
662 idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
663 return MAKE_TCGV_I64(idx);
666 static void tcg_temp_free_internal(int idx)
668 TCGContext *s = &tcg_ctx;
669 TCGTemp *ts;
670 int k;
672 #if defined(CONFIG_DEBUG_TCG)
673 s->temps_in_use--;
674 if (s->temps_in_use < 0) {
675 fprintf(stderr, "More temporaries freed than allocated!\n");
677 #endif
679 tcg_debug_assert(idx >= s->nb_globals && idx < s->nb_temps);
680 ts = &s->temps[idx];
681 tcg_debug_assert(ts->temp_allocated != 0);
682 ts->temp_allocated = 0;
684 k = ts->base_type + (ts->temp_local ? TCG_TYPE_COUNT : 0);
685 set_bit(idx, s->free_temps[k].l);
688 void tcg_temp_free_i32(TCGv_i32 arg)
690 tcg_temp_free_internal(GET_TCGV_I32(arg));
693 void tcg_temp_free_i64(TCGv_i64 arg)
695 tcg_temp_free_internal(GET_TCGV_I64(arg));
698 TCGv_i32 tcg_const_i32(int32_t val)
700 TCGv_i32 t0;
701 t0 = tcg_temp_new_i32();
702 tcg_gen_movi_i32(t0, val);
703 return t0;
706 TCGv_i64 tcg_const_i64(int64_t val)
708 TCGv_i64 t0;
709 t0 = tcg_temp_new_i64();
710 tcg_gen_movi_i64(t0, val);
711 return t0;
714 TCGv_i32 tcg_const_local_i32(int32_t val)
716 TCGv_i32 t0;
717 t0 = tcg_temp_local_new_i32();
718 tcg_gen_movi_i32(t0, val);
719 return t0;
722 TCGv_i64 tcg_const_local_i64(int64_t val)
724 TCGv_i64 t0;
725 t0 = tcg_temp_local_new_i64();
726 tcg_gen_movi_i64(t0, val);
727 return t0;
730 #if defined(CONFIG_DEBUG_TCG)
731 void tcg_clear_temp_count(void)
733 TCGContext *s = &tcg_ctx;
734 s->temps_in_use = 0;
737 int tcg_check_temp_count(void)
739 TCGContext *s = &tcg_ctx;
740 if (s->temps_in_use) {
741 /* Clear the count so that we don't give another
742 * warning immediately next time around.
744 s->temps_in_use = 0;
745 return 1;
747 return 0;
749 #endif
751 /* Return true if OP may appear in the opcode stream.
752 Test the runtime variable that controls each opcode. */
753 bool tcg_op_supported(TCGOpcode op)
755 switch (op) {
756 case INDEX_op_discard:
757 case INDEX_op_set_label:
758 case INDEX_op_call:
759 case INDEX_op_br:
760 case INDEX_op_mb:
761 case INDEX_op_insn_start:
762 case INDEX_op_exit_tb:
763 case INDEX_op_goto_tb:
764 case INDEX_op_qemu_ld_i32:
765 case INDEX_op_qemu_st_i32:
766 case INDEX_op_qemu_ld_i64:
767 case INDEX_op_qemu_st_i64:
768 return true;
770 case INDEX_op_goto_ptr:
771 return TCG_TARGET_HAS_goto_ptr;
773 case INDEX_op_mov_i32:
774 case INDEX_op_movi_i32:
775 case INDEX_op_setcond_i32:
776 case INDEX_op_brcond_i32:
777 case INDEX_op_ld8u_i32:
778 case INDEX_op_ld8s_i32:
779 case INDEX_op_ld16u_i32:
780 case INDEX_op_ld16s_i32:
781 case INDEX_op_ld_i32:
782 case INDEX_op_st8_i32:
783 case INDEX_op_st16_i32:
784 case INDEX_op_st_i32:
785 case INDEX_op_add_i32:
786 case INDEX_op_sub_i32:
787 case INDEX_op_mul_i32:
788 case INDEX_op_and_i32:
789 case INDEX_op_or_i32:
790 case INDEX_op_xor_i32:
791 case INDEX_op_shl_i32:
792 case INDEX_op_shr_i32:
793 case INDEX_op_sar_i32:
794 return true;
796 case INDEX_op_movcond_i32:
797 return TCG_TARGET_HAS_movcond_i32;
798 case INDEX_op_div_i32:
799 case INDEX_op_divu_i32:
800 return TCG_TARGET_HAS_div_i32;
801 case INDEX_op_rem_i32:
802 case INDEX_op_remu_i32:
803 return TCG_TARGET_HAS_rem_i32;
804 case INDEX_op_div2_i32:
805 case INDEX_op_divu2_i32:
806 return TCG_TARGET_HAS_div2_i32;
807 case INDEX_op_rotl_i32:
808 case INDEX_op_rotr_i32:
809 return TCG_TARGET_HAS_rot_i32;
810 case INDEX_op_deposit_i32:
811 return TCG_TARGET_HAS_deposit_i32;
812 case INDEX_op_extract_i32:
813 return TCG_TARGET_HAS_extract_i32;
814 case INDEX_op_sextract_i32:
815 return TCG_TARGET_HAS_sextract_i32;
816 case INDEX_op_add2_i32:
817 return TCG_TARGET_HAS_add2_i32;
818 case INDEX_op_sub2_i32:
819 return TCG_TARGET_HAS_sub2_i32;
820 case INDEX_op_mulu2_i32:
821 return TCG_TARGET_HAS_mulu2_i32;
822 case INDEX_op_muls2_i32:
823 return TCG_TARGET_HAS_muls2_i32;
824 case INDEX_op_muluh_i32:
825 return TCG_TARGET_HAS_muluh_i32;
826 case INDEX_op_mulsh_i32:
827 return TCG_TARGET_HAS_mulsh_i32;
828 case INDEX_op_ext8s_i32:
829 return TCG_TARGET_HAS_ext8s_i32;
830 case INDEX_op_ext16s_i32:
831 return TCG_TARGET_HAS_ext16s_i32;
832 case INDEX_op_ext8u_i32:
833 return TCG_TARGET_HAS_ext8u_i32;
834 case INDEX_op_ext16u_i32:
835 return TCG_TARGET_HAS_ext16u_i32;
836 case INDEX_op_bswap16_i32:
837 return TCG_TARGET_HAS_bswap16_i32;
838 case INDEX_op_bswap32_i32:
839 return TCG_TARGET_HAS_bswap32_i32;
840 case INDEX_op_not_i32:
841 return TCG_TARGET_HAS_not_i32;
842 case INDEX_op_neg_i32:
843 return TCG_TARGET_HAS_neg_i32;
844 case INDEX_op_andc_i32:
845 return TCG_TARGET_HAS_andc_i32;
846 case INDEX_op_orc_i32:
847 return TCG_TARGET_HAS_orc_i32;
848 case INDEX_op_eqv_i32:
849 return TCG_TARGET_HAS_eqv_i32;
850 case INDEX_op_nand_i32:
851 return TCG_TARGET_HAS_nand_i32;
852 case INDEX_op_nor_i32:
853 return TCG_TARGET_HAS_nor_i32;
854 case INDEX_op_clz_i32:
855 return TCG_TARGET_HAS_clz_i32;
856 case INDEX_op_ctz_i32:
857 return TCG_TARGET_HAS_ctz_i32;
858 case INDEX_op_ctpop_i32:
859 return TCG_TARGET_HAS_ctpop_i32;
861 case INDEX_op_brcond2_i32:
862 case INDEX_op_setcond2_i32:
863 return TCG_TARGET_REG_BITS == 32;
865 case INDEX_op_mov_i64:
866 case INDEX_op_movi_i64:
867 case INDEX_op_setcond_i64:
868 case INDEX_op_brcond_i64:
869 case INDEX_op_ld8u_i64:
870 case INDEX_op_ld8s_i64:
871 case INDEX_op_ld16u_i64:
872 case INDEX_op_ld16s_i64:
873 case INDEX_op_ld32u_i64:
874 case INDEX_op_ld32s_i64:
875 case INDEX_op_ld_i64:
876 case INDEX_op_st8_i64:
877 case INDEX_op_st16_i64:
878 case INDEX_op_st32_i64:
879 case INDEX_op_st_i64:
880 case INDEX_op_add_i64:
881 case INDEX_op_sub_i64:
882 case INDEX_op_mul_i64:
883 case INDEX_op_and_i64:
884 case INDEX_op_or_i64:
885 case INDEX_op_xor_i64:
886 case INDEX_op_shl_i64:
887 case INDEX_op_shr_i64:
888 case INDEX_op_sar_i64:
889 case INDEX_op_ext_i32_i64:
890 case INDEX_op_extu_i32_i64:
891 return TCG_TARGET_REG_BITS == 64;
893 case INDEX_op_movcond_i64:
894 return TCG_TARGET_HAS_movcond_i64;
895 case INDEX_op_div_i64:
896 case INDEX_op_divu_i64:
897 return TCG_TARGET_HAS_div_i64;
898 case INDEX_op_rem_i64:
899 case INDEX_op_remu_i64:
900 return TCG_TARGET_HAS_rem_i64;
901 case INDEX_op_div2_i64:
902 case INDEX_op_divu2_i64:
903 return TCG_TARGET_HAS_div2_i64;
904 case INDEX_op_rotl_i64:
905 case INDEX_op_rotr_i64:
906 return TCG_TARGET_HAS_rot_i64;
907 case INDEX_op_deposit_i64:
908 return TCG_TARGET_HAS_deposit_i64;
909 case INDEX_op_extract_i64:
910 return TCG_TARGET_HAS_extract_i64;
911 case INDEX_op_sextract_i64:
912 return TCG_TARGET_HAS_sextract_i64;
913 case INDEX_op_extrl_i64_i32:
914 return TCG_TARGET_HAS_extrl_i64_i32;
915 case INDEX_op_extrh_i64_i32:
916 return TCG_TARGET_HAS_extrh_i64_i32;
917 case INDEX_op_ext8s_i64:
918 return TCG_TARGET_HAS_ext8s_i64;
919 case INDEX_op_ext16s_i64:
920 return TCG_TARGET_HAS_ext16s_i64;
921 case INDEX_op_ext32s_i64:
922 return TCG_TARGET_HAS_ext32s_i64;
923 case INDEX_op_ext8u_i64:
924 return TCG_TARGET_HAS_ext8u_i64;
925 case INDEX_op_ext16u_i64:
926 return TCG_TARGET_HAS_ext16u_i64;
927 case INDEX_op_ext32u_i64:
928 return TCG_TARGET_HAS_ext32u_i64;
929 case INDEX_op_bswap16_i64:
930 return TCG_TARGET_HAS_bswap16_i64;
931 case INDEX_op_bswap32_i64:
932 return TCG_TARGET_HAS_bswap32_i64;
933 case INDEX_op_bswap64_i64:
934 return TCG_TARGET_HAS_bswap64_i64;
935 case INDEX_op_not_i64:
936 return TCG_TARGET_HAS_not_i64;
937 case INDEX_op_neg_i64:
938 return TCG_TARGET_HAS_neg_i64;
939 case INDEX_op_andc_i64:
940 return TCG_TARGET_HAS_andc_i64;
941 case INDEX_op_orc_i64:
942 return TCG_TARGET_HAS_orc_i64;
943 case INDEX_op_eqv_i64:
944 return TCG_TARGET_HAS_eqv_i64;
945 case INDEX_op_nand_i64:
946 return TCG_TARGET_HAS_nand_i64;
947 case INDEX_op_nor_i64:
948 return TCG_TARGET_HAS_nor_i64;
949 case INDEX_op_clz_i64:
950 return TCG_TARGET_HAS_clz_i64;
951 case INDEX_op_ctz_i64:
952 return TCG_TARGET_HAS_ctz_i64;
953 case INDEX_op_ctpop_i64:
954 return TCG_TARGET_HAS_ctpop_i64;
955 case INDEX_op_add2_i64:
956 return TCG_TARGET_HAS_add2_i64;
957 case INDEX_op_sub2_i64:
958 return TCG_TARGET_HAS_sub2_i64;
959 case INDEX_op_mulu2_i64:
960 return TCG_TARGET_HAS_mulu2_i64;
961 case INDEX_op_muls2_i64:
962 return TCG_TARGET_HAS_muls2_i64;
963 case INDEX_op_muluh_i64:
964 return TCG_TARGET_HAS_muluh_i64;
965 case INDEX_op_mulsh_i64:
966 return TCG_TARGET_HAS_mulsh_i64;
968 case NB_OPS:
969 break;
971 g_assert_not_reached();
974 /* Note: we convert the 64 bit args to 32 bit and do some alignment
975 and endian swap. Maybe it would be better to do the alignment
976 and endian swap in tcg_reg_alloc_call(). */
977 void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
979 TCGContext *s = &tcg_ctx;
980 int i, real_args, nb_rets, pi;
981 unsigned sizemask, flags;
982 TCGHelperInfo *info;
983 TCGOp *op;
985 info = g_hash_table_lookup(helper_table, (gpointer)func);
986 flags = info->flags;
987 sizemask = info->sizemask;
989 #if defined(__sparc__) && !defined(__arch64__) \
990 && !defined(CONFIG_TCG_INTERPRETER)
991 /* We have 64-bit values in one register, but need to pass as two
992 separate parameters. Split them. */
993 int orig_sizemask = sizemask;
994 int orig_nargs = nargs;
995 TCGv_i64 retl, reth;
996 TCGTemp *split_args[MAX_OPC_PARAM];
998 TCGV_UNUSED_I64(retl);
999 TCGV_UNUSED_I64(reth);
1000 if (sizemask != 0) {
1001 for (i = real_args = 0; i < nargs; ++i) {
1002 int is_64bit = sizemask & (1 << (i+1)*2);
1003 if (is_64bit) {
1004 TCGv_i64 orig = MAKE_TCGV_I64(temp_idx(args[i]));
1005 TCGv_i32 h = tcg_temp_new_i32();
1006 TCGv_i32 l = tcg_temp_new_i32();
1007 tcg_gen_extr_i64_i32(l, h, orig);
1008 split_args[real_args++] = tcgv_i32_temp(h);
1009 split_args[real_args++] = tcgv_i32_temp(l);
1010 } else {
1011 split_args[real_args++] = args[i];
1014 nargs = real_args;
1015 args = split_args;
1016 sizemask = 0;
1018 #elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
1019 for (i = 0; i < nargs; ++i) {
1020 int is_64bit = sizemask & (1 << (i+1)*2);
1021 int is_signed = sizemask & (2 << (i+1)*2);
1022 if (!is_64bit) {
1023 TCGv_i64 temp = tcg_temp_new_i64();
1024 TCGv_i64 orig = MAKE_TCGV_I64(temp_idx(args[i]));
1025 if (is_signed) {
1026 tcg_gen_ext32s_i64(temp, orig);
1027 } else {
1028 tcg_gen_ext32u_i64(temp, orig);
1030 args[i] = tcgv_i64_temp(temp);
1033 #endif /* TCG_TARGET_EXTEND_ARGS */
1035 i = s->gen_next_op_idx;
1036 tcg_debug_assert(i < OPC_BUF_SIZE);
1037 s->gen_op_buf[0].prev = i;
1038 s->gen_next_op_idx = i + 1;
1039 op = &s->gen_op_buf[i];
1041 /* Set links for sequential allocation during translation. */
1042 memset(op, 0, offsetof(TCGOp, args));
1043 op->opc = INDEX_op_call;
1044 op->prev = i - 1;
1045 op->next = i + 1;
1047 pi = 0;
1048 if (ret != NULL) {
1049 #if defined(__sparc__) && !defined(__arch64__) \
1050 && !defined(CONFIG_TCG_INTERPRETER)
1051 if (orig_sizemask & 1) {
1052 /* The 32-bit ABI is going to return the 64-bit value in
1053 the %o0/%o1 register pair. Prepare for this by using
1054 two return temporaries, and reassemble below. */
1055 retl = tcg_temp_new_i64();
1056 reth = tcg_temp_new_i64();
1057 op->args[pi++] = tcgv_i64_arg(reth);
1058 op->args[pi++] = tcgv_i64_arg(retl);
1059 nb_rets = 2;
1060 } else {
1061 op->args[pi++] = temp_arg(ret);
1062 nb_rets = 1;
1064 #else
1065 if (TCG_TARGET_REG_BITS < 64 && (sizemask & 1)) {
1066 #ifdef HOST_WORDS_BIGENDIAN
1067 op->args[pi++] = temp_arg(ret + 1);
1068 op->args[pi++] = temp_arg(ret);
1069 #else
1070 op->args[pi++] = temp_arg(ret);
1071 op->args[pi++] = temp_arg(ret + 1);
1072 #endif
1073 nb_rets = 2;
1074 } else {
1075 op->args[pi++] = temp_arg(ret);
1076 nb_rets = 1;
1078 #endif
1079 } else {
1080 nb_rets = 0;
1082 op->callo = nb_rets;
1084 real_args = 0;
1085 for (i = 0; i < nargs; i++) {
1086 int is_64bit = sizemask & (1 << (i+1)*2);
1087 if (TCG_TARGET_REG_BITS < 64 && is_64bit) {
1088 #ifdef TCG_TARGET_CALL_ALIGN_ARGS
1089 /* some targets want aligned 64 bit args */
1090 if (real_args & 1) {
1091 op->args[pi++] = TCG_CALL_DUMMY_ARG;
1092 real_args++;
1094 #endif
1095 /* If stack grows up, then we will be placing successive
1096 arguments at lower addresses, which means we need to
1097 reverse the order compared to how we would normally
1098 treat either big or little-endian. For those arguments
1099 that will wind up in registers, this still works for
1100 HPPA (the only current STACK_GROWSUP target) since the
1101 argument registers are *also* allocated in decreasing
1102 order. If another such target is added, this logic may
1103 have to get more complicated to differentiate between
1104 stack arguments and register arguments. */
1105 #if defined(HOST_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
1106 op->args[pi++] = temp_arg(args[i] + 1);
1107 op->args[pi++] = temp_arg(args[i]);
1108 #else
1109 op->args[pi++] = temp_arg(args[i]);
1110 op->args[pi++] = temp_arg(args[i] + 1);
1111 #endif
1112 real_args += 2;
1113 continue;
1116 op->args[pi++] = temp_arg(args[i]);
1117 real_args++;
1119 op->args[pi++] = (uintptr_t)func;
1120 op->args[pi++] = flags;
1121 op->calli = real_args;
1123 /* Make sure the fields didn't overflow. */
1124 tcg_debug_assert(op->calli == real_args);
1125 tcg_debug_assert(pi <= ARRAY_SIZE(op->args));
1127 #if defined(__sparc__) && !defined(__arch64__) \
1128 && !defined(CONFIG_TCG_INTERPRETER)
1129 /* Free all of the parts we allocated above. */
1130 for (i = real_args = 0; i < orig_nargs; ++i) {
1131 int is_64bit = orig_sizemask & (1 << (i+1)*2);
1132 if (is_64bit) {
1133 TCGv_i32 h = MAKE_TCGV_I32(temp_idx(args[real_args++]));
1134 TCGv_i32 l = MAKE_TCGV_I32(temp_idx(args[real_args++]));
1135 tcg_temp_free_i32(h);
1136 tcg_temp_free_i32(l);
1137 } else {
1138 real_args++;
1141 if (orig_sizemask & 1) {
1142 /* The 32-bit ABI returned two 32-bit pieces. Re-assemble them.
1143 Note that describing these as TCGv_i64 eliminates an unnecessary
1144 zero-extension that tcg_gen_concat_i32_i64 would create. */
1145 tcg_gen_concat32_i64(MAKE_TCGV_I64(temp_idx(ret)), retl, reth);
1146 tcg_temp_free_i64(retl);
1147 tcg_temp_free_i64(reth);
1149 #elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
1150 for (i = 0; i < nargs; ++i) {
1151 int is_64bit = sizemask & (1 << (i+1)*2);
1152 if (!is_64bit) {
1153 TCGv_i64 temp = MAKE_TCGV_I64(temp_idx(args[i]));
1154 tcg_temp_free_i64(temp);
1157 #endif /* TCG_TARGET_EXTEND_ARGS */
1160 static void tcg_reg_alloc_start(TCGContext *s)
1162 int i, n;
1163 TCGTemp *ts;
1165 for (i = 0, n = s->nb_globals; i < n; i++) {
1166 ts = &s->temps[i];
1167 ts->val_type = (ts->fixed_reg ? TEMP_VAL_REG : TEMP_VAL_MEM);
1169 for (n = s->nb_temps; i < n; i++) {
1170 ts = &s->temps[i];
1171 ts->val_type = (ts->temp_local ? TEMP_VAL_MEM : TEMP_VAL_DEAD);
1172 ts->mem_allocated = 0;
1173 ts->fixed_reg = 0;
1176 memset(s->reg_to_temp, 0, sizeof(s->reg_to_temp));
1179 static char *tcg_get_arg_str_ptr(TCGContext *s, char *buf, int buf_size,
1180 TCGTemp *ts)
1182 int idx = temp_idx(ts);
1184 if (ts->temp_global) {
1185 pstrcpy(buf, buf_size, ts->name);
1186 } else if (ts->temp_local) {
1187 snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
1188 } else {
1189 snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
1191 return buf;
1194 static char *tcg_get_arg_str(TCGContext *s, char *buf,
1195 int buf_size, TCGArg arg)
1197 return tcg_get_arg_str_ptr(s, buf, buf_size, arg_temp(arg));
1200 /* Find helper name. */
1201 static inline const char *tcg_find_helper(TCGContext *s, uintptr_t val)
1203 const char *ret = NULL;
1204 if (helper_table) {
1205 TCGHelperInfo *info = g_hash_table_lookup(helper_table, (gpointer)val);
1206 if (info) {
1207 ret = info->name;
1210 return ret;
1213 static const char * const cond_name[] =
1215 [TCG_COND_NEVER] = "never",
1216 [TCG_COND_ALWAYS] = "always",
1217 [TCG_COND_EQ] = "eq",
1218 [TCG_COND_NE] = "ne",
1219 [TCG_COND_LT] = "lt",
1220 [TCG_COND_GE] = "ge",
1221 [TCG_COND_LE] = "le",
1222 [TCG_COND_GT] = "gt",
1223 [TCG_COND_LTU] = "ltu",
1224 [TCG_COND_GEU] = "geu",
1225 [TCG_COND_LEU] = "leu",
1226 [TCG_COND_GTU] = "gtu"
1229 static const char * const ldst_name[] =
1231 [MO_UB] = "ub",
1232 [MO_SB] = "sb",
1233 [MO_LEUW] = "leuw",
1234 [MO_LESW] = "lesw",
1235 [MO_LEUL] = "leul",
1236 [MO_LESL] = "lesl",
1237 [MO_LEQ] = "leq",
1238 [MO_BEUW] = "beuw",
1239 [MO_BESW] = "besw",
1240 [MO_BEUL] = "beul",
1241 [MO_BESL] = "besl",
1242 [MO_BEQ] = "beq",
1245 static const char * const alignment_name[(MO_AMASK >> MO_ASHIFT) + 1] = {
1246 #ifdef ALIGNED_ONLY
1247 [MO_UNALN >> MO_ASHIFT] = "un+",
1248 [MO_ALIGN >> MO_ASHIFT] = "",
1249 #else
1250 [MO_UNALN >> MO_ASHIFT] = "",
1251 [MO_ALIGN >> MO_ASHIFT] = "al+",
1252 #endif
1253 [MO_ALIGN_2 >> MO_ASHIFT] = "al2+",
1254 [MO_ALIGN_4 >> MO_ASHIFT] = "al4+",
1255 [MO_ALIGN_8 >> MO_ASHIFT] = "al8+",
1256 [MO_ALIGN_16 >> MO_ASHIFT] = "al16+",
1257 [MO_ALIGN_32 >> MO_ASHIFT] = "al32+",
1258 [MO_ALIGN_64 >> MO_ASHIFT] = "al64+",
1261 void tcg_dump_ops(TCGContext *s)
1263 char buf[128];
1264 TCGOp *op;
1265 int oi;
1267 for (oi = s->gen_op_buf[0].next; oi != 0; oi = op->next) {
1268 int i, k, nb_oargs, nb_iargs, nb_cargs;
1269 const TCGOpDef *def;
1270 TCGOpcode c;
1271 int col = 0;
1273 op = &s->gen_op_buf[oi];
1274 c = op->opc;
1275 def = &tcg_op_defs[c];
1277 if (c == INDEX_op_insn_start) {
1278 col += qemu_log("%s ----", oi != s->gen_op_buf[0].next ? "\n" : "");
1280 for (i = 0; i < TARGET_INSN_START_WORDS; ++i) {
1281 target_ulong a;
1282 #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
1283 a = deposit64(op->args[i * 2], 32, 32, op->args[i * 2 + 1]);
1284 #else
1285 a = op->args[i];
1286 #endif
1287 col += qemu_log(" " TARGET_FMT_lx, a);
1289 } else if (c == INDEX_op_call) {
1290 /* variable number of arguments */
1291 nb_oargs = op->callo;
1292 nb_iargs = op->calli;
1293 nb_cargs = def->nb_cargs;
1295 /* function name, flags, out args */
1296 col += qemu_log(" %s %s,$0x%" TCG_PRIlx ",$%d", def->name,
1297 tcg_find_helper(s, op->args[nb_oargs + nb_iargs]),
1298 op->args[nb_oargs + nb_iargs + 1], nb_oargs);
1299 for (i = 0; i < nb_oargs; i++) {
1300 col += qemu_log(",%s", tcg_get_arg_str(s, buf, sizeof(buf),
1301 op->args[i]));
1303 for (i = 0; i < nb_iargs; i++) {
1304 TCGArg arg = op->args[nb_oargs + i];
1305 const char *t = "<dummy>";
1306 if (arg != TCG_CALL_DUMMY_ARG) {
1307 t = tcg_get_arg_str(s, buf, sizeof(buf), arg);
1309 col += qemu_log(",%s", t);
1311 } else {
1312 col += qemu_log(" %s ", def->name);
1314 nb_oargs = def->nb_oargs;
1315 nb_iargs = def->nb_iargs;
1316 nb_cargs = def->nb_cargs;
1318 k = 0;
1319 for (i = 0; i < nb_oargs; i++) {
1320 if (k != 0) {
1321 col += qemu_log(",");
1323 col += qemu_log("%s", tcg_get_arg_str(s, buf, sizeof(buf),
1324 op->args[k++]));
1326 for (i = 0; i < nb_iargs; i++) {
1327 if (k != 0) {
1328 col += qemu_log(",");
1330 col += qemu_log("%s", tcg_get_arg_str(s, buf, sizeof(buf),
1331 op->args[k++]));
1333 switch (c) {
1334 case INDEX_op_brcond_i32:
1335 case INDEX_op_setcond_i32:
1336 case INDEX_op_movcond_i32:
1337 case INDEX_op_brcond2_i32:
1338 case INDEX_op_setcond2_i32:
1339 case INDEX_op_brcond_i64:
1340 case INDEX_op_setcond_i64:
1341 case INDEX_op_movcond_i64:
1342 if (op->args[k] < ARRAY_SIZE(cond_name)
1343 && cond_name[op->args[k]]) {
1344 col += qemu_log(",%s", cond_name[op->args[k++]]);
1345 } else {
1346 col += qemu_log(",$0x%" TCG_PRIlx, op->args[k++]);
1348 i = 1;
1349 break;
1350 case INDEX_op_qemu_ld_i32:
1351 case INDEX_op_qemu_st_i32:
1352 case INDEX_op_qemu_ld_i64:
1353 case INDEX_op_qemu_st_i64:
1355 TCGMemOpIdx oi = op->args[k++];
1356 TCGMemOp op = get_memop(oi);
1357 unsigned ix = get_mmuidx(oi);
1359 if (op & ~(MO_AMASK | MO_BSWAP | MO_SSIZE)) {
1360 col += qemu_log(",$0x%x,%u", op, ix);
1361 } else {
1362 const char *s_al, *s_op;
1363 s_al = alignment_name[(op & MO_AMASK) >> MO_ASHIFT];
1364 s_op = ldst_name[op & (MO_BSWAP | MO_SSIZE)];
1365 col += qemu_log(",%s%s,%u", s_al, s_op, ix);
1367 i = 1;
1369 break;
1370 default:
1371 i = 0;
1372 break;
1374 switch (c) {
1375 case INDEX_op_set_label:
1376 case INDEX_op_br:
1377 case INDEX_op_brcond_i32:
1378 case INDEX_op_brcond_i64:
1379 case INDEX_op_brcond2_i32:
1380 col += qemu_log("%s$L%d", k ? "," : "",
1381 arg_label(op->args[k])->id);
1382 i++, k++;
1383 break;
1384 default:
1385 break;
1387 for (; i < nb_cargs; i++, k++) {
1388 col += qemu_log("%s$0x%" TCG_PRIlx, k ? "," : "", op->args[k]);
1391 if (op->life) {
1392 unsigned life = op->life;
1394 for (; col < 48; ++col) {
1395 putc(' ', qemu_logfile);
1398 if (life & (SYNC_ARG * 3)) {
1399 qemu_log(" sync:");
1400 for (i = 0; i < 2; ++i) {
1401 if (life & (SYNC_ARG << i)) {
1402 qemu_log(" %d", i);
1406 life /= DEAD_ARG;
1407 if (life) {
1408 qemu_log(" dead:");
1409 for (i = 0; life; ++i, life >>= 1) {
1410 if (life & 1) {
1411 qemu_log(" %d", i);
1416 qemu_log("\n");
1420 /* we give more priority to constraints with less registers */
1421 static int get_constraint_priority(const TCGOpDef *def, int k)
1423 const TCGArgConstraint *arg_ct;
1425 int i, n;
1426 arg_ct = &def->args_ct[k];
1427 if (arg_ct->ct & TCG_CT_ALIAS) {
1428 /* an alias is equivalent to a single register */
1429 n = 1;
1430 } else {
1431 if (!(arg_ct->ct & TCG_CT_REG))
1432 return 0;
1433 n = 0;
1434 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1435 if (tcg_regset_test_reg(arg_ct->u.regs, i))
1436 n++;
1439 return TCG_TARGET_NB_REGS - n + 1;
1442 /* sort from highest priority to lowest */
1443 static void sort_constraints(TCGOpDef *def, int start, int n)
1445 int i, j, p1, p2, tmp;
1447 for(i = 0; i < n; i++)
1448 def->sorted_args[start + i] = start + i;
1449 if (n <= 1)
1450 return;
1451 for(i = 0; i < n - 1; i++) {
1452 for(j = i + 1; j < n; j++) {
1453 p1 = get_constraint_priority(def, def->sorted_args[start + i]);
1454 p2 = get_constraint_priority(def, def->sorted_args[start + j]);
1455 if (p1 < p2) {
1456 tmp = def->sorted_args[start + i];
1457 def->sorted_args[start + i] = def->sorted_args[start + j];
1458 def->sorted_args[start + j] = tmp;
1464 static void process_op_defs(TCGContext *s)
1466 TCGOpcode op;
1468 for (op = 0; op < NB_OPS; op++) {
1469 TCGOpDef *def = &tcg_op_defs[op];
1470 const TCGTargetOpDef *tdefs;
1471 TCGType type;
1472 int i, nb_args;
1474 if (def->flags & TCG_OPF_NOT_PRESENT) {
1475 continue;
1478 nb_args = def->nb_iargs + def->nb_oargs;
1479 if (nb_args == 0) {
1480 continue;
1483 tdefs = tcg_target_op_def(op);
1484 /* Missing TCGTargetOpDef entry. */
1485 tcg_debug_assert(tdefs != NULL);
1487 type = (def->flags & TCG_OPF_64BIT ? TCG_TYPE_I64 : TCG_TYPE_I32);
1488 for (i = 0; i < nb_args; i++) {
1489 const char *ct_str = tdefs->args_ct_str[i];
1490 /* Incomplete TCGTargetOpDef entry. */
1491 tcg_debug_assert(ct_str != NULL);
1493 def->args_ct[i].u.regs = 0;
1494 def->args_ct[i].ct = 0;
1495 while (*ct_str != '\0') {
1496 switch(*ct_str) {
1497 case '0' ... '9':
1499 int oarg = *ct_str - '0';
1500 tcg_debug_assert(ct_str == tdefs->args_ct_str[i]);
1501 tcg_debug_assert(oarg < def->nb_oargs);
1502 tcg_debug_assert(def->args_ct[oarg].ct & TCG_CT_REG);
1503 /* TCG_CT_ALIAS is for the output arguments.
1504 The input is tagged with TCG_CT_IALIAS. */
1505 def->args_ct[i] = def->args_ct[oarg];
1506 def->args_ct[oarg].ct |= TCG_CT_ALIAS;
1507 def->args_ct[oarg].alias_index = i;
1508 def->args_ct[i].ct |= TCG_CT_IALIAS;
1509 def->args_ct[i].alias_index = oarg;
1511 ct_str++;
1512 break;
1513 case '&':
1514 def->args_ct[i].ct |= TCG_CT_NEWREG;
1515 ct_str++;
1516 break;
1517 case 'i':
1518 def->args_ct[i].ct |= TCG_CT_CONST;
1519 ct_str++;
1520 break;
1521 default:
1522 ct_str = target_parse_constraint(&def->args_ct[i],
1523 ct_str, type);
1524 /* Typo in TCGTargetOpDef constraint. */
1525 tcg_debug_assert(ct_str != NULL);
1530 /* TCGTargetOpDef entry with too much information? */
1531 tcg_debug_assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL);
1533 /* sort the constraints (XXX: this is just an heuristic) */
1534 sort_constraints(def, 0, def->nb_oargs);
1535 sort_constraints(def, def->nb_oargs, def->nb_iargs);
1539 void tcg_op_remove(TCGContext *s, TCGOp *op)
1541 int next = op->next;
1542 int prev = op->prev;
1544 /* We should never attempt to remove the list terminator. */
1545 tcg_debug_assert(op != &s->gen_op_buf[0]);
1547 s->gen_op_buf[next].prev = prev;
1548 s->gen_op_buf[prev].next = next;
1550 memset(op, 0, sizeof(*op));
1552 #ifdef CONFIG_PROFILER
1553 s->del_op_count++;
1554 #endif
1557 TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *old_op,
1558 TCGOpcode opc, int nargs)
1560 int oi = s->gen_next_op_idx;
1561 int prev = old_op->prev;
1562 int next = old_op - s->gen_op_buf;
1563 TCGOp *new_op;
1565 tcg_debug_assert(oi < OPC_BUF_SIZE);
1566 s->gen_next_op_idx = oi + 1;
1568 new_op = &s->gen_op_buf[oi];
1569 *new_op = (TCGOp){
1570 .opc = opc,
1571 .prev = prev,
1572 .next = next
1574 s->gen_op_buf[prev].next = oi;
1575 old_op->prev = oi;
1577 return new_op;
1580 TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *old_op,
1581 TCGOpcode opc, int nargs)
1583 int oi = s->gen_next_op_idx;
1584 int prev = old_op - s->gen_op_buf;
1585 int next = old_op->next;
1586 TCGOp *new_op;
1588 tcg_debug_assert(oi < OPC_BUF_SIZE);
1589 s->gen_next_op_idx = oi + 1;
1591 new_op = &s->gen_op_buf[oi];
1592 *new_op = (TCGOp){
1593 .opc = opc,
1594 .prev = prev,
1595 .next = next
1597 s->gen_op_buf[next].prev = oi;
1598 old_op->next = oi;
1600 return new_op;
1603 #define TS_DEAD 1
1604 #define TS_MEM 2
1606 #define IS_DEAD_ARG(n) (arg_life & (DEAD_ARG << (n)))
1607 #define NEED_SYNC_ARG(n) (arg_life & (SYNC_ARG << (n)))
1609 /* liveness analysis: end of function: all temps are dead, and globals
1610 should be in memory. */
1611 static void tcg_la_func_end(TCGContext *s)
1613 int ng = s->nb_globals;
1614 int nt = s->nb_temps;
1615 int i;
1617 for (i = 0; i < ng; ++i) {
1618 s->temps[i].state = TS_DEAD | TS_MEM;
1620 for (i = ng; i < nt; ++i) {
1621 s->temps[i].state = TS_DEAD;
1625 /* liveness analysis: end of basic block: all temps are dead, globals
1626 and local temps should be in memory. */
1627 static void tcg_la_bb_end(TCGContext *s)
1629 int ng = s->nb_globals;
1630 int nt = s->nb_temps;
1631 int i;
1633 for (i = 0; i < ng; ++i) {
1634 s->temps[i].state = TS_DEAD | TS_MEM;
1636 for (i = ng; i < nt; ++i) {
1637 s->temps[i].state = (s->temps[i].temp_local
1638 ? TS_DEAD | TS_MEM
1639 : TS_DEAD);
1643 /* Liveness analysis : update the opc_arg_life array to tell if a
1644 given input arguments is dead. Instructions updating dead
1645 temporaries are removed. */
1646 static void liveness_pass_1(TCGContext *s)
1648 int nb_globals = s->nb_globals;
1649 int oi, oi_prev;
1651 tcg_la_func_end(s);
1653 for (oi = s->gen_op_buf[0].prev; oi != 0; oi = oi_prev) {
1654 int i, nb_iargs, nb_oargs;
1655 TCGOpcode opc_new, opc_new2;
1656 bool have_opc_new2;
1657 TCGLifeData arg_life = 0;
1658 TCGTemp *arg_ts;
1660 TCGOp * const op = &s->gen_op_buf[oi];
1661 TCGOpcode opc = op->opc;
1662 const TCGOpDef *def = &tcg_op_defs[opc];
1664 oi_prev = op->prev;
1666 switch (opc) {
1667 case INDEX_op_call:
1669 int call_flags;
1671 nb_oargs = op->callo;
1672 nb_iargs = op->calli;
1673 call_flags = op->args[nb_oargs + nb_iargs + 1];
1675 /* pure functions can be removed if their result is unused */
1676 if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
1677 for (i = 0; i < nb_oargs; i++) {
1678 arg_ts = arg_temp(op->args[i]);
1679 if (arg_ts->state != TS_DEAD) {
1680 goto do_not_remove_call;
1683 goto do_remove;
1684 } else {
1685 do_not_remove_call:
1687 /* output args are dead */
1688 for (i = 0; i < nb_oargs; i++) {
1689 arg_ts = arg_temp(op->args[i]);
1690 if (arg_ts->state & TS_DEAD) {
1691 arg_life |= DEAD_ARG << i;
1693 if (arg_ts->state & TS_MEM) {
1694 arg_life |= SYNC_ARG << i;
1696 arg_ts->state = TS_DEAD;
1699 if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
1700 TCG_CALL_NO_READ_GLOBALS))) {
1701 /* globals should go back to memory */
1702 for (i = 0; i < nb_globals; i++) {
1703 s->temps[i].state = TS_DEAD | TS_MEM;
1705 } else if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
1706 /* globals should be synced to memory */
1707 for (i = 0; i < nb_globals; i++) {
1708 s->temps[i].state |= TS_MEM;
1712 /* record arguments that die in this helper */
1713 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1714 arg_ts = arg_temp(op->args[i]);
1715 if (arg_ts && arg_ts->state & TS_DEAD) {
1716 arg_life |= DEAD_ARG << i;
1719 /* input arguments are live for preceding opcodes */
1720 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1721 arg_ts = arg_temp(op->args[i]);
1722 if (arg_ts) {
1723 arg_ts->state &= ~TS_DEAD;
1728 break;
1729 case INDEX_op_insn_start:
1730 break;
1731 case INDEX_op_discard:
1732 /* mark the temporary as dead */
1733 arg_temp(op->args[0])->state = TS_DEAD;
1734 break;
1736 case INDEX_op_add2_i32:
1737 opc_new = INDEX_op_add_i32;
1738 goto do_addsub2;
1739 case INDEX_op_sub2_i32:
1740 opc_new = INDEX_op_sub_i32;
1741 goto do_addsub2;
1742 case INDEX_op_add2_i64:
1743 opc_new = INDEX_op_add_i64;
1744 goto do_addsub2;
1745 case INDEX_op_sub2_i64:
1746 opc_new = INDEX_op_sub_i64;
1747 do_addsub2:
1748 nb_iargs = 4;
1749 nb_oargs = 2;
1750 /* Test if the high part of the operation is dead, but not
1751 the low part. The result can be optimized to a simple
1752 add or sub. This happens often for x86_64 guest when the
1753 cpu mode is set to 32 bit. */
1754 if (arg_temp(op->args[1])->state == TS_DEAD) {
1755 if (arg_temp(op->args[0])->state == TS_DEAD) {
1756 goto do_remove;
1758 /* Replace the opcode and adjust the args in place,
1759 leaving 3 unused args at the end. */
1760 op->opc = opc = opc_new;
1761 op->args[1] = op->args[2];
1762 op->args[2] = op->args[4];
1763 /* Fall through and mark the single-word operation live. */
1764 nb_iargs = 2;
1765 nb_oargs = 1;
1767 goto do_not_remove;
1769 case INDEX_op_mulu2_i32:
1770 opc_new = INDEX_op_mul_i32;
1771 opc_new2 = INDEX_op_muluh_i32;
1772 have_opc_new2 = TCG_TARGET_HAS_muluh_i32;
1773 goto do_mul2;
1774 case INDEX_op_muls2_i32:
1775 opc_new = INDEX_op_mul_i32;
1776 opc_new2 = INDEX_op_mulsh_i32;
1777 have_opc_new2 = TCG_TARGET_HAS_mulsh_i32;
1778 goto do_mul2;
1779 case INDEX_op_mulu2_i64:
1780 opc_new = INDEX_op_mul_i64;
1781 opc_new2 = INDEX_op_muluh_i64;
1782 have_opc_new2 = TCG_TARGET_HAS_muluh_i64;
1783 goto do_mul2;
1784 case INDEX_op_muls2_i64:
1785 opc_new = INDEX_op_mul_i64;
1786 opc_new2 = INDEX_op_mulsh_i64;
1787 have_opc_new2 = TCG_TARGET_HAS_mulsh_i64;
1788 goto do_mul2;
1789 do_mul2:
1790 nb_iargs = 2;
1791 nb_oargs = 2;
1792 if (arg_temp(op->args[1])->state == TS_DEAD) {
1793 if (arg_temp(op->args[0])->state == TS_DEAD) {
1794 /* Both parts of the operation are dead. */
1795 goto do_remove;
1797 /* The high part of the operation is dead; generate the low. */
1798 op->opc = opc = opc_new;
1799 op->args[1] = op->args[2];
1800 op->args[2] = op->args[3];
1801 } else if (arg_temp(op->args[0])->state == TS_DEAD && have_opc_new2) {
1802 /* The low part of the operation is dead; generate the high. */
1803 op->opc = opc = opc_new2;
1804 op->args[0] = op->args[1];
1805 op->args[1] = op->args[2];
1806 op->args[2] = op->args[3];
1807 } else {
1808 goto do_not_remove;
1810 /* Mark the single-word operation live. */
1811 nb_oargs = 1;
1812 goto do_not_remove;
1814 default:
1815 /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
1816 nb_iargs = def->nb_iargs;
1817 nb_oargs = def->nb_oargs;
1819 /* Test if the operation can be removed because all
1820 its outputs are dead. We assume that nb_oargs == 0
1821 implies side effects */
1822 if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
1823 for (i = 0; i < nb_oargs; i++) {
1824 if (arg_temp(op->args[i])->state != TS_DEAD) {
1825 goto do_not_remove;
1828 do_remove:
1829 tcg_op_remove(s, op);
1830 } else {
1831 do_not_remove:
1832 /* output args are dead */
1833 for (i = 0; i < nb_oargs; i++) {
1834 arg_ts = arg_temp(op->args[i]);
1835 if (arg_ts->state & TS_DEAD) {
1836 arg_life |= DEAD_ARG << i;
1838 if (arg_ts->state & TS_MEM) {
1839 arg_life |= SYNC_ARG << i;
1841 arg_ts->state = TS_DEAD;
1844 /* if end of basic block, update */
1845 if (def->flags & TCG_OPF_BB_END) {
1846 tcg_la_bb_end(s);
1847 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
1848 /* globals should be synced to memory */
1849 for (i = 0; i < nb_globals; i++) {
1850 s->temps[i].state |= TS_MEM;
1854 /* record arguments that die in this opcode */
1855 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1856 arg_ts = arg_temp(op->args[i]);
1857 if (arg_ts->state & TS_DEAD) {
1858 arg_life |= DEAD_ARG << i;
1861 /* input arguments are live for preceding opcodes */
1862 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1863 arg_temp(op->args[i])->state &= ~TS_DEAD;
1866 break;
1868 op->life = arg_life;
1872 /* Liveness analysis: Convert indirect regs to direct temporaries. */
1873 static bool liveness_pass_2(TCGContext *s)
1875 int nb_globals = s->nb_globals;
1876 int nb_temps, i, oi, oi_next;
1877 bool changes = false;
1879 /* Create a temporary for each indirect global. */
1880 for (i = 0; i < nb_globals; ++i) {
1881 TCGTemp *its = &s->temps[i];
1882 if (its->indirect_reg) {
1883 TCGTemp *dts = tcg_temp_alloc(s);
1884 dts->type = its->type;
1885 dts->base_type = its->base_type;
1886 its->state_ptr = dts;
1887 } else {
1888 its->state_ptr = NULL;
1890 /* All globals begin dead. */
1891 its->state = TS_DEAD;
1893 for (nb_temps = s->nb_temps; i < nb_temps; ++i) {
1894 TCGTemp *its = &s->temps[i];
1895 its->state_ptr = NULL;
1896 its->state = TS_DEAD;
1899 for (oi = s->gen_op_buf[0].next; oi != 0; oi = oi_next) {
1900 TCGOp *op = &s->gen_op_buf[oi];
1901 TCGOpcode opc = op->opc;
1902 const TCGOpDef *def = &tcg_op_defs[opc];
1903 TCGLifeData arg_life = op->life;
1904 int nb_iargs, nb_oargs, call_flags;
1905 TCGTemp *arg_ts, *dir_ts;
1907 oi_next = op->next;
1909 if (opc == INDEX_op_call) {
1910 nb_oargs = op->callo;
1911 nb_iargs = op->calli;
1912 call_flags = op->args[nb_oargs + nb_iargs + 1];
1913 } else {
1914 nb_iargs = def->nb_iargs;
1915 nb_oargs = def->nb_oargs;
1917 /* Set flags similar to how calls require. */
1918 if (def->flags & TCG_OPF_BB_END) {
1919 /* Like writing globals: save_globals */
1920 call_flags = 0;
1921 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
1922 /* Like reading globals: sync_globals */
1923 call_flags = TCG_CALL_NO_WRITE_GLOBALS;
1924 } else {
1925 /* No effect on globals. */
1926 call_flags = (TCG_CALL_NO_READ_GLOBALS |
1927 TCG_CALL_NO_WRITE_GLOBALS);
1931 /* Make sure that input arguments are available. */
1932 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1933 arg_ts = arg_temp(op->args[i]);
1934 if (arg_ts) {
1935 dir_ts = arg_ts->state_ptr;
1936 if (dir_ts && arg_ts->state == TS_DEAD) {
1937 TCGOpcode lopc = (arg_ts->type == TCG_TYPE_I32
1938 ? INDEX_op_ld_i32
1939 : INDEX_op_ld_i64);
1940 TCGOp *lop = tcg_op_insert_before(s, op, lopc, 3);
1942 lop->args[0] = temp_arg(dir_ts);
1943 lop->args[1] = temp_arg(arg_ts->mem_base);
1944 lop->args[2] = arg_ts->mem_offset;
1946 /* Loaded, but synced with memory. */
1947 arg_ts->state = TS_MEM;
1952 /* Perform input replacement, and mark inputs that became dead.
1953 No action is required except keeping temp_state up to date
1954 so that we reload when needed. */
1955 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1956 arg_ts = arg_temp(op->args[i]);
1957 if (arg_ts) {
1958 dir_ts = arg_ts->state_ptr;
1959 if (dir_ts) {
1960 op->args[i] = temp_arg(dir_ts);
1961 changes = true;
1962 if (IS_DEAD_ARG(i)) {
1963 arg_ts->state = TS_DEAD;
1969 /* Liveness analysis should ensure that the following are
1970 all correct, for call sites and basic block end points. */
1971 if (call_flags & TCG_CALL_NO_READ_GLOBALS) {
1972 /* Nothing to do */
1973 } else if (call_flags & TCG_CALL_NO_WRITE_GLOBALS) {
1974 for (i = 0; i < nb_globals; ++i) {
1975 /* Liveness should see that globals are synced back,
1976 that is, either TS_DEAD or TS_MEM. */
1977 arg_ts = &s->temps[i];
1978 tcg_debug_assert(arg_ts->state_ptr == 0
1979 || arg_ts->state != 0);
1981 } else {
1982 for (i = 0; i < nb_globals; ++i) {
1983 /* Liveness should see that globals are saved back,
1984 that is, TS_DEAD, waiting to be reloaded. */
1985 arg_ts = &s->temps[i];
1986 tcg_debug_assert(arg_ts->state_ptr == 0
1987 || arg_ts->state == TS_DEAD);
1991 /* Outputs become available. */
1992 for (i = 0; i < nb_oargs; i++) {
1993 arg_ts = arg_temp(op->args[i]);
1994 dir_ts = arg_ts->state_ptr;
1995 if (!dir_ts) {
1996 continue;
1998 op->args[i] = temp_arg(dir_ts);
1999 changes = true;
2001 /* The output is now live and modified. */
2002 arg_ts->state = 0;
2004 /* Sync outputs upon their last write. */
2005 if (NEED_SYNC_ARG(i)) {
2006 TCGOpcode sopc = (arg_ts->type == TCG_TYPE_I32
2007 ? INDEX_op_st_i32
2008 : INDEX_op_st_i64);
2009 TCGOp *sop = tcg_op_insert_after(s, op, sopc, 3);
2011 sop->args[0] = temp_arg(dir_ts);
2012 sop->args[1] = temp_arg(arg_ts->mem_base);
2013 sop->args[2] = arg_ts->mem_offset;
2015 arg_ts->state = TS_MEM;
2017 /* Drop outputs that are dead. */
2018 if (IS_DEAD_ARG(i)) {
2019 arg_ts->state = TS_DEAD;
2024 return changes;
2027 #ifdef CONFIG_DEBUG_TCG
2028 static void dump_regs(TCGContext *s)
2030 TCGTemp *ts;
2031 int i;
2032 char buf[64];
2034 for(i = 0; i < s->nb_temps; i++) {
2035 ts = &s->temps[i];
2036 printf(" %10s: ", tcg_get_arg_str_ptr(s, buf, sizeof(buf), ts));
2037 switch(ts->val_type) {
2038 case TEMP_VAL_REG:
2039 printf("%s", tcg_target_reg_names[ts->reg]);
2040 break;
2041 case TEMP_VAL_MEM:
2042 printf("%d(%s)", (int)ts->mem_offset,
2043 tcg_target_reg_names[ts->mem_base->reg]);
2044 break;
2045 case TEMP_VAL_CONST:
2046 printf("$0x%" TCG_PRIlx, ts->val);
2047 break;
2048 case TEMP_VAL_DEAD:
2049 printf("D");
2050 break;
2051 default:
2052 printf("???");
2053 break;
2055 printf("\n");
2058 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
2059 if (s->reg_to_temp[i] != NULL) {
2060 printf("%s: %s\n",
2061 tcg_target_reg_names[i],
2062 tcg_get_arg_str_ptr(s, buf, sizeof(buf), s->reg_to_temp[i]));
2067 static void check_regs(TCGContext *s)
2069 int reg;
2070 int k;
2071 TCGTemp *ts;
2072 char buf[64];
2074 for (reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
2075 ts = s->reg_to_temp[reg];
2076 if (ts != NULL) {
2077 if (ts->val_type != TEMP_VAL_REG || ts->reg != reg) {
2078 printf("Inconsistency for register %s:\n",
2079 tcg_target_reg_names[reg]);
2080 goto fail;
2084 for (k = 0; k < s->nb_temps; k++) {
2085 ts = &s->temps[k];
2086 if (ts->val_type == TEMP_VAL_REG && !ts->fixed_reg
2087 && s->reg_to_temp[ts->reg] != ts) {
2088 printf("Inconsistency for temp %s:\n",
2089 tcg_get_arg_str_ptr(s, buf, sizeof(buf), ts));
2090 fail:
2091 printf("reg state:\n");
2092 dump_regs(s);
2093 tcg_abort();
2097 #endif
2099 static void temp_allocate_frame(TCGContext *s, TCGTemp *ts)
2101 #if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64)
2102 /* Sparc64 stack is accessed with offset of 2047 */
2103 s->current_frame_offset = (s->current_frame_offset +
2104 (tcg_target_long)sizeof(tcg_target_long) - 1) &
2105 ~(sizeof(tcg_target_long) - 1);
2106 #endif
2107 if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
2108 s->frame_end) {
2109 tcg_abort();
2111 ts->mem_offset = s->current_frame_offset;
2112 ts->mem_base = s->frame_temp;
2113 ts->mem_allocated = 1;
2114 s->current_frame_offset += sizeof(tcg_target_long);
2117 static void temp_load(TCGContext *, TCGTemp *, TCGRegSet, TCGRegSet);
2119 /* Mark a temporary as free or dead. If 'free_or_dead' is negative,
2120 mark it free; otherwise mark it dead. */
2121 static void temp_free_or_dead(TCGContext *s, TCGTemp *ts, int free_or_dead)
2123 if (ts->fixed_reg) {
2124 return;
2126 if (ts->val_type == TEMP_VAL_REG) {
2127 s->reg_to_temp[ts->reg] = NULL;
2129 ts->val_type = (free_or_dead < 0
2130 || ts->temp_local
2131 || ts->temp_global
2132 ? TEMP_VAL_MEM : TEMP_VAL_DEAD);
2135 /* Mark a temporary as dead. */
2136 static inline void temp_dead(TCGContext *s, TCGTemp *ts)
2138 temp_free_or_dead(s, ts, 1);
2141 /* Sync a temporary to memory. 'allocated_regs' is used in case a temporary
2142 registers needs to be allocated to store a constant. If 'free_or_dead'
2143 is non-zero, subsequently release the temporary; if it is positive, the
2144 temp is dead; if it is negative, the temp is free. */
2145 static void temp_sync(TCGContext *s, TCGTemp *ts,
2146 TCGRegSet allocated_regs, int free_or_dead)
2148 if (ts->fixed_reg) {
2149 return;
2151 if (!ts->mem_coherent) {
2152 if (!ts->mem_allocated) {
2153 temp_allocate_frame(s, ts);
2155 switch (ts->val_type) {
2156 case TEMP_VAL_CONST:
2157 /* If we're going to free the temp immediately, then we won't
2158 require it later in a register, so attempt to store the
2159 constant to memory directly. */
2160 if (free_or_dead
2161 && tcg_out_sti(s, ts->type, ts->val,
2162 ts->mem_base->reg, ts->mem_offset)) {
2163 break;
2165 temp_load(s, ts, tcg_target_available_regs[ts->type],
2166 allocated_regs);
2167 /* fallthrough */
2169 case TEMP_VAL_REG:
2170 tcg_out_st(s, ts->type, ts->reg,
2171 ts->mem_base->reg, ts->mem_offset);
2172 break;
2174 case TEMP_VAL_MEM:
2175 break;
2177 case TEMP_VAL_DEAD:
2178 default:
2179 tcg_abort();
2181 ts->mem_coherent = 1;
2183 if (free_or_dead) {
2184 temp_free_or_dead(s, ts, free_or_dead);
2188 /* free register 'reg' by spilling the corresponding temporary if necessary */
2189 static void tcg_reg_free(TCGContext *s, TCGReg reg, TCGRegSet allocated_regs)
2191 TCGTemp *ts = s->reg_to_temp[reg];
2192 if (ts != NULL) {
2193 temp_sync(s, ts, allocated_regs, -1);
2197 /* Allocate a register belonging to reg1 & ~reg2 */
2198 static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet desired_regs,
2199 TCGRegSet allocated_regs, bool rev)
2201 int i, n = ARRAY_SIZE(tcg_target_reg_alloc_order);
2202 const int *order;
2203 TCGReg reg;
2204 TCGRegSet reg_ct;
2206 reg_ct = desired_regs & ~allocated_regs;
2207 order = rev ? indirect_reg_alloc_order : tcg_target_reg_alloc_order;
2209 /* first try free registers */
2210 for(i = 0; i < n; i++) {
2211 reg = order[i];
2212 if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == NULL)
2213 return reg;
2216 /* XXX: do better spill choice */
2217 for(i = 0; i < n; i++) {
2218 reg = order[i];
2219 if (tcg_regset_test_reg(reg_ct, reg)) {
2220 tcg_reg_free(s, reg, allocated_regs);
2221 return reg;
2225 tcg_abort();
2228 /* Make sure the temporary is in a register. If needed, allocate the register
2229 from DESIRED while avoiding ALLOCATED. */
2230 static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs,
2231 TCGRegSet allocated_regs)
2233 TCGReg reg;
2235 switch (ts->val_type) {
2236 case TEMP_VAL_REG:
2237 return;
2238 case TEMP_VAL_CONST:
2239 reg = tcg_reg_alloc(s, desired_regs, allocated_regs, ts->indirect_base);
2240 tcg_out_movi(s, ts->type, reg, ts->val);
2241 ts->mem_coherent = 0;
2242 break;
2243 case TEMP_VAL_MEM:
2244 reg = tcg_reg_alloc(s, desired_regs, allocated_regs, ts->indirect_base);
2245 tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
2246 ts->mem_coherent = 1;
2247 break;
2248 case TEMP_VAL_DEAD:
2249 default:
2250 tcg_abort();
2252 ts->reg = reg;
2253 ts->val_type = TEMP_VAL_REG;
2254 s->reg_to_temp[reg] = ts;
2257 /* Save a temporary to memory. 'allocated_regs' is used in case a
2258 temporary registers needs to be allocated to store a constant. */
2259 static void temp_save(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs)
2261 /* The liveness analysis already ensures that globals are back
2262 in memory. Keep an tcg_debug_assert for safety. */
2263 tcg_debug_assert(ts->val_type == TEMP_VAL_MEM || ts->fixed_reg);
2266 /* save globals to their canonical location and assume they can be
2267 modified be the following code. 'allocated_regs' is used in case a
2268 temporary registers needs to be allocated to store a constant. */
2269 static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
2271 int i, n;
2273 for (i = 0, n = s->nb_globals; i < n; i++) {
2274 temp_save(s, &s->temps[i], allocated_regs);
2278 /* sync globals to their canonical location and assume they can be
2279 read by the following code. 'allocated_regs' is used in case a
2280 temporary registers needs to be allocated to store a constant. */
2281 static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
2283 int i, n;
2285 for (i = 0, n = s->nb_globals; i < n; i++) {
2286 TCGTemp *ts = &s->temps[i];
2287 tcg_debug_assert(ts->val_type != TEMP_VAL_REG
2288 || ts->fixed_reg
2289 || ts->mem_coherent);
2293 /* at the end of a basic block, we assume all temporaries are dead and
2294 all globals are stored at their canonical location. */
2295 static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
2297 int i;
2299 for (i = s->nb_globals; i < s->nb_temps; i++) {
2300 TCGTemp *ts = &s->temps[i];
2301 if (ts->temp_local) {
2302 temp_save(s, ts, allocated_regs);
2303 } else {
2304 /* The liveness analysis already ensures that temps are dead.
2305 Keep an tcg_debug_assert for safety. */
2306 tcg_debug_assert(ts->val_type == TEMP_VAL_DEAD);
2310 save_globals(s, allocated_regs);
2313 static void tcg_reg_alloc_do_movi(TCGContext *s, TCGTemp *ots,
2314 tcg_target_ulong val, TCGLifeData arg_life)
2316 if (ots->fixed_reg) {
2317 /* For fixed registers, we do not do any constant propagation. */
2318 tcg_out_movi(s, ots->type, ots->reg, val);
2319 return;
2322 /* The movi is not explicitly generated here. */
2323 if (ots->val_type == TEMP_VAL_REG) {
2324 s->reg_to_temp[ots->reg] = NULL;
2326 ots->val_type = TEMP_VAL_CONST;
2327 ots->val = val;
2328 ots->mem_coherent = 0;
2329 if (NEED_SYNC_ARG(0)) {
2330 temp_sync(s, ots, s->reserved_regs, IS_DEAD_ARG(0));
2331 } else if (IS_DEAD_ARG(0)) {
2332 temp_dead(s, ots);
2336 static void tcg_reg_alloc_movi(TCGContext *s, const TCGOp *op)
2338 TCGTemp *ots = arg_temp(op->args[0]);
2339 tcg_target_ulong val = op->args[1];
2341 tcg_reg_alloc_do_movi(s, ots, val, op->life);
2344 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp *op)
2346 const TCGLifeData arg_life = op->life;
2347 TCGRegSet allocated_regs;
2348 TCGTemp *ts, *ots;
2349 TCGType otype, itype;
2351 allocated_regs = s->reserved_regs;
2352 ots = arg_temp(op->args[0]);
2353 ts = arg_temp(op->args[1]);
2355 /* Note that otype != itype for no-op truncation. */
2356 otype = ots->type;
2357 itype = ts->type;
2359 if (ts->val_type == TEMP_VAL_CONST) {
2360 /* propagate constant or generate sti */
2361 tcg_target_ulong val = ts->val;
2362 if (IS_DEAD_ARG(1)) {
2363 temp_dead(s, ts);
2365 tcg_reg_alloc_do_movi(s, ots, val, arg_life);
2366 return;
2369 /* If the source value is in memory we're going to be forced
2370 to have it in a register in order to perform the copy. Copy
2371 the SOURCE value into its own register first, that way we
2372 don't have to reload SOURCE the next time it is used. */
2373 if (ts->val_type == TEMP_VAL_MEM) {
2374 temp_load(s, ts, tcg_target_available_regs[itype], allocated_regs);
2377 tcg_debug_assert(ts->val_type == TEMP_VAL_REG);
2378 if (IS_DEAD_ARG(0) && !ots->fixed_reg) {
2379 /* mov to a non-saved dead register makes no sense (even with
2380 liveness analysis disabled). */
2381 tcg_debug_assert(NEED_SYNC_ARG(0));
2382 if (!ots->mem_allocated) {
2383 temp_allocate_frame(s, ots);
2385 tcg_out_st(s, otype, ts->reg, ots->mem_base->reg, ots->mem_offset);
2386 if (IS_DEAD_ARG(1)) {
2387 temp_dead(s, ts);
2389 temp_dead(s, ots);
2390 } else {
2391 if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
2392 /* the mov can be suppressed */
2393 if (ots->val_type == TEMP_VAL_REG) {
2394 s->reg_to_temp[ots->reg] = NULL;
2396 ots->reg = ts->reg;
2397 temp_dead(s, ts);
2398 } else {
2399 if (ots->val_type != TEMP_VAL_REG) {
2400 /* When allocating a new register, make sure to not spill the
2401 input one. */
2402 tcg_regset_set_reg(allocated_regs, ts->reg);
2403 ots->reg = tcg_reg_alloc(s, tcg_target_available_regs[otype],
2404 allocated_regs, ots->indirect_base);
2406 tcg_out_mov(s, otype, ots->reg, ts->reg);
2408 ots->val_type = TEMP_VAL_REG;
2409 ots->mem_coherent = 0;
2410 s->reg_to_temp[ots->reg] = ots;
2411 if (NEED_SYNC_ARG(0)) {
2412 temp_sync(s, ots, allocated_regs, 0);
2417 static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
2419 const TCGLifeData arg_life = op->life;
2420 const TCGOpDef * const def = &tcg_op_defs[op->opc];
2421 TCGRegSet i_allocated_regs;
2422 TCGRegSet o_allocated_regs;
2423 int i, k, nb_iargs, nb_oargs;
2424 TCGReg reg;
2425 TCGArg arg;
2426 const TCGArgConstraint *arg_ct;
2427 TCGTemp *ts;
2428 TCGArg new_args[TCG_MAX_OP_ARGS];
2429 int const_args[TCG_MAX_OP_ARGS];
2431 nb_oargs = def->nb_oargs;
2432 nb_iargs = def->nb_iargs;
2434 /* copy constants */
2435 memcpy(new_args + nb_oargs + nb_iargs,
2436 op->args + nb_oargs + nb_iargs,
2437 sizeof(TCGArg) * def->nb_cargs);
2439 i_allocated_regs = s->reserved_regs;
2440 o_allocated_regs = s->reserved_regs;
2442 /* satisfy input constraints */
2443 for (k = 0; k < nb_iargs; k++) {
2444 i = def->sorted_args[nb_oargs + k];
2445 arg = op->args[i];
2446 arg_ct = &def->args_ct[i];
2447 ts = arg_temp(arg);
2449 if (ts->val_type == TEMP_VAL_CONST
2450 && tcg_target_const_match(ts->val, ts->type, arg_ct)) {
2451 /* constant is OK for instruction */
2452 const_args[i] = 1;
2453 new_args[i] = ts->val;
2454 goto iarg_end;
2457 temp_load(s, ts, arg_ct->u.regs, i_allocated_regs);
2459 if (arg_ct->ct & TCG_CT_IALIAS) {
2460 if (ts->fixed_reg) {
2461 /* if fixed register, we must allocate a new register
2462 if the alias is not the same register */
2463 if (arg != op->args[arg_ct->alias_index])
2464 goto allocate_in_reg;
2465 } else {
2466 /* if the input is aliased to an output and if it is
2467 not dead after the instruction, we must allocate
2468 a new register and move it */
2469 if (!IS_DEAD_ARG(i)) {
2470 goto allocate_in_reg;
2472 /* check if the current register has already been allocated
2473 for another input aliased to an output */
2474 int k2, i2;
2475 for (k2 = 0 ; k2 < k ; k2++) {
2476 i2 = def->sorted_args[nb_oargs + k2];
2477 if ((def->args_ct[i2].ct & TCG_CT_IALIAS) &&
2478 (new_args[i2] == ts->reg)) {
2479 goto allocate_in_reg;
2484 reg = ts->reg;
2485 if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
2486 /* nothing to do : the constraint is satisfied */
2487 } else {
2488 allocate_in_reg:
2489 /* allocate a new register matching the constraint
2490 and move the temporary register into it */
2491 reg = tcg_reg_alloc(s, arg_ct->u.regs, i_allocated_regs,
2492 ts->indirect_base);
2493 tcg_out_mov(s, ts->type, reg, ts->reg);
2495 new_args[i] = reg;
2496 const_args[i] = 0;
2497 tcg_regset_set_reg(i_allocated_regs, reg);
2498 iarg_end: ;
2501 /* mark dead temporaries and free the associated registers */
2502 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
2503 if (IS_DEAD_ARG(i)) {
2504 temp_dead(s, arg_temp(op->args[i]));
2508 if (def->flags & TCG_OPF_BB_END) {
2509 tcg_reg_alloc_bb_end(s, i_allocated_regs);
2510 } else {
2511 if (def->flags & TCG_OPF_CALL_CLOBBER) {
2512 /* XXX: permit generic clobber register list ? */
2513 for (i = 0; i < TCG_TARGET_NB_REGS; i++) {
2514 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, i)) {
2515 tcg_reg_free(s, i, i_allocated_regs);
2519 if (def->flags & TCG_OPF_SIDE_EFFECTS) {
2520 /* sync globals if the op has side effects and might trigger
2521 an exception. */
2522 sync_globals(s, i_allocated_regs);
2525 /* satisfy the output constraints */
2526 for(k = 0; k < nb_oargs; k++) {
2527 i = def->sorted_args[k];
2528 arg = op->args[i];
2529 arg_ct = &def->args_ct[i];
2530 ts = arg_temp(arg);
2531 if ((arg_ct->ct & TCG_CT_ALIAS)
2532 && !const_args[arg_ct->alias_index]) {
2533 reg = new_args[arg_ct->alias_index];
2534 } else if (arg_ct->ct & TCG_CT_NEWREG) {
2535 reg = tcg_reg_alloc(s, arg_ct->u.regs,
2536 i_allocated_regs | o_allocated_regs,
2537 ts->indirect_base);
2538 } else {
2539 /* if fixed register, we try to use it */
2540 reg = ts->reg;
2541 if (ts->fixed_reg &&
2542 tcg_regset_test_reg(arg_ct->u.regs, reg)) {
2543 goto oarg_end;
2545 reg = tcg_reg_alloc(s, arg_ct->u.regs, o_allocated_regs,
2546 ts->indirect_base);
2548 tcg_regset_set_reg(o_allocated_regs, reg);
2549 /* if a fixed register is used, then a move will be done afterwards */
2550 if (!ts->fixed_reg) {
2551 if (ts->val_type == TEMP_VAL_REG) {
2552 s->reg_to_temp[ts->reg] = NULL;
2554 ts->val_type = TEMP_VAL_REG;
2555 ts->reg = reg;
2556 /* temp value is modified, so the value kept in memory is
2557 potentially not the same */
2558 ts->mem_coherent = 0;
2559 s->reg_to_temp[reg] = ts;
2561 oarg_end:
2562 new_args[i] = reg;
2566 /* emit instruction */
2567 tcg_out_op(s, op->opc, new_args, const_args);
2569 /* move the outputs in the correct register if needed */
2570 for(i = 0; i < nb_oargs; i++) {
2571 ts = arg_temp(op->args[i]);
2572 reg = new_args[i];
2573 if (ts->fixed_reg && ts->reg != reg) {
2574 tcg_out_mov(s, ts->type, ts->reg, reg);
2576 if (NEED_SYNC_ARG(i)) {
2577 temp_sync(s, ts, o_allocated_regs, IS_DEAD_ARG(i));
2578 } else if (IS_DEAD_ARG(i)) {
2579 temp_dead(s, ts);
2584 #ifdef TCG_TARGET_STACK_GROWSUP
2585 #define STACK_DIR(x) (-(x))
2586 #else
2587 #define STACK_DIR(x) (x)
2588 #endif
2590 static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
2592 const int nb_oargs = op->callo;
2593 const int nb_iargs = op->calli;
2594 const TCGLifeData arg_life = op->life;
2595 int flags, nb_regs, i;
2596 TCGReg reg;
2597 TCGArg arg;
2598 TCGTemp *ts;
2599 intptr_t stack_offset;
2600 size_t call_stack_size;
2601 tcg_insn_unit *func_addr;
2602 int allocate_args;
2603 TCGRegSet allocated_regs;
2605 func_addr = (tcg_insn_unit *)(intptr_t)op->args[nb_oargs + nb_iargs];
2606 flags = op->args[nb_oargs + nb_iargs + 1];
2608 nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
2609 if (nb_regs > nb_iargs) {
2610 nb_regs = nb_iargs;
2613 /* assign stack slots first */
2614 call_stack_size = (nb_iargs - nb_regs) * sizeof(tcg_target_long);
2615 call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) &
2616 ~(TCG_TARGET_STACK_ALIGN - 1);
2617 allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
2618 if (allocate_args) {
2619 /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
2620 preallocate call stack */
2621 tcg_abort();
2624 stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
2625 for (i = nb_regs; i < nb_iargs; i++) {
2626 arg = op->args[nb_oargs + i];
2627 #ifdef TCG_TARGET_STACK_GROWSUP
2628 stack_offset -= sizeof(tcg_target_long);
2629 #endif
2630 if (arg != TCG_CALL_DUMMY_ARG) {
2631 ts = arg_temp(arg);
2632 temp_load(s, ts, tcg_target_available_regs[ts->type],
2633 s->reserved_regs);
2634 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
2636 #ifndef TCG_TARGET_STACK_GROWSUP
2637 stack_offset += sizeof(tcg_target_long);
2638 #endif
2641 /* assign input registers */
2642 allocated_regs = s->reserved_regs;
2643 for (i = 0; i < nb_regs; i++) {
2644 arg = op->args[nb_oargs + i];
2645 if (arg != TCG_CALL_DUMMY_ARG) {
2646 ts = arg_temp(arg);
2647 reg = tcg_target_call_iarg_regs[i];
2648 tcg_reg_free(s, reg, allocated_regs);
2650 if (ts->val_type == TEMP_VAL_REG) {
2651 if (ts->reg != reg) {
2652 tcg_out_mov(s, ts->type, reg, ts->reg);
2654 } else {
2655 TCGRegSet arg_set = 0;
2657 tcg_regset_set_reg(arg_set, reg);
2658 temp_load(s, ts, arg_set, allocated_regs);
2661 tcg_regset_set_reg(allocated_regs, reg);
2665 /* mark dead temporaries and free the associated registers */
2666 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
2667 if (IS_DEAD_ARG(i)) {
2668 temp_dead(s, arg_temp(op->args[i]));
2672 /* clobber call registers */
2673 for (i = 0; i < TCG_TARGET_NB_REGS; i++) {
2674 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, i)) {
2675 tcg_reg_free(s, i, allocated_regs);
2679 /* Save globals if they might be written by the helper, sync them if
2680 they might be read. */
2681 if (flags & TCG_CALL_NO_READ_GLOBALS) {
2682 /* Nothing to do */
2683 } else if (flags & TCG_CALL_NO_WRITE_GLOBALS) {
2684 sync_globals(s, allocated_regs);
2685 } else {
2686 save_globals(s, allocated_regs);
2689 tcg_out_call(s, func_addr);
2691 /* assign output registers and emit moves if needed */
2692 for(i = 0; i < nb_oargs; i++) {
2693 arg = op->args[i];
2694 ts = arg_temp(arg);
2695 reg = tcg_target_call_oarg_regs[i];
2696 tcg_debug_assert(s->reg_to_temp[reg] == NULL);
2698 if (ts->fixed_reg) {
2699 if (ts->reg != reg) {
2700 tcg_out_mov(s, ts->type, ts->reg, reg);
2702 } else {
2703 if (ts->val_type == TEMP_VAL_REG) {
2704 s->reg_to_temp[ts->reg] = NULL;
2706 ts->val_type = TEMP_VAL_REG;
2707 ts->reg = reg;
2708 ts->mem_coherent = 0;
2709 s->reg_to_temp[reg] = ts;
2710 if (NEED_SYNC_ARG(i)) {
2711 temp_sync(s, ts, allocated_regs, IS_DEAD_ARG(i));
2712 } else if (IS_DEAD_ARG(i)) {
2713 temp_dead(s, ts);
2719 #ifdef CONFIG_PROFILER
2721 static int64_t tcg_table_op_count[NB_OPS];
2723 void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf)
2725 int i;
2727 for (i = 0; i < NB_OPS; i++) {
2728 cpu_fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name,
2729 tcg_table_op_count[i]);
2732 #else
2733 void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf)
2735 cpu_fprintf(f, "[TCG profiler not compiled]\n");
2737 #endif
2740 int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
2742 int i, oi, oi_next, num_insns;
2744 #ifdef CONFIG_PROFILER
2746 int n;
2748 n = s->gen_op_buf[0].prev + 1;
2749 s->op_count += n;
2750 if (n > s->op_count_max) {
2751 s->op_count_max = n;
2754 n = s->nb_temps;
2755 s->temp_count += n;
2756 if (n > s->temp_count_max) {
2757 s->temp_count_max = n;
2760 #endif
2762 #ifdef DEBUG_DISAS
2763 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)
2764 && qemu_log_in_addr_range(tb->pc))) {
2765 qemu_log_lock();
2766 qemu_log("OP:\n");
2767 tcg_dump_ops(s);
2768 qemu_log("\n");
2769 qemu_log_unlock();
2771 #endif
2773 #ifdef CONFIG_PROFILER
2774 s->opt_time -= profile_getclock();
2775 #endif
2777 #ifdef USE_TCG_OPTIMIZATIONS
2778 tcg_optimize(s);
2779 #endif
2781 #ifdef CONFIG_PROFILER
2782 s->opt_time += profile_getclock();
2783 s->la_time -= profile_getclock();
2784 #endif
2786 liveness_pass_1(s);
2788 if (s->nb_indirects > 0) {
2789 #ifdef DEBUG_DISAS
2790 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_IND)
2791 && qemu_log_in_addr_range(tb->pc))) {
2792 qemu_log_lock();
2793 qemu_log("OP before indirect lowering:\n");
2794 tcg_dump_ops(s);
2795 qemu_log("\n");
2796 qemu_log_unlock();
2798 #endif
2799 /* Replace indirect temps with direct temps. */
2800 if (liveness_pass_2(s)) {
2801 /* If changes were made, re-run liveness. */
2802 liveness_pass_1(s);
2806 #ifdef CONFIG_PROFILER
2807 s->la_time += profile_getclock();
2808 #endif
2810 #ifdef DEBUG_DISAS
2811 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT)
2812 && qemu_log_in_addr_range(tb->pc))) {
2813 qemu_log_lock();
2814 qemu_log("OP after optimization and liveness analysis:\n");
2815 tcg_dump_ops(s);
2816 qemu_log("\n");
2817 qemu_log_unlock();
2819 #endif
2821 tcg_reg_alloc_start(s);
2823 s->code_buf = tb->tc.ptr;
2824 s->code_ptr = tb->tc.ptr;
2826 #ifdef TCG_TARGET_NEED_LDST_LABELS
2827 s->ldst_labels = NULL;
2828 #endif
2829 #ifdef TCG_TARGET_NEED_POOL_LABELS
2830 s->pool_labels = NULL;
2831 #endif
2833 num_insns = -1;
2834 for (oi = s->gen_op_buf[0].next; oi != 0; oi = oi_next) {
2835 TCGOp * const op = &s->gen_op_buf[oi];
2836 TCGOpcode opc = op->opc;
2838 oi_next = op->next;
2839 #ifdef CONFIG_PROFILER
2840 tcg_table_op_count[opc]++;
2841 #endif
2843 switch (opc) {
2844 case INDEX_op_mov_i32:
2845 case INDEX_op_mov_i64:
2846 tcg_reg_alloc_mov(s, op);
2847 break;
2848 case INDEX_op_movi_i32:
2849 case INDEX_op_movi_i64:
2850 tcg_reg_alloc_movi(s, op);
2851 break;
2852 case INDEX_op_insn_start:
2853 if (num_insns >= 0) {
2854 s->gen_insn_end_off[num_insns] = tcg_current_code_size(s);
2856 num_insns++;
2857 for (i = 0; i < TARGET_INSN_START_WORDS; ++i) {
2858 target_ulong a;
2859 #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
2860 a = deposit64(op->args[i * 2], 32, 32, op->args[i * 2 + 1]);
2861 #else
2862 a = op->args[i];
2863 #endif
2864 s->gen_insn_data[num_insns][i] = a;
2866 break;
2867 case INDEX_op_discard:
2868 temp_dead(s, arg_temp(op->args[0]));
2869 break;
2870 case INDEX_op_set_label:
2871 tcg_reg_alloc_bb_end(s, s->reserved_regs);
2872 tcg_out_label(s, arg_label(op->args[0]), s->code_ptr);
2873 break;
2874 case INDEX_op_call:
2875 tcg_reg_alloc_call(s, op);
2876 break;
2877 default:
2878 /* Sanity check that we've not introduced any unhandled opcodes. */
2879 tcg_debug_assert(tcg_op_supported(opc));
2880 /* Note: in order to speed up the code, it would be much
2881 faster to have specialized register allocator functions for
2882 some common argument patterns */
2883 tcg_reg_alloc_op(s, op);
2884 break;
2886 #ifdef CONFIG_DEBUG_TCG
2887 check_regs(s);
2888 #endif
2889 /* Test for (pending) buffer overflow. The assumption is that any
2890 one operation beginning below the high water mark cannot overrun
2891 the buffer completely. Thus we can test for overflow after
2892 generating code without having to check during generation. */
2893 if (unlikely((void *)s->code_ptr > s->code_gen_highwater)) {
2894 return -1;
2897 tcg_debug_assert(num_insns >= 0);
2898 s->gen_insn_end_off[num_insns] = tcg_current_code_size(s);
2900 /* Generate TB finalization at the end of block */
2901 #ifdef TCG_TARGET_NEED_LDST_LABELS
2902 if (!tcg_out_ldst_finalize(s)) {
2903 return -1;
2905 #endif
2906 #ifdef TCG_TARGET_NEED_POOL_LABELS
2907 if (!tcg_out_pool_finalize(s)) {
2908 return -1;
2910 #endif
2912 /* flush instruction cache */
2913 flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);
2915 return tcg_current_code_size(s);
2918 #ifdef CONFIG_PROFILER
2919 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2921 TCGContext *s = &tcg_ctx;
2922 int64_t tb_count = s->tb_count;
2923 int64_t tb_div_count = tb_count ? tb_count : 1;
2924 int64_t tot = s->interm_time + s->code_time;
2926 cpu_fprintf(f, "JIT cycles %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2927 tot, tot / 2.4e9);
2928 cpu_fprintf(f, "translated TBs %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n",
2929 tb_count, s->tb_count1 - tb_count,
2930 (double)(s->tb_count1 - s->tb_count)
2931 / (s->tb_count1 ? s->tb_count1 : 1) * 100.0);
2932 cpu_fprintf(f, "avg ops/TB %0.1f max=%d\n",
2933 (double)s->op_count / tb_div_count, s->op_count_max);
2934 cpu_fprintf(f, "deleted ops/TB %0.2f\n",
2935 (double)s->del_op_count / tb_div_count);
2936 cpu_fprintf(f, "avg temps/TB %0.2f max=%d\n",
2937 (double)s->temp_count / tb_div_count, s->temp_count_max);
2938 cpu_fprintf(f, "avg host code/TB %0.1f\n",
2939 (double)s->code_out_len / tb_div_count);
2940 cpu_fprintf(f, "avg search data/TB %0.1f\n",
2941 (double)s->search_out_len / tb_div_count);
2943 cpu_fprintf(f, "cycles/op %0.1f\n",
2944 s->op_count ? (double)tot / s->op_count : 0);
2945 cpu_fprintf(f, "cycles/in byte %0.1f\n",
2946 s->code_in_len ? (double)tot / s->code_in_len : 0);
2947 cpu_fprintf(f, "cycles/out byte %0.1f\n",
2948 s->code_out_len ? (double)tot / s->code_out_len : 0);
2949 cpu_fprintf(f, "cycles/search byte %0.1f\n",
2950 s->search_out_len ? (double)tot / s->search_out_len : 0);
2951 if (tot == 0) {
2952 tot = 1;
2954 cpu_fprintf(f, " gen_interm time %0.1f%%\n",
2955 (double)s->interm_time / tot * 100.0);
2956 cpu_fprintf(f, " gen_code time %0.1f%%\n",
2957 (double)s->code_time / tot * 100.0);
2958 cpu_fprintf(f, "optim./code time %0.1f%%\n",
2959 (double)s->opt_time / (s->code_time ? s->code_time : 1)
2960 * 100.0);
2961 cpu_fprintf(f, "liveness/code time %0.1f%%\n",
2962 (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2963 cpu_fprintf(f, "cpu_restore count %" PRId64 "\n",
2964 s->restore_count);
2965 cpu_fprintf(f, " avg cycles %0.1f\n",
2966 s->restore_count ? (double)s->restore_time / s->restore_count : 0);
2968 #else
2969 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2971 cpu_fprintf(f, "[TCG profiler not compiled]\n");
2973 #endif
2975 #ifdef ELF_HOST_MACHINE
2976 /* In order to use this feature, the backend needs to do three things:
2978 (1) Define ELF_HOST_MACHINE to indicate both what value to
2979 put into the ELF image and to indicate support for the feature.
2981 (2) Define tcg_register_jit. This should create a buffer containing
2982 the contents of a .debug_frame section that describes the post-
2983 prologue unwind info for the tcg machine.
2985 (3) Call tcg_register_jit_int, with the constructed .debug_frame.
2988 /* Begin GDB interface. THE FOLLOWING MUST MATCH GDB DOCS. */
2989 typedef enum {
2990 JIT_NOACTION = 0,
2991 JIT_REGISTER_FN,
2992 JIT_UNREGISTER_FN
2993 } jit_actions_t;
2995 struct jit_code_entry {
2996 struct jit_code_entry *next_entry;
2997 struct jit_code_entry *prev_entry;
2998 const void *symfile_addr;
2999 uint64_t symfile_size;
3002 struct jit_descriptor {
3003 uint32_t version;
3004 uint32_t action_flag;
3005 struct jit_code_entry *relevant_entry;
3006 struct jit_code_entry *first_entry;
3009 void __jit_debug_register_code(void) __attribute__((noinline));
3010 void __jit_debug_register_code(void)
3012 asm("");
3015 /* Must statically initialize the version, because GDB may check
3016 the version before we can set it. */
3017 struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
3019 /* End GDB interface. */
3021 static int find_string(const char *strtab, const char *str)
3023 const char *p = strtab + 1;
3025 while (1) {
3026 if (strcmp(p, str) == 0) {
3027 return p - strtab;
3029 p += strlen(p) + 1;
3033 static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
3034 const void *debug_frame,
3035 size_t debug_frame_size)
3037 struct __attribute__((packed)) DebugInfo {
3038 uint32_t len;
3039 uint16_t version;
3040 uint32_t abbrev;
3041 uint8_t ptr_size;
3042 uint8_t cu_die;
3043 uint16_t cu_lang;
3044 uintptr_t cu_low_pc;
3045 uintptr_t cu_high_pc;
3046 uint8_t fn_die;
3047 char fn_name[16];
3048 uintptr_t fn_low_pc;
3049 uintptr_t fn_high_pc;
3050 uint8_t cu_eoc;
3053 struct ElfImage {
3054 ElfW(Ehdr) ehdr;
3055 ElfW(Phdr) phdr;
3056 ElfW(Shdr) shdr[7];
3057 ElfW(Sym) sym[2];
3058 struct DebugInfo di;
3059 uint8_t da[24];
3060 char str[80];
3063 struct ElfImage *img;
3065 static const struct ElfImage img_template = {
3066 .ehdr = {
3067 .e_ident[EI_MAG0] = ELFMAG0,
3068 .e_ident[EI_MAG1] = ELFMAG1,
3069 .e_ident[EI_MAG2] = ELFMAG2,
3070 .e_ident[EI_MAG3] = ELFMAG3,
3071 .e_ident[EI_CLASS] = ELF_CLASS,
3072 .e_ident[EI_DATA] = ELF_DATA,
3073 .e_ident[EI_VERSION] = EV_CURRENT,
3074 .e_type = ET_EXEC,
3075 .e_machine = ELF_HOST_MACHINE,
3076 .e_version = EV_CURRENT,
3077 .e_phoff = offsetof(struct ElfImage, phdr),
3078 .e_shoff = offsetof(struct ElfImage, shdr),
3079 .e_ehsize = sizeof(ElfW(Shdr)),
3080 .e_phentsize = sizeof(ElfW(Phdr)),
3081 .e_phnum = 1,
3082 .e_shentsize = sizeof(ElfW(Shdr)),
3083 .e_shnum = ARRAY_SIZE(img->shdr),
3084 .e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
3085 #ifdef ELF_HOST_FLAGS
3086 .e_flags = ELF_HOST_FLAGS,
3087 #endif
3088 #ifdef ELF_OSABI
3089 .e_ident[EI_OSABI] = ELF_OSABI,
3090 #endif
3092 .phdr = {
3093 .p_type = PT_LOAD,
3094 .p_flags = PF_X,
3096 .shdr = {
3097 [0] = { .sh_type = SHT_NULL },
3098 /* Trick: The contents of code_gen_buffer are not present in
3099 this fake ELF file; that got allocated elsewhere. Therefore
3100 we mark .text as SHT_NOBITS (similar to .bss) so that readers
3101 will not look for contents. We can record any address. */
3102 [1] = { /* .text */
3103 .sh_type = SHT_NOBITS,
3104 .sh_flags = SHF_EXECINSTR | SHF_ALLOC,
3106 [2] = { /* .debug_info */
3107 .sh_type = SHT_PROGBITS,
3108 .sh_offset = offsetof(struct ElfImage, di),
3109 .sh_size = sizeof(struct DebugInfo),
3111 [3] = { /* .debug_abbrev */
3112 .sh_type = SHT_PROGBITS,
3113 .sh_offset = offsetof(struct ElfImage, da),
3114 .sh_size = sizeof(img->da),
3116 [4] = { /* .debug_frame */
3117 .sh_type = SHT_PROGBITS,
3118 .sh_offset = sizeof(struct ElfImage),
3120 [5] = { /* .symtab */
3121 .sh_type = SHT_SYMTAB,
3122 .sh_offset = offsetof(struct ElfImage, sym),
3123 .sh_size = sizeof(img->sym),
3124 .sh_info = 1,
3125 .sh_link = ARRAY_SIZE(img->shdr) - 1,
3126 .sh_entsize = sizeof(ElfW(Sym)),
3128 [6] = { /* .strtab */
3129 .sh_type = SHT_STRTAB,
3130 .sh_offset = offsetof(struct ElfImage, str),
3131 .sh_size = sizeof(img->str),
3134 .sym = {
3135 [1] = { /* code_gen_buffer */
3136 .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
3137 .st_shndx = 1,
3140 .di = {
3141 .len = sizeof(struct DebugInfo) - 4,
3142 .version = 2,
3143 .ptr_size = sizeof(void *),
3144 .cu_die = 1,
3145 .cu_lang = 0x8001, /* DW_LANG_Mips_Assembler */
3146 .fn_die = 2,
3147 .fn_name = "code_gen_buffer"
3149 .da = {
3150 1, /* abbrev number (the cu) */
3151 0x11, 1, /* DW_TAG_compile_unit, has children */
3152 0x13, 0x5, /* DW_AT_language, DW_FORM_data2 */
3153 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
3154 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
3155 0, 0, /* end of abbrev */
3156 2, /* abbrev number (the fn) */
3157 0x2e, 0, /* DW_TAG_subprogram, no children */
3158 0x3, 0x8, /* DW_AT_name, DW_FORM_string */
3159 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
3160 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
3161 0, 0, /* end of abbrev */
3162 0 /* no more abbrev */
3164 .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
3165 ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
3168 /* We only need a single jit entry; statically allocate it. */
3169 static struct jit_code_entry one_entry;
3171 uintptr_t buf = (uintptr_t)buf_ptr;
3172 size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
3173 DebugFrameHeader *dfh;
3175 img = g_malloc(img_size);
3176 *img = img_template;
3178 img->phdr.p_vaddr = buf;
3179 img->phdr.p_paddr = buf;
3180 img->phdr.p_memsz = buf_size;
3182 img->shdr[1].sh_name = find_string(img->str, ".text");
3183 img->shdr[1].sh_addr = buf;
3184 img->shdr[1].sh_size = buf_size;
3186 img->shdr[2].sh_name = find_string(img->str, ".debug_info");
3187 img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
3189 img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
3190 img->shdr[4].sh_size = debug_frame_size;
3192 img->shdr[5].sh_name = find_string(img->str, ".symtab");
3193 img->shdr[6].sh_name = find_string(img->str, ".strtab");
3195 img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
3196 img->sym[1].st_value = buf;
3197 img->sym[1].st_size = buf_size;
3199 img->di.cu_low_pc = buf;
3200 img->di.cu_high_pc = buf + buf_size;
3201 img->di.fn_low_pc = buf;
3202 img->di.fn_high_pc = buf + buf_size;
3204 dfh = (DebugFrameHeader *)(img + 1);
3205 memcpy(dfh, debug_frame, debug_frame_size);
3206 dfh->fde.func_start = buf;
3207 dfh->fde.func_len = buf_size;
3209 #ifdef DEBUG_JIT
3210 /* Enable this block to be able to debug the ELF image file creation.
3211 One can use readelf, objdump, or other inspection utilities. */
3213 FILE *f = fopen("/tmp/qemu.jit", "w+b");
3214 if (f) {
3215 if (fwrite(img, img_size, 1, f) != img_size) {
3216 /* Avoid stupid unused return value warning for fwrite. */
3218 fclose(f);
3221 #endif
3223 one_entry.symfile_addr = img;
3224 one_entry.symfile_size = img_size;
3226 __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
3227 __jit_debug_descriptor.relevant_entry = &one_entry;
3228 __jit_debug_descriptor.first_entry = &one_entry;
3229 __jit_debug_register_code();
3231 #else
3232 /* No support for the feature. Provide the entry point expected by exec.c,
3233 and implement the internal function we declared earlier. */
3235 static void tcg_register_jit_int(void *buf, size_t size,
3236 const void *debug_frame,
3237 size_t debug_frame_size)
3241 void tcg_register_jit(void *buf, size_t buf_size)
3244 #endif /* ELF_HOST_MACHINE */