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
25 /* define it to use liveness analysis (better code) */
26 #define USE_LIVENESS_ANALYSIS
27 #define USE_TCG_OPTIMIZATIONS
31 /* Define to jump the ELF file used to communicate with GDB. */
34 #if !defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG)
35 /* define it to suppress various consistency checks (faster) */
39 #include "qemu-common.h"
40 #include "cache-utils.h"
41 #include "host-utils.h"
42 #include "qemu-timer.h"
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
47 #define NO_CPU_IO_DEFS
52 #if TCG_TARGET_REG_BITS == 64
53 # define ELF_CLASS ELFCLASS64
55 # define ELF_CLASS ELFCLASS32
57 #ifdef HOST_WORDS_BIGENDIAN
58 # define ELF_DATA ELFDATA2MSB
60 # define ELF_DATA ELFDATA2LSB
65 #if defined(CONFIG_USE_GUEST_BASE) && !defined(TCG_TARGET_HAS_GUEST_BASE)
66 #error GUEST_BASE not supported on this host.
69 /* Forward declarations for functions declared in tcg-target.c and used here. */
70 static void tcg_target_init(TCGContext *s);
71 static void tcg_target_qemu_prologue(TCGContext *s);
72 static void patch_reloc(uint8_t *code_ptr, int type,
73 tcg_target_long value, tcg_target_long addend);
75 static void tcg_register_jit_int(void *buf, size_t size,
76 void *debug_frame, size_t debug_frame_size)
77 __attribute__((unused));
79 /* Forward declarations for functions declared and used in tcg-target.c. */
80 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str);
81 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
82 tcg_target_long arg2);
83 static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
84 static void tcg_out_movi(TCGContext *s, TCGType type,
85 TCGReg ret, tcg_target_long arg);
86 static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
87 const int *const_args);
88 static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
89 tcg_target_long arg2);
90 static int tcg_target_const_match(tcg_target_long val,
91 const TCGArgConstraint *arg_ct);
93 TCGOpDef tcg_op_defs[] = {
94 #define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags },
98 const size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs);
100 static TCGRegSet tcg_target_available_regs[2];
101 static TCGRegSet tcg_target_call_clobber_regs;
103 /* XXX: move that inside the context */
104 uint16_t *gen_opc_ptr;
105 TCGArg *gen_opparam_ptr;
107 static inline void tcg_out8(TCGContext *s, uint8_t v)
112 static inline void tcg_out16(TCGContext *s, uint16_t v)
114 *(uint16_t *)s->code_ptr = v;
118 static inline void tcg_out32(TCGContext *s, uint32_t v)
120 *(uint32_t *)s->code_ptr = v;
124 /* label relocation processing */
126 static void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
127 int label_index, long addend)
132 l = &s->labels[label_index];
134 /* FIXME: This may break relocations on RISC targets that
135 modify instruction fields in place. The caller may not have
136 written the initial value. */
137 patch_reloc(code_ptr, type, l->u.value, addend);
139 /* add a new relocation entry */
140 r = tcg_malloc(sizeof(TCGRelocation));
144 r->next = l->u.first_reloc;
145 l->u.first_reloc = r;
149 static void tcg_out_label(TCGContext *s, int label_index, void *ptr)
153 tcg_target_long value = (tcg_target_long)ptr;
155 l = &s->labels[label_index];
158 r = l->u.first_reloc;
160 patch_reloc(r->ptr, r->type, value, r->addend);
167 int gen_new_label(void)
169 TCGContext *s = &tcg_ctx;
173 if (s->nb_labels >= TCG_MAX_LABELS)
175 idx = s->nb_labels++;
178 l->u.first_reloc = NULL;
182 #include "tcg-target.c"
184 /* pool based memory allocation */
185 void *tcg_malloc_internal(TCGContext *s, int size)
190 if (size > TCG_POOL_CHUNK_SIZE) {
191 /* big malloc: insert a new pool (XXX: could optimize) */
192 p = g_malloc(sizeof(TCGPool) + size);
194 p->next = s->pool_first_large;
195 s->pool_first_large = p;
206 pool_size = TCG_POOL_CHUNK_SIZE;
207 p = g_malloc(sizeof(TCGPool) + pool_size);
211 s->pool_current->next = p;
220 s->pool_cur = p->data + size;
221 s->pool_end = p->data + p->size;
225 void tcg_pool_reset(TCGContext *s)
228 for (p = s->pool_first_large; p; p = t) {
232 s->pool_first_large = NULL;
233 s->pool_cur = s->pool_end = NULL;
234 s->pool_current = NULL;
237 void tcg_context_init(TCGContext *s)
239 int op, total_args, n;
241 TCGArgConstraint *args_ct;
244 memset(s, 0, sizeof(*s));
245 s->temps = s->static_temps;
248 /* Count total number of arguments and allocate the corresponding
251 for(op = 0; op < NB_OPS; op++) {
252 def = &tcg_op_defs[op];
253 n = def->nb_iargs + def->nb_oargs;
257 args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args);
258 sorted_args = g_malloc(sizeof(int) * total_args);
260 for(op = 0; op < NB_OPS; op++) {
261 def = &tcg_op_defs[op];
262 def->args_ct = args_ct;
263 def->sorted_args = sorted_args;
264 n = def->nb_iargs + def->nb_oargs;
272 void tcg_prologue_init(TCGContext *s)
274 /* init global prologue and epilogue */
275 s->code_buf = code_gen_prologue;
276 s->code_ptr = s->code_buf;
277 tcg_target_qemu_prologue(s);
278 flush_icache_range((tcg_target_ulong)s->code_buf,
279 (tcg_target_ulong)s->code_ptr);
282 void tcg_set_frame(TCGContext *s, int reg,
283 tcg_target_long start, tcg_target_long size)
285 s->frame_start = start;
286 s->frame_end = start + size;
290 void tcg_func_start(TCGContext *s)
294 s->nb_temps = s->nb_globals;
295 for(i = 0; i < (TCG_TYPE_COUNT * 2); i++)
296 s->first_free_temp[i] = -1;
297 s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
299 s->current_frame_offset = s->frame_start;
301 #ifdef CONFIG_DEBUG_TCG
302 s->goto_tb_issue_mask = 0;
305 gen_opc_ptr = gen_opc_buf;
306 gen_opparam_ptr = gen_opparam_buf;
309 static inline void tcg_temp_alloc(TCGContext *s, int n)
311 if (n > TCG_MAX_TEMPS)
315 static inline int tcg_global_reg_new_internal(TCGType type, int reg,
318 TCGContext *s = &tcg_ctx;
322 #if TCG_TARGET_REG_BITS == 32
323 if (type != TCG_TYPE_I32)
326 if (tcg_regset_test_reg(s->reserved_regs, reg))
329 tcg_temp_alloc(s, s->nb_globals + 1);
330 ts = &s->temps[s->nb_globals];
331 ts->base_type = type;
337 tcg_regset_set_reg(s->reserved_regs, reg);
341 TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
345 idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name);
346 return MAKE_TCGV_I32(idx);
349 TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
353 idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);
354 return MAKE_TCGV_I64(idx);
357 static inline int tcg_global_mem_new_internal(TCGType type, int reg,
358 tcg_target_long offset,
361 TCGContext *s = &tcg_ctx;
366 #if TCG_TARGET_REG_BITS == 32
367 if (type == TCG_TYPE_I64) {
369 tcg_temp_alloc(s, s->nb_globals + 2);
370 ts = &s->temps[s->nb_globals];
371 ts->base_type = type;
372 ts->type = TCG_TYPE_I32;
374 ts->mem_allocated = 1;
376 #ifdef TCG_TARGET_WORDS_BIGENDIAN
377 ts->mem_offset = offset + 4;
379 ts->mem_offset = offset;
381 pstrcpy(buf, sizeof(buf), name);
382 pstrcat(buf, sizeof(buf), "_0");
383 ts->name = strdup(buf);
386 ts->base_type = type;
387 ts->type = TCG_TYPE_I32;
389 ts->mem_allocated = 1;
391 #ifdef TCG_TARGET_WORDS_BIGENDIAN
392 ts->mem_offset = offset;
394 ts->mem_offset = offset + 4;
396 pstrcpy(buf, sizeof(buf), name);
397 pstrcat(buf, sizeof(buf), "_1");
398 ts->name = strdup(buf);
404 tcg_temp_alloc(s, s->nb_globals + 1);
405 ts = &s->temps[s->nb_globals];
406 ts->base_type = type;
409 ts->mem_allocated = 1;
411 ts->mem_offset = offset;
418 TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
423 idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
424 return MAKE_TCGV_I32(idx);
427 TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
432 idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
433 return MAKE_TCGV_I64(idx);
436 static inline int tcg_temp_new_internal(TCGType type, int temp_local)
438 TCGContext *s = &tcg_ctx;
445 idx = s->first_free_temp[k];
447 /* There is already an available temp with the
450 s->first_free_temp[k] = ts->next_free_temp;
451 ts->temp_allocated = 1;
452 assert(ts->temp_local == temp_local);
455 #if TCG_TARGET_REG_BITS == 32
456 if (type == TCG_TYPE_I64) {
457 tcg_temp_alloc(s, s->nb_temps + 2);
458 ts = &s->temps[s->nb_temps];
459 ts->base_type = type;
460 ts->type = TCG_TYPE_I32;
461 ts->temp_allocated = 1;
462 ts->temp_local = temp_local;
465 ts->base_type = TCG_TYPE_I32;
466 ts->type = TCG_TYPE_I32;
467 ts->temp_allocated = 1;
468 ts->temp_local = temp_local;
474 tcg_temp_alloc(s, s->nb_temps + 1);
475 ts = &s->temps[s->nb_temps];
476 ts->base_type = type;
478 ts->temp_allocated = 1;
479 ts->temp_local = temp_local;
485 #if defined(CONFIG_DEBUG_TCG)
491 TCGv_i32 tcg_temp_new_internal_i32(int temp_local)
495 idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
496 return MAKE_TCGV_I32(idx);
499 TCGv_i64 tcg_temp_new_internal_i64(int temp_local)
503 idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
504 return MAKE_TCGV_I64(idx);
507 static inline void tcg_temp_free_internal(int idx)
509 TCGContext *s = &tcg_ctx;
513 #if defined(CONFIG_DEBUG_TCG)
515 if (s->temps_in_use < 0) {
516 fprintf(stderr, "More temporaries freed than allocated!\n");
520 assert(idx >= s->nb_globals && idx < s->nb_temps);
522 assert(ts->temp_allocated != 0);
523 ts->temp_allocated = 0;
527 ts->next_free_temp = s->first_free_temp[k];
528 s->first_free_temp[k] = idx;
531 void tcg_temp_free_i32(TCGv_i32 arg)
533 tcg_temp_free_internal(GET_TCGV_I32(arg));
536 void tcg_temp_free_i64(TCGv_i64 arg)
538 tcg_temp_free_internal(GET_TCGV_I64(arg));
541 TCGv_i32 tcg_const_i32(int32_t val)
544 t0 = tcg_temp_new_i32();
545 tcg_gen_movi_i32(t0, val);
549 TCGv_i64 tcg_const_i64(int64_t val)
552 t0 = tcg_temp_new_i64();
553 tcg_gen_movi_i64(t0, val);
557 TCGv_i32 tcg_const_local_i32(int32_t val)
560 t0 = tcg_temp_local_new_i32();
561 tcg_gen_movi_i32(t0, val);
565 TCGv_i64 tcg_const_local_i64(int64_t val)
568 t0 = tcg_temp_local_new_i64();
569 tcg_gen_movi_i64(t0, val);
573 #if defined(CONFIG_DEBUG_TCG)
574 void tcg_clear_temp_count(void)
576 TCGContext *s = &tcg_ctx;
580 int tcg_check_temp_count(void)
582 TCGContext *s = &tcg_ctx;
583 if (s->temps_in_use) {
584 /* Clear the count so that we don't give another
585 * warning immediately next time around.
594 void tcg_register_helper(void *func, const char *name)
596 TCGContext *s = &tcg_ctx;
598 if ((s->nb_helpers + 1) > s->allocated_helpers) {
599 n = s->allocated_helpers;
605 s->helpers = realloc(s->helpers, n * sizeof(TCGHelperInfo));
606 s->allocated_helpers = n;
608 s->helpers[s->nb_helpers].func = (tcg_target_ulong)func;
609 s->helpers[s->nb_helpers].name = name;
613 /* Note: we convert the 64 bit args to 32 bit and do some alignment
614 and endian swap. Maybe it would be better to do the alignment
615 and endian swap in tcg_reg_alloc_call(). */
616 void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
617 int sizemask, TCGArg ret, int nargs, TCGArg *args)
624 #if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
625 for (i = 0; i < nargs; ++i) {
626 int is_64bit = sizemask & (1 << (i+1)*2);
627 int is_signed = sizemask & (2 << (i+1)*2);
629 TCGv_i64 temp = tcg_temp_new_i64();
630 TCGv_i64 orig = MAKE_TCGV_I64(args[i]);
632 tcg_gen_ext32s_i64(temp, orig);
634 tcg_gen_ext32u_i64(temp, orig);
636 args[i] = GET_TCGV_I64(temp);
639 #endif /* TCG_TARGET_EXTEND_ARGS */
641 *gen_opc_ptr++ = INDEX_op_call;
642 nparam = gen_opparam_ptr++;
643 if (ret != TCG_CALL_DUMMY_ARG) {
644 #if TCG_TARGET_REG_BITS < 64
646 #ifdef TCG_TARGET_WORDS_BIGENDIAN
647 *gen_opparam_ptr++ = ret + 1;
648 *gen_opparam_ptr++ = ret;
650 *gen_opparam_ptr++ = ret;
651 *gen_opparam_ptr++ = ret + 1;
657 *gen_opparam_ptr++ = ret;
664 for (i = 0; i < nargs; i++) {
665 #if TCG_TARGET_REG_BITS < 64
666 int is_64bit = sizemask & (1 << (i+1)*2);
668 #ifdef TCG_TARGET_CALL_ALIGN_ARGS
669 /* some targets want aligned 64 bit args */
671 *gen_opparam_ptr++ = TCG_CALL_DUMMY_ARG;
675 /* If stack grows up, then we will be placing successive
676 arguments at lower addresses, which means we need to
677 reverse the order compared to how we would normally
678 treat either big or little-endian. For those arguments
679 that will wind up in registers, this still works for
680 HPPA (the only current STACK_GROWSUP target) since the
681 argument registers are *also* allocated in decreasing
682 order. If another such target is added, this logic may
683 have to get more complicated to differentiate between
684 stack arguments and register arguments. */
685 #if defined(TCG_TARGET_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
686 *gen_opparam_ptr++ = args[i] + 1;
687 *gen_opparam_ptr++ = args[i];
689 *gen_opparam_ptr++ = args[i];
690 *gen_opparam_ptr++ = args[i] + 1;
695 #endif /* TCG_TARGET_REG_BITS < 64 */
697 *gen_opparam_ptr++ = args[i];
700 *gen_opparam_ptr++ = GET_TCGV_PTR(func);
702 *gen_opparam_ptr++ = flags;
704 *nparam = (nb_rets << 16) | (real_args + 1);
706 /* total parameters, needed to go backward in the instruction stream */
707 *gen_opparam_ptr++ = 1 + nb_rets + real_args + 3;
709 #if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
710 for (i = 0; i < nargs; ++i) {
711 int is_64bit = sizemask & (1 << (i+1)*2);
713 TCGv_i64 temp = MAKE_TCGV_I64(args[i]);
714 tcg_temp_free_i64(temp);
717 #endif /* TCG_TARGET_EXTEND_ARGS */
720 #if TCG_TARGET_REG_BITS == 32
721 void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
722 int c, int right, int arith)
725 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
726 tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
727 } else if (c >= 32) {
731 tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
732 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
734 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
735 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
738 tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
739 tcg_gen_movi_i32(TCGV_LOW(ret), 0);
744 t0 = tcg_temp_new_i32();
745 t1 = tcg_temp_new_i32();
747 tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c);
749 tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c);
751 tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c);
752 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
753 tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t0);
754 tcg_gen_mov_i32(TCGV_HIGH(ret), t1);
756 tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
757 /* Note: ret can be the same as arg1, so we use t1 */
758 tcg_gen_shli_i32(t1, TCGV_LOW(arg1), c);
759 tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
760 tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
761 tcg_gen_mov_i32(TCGV_LOW(ret), t1);
763 tcg_temp_free_i32(t0);
764 tcg_temp_free_i32(t1);
770 static void tcg_reg_alloc_start(TCGContext *s)
774 for(i = 0; i < s->nb_globals; i++) {
777 ts->val_type = TEMP_VAL_REG;
779 ts->val_type = TEMP_VAL_MEM;
782 for(i = s->nb_globals; i < s->nb_temps; i++) {
784 ts->val_type = TEMP_VAL_DEAD;
785 ts->mem_allocated = 0;
788 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
789 s->reg_to_temp[i] = -1;
793 static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
798 assert(idx >= 0 && idx < s->nb_temps);
801 if (idx < s->nb_globals) {
802 pstrcpy(buf, buf_size, ts->name);
805 snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
807 snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
812 char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg)
814 return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg));
817 char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg)
819 return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg));
822 static int helper_cmp(const void *p1, const void *p2)
824 const TCGHelperInfo *th1 = p1;
825 const TCGHelperInfo *th2 = p2;
826 if (th1->func < th2->func)
828 else if (th1->func == th2->func)
834 /* find helper definition (Note: A hash table would be better) */
835 static TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val)
841 if (unlikely(!s->helpers_sorted)) {
842 qsort(s->helpers, s->nb_helpers, sizeof(TCGHelperInfo),
844 s->helpers_sorted = 1;
849 m_max = s->nb_helpers - 1;
850 while (m_min <= m_max) {
851 m = (m_min + m_max) >> 1;
865 static const char * const cond_name[] =
867 [TCG_COND_EQ] = "eq",
868 [TCG_COND_NE] = "ne",
869 [TCG_COND_LT] = "lt",
870 [TCG_COND_GE] = "ge",
871 [TCG_COND_LE] = "le",
872 [TCG_COND_GT] = "gt",
873 [TCG_COND_LTU] = "ltu",
874 [TCG_COND_GEU] = "geu",
875 [TCG_COND_LEU] = "leu",
876 [TCG_COND_GTU] = "gtu"
879 void tcg_dump_ops(TCGContext *s)
881 const uint16_t *opc_ptr;
885 int i, k, nb_oargs, nb_iargs, nb_cargs, first_insn;
890 opc_ptr = gen_opc_buf;
891 args = gen_opparam_buf;
892 while (opc_ptr < gen_opc_ptr) {
894 def = &tcg_op_defs[c];
895 if (c == INDEX_op_debug_insn_start) {
897 #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
898 pc = ((uint64_t)args[1] << 32) | args[0];
905 qemu_log(" ---- 0x%" PRIx64, pc);
907 nb_oargs = def->nb_oargs;
908 nb_iargs = def->nb_iargs;
909 nb_cargs = def->nb_cargs;
910 } else if (c == INDEX_op_call) {
913 /* variable number of arguments */
915 nb_oargs = arg >> 16;
916 nb_iargs = arg & 0xffff;
917 nb_cargs = def->nb_cargs;
919 qemu_log(" %s ", def->name);
923 tcg_get_arg_str_idx(s, buf, sizeof(buf),
924 args[nb_oargs + nb_iargs - 1]));
926 qemu_log(",$0x%" TCG_PRIlx, args[nb_oargs + nb_iargs]);
928 qemu_log(",$%d", nb_oargs);
929 for(i = 0; i < nb_oargs; i++) {
931 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
934 for(i = 0; i < (nb_iargs - 1); i++) {
936 if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) {
939 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
940 args[nb_oargs + i]));
943 } else if (c == INDEX_op_movi_i32 || c == INDEX_op_movi_i64) {
944 tcg_target_ulong val;
947 nb_oargs = def->nb_oargs;
948 nb_iargs = def->nb_iargs;
949 nb_cargs = def->nb_cargs;
950 qemu_log(" %s %s,$", def->name,
951 tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
953 th = tcg_find_helper(s, val);
955 qemu_log("%s", th->name);
957 if (c == INDEX_op_movi_i32) {
958 qemu_log("0x%x", (uint32_t)val);
960 qemu_log("0x%" PRIx64 , (uint64_t)val);
964 qemu_log(" %s ", def->name);
965 if (c == INDEX_op_nopn) {
966 /* variable number of arguments */
971 nb_oargs = def->nb_oargs;
972 nb_iargs = def->nb_iargs;
973 nb_cargs = def->nb_cargs;
977 for(i = 0; i < nb_oargs; i++) {
981 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
984 for(i = 0; i < nb_iargs; i++) {
988 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
992 case INDEX_op_brcond_i32:
993 case INDEX_op_setcond_i32:
994 case INDEX_op_movcond_i32:
995 case INDEX_op_brcond2_i32:
996 case INDEX_op_setcond2_i32:
997 case INDEX_op_brcond_i64:
998 case INDEX_op_setcond_i64:
999 case INDEX_op_movcond_i64:
1000 if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) {
1001 qemu_log(",%s", cond_name[args[k++]]);
1003 qemu_log(",$0x%" TCG_PRIlx, args[k++]);
1011 for(; i < nb_cargs; i++) {
1016 qemu_log("$0x%" TCG_PRIlx, arg);
1020 args += nb_iargs + nb_oargs + nb_cargs;
1024 /* we give more priority to constraints with less registers */
1025 static int get_constraint_priority(const TCGOpDef *def, int k)
1027 const TCGArgConstraint *arg_ct;
1030 arg_ct = &def->args_ct[k];
1031 if (arg_ct->ct & TCG_CT_ALIAS) {
1032 /* an alias is equivalent to a single register */
1035 if (!(arg_ct->ct & TCG_CT_REG))
1038 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1039 if (tcg_regset_test_reg(arg_ct->u.regs, i))
1043 return TCG_TARGET_NB_REGS - n + 1;
1046 /* sort from highest priority to lowest */
1047 static void sort_constraints(TCGOpDef *def, int start, int n)
1049 int i, j, p1, p2, tmp;
1051 for(i = 0; i < n; i++)
1052 def->sorted_args[start + i] = start + i;
1055 for(i = 0; i < n - 1; i++) {
1056 for(j = i + 1; j < n; j++) {
1057 p1 = get_constraint_priority(def, def->sorted_args[start + i]);
1058 p2 = get_constraint_priority(def, def->sorted_args[start + j]);
1060 tmp = def->sorted_args[start + i];
1061 def->sorted_args[start + i] = def->sorted_args[start + j];
1062 def->sorted_args[start + j] = tmp;
1068 void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
1076 if (tdefs->op == (TCGOpcode)-1)
1079 assert((unsigned)op < NB_OPS);
1080 def = &tcg_op_defs[op];
1081 #if defined(CONFIG_DEBUG_TCG)
1082 /* Duplicate entry in op definitions? */
1086 nb_args = def->nb_iargs + def->nb_oargs;
1087 for(i = 0; i < nb_args; i++) {
1088 ct_str = tdefs->args_ct_str[i];
1089 /* Incomplete TCGTargetOpDef entry? */
1090 assert(ct_str != NULL);
1091 tcg_regset_clear(def->args_ct[i].u.regs);
1092 def->args_ct[i].ct = 0;
1093 if (ct_str[0] >= '0' && ct_str[0] <= '9') {
1095 oarg = ct_str[0] - '0';
1096 assert(oarg < def->nb_oargs);
1097 assert(def->args_ct[oarg].ct & TCG_CT_REG);
1098 /* TCG_CT_ALIAS is for the output arguments. The input
1099 argument is tagged with TCG_CT_IALIAS. */
1100 def->args_ct[i] = def->args_ct[oarg];
1101 def->args_ct[oarg].ct = TCG_CT_ALIAS;
1102 def->args_ct[oarg].alias_index = i;
1103 def->args_ct[i].ct |= TCG_CT_IALIAS;
1104 def->args_ct[i].alias_index = oarg;
1107 if (*ct_str == '\0')
1111 def->args_ct[i].ct |= TCG_CT_CONST;
1115 if (target_parse_constraint(&def->args_ct[i], &ct_str) < 0) {
1116 fprintf(stderr, "Invalid constraint '%s' for arg %d of operation '%s'\n",
1117 ct_str, i, def->name);
1125 /* TCGTargetOpDef entry with too much information? */
1126 assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL);
1128 /* sort the constraints (XXX: this is just an heuristic) */
1129 sort_constraints(def, 0, def->nb_oargs);
1130 sort_constraints(def, def->nb_oargs, def->nb_iargs);
1136 printf("%s: sorted=", def->name);
1137 for(i = 0; i < def->nb_oargs + def->nb_iargs; i++)
1138 printf(" %d", def->sorted_args[i]);
1145 #if defined(CONFIG_DEBUG_TCG)
1147 for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) {
1148 const TCGOpDef *def = &tcg_op_defs[op];
1149 if (op < INDEX_op_call
1150 || op == INDEX_op_debug_insn_start
1151 || (def->flags & TCG_OPF_NOT_PRESENT)) {
1152 /* Wrong entry in op definitions? */
1154 fprintf(stderr, "Invalid op definition for %s\n", def->name);
1158 /* Missing entry in op definitions? */
1160 fprintf(stderr, "Missing op definition for %s\n", def->name);
1171 #ifdef USE_LIVENESS_ANALYSIS
1173 /* set a nop for an operation using 'nb_args' */
1174 static inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr,
1175 TCGArg *args, int nb_args)
1178 *opc_ptr = INDEX_op_nop;
1180 *opc_ptr = INDEX_op_nopn;
1182 args[nb_args - 1] = nb_args;
1186 /* liveness analysis: end of function: globals are live, temps are
1188 /* XXX: at this stage, not used as there would be little gains because
1189 most TBs end with a conditional jump. */
1190 static inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps)
1192 memset(dead_temps, 0, s->nb_globals);
1193 memset(dead_temps + s->nb_globals, 1, s->nb_temps - s->nb_globals);
1196 /* liveness analysis: end of basic block: globals are live, temps are
1197 dead, local temps are live. */
1198 static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps)
1203 memset(dead_temps, 0, s->nb_globals);
1204 ts = &s->temps[s->nb_globals];
1205 for(i = s->nb_globals; i < s->nb_temps; i++) {
1214 /* Liveness analysis : update the opc_dead_args array to tell if a
1215 given input arguments is dead. Instructions updating dead
1216 temporaries are removed. */
1217 static void tcg_liveness_analysis(TCGContext *s)
1219 int i, op_index, nb_args, nb_iargs, nb_oargs, arg, nb_ops;
1222 const TCGOpDef *def;
1223 uint8_t *dead_temps;
1224 unsigned int dead_args;
1226 gen_opc_ptr++; /* skip end */
1228 nb_ops = gen_opc_ptr - gen_opc_buf;
1230 s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1232 dead_temps = tcg_malloc(s->nb_temps);
1233 memset(dead_temps, 1, s->nb_temps);
1235 args = gen_opparam_ptr;
1236 op_index = nb_ops - 1;
1237 while (op_index >= 0) {
1238 op = gen_opc_buf[op_index];
1239 def = &tcg_op_defs[op];
1247 nb_iargs = args[0] & 0xffff;
1248 nb_oargs = args[0] >> 16;
1250 call_flags = args[nb_oargs + nb_iargs];
1252 /* pure functions can be removed if their result is not
1254 if (call_flags & TCG_CALL_PURE) {
1255 for(i = 0; i < nb_oargs; i++) {
1257 if (!dead_temps[arg])
1258 goto do_not_remove_call;
1260 tcg_set_nop(s, gen_opc_buf + op_index,
1265 /* output args are dead */
1267 for(i = 0; i < nb_oargs; i++) {
1269 if (dead_temps[arg]) {
1270 dead_args |= (1 << i);
1272 dead_temps[arg] = 1;
1275 if (!(call_flags & TCG_CALL_CONST)) {
1276 /* globals are live (they may be used by the call) */
1277 memset(dead_temps, 0, s->nb_globals);
1280 /* input args are live */
1281 for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1283 if (arg != TCG_CALL_DUMMY_ARG) {
1284 if (dead_temps[arg]) {
1285 dead_args |= (1 << i);
1287 dead_temps[arg] = 0;
1290 s->op_dead_args[op_index] = dead_args;
1295 case INDEX_op_debug_insn_start:
1296 args -= def->nb_args;
1302 case INDEX_op_discard:
1304 /* mark the temporary as dead */
1305 dead_temps[args[0]] = 1;
1309 /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
1311 args -= def->nb_args;
1312 nb_iargs = def->nb_iargs;
1313 nb_oargs = def->nb_oargs;
1315 /* Test if the operation can be removed because all
1316 its outputs are dead. We assume that nb_oargs == 0
1317 implies side effects */
1318 if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
1319 for(i = 0; i < nb_oargs; i++) {
1321 if (!dead_temps[arg])
1324 tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
1325 #ifdef CONFIG_PROFILER
1331 /* output args are dead */
1333 for(i = 0; i < nb_oargs; i++) {
1335 if (dead_temps[arg]) {
1336 dead_args |= (1 << i);
1338 dead_temps[arg] = 1;
1341 /* if end of basic block, update */
1342 if (def->flags & TCG_OPF_BB_END) {
1343 tcg_la_bb_end(s, dead_temps);
1344 } else if (def->flags & TCG_OPF_CALL_CLOBBER) {
1345 /* globals are live */
1346 memset(dead_temps, 0, s->nb_globals);
1349 /* input args are live */
1350 for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1352 if (dead_temps[arg]) {
1353 dead_args |= (1 << i);
1355 dead_temps[arg] = 0;
1357 s->op_dead_args[op_index] = dead_args;
1364 if (args != gen_opparam_buf)
1368 /* dummy liveness analysis */
1369 static void tcg_liveness_analysis(TCGContext *s)
1372 nb_ops = gen_opc_ptr - gen_opc_buf;
1374 s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1375 memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
1380 static void dump_regs(TCGContext *s)
1386 for(i = 0; i < s->nb_temps; i++) {
1388 printf(" %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
1389 switch(ts->val_type) {
1391 printf("%s", tcg_target_reg_names[ts->reg]);
1394 printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
1396 case TEMP_VAL_CONST:
1397 printf("$0x%" TCG_PRIlx, ts->val);
1409 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1410 if (s->reg_to_temp[i] >= 0) {
1412 tcg_target_reg_names[i],
1413 tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
1418 static void check_regs(TCGContext *s)
1424 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1425 k = s->reg_to_temp[reg];
1428 if (ts->val_type != TEMP_VAL_REG ||
1430 printf("Inconsistency for register %s:\n",
1431 tcg_target_reg_names[reg]);
1436 for(k = 0; k < s->nb_temps; k++) {
1438 if (ts->val_type == TEMP_VAL_REG &&
1440 s->reg_to_temp[ts->reg] != k) {
1441 printf("Inconsistency for temp %s:\n",
1442 tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
1444 printf("reg state:\n");
1452 static void temp_allocate_frame(TCGContext *s, int temp)
1455 ts = &s->temps[temp];
1456 #if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64)
1457 /* Sparc64 stack is accessed with offset of 2047 */
1458 s->current_frame_offset = (s->current_frame_offset +
1459 (tcg_target_long)sizeof(tcg_target_long) - 1) &
1460 ~(sizeof(tcg_target_long) - 1);
1462 if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
1466 ts->mem_offset = s->current_frame_offset;
1467 ts->mem_reg = s->frame_reg;
1468 ts->mem_allocated = 1;
1469 s->current_frame_offset += (tcg_target_long)sizeof(tcg_target_long);
1472 /* free register 'reg' by spilling the corresponding temporary if necessary */
1473 static void tcg_reg_free(TCGContext *s, int reg)
1478 temp = s->reg_to_temp[reg];
1480 ts = &s->temps[temp];
1481 assert(ts->val_type == TEMP_VAL_REG);
1482 if (!ts->mem_coherent) {
1483 if (!ts->mem_allocated)
1484 temp_allocate_frame(s, temp);
1485 tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1487 ts->val_type = TEMP_VAL_MEM;
1488 s->reg_to_temp[reg] = -1;
1492 /* Allocate a register belonging to reg1 & ~reg2 */
1493 static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1498 tcg_regset_andnot(reg_ct, reg1, reg2);
1500 /* first try free registers */
1501 for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1502 reg = tcg_target_reg_alloc_order[i];
1503 if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
1507 /* XXX: do better spill choice */
1508 for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1509 reg = tcg_target_reg_alloc_order[i];
1510 if (tcg_regset_test_reg(reg_ct, reg)) {
1511 tcg_reg_free(s, reg);
1519 /* save a temporary to memory. 'allocated_regs' is used in case a
1520 temporary registers needs to be allocated to store a constant. */
1521 static void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
1526 ts = &s->temps[temp];
1527 if (!ts->fixed_reg) {
1528 switch(ts->val_type) {
1530 tcg_reg_free(s, ts->reg);
1533 ts->val_type = TEMP_VAL_MEM;
1535 case TEMP_VAL_CONST:
1536 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1538 if (!ts->mem_allocated)
1539 temp_allocate_frame(s, temp);
1540 tcg_out_movi(s, ts->type, reg, ts->val);
1541 tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1542 ts->val_type = TEMP_VAL_MEM;
1552 /* save globals to their canonical location and assume they can be
1553 modified be the following code. 'allocated_regs' is used in case a
1554 temporary registers needs to be allocated to store a constant. */
1555 static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
1559 for(i = 0; i < s->nb_globals; i++) {
1560 temp_save(s, i, allocated_regs);
1564 /* at the end of a basic block, we assume all temporaries are dead and
1565 all globals are stored at their canonical location. */
1566 static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
1571 for(i = s->nb_globals; i < s->nb_temps; i++) {
1573 if (ts->temp_local) {
1574 temp_save(s, i, allocated_regs);
1576 if (ts->val_type == TEMP_VAL_REG) {
1577 s->reg_to_temp[ts->reg] = -1;
1579 ts->val_type = TEMP_VAL_DEAD;
1583 save_globals(s, allocated_regs);
1586 #define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
1588 static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args)
1591 tcg_target_ulong val;
1593 ots = &s->temps[args[0]];
1596 if (ots->fixed_reg) {
1597 /* for fixed registers, we do not do any constant
1599 tcg_out_movi(s, ots->type, ots->reg, val);
1601 /* The movi is not explicitly generated here */
1602 if (ots->val_type == TEMP_VAL_REG)
1603 s->reg_to_temp[ots->reg] = -1;
1604 ots->val_type = TEMP_VAL_CONST;
1609 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
1611 unsigned int dead_args)
1615 const TCGArgConstraint *arg_ct;
1617 ots = &s->temps[args[0]];
1618 ts = &s->temps[args[1]];
1619 arg_ct = &def->args_ct[0];
1621 /* XXX: always mark arg dead if IS_DEAD_ARG(1) */
1622 if (ts->val_type == TEMP_VAL_REG) {
1623 if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
1624 /* the mov can be suppressed */
1625 if (ots->val_type == TEMP_VAL_REG)
1626 s->reg_to_temp[ots->reg] = -1;
1628 s->reg_to_temp[reg] = -1;
1629 ts->val_type = TEMP_VAL_DEAD;
1631 if (ots->val_type == TEMP_VAL_REG) {
1634 reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
1636 if (ts->reg != reg) {
1637 tcg_out_mov(s, ots->type, reg, ts->reg);
1640 } else if (ts->val_type == TEMP_VAL_MEM) {
1641 if (ots->val_type == TEMP_VAL_REG) {
1644 reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
1646 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1647 } else if (ts->val_type == TEMP_VAL_CONST) {
1648 if (ots->fixed_reg) {
1650 tcg_out_movi(s, ots->type, reg, ts->val);
1652 /* propagate constant */
1653 if (ots->val_type == TEMP_VAL_REG)
1654 s->reg_to_temp[ots->reg] = -1;
1655 ots->val_type = TEMP_VAL_CONST;
1662 s->reg_to_temp[reg] = args[0];
1664 ots->val_type = TEMP_VAL_REG;
1665 ots->mem_coherent = 0;
1668 static void tcg_reg_alloc_op(TCGContext *s,
1669 const TCGOpDef *def, TCGOpcode opc,
1671 unsigned int dead_args)
1673 TCGRegSet allocated_regs;
1674 int i, k, nb_iargs, nb_oargs, reg;
1676 const TCGArgConstraint *arg_ct;
1678 TCGArg new_args[TCG_MAX_OP_ARGS];
1679 int const_args[TCG_MAX_OP_ARGS];
1681 nb_oargs = def->nb_oargs;
1682 nb_iargs = def->nb_iargs;
1684 /* copy constants */
1685 memcpy(new_args + nb_oargs + nb_iargs,
1686 args + nb_oargs + nb_iargs,
1687 sizeof(TCGArg) * def->nb_cargs);
1689 /* satisfy input constraints */
1690 tcg_regset_set(allocated_regs, s->reserved_regs);
1691 for(k = 0; k < nb_iargs; k++) {
1692 i = def->sorted_args[nb_oargs + k];
1694 arg_ct = &def->args_ct[i];
1695 ts = &s->temps[arg];
1696 if (ts->val_type == TEMP_VAL_MEM) {
1697 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1698 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1699 ts->val_type = TEMP_VAL_REG;
1701 ts->mem_coherent = 1;
1702 s->reg_to_temp[reg] = arg;
1703 } else if (ts->val_type == TEMP_VAL_CONST) {
1704 if (tcg_target_const_match(ts->val, arg_ct)) {
1705 /* constant is OK for instruction */
1707 new_args[i] = ts->val;
1710 /* need to move to a register */
1711 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1712 tcg_out_movi(s, ts->type, reg, ts->val);
1713 ts->val_type = TEMP_VAL_REG;
1715 ts->mem_coherent = 0;
1716 s->reg_to_temp[reg] = arg;
1719 assert(ts->val_type == TEMP_VAL_REG);
1720 if (arg_ct->ct & TCG_CT_IALIAS) {
1721 if (ts->fixed_reg) {
1722 /* if fixed register, we must allocate a new register
1723 if the alias is not the same register */
1724 if (arg != args[arg_ct->alias_index])
1725 goto allocate_in_reg;
1727 /* if the input is aliased to an output and if it is
1728 not dead after the instruction, we must allocate
1729 a new register and move it */
1730 if (!IS_DEAD_ARG(i)) {
1731 goto allocate_in_reg;
1736 if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1737 /* nothing to do : the constraint is satisfied */
1740 /* allocate a new register matching the constraint
1741 and move the temporary register into it */
1742 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1743 tcg_out_mov(s, ts->type, reg, ts->reg);
1747 tcg_regset_set_reg(allocated_regs, reg);
1751 if (def->flags & TCG_OPF_BB_END) {
1752 tcg_reg_alloc_bb_end(s, allocated_regs);
1754 /* mark dead temporaries and free the associated registers */
1755 for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1757 if (IS_DEAD_ARG(i)) {
1758 ts = &s->temps[arg];
1759 if (!ts->fixed_reg) {
1760 if (ts->val_type == TEMP_VAL_REG)
1761 s->reg_to_temp[ts->reg] = -1;
1762 ts->val_type = TEMP_VAL_DEAD;
1767 if (def->flags & TCG_OPF_CALL_CLOBBER) {
1768 /* XXX: permit generic clobber register list ? */
1769 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1770 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1771 tcg_reg_free(s, reg);
1774 /* XXX: for load/store we could do that only for the slow path
1775 (i.e. when a memory callback is called) */
1777 /* store globals and free associated registers (we assume the insn
1778 can modify any global. */
1779 save_globals(s, allocated_regs);
1782 /* satisfy the output constraints */
1783 tcg_regset_set(allocated_regs, s->reserved_regs);
1784 for(k = 0; k < nb_oargs; k++) {
1785 i = def->sorted_args[k];
1787 arg_ct = &def->args_ct[i];
1788 ts = &s->temps[arg];
1789 if (arg_ct->ct & TCG_CT_ALIAS) {
1790 reg = new_args[arg_ct->alias_index];
1792 /* if fixed register, we try to use it */
1794 if (ts->fixed_reg &&
1795 tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1798 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1800 tcg_regset_set_reg(allocated_regs, reg);
1801 /* if a fixed register is used, then a move will be done afterwards */
1802 if (!ts->fixed_reg) {
1803 if (ts->val_type == TEMP_VAL_REG)
1804 s->reg_to_temp[ts->reg] = -1;
1805 if (IS_DEAD_ARG(i)) {
1806 ts->val_type = TEMP_VAL_DEAD;
1808 ts->val_type = TEMP_VAL_REG;
1810 /* temp value is modified, so the value kept in memory is
1811 potentially not the same */
1812 ts->mem_coherent = 0;
1813 s->reg_to_temp[reg] = arg;
1821 /* emit instruction */
1822 tcg_out_op(s, opc, new_args, const_args);
1824 /* move the outputs in the correct register if needed */
1825 for(i = 0; i < nb_oargs; i++) {
1826 ts = &s->temps[args[i]];
1828 if (ts->fixed_reg && ts->reg != reg) {
1829 tcg_out_mov(s, ts->type, ts->reg, reg);
1834 #ifdef TCG_TARGET_STACK_GROWSUP
1835 #define STACK_DIR(x) (-(x))
1837 #define STACK_DIR(x) (x)
1840 static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1841 TCGOpcode opc, const TCGArg *args,
1842 unsigned int dead_args)
1844 int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
1845 TCGArg arg, func_arg;
1847 tcg_target_long stack_offset, call_stack_size, func_addr;
1848 int const_func_arg, allocate_args;
1849 TCGRegSet allocated_regs;
1850 const TCGArgConstraint *arg_ct;
1854 nb_oargs = arg >> 16;
1855 nb_iargs = arg & 0xffff;
1856 nb_params = nb_iargs - 1;
1858 flags = args[nb_oargs + nb_iargs];
1860 nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
1861 if (nb_regs > nb_params)
1862 nb_regs = nb_params;
1864 /* assign stack slots first */
1865 call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
1866 call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) &
1867 ~(TCG_TARGET_STACK_ALIGN - 1);
1868 allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
1869 if (allocate_args) {
1870 /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
1871 preallocate call stack */
1875 stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
1876 for(i = nb_regs; i < nb_params; i++) {
1877 arg = args[nb_oargs + i];
1878 #ifdef TCG_TARGET_STACK_GROWSUP
1879 stack_offset -= sizeof(tcg_target_long);
1881 if (arg != TCG_CALL_DUMMY_ARG) {
1882 ts = &s->temps[arg];
1883 if (ts->val_type == TEMP_VAL_REG) {
1884 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
1885 } else if (ts->val_type == TEMP_VAL_MEM) {
1886 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1888 /* XXX: not correct if reading values from the stack */
1889 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1890 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
1891 } else if (ts->val_type == TEMP_VAL_CONST) {
1892 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1894 /* XXX: sign extend may be needed on some targets */
1895 tcg_out_movi(s, ts->type, reg, ts->val);
1896 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
1901 #ifndef TCG_TARGET_STACK_GROWSUP
1902 stack_offset += sizeof(tcg_target_long);
1906 /* assign input registers */
1907 tcg_regset_set(allocated_regs, s->reserved_regs);
1908 for(i = 0; i < nb_regs; i++) {
1909 arg = args[nb_oargs + i];
1910 if (arg != TCG_CALL_DUMMY_ARG) {
1911 ts = &s->temps[arg];
1912 reg = tcg_target_call_iarg_regs[i];
1913 tcg_reg_free(s, reg);
1914 if (ts->val_type == TEMP_VAL_REG) {
1915 if (ts->reg != reg) {
1916 tcg_out_mov(s, ts->type, reg, ts->reg);
1918 } else if (ts->val_type == TEMP_VAL_MEM) {
1919 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1920 } else if (ts->val_type == TEMP_VAL_CONST) {
1921 /* XXX: sign extend ? */
1922 tcg_out_movi(s, ts->type, reg, ts->val);
1926 tcg_regset_set_reg(allocated_regs, reg);
1930 /* assign function address */
1931 func_arg = args[nb_oargs + nb_iargs - 1];
1932 arg_ct = &def->args_ct[0];
1933 ts = &s->temps[func_arg];
1934 func_addr = ts->val;
1936 if (ts->val_type == TEMP_VAL_MEM) {
1937 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1938 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1940 tcg_regset_set_reg(allocated_regs, reg);
1941 } else if (ts->val_type == TEMP_VAL_REG) {
1943 if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1944 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1945 tcg_out_mov(s, ts->type, reg, ts->reg);
1948 tcg_regset_set_reg(allocated_regs, reg);
1949 } else if (ts->val_type == TEMP_VAL_CONST) {
1950 if (tcg_target_const_match(func_addr, arg_ct)) {
1952 func_arg = func_addr;
1954 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1955 tcg_out_movi(s, ts->type, reg, func_addr);
1957 tcg_regset_set_reg(allocated_regs, reg);
1964 /* mark dead temporaries and free the associated registers */
1965 for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1967 if (IS_DEAD_ARG(i)) {
1968 ts = &s->temps[arg];
1969 if (!ts->fixed_reg) {
1970 if (ts->val_type == TEMP_VAL_REG)
1971 s->reg_to_temp[ts->reg] = -1;
1972 ts->val_type = TEMP_VAL_DEAD;
1977 /* clobber call registers */
1978 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1979 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1980 tcg_reg_free(s, reg);
1984 /* store globals and free associated registers (we assume the call
1985 can modify any global. */
1986 if (!(flags & TCG_CALL_CONST)) {
1987 save_globals(s, allocated_regs);
1990 tcg_out_op(s, opc, &func_arg, &const_func_arg);
1992 /* assign output registers and emit moves if needed */
1993 for(i = 0; i < nb_oargs; i++) {
1995 ts = &s->temps[arg];
1996 reg = tcg_target_call_oarg_regs[i];
1997 assert(s->reg_to_temp[reg] == -1);
1998 if (ts->fixed_reg) {
1999 if (ts->reg != reg) {
2000 tcg_out_mov(s, ts->type, ts->reg, reg);
2003 if (ts->val_type == TEMP_VAL_REG)
2004 s->reg_to_temp[ts->reg] = -1;
2005 if (IS_DEAD_ARG(i)) {
2006 ts->val_type = TEMP_VAL_DEAD;
2008 ts->val_type = TEMP_VAL_REG;
2010 ts->mem_coherent = 0;
2011 s->reg_to_temp[reg] = arg;
2016 return nb_iargs + nb_oargs + def->nb_cargs + 1;
2019 #ifdef CONFIG_PROFILER
2021 static int64_t tcg_table_op_count[NB_OPS];
2023 static void dump_op_count(void)
2027 f = fopen("/tmp/op.log", "w");
2028 for(i = INDEX_op_end; i < NB_OPS; i++) {
2029 fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
2036 static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
2041 const TCGOpDef *def;
2042 unsigned int dead_args;
2046 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2053 #ifdef CONFIG_PROFILER
2054 s->opt_time -= profile_getclock();
2057 #ifdef USE_TCG_OPTIMIZATIONS
2059 tcg_optimize(s, gen_opc_ptr, gen_opparam_buf, tcg_op_defs);
2062 #ifdef CONFIG_PROFILER
2063 s->opt_time += profile_getclock();
2064 s->la_time -= profile_getclock();
2067 tcg_liveness_analysis(s);
2069 #ifdef CONFIG_PROFILER
2070 s->la_time += profile_getclock();
2074 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
2075 qemu_log("OP after optimization and liveness analysis:\n");
2081 tcg_reg_alloc_start(s);
2083 s->code_buf = gen_code_buf;
2084 s->code_ptr = gen_code_buf;
2086 args = gen_opparam_buf;
2090 opc = gen_opc_buf[op_index];
2091 #ifdef CONFIG_PROFILER
2092 tcg_table_op_count[opc]++;
2094 def = &tcg_op_defs[opc];
2096 printf("%s: %d %d %d\n", def->name,
2097 def->nb_oargs, def->nb_iargs, def->nb_cargs);
2101 case INDEX_op_mov_i32:
2102 case INDEX_op_mov_i64:
2103 dead_args = s->op_dead_args[op_index];
2104 tcg_reg_alloc_mov(s, def, args, dead_args);
2106 case INDEX_op_movi_i32:
2107 case INDEX_op_movi_i64:
2108 tcg_reg_alloc_movi(s, args);
2110 case INDEX_op_debug_insn_start:
2111 /* debug instruction */
2121 case INDEX_op_discard:
2124 ts = &s->temps[args[0]];
2125 /* mark the temporary as dead */
2126 if (!ts->fixed_reg) {
2127 if (ts->val_type == TEMP_VAL_REG)
2128 s->reg_to_temp[ts->reg] = -1;
2129 ts->val_type = TEMP_VAL_DEAD;
2133 case INDEX_op_set_label:
2134 tcg_reg_alloc_bb_end(s, s->reserved_regs);
2135 tcg_out_label(s, args[0], s->code_ptr);
2138 dead_args = s->op_dead_args[op_index];
2139 args += tcg_reg_alloc_call(s, def, opc, args, dead_args);
2144 /* Sanity check that we've not introduced any unhandled opcodes. */
2145 if (def->flags & TCG_OPF_NOT_PRESENT) {
2148 /* Note: in order to speed up the code, it would be much
2149 faster to have specialized register allocator functions for
2150 some common argument patterns */
2151 dead_args = s->op_dead_args[op_index];
2152 tcg_reg_alloc_op(s, def, opc, args, dead_args);
2155 args += def->nb_args;
2157 if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
2169 int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
2171 #ifdef CONFIG_PROFILER
2174 n = (gen_opc_ptr - gen_opc_buf);
2176 if (n > s->op_count_max)
2177 s->op_count_max = n;
2179 s->temp_count += s->nb_temps;
2180 if (s->nb_temps > s->temp_count_max)
2181 s->temp_count_max = s->nb_temps;
2185 tcg_gen_code_common(s, gen_code_buf, -1);
2187 /* flush instruction cache */
2188 flush_icache_range((tcg_target_ulong)gen_code_buf,
2189 (tcg_target_ulong)s->code_ptr);
2191 return s->code_ptr - gen_code_buf;
2194 /* Return the index of the micro operation such as the pc after is <
2195 offset bytes from the start of the TB. The contents of gen_code_buf must
2196 not be changed, though writing the same values is ok.
2197 Return -1 if not found. */
2198 int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
2200 return tcg_gen_code_common(s, gen_code_buf, offset);
2203 #ifdef CONFIG_PROFILER
2204 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2206 TCGContext *s = &tcg_ctx;
2209 tot = s->interm_time + s->code_time;
2210 cpu_fprintf(f, "JIT cycles %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2212 cpu_fprintf(f, "translated TBs %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n",
2214 s->tb_count1 - s->tb_count,
2215 s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
2216 cpu_fprintf(f, "avg ops/TB %0.1f max=%d\n",
2217 s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
2218 cpu_fprintf(f, "deleted ops/TB %0.2f\n",
2220 (double)s->del_op_count / s->tb_count : 0);
2221 cpu_fprintf(f, "avg temps/TB %0.2f max=%d\n",
2223 (double)s->temp_count / s->tb_count : 0,
2226 cpu_fprintf(f, "cycles/op %0.1f\n",
2227 s->op_count ? (double)tot / s->op_count : 0);
2228 cpu_fprintf(f, "cycles/in byte %0.1f\n",
2229 s->code_in_len ? (double)tot / s->code_in_len : 0);
2230 cpu_fprintf(f, "cycles/out byte %0.1f\n",
2231 s->code_out_len ? (double)tot / s->code_out_len : 0);
2234 cpu_fprintf(f, " gen_interm time %0.1f%%\n",
2235 (double)s->interm_time / tot * 100.0);
2236 cpu_fprintf(f, " gen_code time %0.1f%%\n",
2237 (double)s->code_time / tot * 100.0);
2238 cpu_fprintf(f, "optim./code time %0.1f%%\n",
2239 (double)s->opt_time / (s->code_time ? s->code_time : 1)
2241 cpu_fprintf(f, "liveness/code time %0.1f%%\n",
2242 (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2243 cpu_fprintf(f, "cpu_restore count %" PRId64 "\n",
2245 cpu_fprintf(f, " avg cycles %0.1f\n",
2246 s->restore_count ? (double)s->restore_time / s->restore_count : 0);
2251 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2253 cpu_fprintf(f, "[TCG profiler not compiled]\n");
2257 #ifdef ELF_HOST_MACHINE
2258 /* In order to use this feature, the backend needs to do three things:
2260 (1) Define ELF_HOST_MACHINE to indicate both what value to
2261 put into the ELF image and to indicate support for the feature.
2263 (2) Define tcg_register_jit. This should create a buffer containing
2264 the contents of a .debug_frame section that describes the post-
2265 prologue unwind info for the tcg machine.
2267 (3) Call tcg_register_jit_int, with the constructed .debug_frame.
2270 /* Begin GDB interface. THE FOLLOWING MUST MATCH GDB DOCS. */
2277 struct jit_code_entry {
2278 struct jit_code_entry *next_entry;
2279 struct jit_code_entry *prev_entry;
2280 const void *symfile_addr;
2281 uint64_t symfile_size;
2284 struct jit_descriptor {
2286 uint32_t action_flag;
2287 struct jit_code_entry *relevant_entry;
2288 struct jit_code_entry *first_entry;
2291 void __jit_debug_register_code(void) __attribute__((noinline));
2292 void __jit_debug_register_code(void)
2297 /* Must statically initialize the version, because GDB may check
2298 the version before we can set it. */
2299 struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
2301 /* End GDB interface. */
2303 static int find_string(const char *strtab, const char *str)
2305 const char *p = strtab + 1;
2308 if (strcmp(p, str) == 0) {
2315 static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
2316 void *debug_frame, size_t debug_frame_size)
2318 struct __attribute__((packed)) DebugInfo {
2325 uintptr_t cu_low_pc;
2326 uintptr_t cu_high_pc;
2329 uintptr_t fn_low_pc;
2330 uintptr_t fn_high_pc;
2339 struct DebugInfo di;
2344 struct ElfImage *img;
2346 static const struct ElfImage img_template = {
2348 .e_ident[EI_MAG0] = ELFMAG0,
2349 .e_ident[EI_MAG1] = ELFMAG1,
2350 .e_ident[EI_MAG2] = ELFMAG2,
2351 .e_ident[EI_MAG3] = ELFMAG3,
2352 .e_ident[EI_CLASS] = ELF_CLASS,
2353 .e_ident[EI_DATA] = ELF_DATA,
2354 .e_ident[EI_VERSION] = EV_CURRENT,
2356 .e_machine = ELF_HOST_MACHINE,
2357 .e_version = EV_CURRENT,
2358 .e_phoff = offsetof(struct ElfImage, phdr),
2359 .e_shoff = offsetof(struct ElfImage, shdr),
2360 .e_ehsize = sizeof(ElfW(Shdr)),
2361 .e_phentsize = sizeof(ElfW(Phdr)),
2363 .e_shentsize = sizeof(ElfW(Shdr)),
2364 .e_shnum = ARRAY_SIZE(img->shdr),
2365 .e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
2366 #ifdef ELF_HOST_FLAGS
2367 .e_flags = ELF_HOST_FLAGS,
2370 .e_ident[EI_OSABI] = ELF_OSABI,
2378 [0] = { .sh_type = SHT_NULL },
2379 /* Trick: The contents of code_gen_buffer are not present in
2380 this fake ELF file; that got allocated elsewhere. Therefore
2381 we mark .text as SHT_NOBITS (similar to .bss) so that readers
2382 will not look for contents. We can record any address. */
2384 .sh_type = SHT_NOBITS,
2385 .sh_flags = SHF_EXECINSTR | SHF_ALLOC,
2387 [2] = { /* .debug_info */
2388 .sh_type = SHT_PROGBITS,
2389 .sh_offset = offsetof(struct ElfImage, di),
2390 .sh_size = sizeof(struct DebugInfo),
2392 [3] = { /* .debug_abbrev */
2393 .sh_type = SHT_PROGBITS,
2394 .sh_offset = offsetof(struct ElfImage, da),
2395 .sh_size = sizeof(img->da),
2397 [4] = { /* .debug_frame */
2398 .sh_type = SHT_PROGBITS,
2399 .sh_offset = sizeof(struct ElfImage),
2401 [5] = { /* .symtab */
2402 .sh_type = SHT_SYMTAB,
2403 .sh_offset = offsetof(struct ElfImage, sym),
2404 .sh_size = sizeof(img->sym),
2406 .sh_link = ARRAY_SIZE(img->shdr) - 1,
2407 .sh_entsize = sizeof(ElfW(Sym)),
2409 [6] = { /* .strtab */
2410 .sh_type = SHT_STRTAB,
2411 .sh_offset = offsetof(struct ElfImage, str),
2412 .sh_size = sizeof(img->str),
2416 [1] = { /* code_gen_buffer */
2417 .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
2422 .len = sizeof(struct DebugInfo) - 4,
2424 .ptr_size = sizeof(void *),
2426 .cu_lang = 0x8001, /* DW_LANG_Mips_Assembler */
2428 .fn_name = "code_gen_buffer"
2431 1, /* abbrev number (the cu) */
2432 0x11, 1, /* DW_TAG_compile_unit, has children */
2433 0x13, 0x5, /* DW_AT_language, DW_FORM_data2 */
2434 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
2435 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
2436 0, 0, /* end of abbrev */
2437 2, /* abbrev number (the fn) */
2438 0x2e, 0, /* DW_TAG_subprogram, no children */
2439 0x3, 0x8, /* DW_AT_name, DW_FORM_string */
2440 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
2441 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
2442 0, 0, /* end of abbrev */
2443 0 /* no more abbrev */
2445 .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
2446 ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
2449 /* We only need a single jit entry; statically allocate it. */
2450 static struct jit_code_entry one_entry;
2452 uintptr_t buf = (uintptr_t)buf_ptr;
2453 size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
2455 img = g_malloc(img_size);
2456 *img = img_template;
2457 memcpy(img + 1, debug_frame, debug_frame_size);
2459 img->phdr.p_vaddr = buf;
2460 img->phdr.p_paddr = buf;
2461 img->phdr.p_memsz = buf_size;
2463 img->shdr[1].sh_name = find_string(img->str, ".text");
2464 img->shdr[1].sh_addr = buf;
2465 img->shdr[1].sh_size = buf_size;
2467 img->shdr[2].sh_name = find_string(img->str, ".debug_info");
2468 img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
2470 img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
2471 img->shdr[4].sh_size = debug_frame_size;
2473 img->shdr[5].sh_name = find_string(img->str, ".symtab");
2474 img->shdr[6].sh_name = find_string(img->str, ".strtab");
2476 img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
2477 img->sym[1].st_value = buf;
2478 img->sym[1].st_size = buf_size;
2480 img->di.cu_low_pc = buf;
2481 img->di.cu_high_pc = buf_size;
2482 img->di.fn_low_pc = buf;
2483 img->di.fn_high_pc = buf_size;
2486 /* Enable this block to be able to debug the ELF image file creation.
2487 One can use readelf, objdump, or other inspection utilities. */
2489 FILE *f = fopen("/tmp/qemu.jit", "w+b");
2491 if (fwrite(img, img_size, 1, f) != img_size) {
2492 /* Avoid stupid unused return value warning for fwrite. */
2499 one_entry.symfile_addr = img;
2500 one_entry.symfile_size = img_size;
2502 __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
2503 __jit_debug_descriptor.relevant_entry = &one_entry;
2504 __jit_debug_descriptor.first_entry = &one_entry;
2505 __jit_debug_register_code();
2508 /* No support for the feature. Provide the entry point expected by exec.c,
2509 and implement the internal function we declared earlier. */
2511 static void tcg_register_jit_int(void *buf, size_t size,
2512 void *debug_frame, size_t debug_frame_size)
2516 void tcg_register_jit(void *buf, size_t buf_size)
2519 #endif /* ELF_HOST_MACHINE */