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_TCG_OPTIMIZATIONS
28 #include "qemu/osdep.h"
30 /* Define to jump the ELF file used to communicate with GDB. */
33 #include "qemu/error-report.h"
34 #include "qemu/cutils.h"
35 #include "qemu/host-utils.h"
36 #include "qemu/qemu-print.h"
37 #include "qemu/timer.h"
38 #include "qemu/cacheflush.h"
40 /* Note: the long term plan is to reduce the dependencies on the QEMU
41 CPU definitions. Currently they are used for qemu_ld/st
43 #define NO_CPU_IO_DEFS
46 #include "exec/exec-all.h"
48 #if !defined(CONFIG_USER_ONLY)
49 #include "hw/boards.h"
52 #include "tcg/tcg-op.h"
54 #if UINTPTR_MAX == UINT32_MAX
55 # define ELF_CLASS ELFCLASS32
57 # define ELF_CLASS ELFCLASS64
59 #ifdef HOST_WORDS_BIGENDIAN
60 # define ELF_DATA ELFDATA2MSB
62 # define ELF_DATA ELFDATA2LSB
67 #include "sysemu/sysemu.h"
69 /* Forward declarations for functions declared in tcg-target.c.inc and
71 static void tcg_target_init(TCGContext *s);
72 static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode);
73 static void tcg_target_qemu_prologue(TCGContext *s);
74 static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
75 intptr_t value, intptr_t addend);
77 /* The CIE and FDE header definitions will be common to all hosts. */
79 uint32_t len __attribute__((aligned((sizeof(void *)))));
85 uint8_t return_column;
88 typedef struct QEMU_PACKED {
89 uint32_t len __attribute__((aligned((sizeof(void *)))));
93 } DebugFrameFDEHeader;
95 typedef struct QEMU_PACKED {
97 DebugFrameFDEHeader fde;
100 static void tcg_register_jit_int(void *buf, size_t size,
101 const void *debug_frame,
102 size_t debug_frame_size)
103 __attribute__((unused));
105 /* Forward declarations for functions declared and used in tcg-target.c.inc. */
106 static const char *target_parse_constraint(TCGArgConstraint *ct,
107 const char *ct_str, TCGType type);
108 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
110 static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
111 static void tcg_out_movi(TCGContext *s, TCGType type,
112 TCGReg ret, tcg_target_long arg);
113 static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
114 const int *const_args);
115 #if TCG_TARGET_MAYBE_vec
116 static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
117 TCGReg dst, TCGReg src);
118 static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
119 TCGReg dst, TCGReg base, intptr_t offset);
120 static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
121 TCGReg dst, tcg_target_long arg);
122 static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, unsigned vecl,
123 unsigned vece, const TCGArg *args,
124 const int *const_args);
126 static inline bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
127 TCGReg dst, TCGReg src)
129 g_assert_not_reached();
131 static inline bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
132 TCGReg dst, TCGReg base, intptr_t offset)
134 g_assert_not_reached();
136 static inline void tcg_out_dupi_vec(TCGContext *s, TCGType type,
137 TCGReg dst, tcg_target_long arg)
139 g_assert_not_reached();
141 static inline void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, unsigned vecl,
142 unsigned vece, const TCGArg *args,
143 const int *const_args)
145 g_assert_not_reached();
148 static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
150 static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
151 TCGReg base, intptr_t ofs);
152 static void tcg_out_call(TCGContext *s, tcg_insn_unit *target);
153 static int tcg_target_const_match(tcg_target_long val, TCGType type,
154 const TCGArgConstraint *arg_ct);
155 #ifdef TCG_TARGET_NEED_LDST_LABELS
156 static int tcg_out_ldst_finalize(TCGContext *s);
159 #define TCG_HIGHWATER 1024
161 static TCGContext **tcg_ctxs;
162 static unsigned int n_tcg_ctxs;
163 TCGv_env cpu_env = 0;
164 void *tcg_code_gen_epilogue;
166 #ifndef CONFIG_TCG_INTERPRETER
167 tcg_prologue_fn *tcg_qemu_tb_exec;
170 struct tcg_region_tree {
173 /* padding to avoid false sharing is computed at run-time */
177 * We divide code_gen_buffer into equally-sized "regions" that TCG threads
178 * dynamically allocate from as demand dictates. Given appropriate region
179 * sizing, this minimizes flushes even when some TCG threads generate a lot
180 * more code than others.
182 struct tcg_region_state {
185 /* fields set at init time */
190 size_t size; /* size of one region */
191 size_t stride; /* .size + guard size */
193 /* fields protected by the lock */
194 size_t current; /* current region index */
195 size_t agg_size_full; /* aggregate size of full regions */
198 static struct tcg_region_state region;
200 * This is an array of struct tcg_region_tree's, with padding.
201 * We use void * to simplify the computation of region_trees[i]; each
202 * struct is found every tree_size bytes.
204 static void *region_trees;
205 static size_t tree_size;
206 static TCGRegSet tcg_target_available_regs[TCG_TYPE_COUNT];
207 static TCGRegSet tcg_target_call_clobber_regs;
209 #if TCG_TARGET_INSN_UNIT_SIZE == 1
210 static __attribute__((unused)) inline void tcg_out8(TCGContext *s, uint8_t v)
215 static __attribute__((unused)) inline void tcg_patch8(tcg_insn_unit *p,
222 #if TCG_TARGET_INSN_UNIT_SIZE <= 2
223 static __attribute__((unused)) inline void tcg_out16(TCGContext *s, uint16_t v)
225 if (TCG_TARGET_INSN_UNIT_SIZE == 2) {
228 tcg_insn_unit *p = s->code_ptr;
229 memcpy(p, &v, sizeof(v));
230 s->code_ptr = p + (2 / TCG_TARGET_INSN_UNIT_SIZE);
234 static __attribute__((unused)) inline void tcg_patch16(tcg_insn_unit *p,
237 if (TCG_TARGET_INSN_UNIT_SIZE == 2) {
240 memcpy(p, &v, sizeof(v));
245 #if TCG_TARGET_INSN_UNIT_SIZE <= 4
246 static __attribute__((unused)) inline void tcg_out32(TCGContext *s, uint32_t v)
248 if (TCG_TARGET_INSN_UNIT_SIZE == 4) {
251 tcg_insn_unit *p = s->code_ptr;
252 memcpy(p, &v, sizeof(v));
253 s->code_ptr = p + (4 / TCG_TARGET_INSN_UNIT_SIZE);
257 static __attribute__((unused)) inline void tcg_patch32(tcg_insn_unit *p,
260 if (TCG_TARGET_INSN_UNIT_SIZE == 4) {
263 memcpy(p, &v, sizeof(v));
268 #if TCG_TARGET_INSN_UNIT_SIZE <= 8
269 static __attribute__((unused)) inline void tcg_out64(TCGContext *s, uint64_t v)
271 if (TCG_TARGET_INSN_UNIT_SIZE == 8) {
274 tcg_insn_unit *p = s->code_ptr;
275 memcpy(p, &v, sizeof(v));
276 s->code_ptr = p + (8 / TCG_TARGET_INSN_UNIT_SIZE);
280 static __attribute__((unused)) inline void tcg_patch64(tcg_insn_unit *p,
283 if (TCG_TARGET_INSN_UNIT_SIZE == 8) {
286 memcpy(p, &v, sizeof(v));
291 /* label relocation processing */
293 static void tcg_out_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
294 TCGLabel *l, intptr_t addend)
296 TCGRelocation *r = tcg_malloc(sizeof(TCGRelocation));
301 QSIMPLEQ_INSERT_TAIL(&l->relocs, r, next);
304 static void tcg_out_label(TCGContext *s, TCGLabel *l, tcg_insn_unit *ptr)
306 tcg_debug_assert(!l->has_value);
308 l->u.value_ptr = ptr;
311 TCGLabel *gen_new_label(void)
313 TCGContext *s = tcg_ctx;
314 TCGLabel *l = tcg_malloc(sizeof(TCGLabel));
316 memset(l, 0, sizeof(TCGLabel));
317 l->id = s->nb_labels++;
318 QSIMPLEQ_INIT(&l->relocs);
320 QSIMPLEQ_INSERT_TAIL(&s->labels, l, next);
325 static bool tcg_resolve_relocs(TCGContext *s)
329 QSIMPLEQ_FOREACH(l, &s->labels, next) {
331 uintptr_t value = l->u.value;
333 QSIMPLEQ_FOREACH(r, &l->relocs, next) {
334 if (!patch_reloc(r->ptr, r->type, value, r->addend)) {
342 static void set_jmp_reset_offset(TCGContext *s, int which)
345 * We will check for overflow at the end of the opcode loop in
346 * tcg_gen_code, where we bound tcg_current_code_size to UINT16_MAX.
348 s->tb_jmp_reset_offset[which] = tcg_current_code_size(s);
351 #include "tcg-target.c.inc"
353 /* compare a pointer @ptr and a tb_tc @s */
354 static int ptr_cmp_tb_tc(const void *ptr, const struct tb_tc *s)
356 if (ptr >= s->ptr + s->size) {
358 } else if (ptr < s->ptr) {
364 static gint tb_tc_cmp(gconstpointer ap, gconstpointer bp)
366 const struct tb_tc *a = ap;
367 const struct tb_tc *b = bp;
370 * When both sizes are set, we know this isn't a lookup.
371 * This is the most likely case: every TB must be inserted; lookups
372 * are a lot less frequent.
374 if (likely(a->size && b->size)) {
375 if (a->ptr > b->ptr) {
377 } else if (a->ptr < b->ptr) {
380 /* a->ptr == b->ptr should happen only on deletions */
381 g_assert(a->size == b->size);
385 * All lookups have either .size field set to 0.
386 * From the glib sources we see that @ap is always the lookup key. However
387 * the docs provide no guarantee, so we just mark this case as likely.
389 if (likely(a->size == 0)) {
390 return ptr_cmp_tb_tc(a->ptr, b);
392 return ptr_cmp_tb_tc(b->ptr, a);
395 static void tcg_region_trees_init(void)
399 tree_size = ROUND_UP(sizeof(struct tcg_region_tree), qemu_dcache_linesize);
400 region_trees = qemu_memalign(qemu_dcache_linesize, region.n * tree_size);
401 for (i = 0; i < region.n; i++) {
402 struct tcg_region_tree *rt = region_trees + i * tree_size;
404 qemu_mutex_init(&rt->lock);
405 rt->tree = g_tree_new(tb_tc_cmp);
409 static struct tcg_region_tree *tc_ptr_to_region_tree(void *p)
413 if (p < region.start_aligned) {
416 ptrdiff_t offset = p - region.start_aligned;
418 if (offset > region.stride * (region.n - 1)) {
419 region_idx = region.n - 1;
421 region_idx = offset / region.stride;
424 return region_trees + region_idx * tree_size;
427 void tcg_tb_insert(TranslationBlock *tb)
429 struct tcg_region_tree *rt = tc_ptr_to_region_tree(tb->tc.ptr);
431 qemu_mutex_lock(&rt->lock);
432 g_tree_insert(rt->tree, &tb->tc, tb);
433 qemu_mutex_unlock(&rt->lock);
436 void tcg_tb_remove(TranslationBlock *tb)
438 struct tcg_region_tree *rt = tc_ptr_to_region_tree(tb->tc.ptr);
440 qemu_mutex_lock(&rt->lock);
441 g_tree_remove(rt->tree, &tb->tc);
442 qemu_mutex_unlock(&rt->lock);
446 * Find the TB 'tb' such that
447 * tb->tc.ptr <= tc_ptr < tb->tc.ptr + tb->tc.size
448 * Return NULL if not found.
450 TranslationBlock *tcg_tb_lookup(uintptr_t tc_ptr)
452 struct tcg_region_tree *rt = tc_ptr_to_region_tree((void *)tc_ptr);
453 TranslationBlock *tb;
454 struct tb_tc s = { .ptr = (void *)tc_ptr };
456 qemu_mutex_lock(&rt->lock);
457 tb = g_tree_lookup(rt->tree, &s);
458 qemu_mutex_unlock(&rt->lock);
462 static void tcg_region_tree_lock_all(void)
466 for (i = 0; i < region.n; i++) {
467 struct tcg_region_tree *rt = region_trees + i * tree_size;
469 qemu_mutex_lock(&rt->lock);
473 static void tcg_region_tree_unlock_all(void)
477 for (i = 0; i < region.n; i++) {
478 struct tcg_region_tree *rt = region_trees + i * tree_size;
480 qemu_mutex_unlock(&rt->lock);
484 void tcg_tb_foreach(GTraverseFunc func, gpointer user_data)
488 tcg_region_tree_lock_all();
489 for (i = 0; i < region.n; i++) {
490 struct tcg_region_tree *rt = region_trees + i * tree_size;
492 g_tree_foreach(rt->tree, func, user_data);
494 tcg_region_tree_unlock_all();
497 size_t tcg_nb_tbs(void)
502 tcg_region_tree_lock_all();
503 for (i = 0; i < region.n; i++) {
504 struct tcg_region_tree *rt = region_trees + i * tree_size;
506 nb_tbs += g_tree_nnodes(rt->tree);
508 tcg_region_tree_unlock_all();
512 static gboolean tcg_region_tree_traverse(gpointer k, gpointer v, gpointer data)
514 TranslationBlock *tb = v;
520 static void tcg_region_tree_reset_all(void)
524 tcg_region_tree_lock_all();
525 for (i = 0; i < region.n; i++) {
526 struct tcg_region_tree *rt = region_trees + i * tree_size;
528 g_tree_foreach(rt->tree, tcg_region_tree_traverse, NULL);
529 /* Increment the refcount first so that destroy acts as a reset */
530 g_tree_ref(rt->tree);
531 g_tree_destroy(rt->tree);
533 tcg_region_tree_unlock_all();
536 static void tcg_region_bounds(size_t curr_region, void **pstart, void **pend)
540 start = region.start_aligned + curr_region * region.stride;
541 end = start + region.size;
543 if (curr_region == 0) {
544 start = region.start;
546 if (curr_region == region.n - 1) {
554 static void tcg_region_assign(TCGContext *s, size_t curr_region)
558 tcg_region_bounds(curr_region, &start, &end);
560 s->code_gen_buffer = start;
561 s->code_gen_ptr = start;
562 s->code_gen_buffer_size = end - start;
563 s->code_gen_highwater = end - TCG_HIGHWATER;
566 static bool tcg_region_alloc__locked(TCGContext *s)
568 if (region.current == region.n) {
571 tcg_region_assign(s, region.current);
577 * Request a new region once the one in use has filled up.
578 * Returns true on error.
580 static bool tcg_region_alloc(TCGContext *s)
583 /* read the region size now; alloc__locked will overwrite it on success */
584 size_t size_full = s->code_gen_buffer_size;
586 qemu_mutex_lock(®ion.lock);
587 err = tcg_region_alloc__locked(s);
589 region.agg_size_full += size_full - TCG_HIGHWATER;
591 qemu_mutex_unlock(®ion.lock);
596 * Perform a context's first region allocation.
597 * This function does _not_ increment region.agg_size_full.
599 static inline bool tcg_region_initial_alloc__locked(TCGContext *s)
601 return tcg_region_alloc__locked(s);
604 /* Call from a safe-work context */
605 void tcg_region_reset_all(void)
607 unsigned int n_ctxs = qatomic_read(&n_tcg_ctxs);
610 qemu_mutex_lock(®ion.lock);
612 region.agg_size_full = 0;
614 for (i = 0; i < n_ctxs; i++) {
615 TCGContext *s = qatomic_read(&tcg_ctxs[i]);
616 bool err = tcg_region_initial_alloc__locked(s);
620 qemu_mutex_unlock(®ion.lock);
622 tcg_region_tree_reset_all();
625 #ifdef CONFIG_USER_ONLY
626 static size_t tcg_n_regions(void)
632 * It is likely that some vCPUs will translate more code than others, so we
633 * first try to set more regions than max_cpus, with those regions being of
634 * reasonable size. If that's not possible we make do by evenly dividing
635 * the code_gen_buffer among the vCPUs.
637 static size_t tcg_n_regions(void)
641 /* Use a single region if all we have is one vCPU thread */
642 #if !defined(CONFIG_USER_ONLY)
643 MachineState *ms = MACHINE(qdev_get_machine());
644 unsigned int max_cpus = ms->smp.max_cpus;
646 if (max_cpus == 1 || !qemu_tcg_mttcg_enabled()) {
650 /* Try to have more regions than max_cpus, with each region being >= 2 MB */
651 for (i = 8; i > 0; i--) {
652 size_t regions_per_thread = i;
655 region_size = tcg_init_ctx.code_gen_buffer_size;
656 region_size /= max_cpus * regions_per_thread;
658 if (region_size >= 2 * 1024u * 1024) {
659 return max_cpus * regions_per_thread;
662 /* If we can't, then just allocate one region per vCPU thread */
668 * Initializes region partitioning.
670 * Called at init time from the parent thread (i.e. the one calling
671 * tcg_context_init), after the target's TCG globals have been set.
673 * Region partitioning works by splitting code_gen_buffer into separate regions,
674 * and then assigning regions to TCG threads so that the threads can translate
675 * code in parallel without synchronization.
677 * In softmmu the number of TCG threads is bounded by max_cpus, so we use at
678 * least max_cpus regions in MTTCG. In !MTTCG we use a single region.
679 * Note that the TCG options from the command-line (i.e. -accel accel=tcg,[...])
680 * must have been parsed before calling this function, since it calls
681 * qemu_tcg_mttcg_enabled().
683 * In user-mode we use a single region. Having multiple regions in user-mode
684 * is not supported, because the number of vCPU threads (recall that each thread
685 * spawned by the guest corresponds to a vCPU thread) is only bounded by the
686 * OS, and usually this number is huge (tens of thousands is not uncommon).
687 * Thus, given this large bound on the number of vCPU threads and the fact
688 * that code_gen_buffer is allocated at compile-time, we cannot guarantee
689 * that the availability of at least one region per vCPU thread.
691 * However, this user-mode limitation is unlikely to be a significant problem
692 * in practice. Multi-threaded guests share most if not all of their translated
693 * code, which makes parallel code generation less appealing than in softmmu.
695 void tcg_region_init(void)
697 void *buf = tcg_init_ctx.code_gen_buffer;
699 size_t size = tcg_init_ctx.code_gen_buffer_size;
700 size_t page_size = qemu_real_host_page_size;
705 n_regions = tcg_n_regions();
707 /* The first region will be 'aligned - buf' bytes larger than the others */
708 aligned = QEMU_ALIGN_PTR_UP(buf, page_size);
709 g_assert(aligned < tcg_init_ctx.code_gen_buffer + size);
711 * Make region_size a multiple of page_size, using aligned as the start.
712 * As a result of this we might end up with a few extra pages at the end of
713 * the buffer; we will assign those to the last region.
715 region_size = (size - (aligned - buf)) / n_regions;
716 region_size = QEMU_ALIGN_DOWN(region_size, page_size);
718 /* A region must have at least 2 pages; one code, one guard */
719 g_assert(region_size >= 2 * page_size);
721 /* init the region struct */
722 qemu_mutex_init(®ion.lock);
723 region.n = n_regions;
724 region.size = region_size - page_size;
725 region.stride = region_size;
727 region.start_aligned = aligned;
728 /* page-align the end, since its last page will be a guard page */
729 region.end = QEMU_ALIGN_PTR_DOWN(buf + size, page_size);
730 /* account for that last guard page */
731 region.end -= page_size;
733 /* set guard pages */
734 for (i = 0; i < region.n; i++) {
738 tcg_region_bounds(i, &start, &end);
739 rc = qemu_mprotect_none(end, page_size);
743 tcg_region_trees_init();
745 /* In user-mode we support only one ctx, so do the initial allocation now */
746 #ifdef CONFIG_USER_ONLY
748 bool err = tcg_region_initial_alloc__locked(tcg_ctx);
755 static void alloc_tcg_plugin_context(TCGContext *s)
758 s->plugin_tb = g_new0(struct qemu_plugin_tb, 1);
759 s->plugin_tb->insns =
760 g_ptr_array_new_with_free_func(qemu_plugin_insn_cleanup_fn);
765 * All TCG threads except the parent (i.e. the one that called tcg_context_init
766 * and registered the target's TCG globals) must register with this function
767 * before initiating translation.
769 * In user-mode we just point tcg_ctx to tcg_init_ctx. See the documentation
770 * of tcg_region_init() for the reasoning behind this.
772 * In softmmu each caller registers its context in tcg_ctxs[]. Note that in
773 * softmmu tcg_ctxs[] does not track tcg_ctx_init, since the initial context
774 * is not used anymore for translation once this function is called.
776 * Not tracking tcg_init_ctx in tcg_ctxs[] in softmmu keeps code that iterates
777 * over the array (e.g. tcg_code_size() the same for both softmmu and user-mode.
779 #ifdef CONFIG_USER_ONLY
780 void tcg_register_thread(void)
782 tcg_ctx = &tcg_init_ctx;
785 void tcg_register_thread(void)
787 MachineState *ms = MACHINE(qdev_get_machine());
788 TCGContext *s = g_malloc(sizeof(*s));
794 /* Relink mem_base. */
795 for (i = 0, n = tcg_init_ctx.nb_globals; i < n; ++i) {
796 if (tcg_init_ctx.temps[i].mem_base) {
797 ptrdiff_t b = tcg_init_ctx.temps[i].mem_base - tcg_init_ctx.temps;
798 tcg_debug_assert(b >= 0 && b < n);
799 s->temps[i].mem_base = &s->temps[b];
803 /* Claim an entry in tcg_ctxs */
804 n = qatomic_fetch_inc(&n_tcg_ctxs);
805 g_assert(n < ms->smp.max_cpus);
806 qatomic_set(&tcg_ctxs[n], s);
809 alloc_tcg_plugin_context(s);
813 qemu_mutex_lock(®ion.lock);
814 err = tcg_region_initial_alloc__locked(tcg_ctx);
816 qemu_mutex_unlock(®ion.lock);
818 #endif /* !CONFIG_USER_ONLY */
821 * Returns the size (in bytes) of all translated code (i.e. from all regions)
822 * currently in the cache.
823 * See also: tcg_code_capacity()
824 * Do not confuse with tcg_current_code_size(); that one applies to a single
827 size_t tcg_code_size(void)
829 unsigned int n_ctxs = qatomic_read(&n_tcg_ctxs);
833 qemu_mutex_lock(®ion.lock);
834 total = region.agg_size_full;
835 for (i = 0; i < n_ctxs; i++) {
836 const TCGContext *s = qatomic_read(&tcg_ctxs[i]);
839 size = qatomic_read(&s->code_gen_ptr) - s->code_gen_buffer;
840 g_assert(size <= s->code_gen_buffer_size);
843 qemu_mutex_unlock(®ion.lock);
848 * Returns the code capacity (in bytes) of the entire cache, i.e. including all
850 * See also: tcg_code_size()
852 size_t tcg_code_capacity(void)
854 size_t guard_size, capacity;
856 /* no need for synchronization; these variables are set at init time */
857 guard_size = region.stride - region.size;
858 capacity = region.end + guard_size - region.start;
859 capacity -= region.n * (guard_size + TCG_HIGHWATER);
863 size_t tcg_tb_phys_invalidate_count(void)
865 unsigned int n_ctxs = qatomic_read(&n_tcg_ctxs);
869 for (i = 0; i < n_ctxs; i++) {
870 const TCGContext *s = qatomic_read(&tcg_ctxs[i]);
872 total += qatomic_read(&s->tb_phys_invalidate_count);
877 /* pool based memory allocation */
878 void *tcg_malloc_internal(TCGContext *s, int size)
883 if (size > TCG_POOL_CHUNK_SIZE) {
884 /* big malloc: insert a new pool (XXX: could optimize) */
885 p = g_malloc(sizeof(TCGPool) + size);
887 p->next = s->pool_first_large;
888 s->pool_first_large = p;
899 pool_size = TCG_POOL_CHUNK_SIZE;
900 p = g_malloc(sizeof(TCGPool) + pool_size);
904 s->pool_current->next = p;
913 s->pool_cur = p->data + size;
914 s->pool_end = p->data + p->size;
918 void tcg_pool_reset(TCGContext *s)
921 for (p = s->pool_first_large; p; p = t) {
925 s->pool_first_large = NULL;
926 s->pool_cur = s->pool_end = NULL;
927 s->pool_current = NULL;
930 typedef struct TCGHelperInfo {
937 #include "exec/helper-proto.h"
939 static const TCGHelperInfo all_helpers[] = {
940 #include "exec/helper-tcg.h"
942 static GHashTable *helper_table;
944 static int indirect_reg_alloc_order[ARRAY_SIZE(tcg_target_reg_alloc_order)];
945 static void process_op_defs(TCGContext *s);
946 static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type,
947 TCGReg reg, const char *name);
949 void tcg_context_init(TCGContext *s)
951 int op, total_args, n, i;
953 TCGArgConstraint *args_ct;
956 memset(s, 0, sizeof(*s));
959 /* Count total number of arguments and allocate the corresponding
962 for(op = 0; op < NB_OPS; op++) {
963 def = &tcg_op_defs[op];
964 n = def->nb_iargs + def->nb_oargs;
968 args_ct = g_new0(TCGArgConstraint, total_args);
970 for(op = 0; op < NB_OPS; op++) {
971 def = &tcg_op_defs[op];
972 def->args_ct = args_ct;
973 n = def->nb_iargs + def->nb_oargs;
977 /* Register helpers. */
978 /* Use g_direct_hash/equal for direct pointer comparisons on func. */
979 helper_table = g_hash_table_new(NULL, NULL);
981 for (i = 0; i < ARRAY_SIZE(all_helpers); ++i) {
982 g_hash_table_insert(helper_table, (gpointer)all_helpers[i].func,
983 (gpointer)&all_helpers[i]);
989 /* Reverse the order of the saved registers, assuming they're all at
990 the start of tcg_target_reg_alloc_order. */
991 for (n = 0; n < ARRAY_SIZE(tcg_target_reg_alloc_order); ++n) {
992 int r = tcg_target_reg_alloc_order[n];
993 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, r)) {
997 for (i = 0; i < n; ++i) {
998 indirect_reg_alloc_order[i] = tcg_target_reg_alloc_order[n - 1 - i];
1000 for (; i < ARRAY_SIZE(tcg_target_reg_alloc_order); ++i) {
1001 indirect_reg_alloc_order[i] = tcg_target_reg_alloc_order[i];
1004 alloc_tcg_plugin_context(s);
1008 * In user-mode we simply share the init context among threads, since we
1009 * use a single region. See the documentation tcg_region_init() for the
1010 * reasoning behind this.
1011 * In softmmu we will have at most max_cpus TCG threads.
1013 #ifdef CONFIG_USER_ONLY
1014 tcg_ctxs = &tcg_ctx;
1017 MachineState *ms = MACHINE(qdev_get_machine());
1018 unsigned int max_cpus = ms->smp.max_cpus;
1019 tcg_ctxs = g_new(TCGContext *, max_cpus);
1022 tcg_debug_assert(!tcg_regset_test_reg(s->reserved_regs, TCG_AREG0));
1023 ts = tcg_global_reg_new_internal(s, TCG_TYPE_PTR, TCG_AREG0, "env");
1024 cpu_env = temp_tcgv_ptr(ts);
1028 * Allocate TBs right before their corresponding translated code, making
1029 * sure that TBs and code are on different cache lines.
1031 TranslationBlock *tcg_tb_alloc(TCGContext *s)
1033 uintptr_t align = qemu_icache_linesize;
1034 TranslationBlock *tb;
1038 tb = (void *)ROUND_UP((uintptr_t)s->code_gen_ptr, align);
1039 next = (void *)ROUND_UP((uintptr_t)(tb + 1), align);
1041 if (unlikely(next > s->code_gen_highwater)) {
1042 if (tcg_region_alloc(s)) {
1047 qatomic_set(&s->code_gen_ptr, next);
1048 s->data_gen_ptr = NULL;
1052 void tcg_prologue_init(TCGContext *s)
1054 size_t prologue_size, total_size;
1057 /* Put the prologue at the beginning of code_gen_buffer. */
1058 buf0 = s->code_gen_buffer;
1059 total_size = s->code_gen_buffer_size;
1062 s->data_gen_ptr = NULL;
1064 #ifndef CONFIG_TCG_INTERPRETER
1065 tcg_qemu_tb_exec = (tcg_prologue_fn *)buf0;
1068 /* Compute a high-water mark, at which we voluntarily flush the buffer
1069 and start over. The size here is arbitrary, significantly larger
1070 than we expect the code generation for any one opcode to require. */
1071 s->code_gen_highwater = s->code_gen_buffer + (total_size - TCG_HIGHWATER);
1073 #ifdef TCG_TARGET_NEED_POOL_LABELS
1074 s->pool_labels = NULL;
1077 /* Generate the prologue. */
1078 tcg_target_qemu_prologue(s);
1080 #ifdef TCG_TARGET_NEED_POOL_LABELS
1081 /* Allow the prologue to put e.g. guest_base into a pool entry. */
1083 int result = tcg_out_pool_finalize(s);
1084 tcg_debug_assert(result == 0);
1089 #ifndef CONFIG_TCG_INTERPRETER
1090 flush_idcache_range((uintptr_t)buf0, (uintptr_t)buf0,
1091 tcg_ptr_byte_diff(buf1, buf0));
1094 /* Deduct the prologue from the buffer. */
1095 prologue_size = tcg_current_code_size(s);
1096 s->code_gen_ptr = buf1;
1097 s->code_gen_buffer = buf1;
1099 total_size -= prologue_size;
1100 s->code_gen_buffer_size = total_size;
1102 tcg_register_jit(s->code_gen_buffer, total_size);
1105 if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
1106 FILE *logfile = qemu_log_lock();
1107 qemu_log("PROLOGUE: [size=%zu]\n", prologue_size);
1108 if (s->data_gen_ptr) {
1109 size_t code_size = s->data_gen_ptr - buf0;
1110 size_t data_size = prologue_size - code_size;
1113 log_disas(buf0, code_size);
1115 for (i = 0; i < data_size; i += sizeof(tcg_target_ulong)) {
1116 if (sizeof(tcg_target_ulong) == 8) {
1117 qemu_log("0x%08" PRIxPTR ": .quad 0x%016" PRIx64 "\n",
1118 (uintptr_t)s->data_gen_ptr + i,
1119 *(uint64_t *)(s->data_gen_ptr + i));
1121 qemu_log("0x%08" PRIxPTR ": .long 0x%08x\n",
1122 (uintptr_t)s->data_gen_ptr + i,
1123 *(uint32_t *)(s->data_gen_ptr + i));
1127 log_disas(buf0, prologue_size);
1131 qemu_log_unlock(logfile);
1135 /* Assert that goto_ptr is implemented completely. */
1136 if (TCG_TARGET_HAS_goto_ptr) {
1137 tcg_debug_assert(tcg_code_gen_epilogue != NULL);
1141 void tcg_func_start(TCGContext *s)
1144 s->nb_temps = s->nb_globals;
1146 /* No temps have been previously allocated for size or locality. */
1147 memset(s->free_temps, 0, sizeof(s->free_temps));
1151 s->current_frame_offset = s->frame_start;
1153 #ifdef CONFIG_DEBUG_TCG
1154 s->goto_tb_issue_mask = 0;
1157 QTAILQ_INIT(&s->ops);
1158 QTAILQ_INIT(&s->free_ops);
1159 QSIMPLEQ_INIT(&s->labels);
1162 static inline TCGTemp *tcg_temp_alloc(TCGContext *s)
1164 int n = s->nb_temps++;
1165 tcg_debug_assert(n < TCG_MAX_TEMPS);
1166 return memset(&s->temps[n], 0, sizeof(TCGTemp));
1169 static inline TCGTemp *tcg_global_alloc(TCGContext *s)
1173 tcg_debug_assert(s->nb_globals == s->nb_temps);
1175 ts = tcg_temp_alloc(s);
1176 ts->temp_global = 1;
1181 static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type,
1182 TCGReg reg, const char *name)
1186 if (TCG_TARGET_REG_BITS == 32 && type != TCG_TYPE_I32) {
1190 ts = tcg_global_alloc(s);
1191 ts->base_type = type;
1196 tcg_regset_set_reg(s->reserved_regs, reg);
1201 void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size)
1203 s->frame_start = start;
1204 s->frame_end = start + size;
1206 = tcg_global_reg_new_internal(s, TCG_TYPE_PTR, reg, "_frame");
1209 TCGTemp *tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
1210 intptr_t offset, const char *name)
1212 TCGContext *s = tcg_ctx;
1213 TCGTemp *base_ts = tcgv_ptr_temp(base);
1214 TCGTemp *ts = tcg_global_alloc(s);
1215 int indirect_reg = 0, bigendian = 0;
1216 #ifdef HOST_WORDS_BIGENDIAN
1220 if (!base_ts->fixed_reg) {
1221 /* We do not support double-indirect registers. */
1222 tcg_debug_assert(!base_ts->indirect_reg);
1223 base_ts->indirect_base = 1;
1224 s->nb_indirects += (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64
1229 if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) {
1230 TCGTemp *ts2 = tcg_global_alloc(s);
1233 ts->base_type = TCG_TYPE_I64;
1234 ts->type = TCG_TYPE_I32;
1235 ts->indirect_reg = indirect_reg;
1236 ts->mem_allocated = 1;
1237 ts->mem_base = base_ts;
1238 ts->mem_offset = offset + bigendian * 4;
1239 pstrcpy(buf, sizeof(buf), name);
1240 pstrcat(buf, sizeof(buf), "_0");
1241 ts->name = strdup(buf);
1243 tcg_debug_assert(ts2 == ts + 1);
1244 ts2->base_type = TCG_TYPE_I64;
1245 ts2->type = TCG_TYPE_I32;
1246 ts2->indirect_reg = indirect_reg;
1247 ts2->mem_allocated = 1;
1248 ts2->mem_base = base_ts;
1249 ts2->mem_offset = offset + (1 - bigendian) * 4;
1250 pstrcpy(buf, sizeof(buf), name);
1251 pstrcat(buf, sizeof(buf), "_1");
1252 ts2->name = strdup(buf);
1254 ts->base_type = type;
1256 ts->indirect_reg = indirect_reg;
1257 ts->mem_allocated = 1;
1258 ts->mem_base = base_ts;
1259 ts->mem_offset = offset;
1265 TCGTemp *tcg_temp_new_internal(TCGType type, bool temp_local)
1267 TCGContext *s = tcg_ctx;
1271 k = type + (temp_local ? TCG_TYPE_COUNT : 0);
1272 idx = find_first_bit(s->free_temps[k].l, TCG_MAX_TEMPS);
1273 if (idx < TCG_MAX_TEMPS) {
1274 /* There is already an available temp with the right type. */
1275 clear_bit(idx, s->free_temps[k].l);
1277 ts = &s->temps[idx];
1278 ts->temp_allocated = 1;
1279 tcg_debug_assert(ts->base_type == type);
1280 tcg_debug_assert(ts->temp_local == temp_local);
1282 ts = tcg_temp_alloc(s);
1283 if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) {
1284 TCGTemp *ts2 = tcg_temp_alloc(s);
1286 ts->base_type = type;
1287 ts->type = TCG_TYPE_I32;
1288 ts->temp_allocated = 1;
1289 ts->temp_local = temp_local;
1291 tcg_debug_assert(ts2 == ts + 1);
1292 ts2->base_type = TCG_TYPE_I64;
1293 ts2->type = TCG_TYPE_I32;
1294 ts2->temp_allocated = 1;
1295 ts2->temp_local = temp_local;
1297 ts->base_type = type;
1299 ts->temp_allocated = 1;
1300 ts->temp_local = temp_local;
1304 #if defined(CONFIG_DEBUG_TCG)
1310 TCGv_vec tcg_temp_new_vec(TCGType type)
1314 #ifdef CONFIG_DEBUG_TCG
1317 assert(TCG_TARGET_HAS_v64);
1320 assert(TCG_TARGET_HAS_v128);
1323 assert(TCG_TARGET_HAS_v256);
1326 g_assert_not_reached();
1330 t = tcg_temp_new_internal(type, 0);
1331 return temp_tcgv_vec(t);
1334 /* Create a new temp of the same type as an existing temp. */
1335 TCGv_vec tcg_temp_new_vec_matching(TCGv_vec match)
1337 TCGTemp *t = tcgv_vec_temp(match);
1339 tcg_debug_assert(t->temp_allocated != 0);
1341 t = tcg_temp_new_internal(t->base_type, 0);
1342 return temp_tcgv_vec(t);
1345 void tcg_temp_free_internal(TCGTemp *ts)
1347 TCGContext *s = tcg_ctx;
1350 #if defined(CONFIG_DEBUG_TCG)
1352 if (s->temps_in_use < 0) {
1353 fprintf(stderr, "More temporaries freed than allocated!\n");
1357 tcg_debug_assert(ts->temp_global == 0);
1358 tcg_debug_assert(ts->temp_allocated != 0);
1359 ts->temp_allocated = 0;
1362 k = ts->base_type + (ts->temp_local ? TCG_TYPE_COUNT : 0);
1363 set_bit(idx, s->free_temps[k].l);
1366 TCGv_i32 tcg_const_i32(int32_t val)
1369 t0 = tcg_temp_new_i32();
1370 tcg_gen_movi_i32(t0, val);
1374 TCGv_i64 tcg_const_i64(int64_t val)
1377 t0 = tcg_temp_new_i64();
1378 tcg_gen_movi_i64(t0, val);
1382 TCGv_i32 tcg_const_local_i32(int32_t val)
1385 t0 = tcg_temp_local_new_i32();
1386 tcg_gen_movi_i32(t0, val);
1390 TCGv_i64 tcg_const_local_i64(int64_t val)
1393 t0 = tcg_temp_local_new_i64();
1394 tcg_gen_movi_i64(t0, val);
1398 #if defined(CONFIG_DEBUG_TCG)
1399 void tcg_clear_temp_count(void)
1401 TCGContext *s = tcg_ctx;
1402 s->temps_in_use = 0;
1405 int tcg_check_temp_count(void)
1407 TCGContext *s = tcg_ctx;
1408 if (s->temps_in_use) {
1409 /* Clear the count so that we don't give another
1410 * warning immediately next time around.
1412 s->temps_in_use = 0;
1419 /* Return true if OP may appear in the opcode stream.
1420 Test the runtime variable that controls each opcode. */
1421 bool tcg_op_supported(TCGOpcode op)
1424 = TCG_TARGET_HAS_v64 | TCG_TARGET_HAS_v128 | TCG_TARGET_HAS_v256;
1427 case INDEX_op_discard:
1428 case INDEX_op_set_label:
1432 case INDEX_op_insn_start:
1433 case INDEX_op_exit_tb:
1434 case INDEX_op_goto_tb:
1435 case INDEX_op_qemu_ld_i32:
1436 case INDEX_op_qemu_st_i32:
1437 case INDEX_op_qemu_ld_i64:
1438 case INDEX_op_qemu_st_i64:
1441 case INDEX_op_qemu_st8_i32:
1442 return TCG_TARGET_HAS_qemu_st8_i32;
1444 case INDEX_op_goto_ptr:
1445 return TCG_TARGET_HAS_goto_ptr;
1447 case INDEX_op_mov_i32:
1448 case INDEX_op_movi_i32:
1449 case INDEX_op_setcond_i32:
1450 case INDEX_op_brcond_i32:
1451 case INDEX_op_ld8u_i32:
1452 case INDEX_op_ld8s_i32:
1453 case INDEX_op_ld16u_i32:
1454 case INDEX_op_ld16s_i32:
1455 case INDEX_op_ld_i32:
1456 case INDEX_op_st8_i32:
1457 case INDEX_op_st16_i32:
1458 case INDEX_op_st_i32:
1459 case INDEX_op_add_i32:
1460 case INDEX_op_sub_i32:
1461 case INDEX_op_mul_i32:
1462 case INDEX_op_and_i32:
1463 case INDEX_op_or_i32:
1464 case INDEX_op_xor_i32:
1465 case INDEX_op_shl_i32:
1466 case INDEX_op_shr_i32:
1467 case INDEX_op_sar_i32:
1470 case INDEX_op_movcond_i32:
1471 return TCG_TARGET_HAS_movcond_i32;
1472 case INDEX_op_div_i32:
1473 case INDEX_op_divu_i32:
1474 return TCG_TARGET_HAS_div_i32;
1475 case INDEX_op_rem_i32:
1476 case INDEX_op_remu_i32:
1477 return TCG_TARGET_HAS_rem_i32;
1478 case INDEX_op_div2_i32:
1479 case INDEX_op_divu2_i32:
1480 return TCG_TARGET_HAS_div2_i32;
1481 case INDEX_op_rotl_i32:
1482 case INDEX_op_rotr_i32:
1483 return TCG_TARGET_HAS_rot_i32;
1484 case INDEX_op_deposit_i32:
1485 return TCG_TARGET_HAS_deposit_i32;
1486 case INDEX_op_extract_i32:
1487 return TCG_TARGET_HAS_extract_i32;
1488 case INDEX_op_sextract_i32:
1489 return TCG_TARGET_HAS_sextract_i32;
1490 case INDEX_op_extract2_i32:
1491 return TCG_TARGET_HAS_extract2_i32;
1492 case INDEX_op_add2_i32:
1493 return TCG_TARGET_HAS_add2_i32;
1494 case INDEX_op_sub2_i32:
1495 return TCG_TARGET_HAS_sub2_i32;
1496 case INDEX_op_mulu2_i32:
1497 return TCG_TARGET_HAS_mulu2_i32;
1498 case INDEX_op_muls2_i32:
1499 return TCG_TARGET_HAS_muls2_i32;
1500 case INDEX_op_muluh_i32:
1501 return TCG_TARGET_HAS_muluh_i32;
1502 case INDEX_op_mulsh_i32:
1503 return TCG_TARGET_HAS_mulsh_i32;
1504 case INDEX_op_ext8s_i32:
1505 return TCG_TARGET_HAS_ext8s_i32;
1506 case INDEX_op_ext16s_i32:
1507 return TCG_TARGET_HAS_ext16s_i32;
1508 case INDEX_op_ext8u_i32:
1509 return TCG_TARGET_HAS_ext8u_i32;
1510 case INDEX_op_ext16u_i32:
1511 return TCG_TARGET_HAS_ext16u_i32;
1512 case INDEX_op_bswap16_i32:
1513 return TCG_TARGET_HAS_bswap16_i32;
1514 case INDEX_op_bswap32_i32:
1515 return TCG_TARGET_HAS_bswap32_i32;
1516 case INDEX_op_not_i32:
1517 return TCG_TARGET_HAS_not_i32;
1518 case INDEX_op_neg_i32:
1519 return TCG_TARGET_HAS_neg_i32;
1520 case INDEX_op_andc_i32:
1521 return TCG_TARGET_HAS_andc_i32;
1522 case INDEX_op_orc_i32:
1523 return TCG_TARGET_HAS_orc_i32;
1524 case INDEX_op_eqv_i32:
1525 return TCG_TARGET_HAS_eqv_i32;
1526 case INDEX_op_nand_i32:
1527 return TCG_TARGET_HAS_nand_i32;
1528 case INDEX_op_nor_i32:
1529 return TCG_TARGET_HAS_nor_i32;
1530 case INDEX_op_clz_i32:
1531 return TCG_TARGET_HAS_clz_i32;
1532 case INDEX_op_ctz_i32:
1533 return TCG_TARGET_HAS_ctz_i32;
1534 case INDEX_op_ctpop_i32:
1535 return TCG_TARGET_HAS_ctpop_i32;
1537 case INDEX_op_brcond2_i32:
1538 case INDEX_op_setcond2_i32:
1539 return TCG_TARGET_REG_BITS == 32;
1541 case INDEX_op_mov_i64:
1542 case INDEX_op_movi_i64:
1543 case INDEX_op_setcond_i64:
1544 case INDEX_op_brcond_i64:
1545 case INDEX_op_ld8u_i64:
1546 case INDEX_op_ld8s_i64:
1547 case INDEX_op_ld16u_i64:
1548 case INDEX_op_ld16s_i64:
1549 case INDEX_op_ld32u_i64:
1550 case INDEX_op_ld32s_i64:
1551 case INDEX_op_ld_i64:
1552 case INDEX_op_st8_i64:
1553 case INDEX_op_st16_i64:
1554 case INDEX_op_st32_i64:
1555 case INDEX_op_st_i64:
1556 case INDEX_op_add_i64:
1557 case INDEX_op_sub_i64:
1558 case INDEX_op_mul_i64:
1559 case INDEX_op_and_i64:
1560 case INDEX_op_or_i64:
1561 case INDEX_op_xor_i64:
1562 case INDEX_op_shl_i64:
1563 case INDEX_op_shr_i64:
1564 case INDEX_op_sar_i64:
1565 case INDEX_op_ext_i32_i64:
1566 case INDEX_op_extu_i32_i64:
1567 return TCG_TARGET_REG_BITS == 64;
1569 case INDEX_op_movcond_i64:
1570 return TCG_TARGET_HAS_movcond_i64;
1571 case INDEX_op_div_i64:
1572 case INDEX_op_divu_i64:
1573 return TCG_TARGET_HAS_div_i64;
1574 case INDEX_op_rem_i64:
1575 case INDEX_op_remu_i64:
1576 return TCG_TARGET_HAS_rem_i64;
1577 case INDEX_op_div2_i64:
1578 case INDEX_op_divu2_i64:
1579 return TCG_TARGET_HAS_div2_i64;
1580 case INDEX_op_rotl_i64:
1581 case INDEX_op_rotr_i64:
1582 return TCG_TARGET_HAS_rot_i64;
1583 case INDEX_op_deposit_i64:
1584 return TCG_TARGET_HAS_deposit_i64;
1585 case INDEX_op_extract_i64:
1586 return TCG_TARGET_HAS_extract_i64;
1587 case INDEX_op_sextract_i64:
1588 return TCG_TARGET_HAS_sextract_i64;
1589 case INDEX_op_extract2_i64:
1590 return TCG_TARGET_HAS_extract2_i64;
1591 case INDEX_op_extrl_i64_i32:
1592 return TCG_TARGET_HAS_extrl_i64_i32;
1593 case INDEX_op_extrh_i64_i32:
1594 return TCG_TARGET_HAS_extrh_i64_i32;
1595 case INDEX_op_ext8s_i64:
1596 return TCG_TARGET_HAS_ext8s_i64;
1597 case INDEX_op_ext16s_i64:
1598 return TCG_TARGET_HAS_ext16s_i64;
1599 case INDEX_op_ext32s_i64:
1600 return TCG_TARGET_HAS_ext32s_i64;
1601 case INDEX_op_ext8u_i64:
1602 return TCG_TARGET_HAS_ext8u_i64;
1603 case INDEX_op_ext16u_i64:
1604 return TCG_TARGET_HAS_ext16u_i64;
1605 case INDEX_op_ext32u_i64:
1606 return TCG_TARGET_HAS_ext32u_i64;
1607 case INDEX_op_bswap16_i64:
1608 return TCG_TARGET_HAS_bswap16_i64;
1609 case INDEX_op_bswap32_i64:
1610 return TCG_TARGET_HAS_bswap32_i64;
1611 case INDEX_op_bswap64_i64:
1612 return TCG_TARGET_HAS_bswap64_i64;
1613 case INDEX_op_not_i64:
1614 return TCG_TARGET_HAS_not_i64;
1615 case INDEX_op_neg_i64:
1616 return TCG_TARGET_HAS_neg_i64;
1617 case INDEX_op_andc_i64:
1618 return TCG_TARGET_HAS_andc_i64;
1619 case INDEX_op_orc_i64:
1620 return TCG_TARGET_HAS_orc_i64;
1621 case INDEX_op_eqv_i64:
1622 return TCG_TARGET_HAS_eqv_i64;
1623 case INDEX_op_nand_i64:
1624 return TCG_TARGET_HAS_nand_i64;
1625 case INDEX_op_nor_i64:
1626 return TCG_TARGET_HAS_nor_i64;
1627 case INDEX_op_clz_i64:
1628 return TCG_TARGET_HAS_clz_i64;
1629 case INDEX_op_ctz_i64:
1630 return TCG_TARGET_HAS_ctz_i64;
1631 case INDEX_op_ctpop_i64:
1632 return TCG_TARGET_HAS_ctpop_i64;
1633 case INDEX_op_add2_i64:
1634 return TCG_TARGET_HAS_add2_i64;
1635 case INDEX_op_sub2_i64:
1636 return TCG_TARGET_HAS_sub2_i64;
1637 case INDEX_op_mulu2_i64:
1638 return TCG_TARGET_HAS_mulu2_i64;
1639 case INDEX_op_muls2_i64:
1640 return TCG_TARGET_HAS_muls2_i64;
1641 case INDEX_op_muluh_i64:
1642 return TCG_TARGET_HAS_muluh_i64;
1643 case INDEX_op_mulsh_i64:
1644 return TCG_TARGET_HAS_mulsh_i64;
1646 case INDEX_op_mov_vec:
1647 case INDEX_op_dup_vec:
1648 case INDEX_op_dupi_vec:
1649 case INDEX_op_dupm_vec:
1650 case INDEX_op_ld_vec:
1651 case INDEX_op_st_vec:
1652 case INDEX_op_add_vec:
1653 case INDEX_op_sub_vec:
1654 case INDEX_op_and_vec:
1655 case INDEX_op_or_vec:
1656 case INDEX_op_xor_vec:
1657 case INDEX_op_cmp_vec:
1659 case INDEX_op_dup2_vec:
1660 return have_vec && TCG_TARGET_REG_BITS == 32;
1661 case INDEX_op_not_vec:
1662 return have_vec && TCG_TARGET_HAS_not_vec;
1663 case INDEX_op_neg_vec:
1664 return have_vec && TCG_TARGET_HAS_neg_vec;
1665 case INDEX_op_abs_vec:
1666 return have_vec && TCG_TARGET_HAS_abs_vec;
1667 case INDEX_op_andc_vec:
1668 return have_vec && TCG_TARGET_HAS_andc_vec;
1669 case INDEX_op_orc_vec:
1670 return have_vec && TCG_TARGET_HAS_orc_vec;
1671 case INDEX_op_mul_vec:
1672 return have_vec && TCG_TARGET_HAS_mul_vec;
1673 case INDEX_op_shli_vec:
1674 case INDEX_op_shri_vec:
1675 case INDEX_op_sari_vec:
1676 return have_vec && TCG_TARGET_HAS_shi_vec;
1677 case INDEX_op_shls_vec:
1678 case INDEX_op_shrs_vec:
1679 case INDEX_op_sars_vec:
1680 return have_vec && TCG_TARGET_HAS_shs_vec;
1681 case INDEX_op_shlv_vec:
1682 case INDEX_op_shrv_vec:
1683 case INDEX_op_sarv_vec:
1684 return have_vec && TCG_TARGET_HAS_shv_vec;
1685 case INDEX_op_rotli_vec:
1686 return have_vec && TCG_TARGET_HAS_roti_vec;
1687 case INDEX_op_rotls_vec:
1688 return have_vec && TCG_TARGET_HAS_rots_vec;
1689 case INDEX_op_rotlv_vec:
1690 case INDEX_op_rotrv_vec:
1691 return have_vec && TCG_TARGET_HAS_rotv_vec;
1692 case INDEX_op_ssadd_vec:
1693 case INDEX_op_usadd_vec:
1694 case INDEX_op_sssub_vec:
1695 case INDEX_op_ussub_vec:
1696 return have_vec && TCG_TARGET_HAS_sat_vec;
1697 case INDEX_op_smin_vec:
1698 case INDEX_op_umin_vec:
1699 case INDEX_op_smax_vec:
1700 case INDEX_op_umax_vec:
1701 return have_vec && TCG_TARGET_HAS_minmax_vec;
1702 case INDEX_op_bitsel_vec:
1703 return have_vec && TCG_TARGET_HAS_bitsel_vec;
1704 case INDEX_op_cmpsel_vec:
1705 return have_vec && TCG_TARGET_HAS_cmpsel_vec;
1708 tcg_debug_assert(op > INDEX_op_last_generic && op < NB_OPS);
1713 /* Note: we convert the 64 bit args to 32 bit and do some alignment
1714 and endian swap. Maybe it would be better to do the alignment
1715 and endian swap in tcg_reg_alloc_call(). */
1716 void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
1718 int i, real_args, nb_rets, pi;
1719 unsigned sizemask, flags;
1720 TCGHelperInfo *info;
1723 info = g_hash_table_lookup(helper_table, (gpointer)func);
1724 flags = info->flags;
1725 sizemask = info->sizemask;
1727 #ifdef CONFIG_PLUGIN
1728 /* detect non-plugin helpers */
1729 if (tcg_ctx->plugin_insn && unlikely(strncmp(info->name, "plugin_", 7))) {
1730 tcg_ctx->plugin_insn->calls_helpers = true;
1734 #if defined(__sparc__) && !defined(__arch64__) \
1735 && !defined(CONFIG_TCG_INTERPRETER)
1736 /* We have 64-bit values in one register, but need to pass as two
1737 separate parameters. Split them. */
1738 int orig_sizemask = sizemask;
1739 int orig_nargs = nargs;
1740 TCGv_i64 retl, reth;
1741 TCGTemp *split_args[MAX_OPC_PARAM];
1745 if (sizemask != 0) {
1746 for (i = real_args = 0; i < nargs; ++i) {
1747 int is_64bit = sizemask & (1 << (i+1)*2);
1749 TCGv_i64 orig = temp_tcgv_i64(args[i]);
1750 TCGv_i32 h = tcg_temp_new_i32();
1751 TCGv_i32 l = tcg_temp_new_i32();
1752 tcg_gen_extr_i64_i32(l, h, orig);
1753 split_args[real_args++] = tcgv_i32_temp(h);
1754 split_args[real_args++] = tcgv_i32_temp(l);
1756 split_args[real_args++] = args[i];
1763 #elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
1764 for (i = 0; i < nargs; ++i) {
1765 int is_64bit = sizemask & (1 << (i+1)*2);
1766 int is_signed = sizemask & (2 << (i+1)*2);
1768 TCGv_i64 temp = tcg_temp_new_i64();
1769 TCGv_i64 orig = temp_tcgv_i64(args[i]);
1771 tcg_gen_ext32s_i64(temp, orig);
1773 tcg_gen_ext32u_i64(temp, orig);
1775 args[i] = tcgv_i64_temp(temp);
1778 #endif /* TCG_TARGET_EXTEND_ARGS */
1780 op = tcg_emit_op(INDEX_op_call);
1784 #if defined(__sparc__) && !defined(__arch64__) \
1785 && !defined(CONFIG_TCG_INTERPRETER)
1786 if (orig_sizemask & 1) {
1787 /* The 32-bit ABI is going to return the 64-bit value in
1788 the %o0/%o1 register pair. Prepare for this by using
1789 two return temporaries, and reassemble below. */
1790 retl = tcg_temp_new_i64();
1791 reth = tcg_temp_new_i64();
1792 op->args[pi++] = tcgv_i64_arg(reth);
1793 op->args[pi++] = tcgv_i64_arg(retl);
1796 op->args[pi++] = temp_arg(ret);
1800 if (TCG_TARGET_REG_BITS < 64 && (sizemask & 1)) {
1801 #ifdef HOST_WORDS_BIGENDIAN
1802 op->args[pi++] = temp_arg(ret + 1);
1803 op->args[pi++] = temp_arg(ret);
1805 op->args[pi++] = temp_arg(ret);
1806 op->args[pi++] = temp_arg(ret + 1);
1810 op->args[pi++] = temp_arg(ret);
1817 TCGOP_CALLO(op) = nb_rets;
1820 for (i = 0; i < nargs; i++) {
1821 int is_64bit = sizemask & (1 << (i+1)*2);
1822 if (TCG_TARGET_REG_BITS < 64 && is_64bit) {
1823 #ifdef TCG_TARGET_CALL_ALIGN_ARGS
1824 /* some targets want aligned 64 bit args */
1825 if (real_args & 1) {
1826 op->args[pi++] = TCG_CALL_DUMMY_ARG;
1830 /* If stack grows up, then we will be placing successive
1831 arguments at lower addresses, which means we need to
1832 reverse the order compared to how we would normally
1833 treat either big or little-endian. For those arguments
1834 that will wind up in registers, this still works for
1835 HPPA (the only current STACK_GROWSUP target) since the
1836 argument registers are *also* allocated in decreasing
1837 order. If another such target is added, this logic may
1838 have to get more complicated to differentiate between
1839 stack arguments and register arguments. */
1840 #if defined(HOST_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
1841 op->args[pi++] = temp_arg(args[i] + 1);
1842 op->args[pi++] = temp_arg(args[i]);
1844 op->args[pi++] = temp_arg(args[i]);
1845 op->args[pi++] = temp_arg(args[i] + 1);
1851 op->args[pi++] = temp_arg(args[i]);
1854 op->args[pi++] = (uintptr_t)func;
1855 op->args[pi++] = flags;
1856 TCGOP_CALLI(op) = real_args;
1858 /* Make sure the fields didn't overflow. */
1859 tcg_debug_assert(TCGOP_CALLI(op) == real_args);
1860 tcg_debug_assert(pi <= ARRAY_SIZE(op->args));
1862 #if defined(__sparc__) && !defined(__arch64__) \
1863 && !defined(CONFIG_TCG_INTERPRETER)
1864 /* Free all of the parts we allocated above. */
1865 for (i = real_args = 0; i < orig_nargs; ++i) {
1866 int is_64bit = orig_sizemask & (1 << (i+1)*2);
1868 tcg_temp_free_internal(args[real_args++]);
1869 tcg_temp_free_internal(args[real_args++]);
1874 if (orig_sizemask & 1) {
1875 /* The 32-bit ABI returned two 32-bit pieces. Re-assemble them.
1876 Note that describing these as TCGv_i64 eliminates an unnecessary
1877 zero-extension that tcg_gen_concat_i32_i64 would create. */
1878 tcg_gen_concat32_i64(temp_tcgv_i64(ret), retl, reth);
1879 tcg_temp_free_i64(retl);
1880 tcg_temp_free_i64(reth);
1882 #elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
1883 for (i = 0; i < nargs; ++i) {
1884 int is_64bit = sizemask & (1 << (i+1)*2);
1886 tcg_temp_free_internal(args[i]);
1889 #endif /* TCG_TARGET_EXTEND_ARGS */
1892 static void tcg_reg_alloc_start(TCGContext *s)
1897 for (i = 0, n = s->nb_globals; i < n; i++) {
1899 ts->val_type = (ts->fixed_reg ? TEMP_VAL_REG : TEMP_VAL_MEM);
1901 for (n = s->nb_temps; i < n; i++) {
1903 ts->val_type = (ts->temp_local ? TEMP_VAL_MEM : TEMP_VAL_DEAD);
1904 ts->mem_allocated = 0;
1908 memset(s->reg_to_temp, 0, sizeof(s->reg_to_temp));
1911 static char *tcg_get_arg_str_ptr(TCGContext *s, char *buf, int buf_size,
1914 int idx = temp_idx(ts);
1916 if (ts->temp_global) {
1917 pstrcpy(buf, buf_size, ts->name);
1918 } else if (ts->temp_local) {
1919 snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
1921 snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
1926 static char *tcg_get_arg_str(TCGContext *s, char *buf,
1927 int buf_size, TCGArg arg)
1929 return tcg_get_arg_str_ptr(s, buf, buf_size, arg_temp(arg));
1932 /* Find helper name. */
1933 static inline const char *tcg_find_helper(TCGContext *s, uintptr_t val)
1935 const char *ret = NULL;
1937 TCGHelperInfo *info = g_hash_table_lookup(helper_table, (gpointer)val);
1945 static const char * const cond_name[] =
1947 [TCG_COND_NEVER] = "never",
1948 [TCG_COND_ALWAYS] = "always",
1949 [TCG_COND_EQ] = "eq",
1950 [TCG_COND_NE] = "ne",
1951 [TCG_COND_LT] = "lt",
1952 [TCG_COND_GE] = "ge",
1953 [TCG_COND_LE] = "le",
1954 [TCG_COND_GT] = "gt",
1955 [TCG_COND_LTU] = "ltu",
1956 [TCG_COND_GEU] = "geu",
1957 [TCG_COND_LEU] = "leu",
1958 [TCG_COND_GTU] = "gtu"
1961 static const char * const ldst_name[] =
1977 static const char * const alignment_name[(MO_AMASK >> MO_ASHIFT) + 1] = {
1978 #ifdef TARGET_ALIGNED_ONLY
1979 [MO_UNALN >> MO_ASHIFT] = "un+",
1980 [MO_ALIGN >> MO_ASHIFT] = "",
1982 [MO_UNALN >> MO_ASHIFT] = "",
1983 [MO_ALIGN >> MO_ASHIFT] = "al+",
1985 [MO_ALIGN_2 >> MO_ASHIFT] = "al2+",
1986 [MO_ALIGN_4 >> MO_ASHIFT] = "al4+",
1987 [MO_ALIGN_8 >> MO_ASHIFT] = "al8+",
1988 [MO_ALIGN_16 >> MO_ASHIFT] = "al16+",
1989 [MO_ALIGN_32 >> MO_ASHIFT] = "al32+",
1990 [MO_ALIGN_64 >> MO_ASHIFT] = "al64+",
1993 static inline bool tcg_regset_single(TCGRegSet d)
1995 return (d & (d - 1)) == 0;
1998 static inline TCGReg tcg_regset_first(TCGRegSet d)
2000 if (TCG_TARGET_NB_REGS <= 32) {
2007 static void tcg_dump_ops(TCGContext *s, bool have_prefs)
2012 QTAILQ_FOREACH(op, &s->ops, link) {
2013 int i, k, nb_oargs, nb_iargs, nb_cargs;
2014 const TCGOpDef *def;
2019 def = &tcg_op_defs[c];
2021 if (c == INDEX_op_insn_start) {
2023 col += qemu_log("\n ----");
2025 for (i = 0; i < TARGET_INSN_START_WORDS; ++i) {
2027 #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
2028 a = deposit64(op->args[i * 2], 32, 32, op->args[i * 2 + 1]);
2032 col += qemu_log(" " TARGET_FMT_lx, a);
2034 } else if (c == INDEX_op_call) {
2035 /* variable number of arguments */
2036 nb_oargs = TCGOP_CALLO(op);
2037 nb_iargs = TCGOP_CALLI(op);
2038 nb_cargs = def->nb_cargs;
2040 /* function name, flags, out args */
2041 col += qemu_log(" %s %s,$0x%" TCG_PRIlx ",$%d", def->name,
2042 tcg_find_helper(s, op->args[nb_oargs + nb_iargs]),
2043 op->args[nb_oargs + nb_iargs + 1], nb_oargs);
2044 for (i = 0; i < nb_oargs; i++) {
2045 col += qemu_log(",%s", tcg_get_arg_str(s, buf, sizeof(buf),
2048 for (i = 0; i < nb_iargs; i++) {
2049 TCGArg arg = op->args[nb_oargs + i];
2050 const char *t = "<dummy>";
2051 if (arg != TCG_CALL_DUMMY_ARG) {
2052 t = tcg_get_arg_str(s, buf, sizeof(buf), arg);
2054 col += qemu_log(",%s", t);
2057 col += qemu_log(" %s ", def->name);
2059 nb_oargs = def->nb_oargs;
2060 nb_iargs = def->nb_iargs;
2061 nb_cargs = def->nb_cargs;
2063 if (def->flags & TCG_OPF_VECTOR) {
2064 col += qemu_log("v%d,e%d,", 64 << TCGOP_VECL(op),
2065 8 << TCGOP_VECE(op));
2069 for (i = 0; i < nb_oargs; i++) {
2071 col += qemu_log(",");
2073 col += qemu_log("%s", tcg_get_arg_str(s, buf, sizeof(buf),
2076 for (i = 0; i < nb_iargs; i++) {
2078 col += qemu_log(",");
2080 col += qemu_log("%s", tcg_get_arg_str(s, buf, sizeof(buf),
2084 case INDEX_op_brcond_i32:
2085 case INDEX_op_setcond_i32:
2086 case INDEX_op_movcond_i32:
2087 case INDEX_op_brcond2_i32:
2088 case INDEX_op_setcond2_i32:
2089 case INDEX_op_brcond_i64:
2090 case INDEX_op_setcond_i64:
2091 case INDEX_op_movcond_i64:
2092 case INDEX_op_cmp_vec:
2093 case INDEX_op_cmpsel_vec:
2094 if (op->args[k] < ARRAY_SIZE(cond_name)
2095 && cond_name[op->args[k]]) {
2096 col += qemu_log(",%s", cond_name[op->args[k++]]);
2098 col += qemu_log(",$0x%" TCG_PRIlx, op->args[k++]);
2102 case INDEX_op_qemu_ld_i32:
2103 case INDEX_op_qemu_st_i32:
2104 case INDEX_op_qemu_st8_i32:
2105 case INDEX_op_qemu_ld_i64:
2106 case INDEX_op_qemu_st_i64:
2108 TCGMemOpIdx oi = op->args[k++];
2109 MemOp op = get_memop(oi);
2110 unsigned ix = get_mmuidx(oi);
2112 if (op & ~(MO_AMASK | MO_BSWAP | MO_SSIZE)) {
2113 col += qemu_log(",$0x%x,%u", op, ix);
2115 const char *s_al, *s_op;
2116 s_al = alignment_name[(op & MO_AMASK) >> MO_ASHIFT];
2117 s_op = ldst_name[op & (MO_BSWAP | MO_SSIZE)];
2118 col += qemu_log(",%s%s,%u", s_al, s_op, ix);
2128 case INDEX_op_set_label:
2130 case INDEX_op_brcond_i32:
2131 case INDEX_op_brcond_i64:
2132 case INDEX_op_brcond2_i32:
2133 col += qemu_log("%s$L%d", k ? "," : "",
2134 arg_label(op->args[k])->id);
2140 for (; i < nb_cargs; i++, k++) {
2141 col += qemu_log("%s$0x%" TCG_PRIlx, k ? "," : "", op->args[k]);
2145 if (have_prefs || op->life) {
2147 QemuLogFile *logfile;
2150 logfile = qatomic_rcu_read(&qemu_logfile);
2152 for (; col < 40; ++col) {
2153 putc(' ', logfile->fd);
2160 unsigned life = op->life;
2162 if (life & (SYNC_ARG * 3)) {
2164 for (i = 0; i < 2; ++i) {
2165 if (life & (SYNC_ARG << i)) {
2173 for (i = 0; life; ++i, life >>= 1) {
2182 for (i = 0; i < nb_oargs; ++i) {
2183 TCGRegSet set = op->output_pref[i];
2192 } else if (set == MAKE_64BIT_MASK(0, TCG_TARGET_NB_REGS)) {
2194 #ifdef CONFIG_DEBUG_TCG
2195 } else if (tcg_regset_single(set)) {
2196 TCGReg reg = tcg_regset_first(set);
2197 qemu_log("%s", tcg_target_reg_names[reg]);
2199 } else if (TCG_TARGET_NB_REGS <= 32) {
2200 qemu_log("%#x", (uint32_t)set);
2202 qemu_log("%#" PRIx64, (uint64_t)set);
2211 /* we give more priority to constraints with less registers */
2212 static int get_constraint_priority(const TCGOpDef *def, int k)
2214 const TCGArgConstraint *arg_ct = &def->args_ct[k];
2217 if (arg_ct->oalias) {
2218 /* an alias is equivalent to a single register */
2221 n = ctpop64(arg_ct->regs);
2223 return TCG_TARGET_NB_REGS - n + 1;
2226 /* sort from highest priority to lowest */
2227 static void sort_constraints(TCGOpDef *def, int start, int n)
2230 TCGArgConstraint *a = def->args_ct;
2232 for (i = 0; i < n; i++) {
2233 a[start + i].sort_index = start + i;
2238 for (i = 0; i < n - 1; i++) {
2239 for (j = i + 1; j < n; j++) {
2240 int p1 = get_constraint_priority(def, a[start + i].sort_index);
2241 int p2 = get_constraint_priority(def, a[start + j].sort_index);
2243 int tmp = a[start + i].sort_index;
2244 a[start + i].sort_index = a[start + j].sort_index;
2245 a[start + j].sort_index = tmp;
2251 static void process_op_defs(TCGContext *s)
2255 for (op = 0; op < NB_OPS; op++) {
2256 TCGOpDef *def = &tcg_op_defs[op];
2257 const TCGTargetOpDef *tdefs;
2261 if (def->flags & TCG_OPF_NOT_PRESENT) {
2265 nb_args = def->nb_iargs + def->nb_oargs;
2270 tdefs = tcg_target_op_def(op);
2271 /* Missing TCGTargetOpDef entry. */
2272 tcg_debug_assert(tdefs != NULL);
2274 type = (def->flags & TCG_OPF_64BIT ? TCG_TYPE_I64 : TCG_TYPE_I32);
2275 for (i = 0; i < nb_args; i++) {
2276 const char *ct_str = tdefs->args_ct_str[i];
2277 /* Incomplete TCGTargetOpDef entry. */
2278 tcg_debug_assert(ct_str != NULL);
2280 while (*ct_str != '\0') {
2284 int oarg = *ct_str - '0';
2285 tcg_debug_assert(ct_str == tdefs->args_ct_str[i]);
2286 tcg_debug_assert(oarg < def->nb_oargs);
2287 tcg_debug_assert(def->args_ct[oarg].regs != 0);
2288 def->args_ct[i] = def->args_ct[oarg];
2289 /* The output sets oalias. */
2290 def->args_ct[oarg].oalias = true;
2291 def->args_ct[oarg].alias_index = i;
2292 /* The input sets ialias. */
2293 def->args_ct[i].ialias = true;
2294 def->args_ct[i].alias_index = oarg;
2299 def->args_ct[i].newreg = true;
2303 def->args_ct[i].ct |= TCG_CT_CONST;
2307 ct_str = target_parse_constraint(&def->args_ct[i],
2309 /* Typo in TCGTargetOpDef constraint. */
2310 tcg_debug_assert(ct_str != NULL);
2315 /* TCGTargetOpDef entry with too much information? */
2316 tcg_debug_assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL);
2318 /* sort the constraints (XXX: this is just an heuristic) */
2319 sort_constraints(def, 0, def->nb_oargs);
2320 sort_constraints(def, def->nb_oargs, def->nb_iargs);
2324 void tcg_op_remove(TCGContext *s, TCGOp *op)
2330 label = arg_label(op->args[0]);
2333 case INDEX_op_brcond_i32:
2334 case INDEX_op_brcond_i64:
2335 label = arg_label(op->args[3]);
2338 case INDEX_op_brcond2_i32:
2339 label = arg_label(op->args[5]);
2346 QTAILQ_REMOVE(&s->ops, op, link);
2347 QTAILQ_INSERT_TAIL(&s->free_ops, op, link);
2350 #ifdef CONFIG_PROFILER
2351 qatomic_set(&s->prof.del_op_count, s->prof.del_op_count + 1);
2355 static TCGOp *tcg_op_alloc(TCGOpcode opc)
2357 TCGContext *s = tcg_ctx;
2360 if (likely(QTAILQ_EMPTY(&s->free_ops))) {
2361 op = tcg_malloc(sizeof(TCGOp));
2363 op = QTAILQ_FIRST(&s->free_ops);
2364 QTAILQ_REMOVE(&s->free_ops, op, link);
2366 memset(op, 0, offsetof(TCGOp, link));
2373 TCGOp *tcg_emit_op(TCGOpcode opc)
2375 TCGOp *op = tcg_op_alloc(opc);
2376 QTAILQ_INSERT_TAIL(&tcg_ctx->ops, op, link);
2380 TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *old_op, TCGOpcode opc)
2382 TCGOp *new_op = tcg_op_alloc(opc);
2383 QTAILQ_INSERT_BEFORE(old_op, new_op, link);
2387 TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *old_op, TCGOpcode opc)
2389 TCGOp *new_op = tcg_op_alloc(opc);
2390 QTAILQ_INSERT_AFTER(&s->ops, old_op, new_op, link);
2394 /* Reachable analysis : remove unreachable code. */
2395 static void reachable_code_pass(TCGContext *s)
2397 TCGOp *op, *op_next;
2400 QTAILQ_FOREACH_SAFE(op, &s->ops, link, op_next) {
2406 case INDEX_op_set_label:
2407 label = arg_label(op->args[0]);
2408 if (label->refs == 0) {
2410 * While there is an occasional backward branch, virtually
2411 * all branches generated by the translators are forward.
2412 * Which means that generally we will have already removed
2413 * all references to the label that will be, and there is
2414 * little to be gained by iterating.
2418 /* Once we see a label, insns become live again. */
2423 * Optimization can fold conditional branches to unconditional.
2424 * If we find a label with one reference which is preceded by
2425 * an unconditional branch to it, remove both. This needed to
2426 * wait until the dead code in between them was removed.
2428 if (label->refs == 1) {
2429 TCGOp *op_prev = QTAILQ_PREV(op, link);
2430 if (op_prev->opc == INDEX_op_br &&
2431 label == arg_label(op_prev->args[0])) {
2432 tcg_op_remove(s, op_prev);
2440 case INDEX_op_exit_tb:
2441 case INDEX_op_goto_ptr:
2442 /* Unconditional branches; everything following is dead. */
2447 /* Notice noreturn helper calls, raising exceptions. */
2448 call_flags = op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op) + 1];
2449 if (call_flags & TCG_CALL_NO_RETURN) {
2454 case INDEX_op_insn_start:
2455 /* Never remove -- we need to keep these for unwind. */
2464 tcg_op_remove(s, op);
2472 #define IS_DEAD_ARG(n) (arg_life & (DEAD_ARG << (n)))
2473 #define NEED_SYNC_ARG(n) (arg_life & (SYNC_ARG << (n)))
2475 /* For liveness_pass_1, the register preferences for a given temp. */
2476 static inline TCGRegSet *la_temp_pref(TCGTemp *ts)
2478 return ts->state_ptr;
2481 /* For liveness_pass_1, reset the preferences for a given temp to the
2482 * maximal regset for its type.
2484 static inline void la_reset_pref(TCGTemp *ts)
2487 = (ts->state == TS_DEAD ? 0 : tcg_target_available_regs[ts->type]);
2490 /* liveness analysis: end of function: all temps are dead, and globals
2491 should be in memory. */
2492 static void la_func_end(TCGContext *s, int ng, int nt)
2496 for (i = 0; i < ng; ++i) {
2497 s->temps[i].state = TS_DEAD | TS_MEM;
2498 la_reset_pref(&s->temps[i]);
2500 for (i = ng; i < nt; ++i) {
2501 s->temps[i].state = TS_DEAD;
2502 la_reset_pref(&s->temps[i]);
2506 /* liveness analysis: end of basic block: all temps are dead, globals
2507 and local temps should be in memory. */
2508 static void la_bb_end(TCGContext *s, int ng, int nt)
2512 for (i = 0; i < ng; ++i) {
2513 s->temps[i].state = TS_DEAD | TS_MEM;
2514 la_reset_pref(&s->temps[i]);
2516 for (i = ng; i < nt; ++i) {
2517 s->temps[i].state = (s->temps[i].temp_local
2520 la_reset_pref(&s->temps[i]);
2524 /* liveness analysis: sync globals back to memory. */
2525 static void la_global_sync(TCGContext *s, int ng)
2529 for (i = 0; i < ng; ++i) {
2530 int state = s->temps[i].state;
2531 s->temps[i].state = state | TS_MEM;
2532 if (state == TS_DEAD) {
2533 /* If the global was previously dead, reset prefs. */
2534 la_reset_pref(&s->temps[i]);
2540 * liveness analysis: conditional branch: all temps are dead,
2541 * globals and local temps should be synced.
2543 static void la_bb_sync(TCGContext *s, int ng, int nt)
2545 la_global_sync(s, ng);
2547 for (int i = ng; i < nt; ++i) {
2548 if (s->temps[i].temp_local) {
2549 int state = s->temps[i].state;
2550 s->temps[i].state = state | TS_MEM;
2551 if (state != TS_DEAD) {
2555 s->temps[i].state = TS_DEAD;
2557 la_reset_pref(&s->temps[i]);
2561 /* liveness analysis: sync globals back to memory and kill. */
2562 static void la_global_kill(TCGContext *s, int ng)
2566 for (i = 0; i < ng; i++) {
2567 s->temps[i].state = TS_DEAD | TS_MEM;
2568 la_reset_pref(&s->temps[i]);
2572 /* liveness analysis: note live globals crossing calls. */
2573 static void la_cross_call(TCGContext *s, int nt)
2575 TCGRegSet mask = ~tcg_target_call_clobber_regs;
2578 for (i = 0; i < nt; i++) {
2579 TCGTemp *ts = &s->temps[i];
2580 if (!(ts->state & TS_DEAD)) {
2581 TCGRegSet *pset = la_temp_pref(ts);
2582 TCGRegSet set = *pset;
2585 /* If the combination is not possible, restart. */
2587 set = tcg_target_available_regs[ts->type] & mask;
2594 /* Liveness analysis : update the opc_arg_life array to tell if a
2595 given input arguments is dead. Instructions updating dead
2596 temporaries are removed. */
2597 static void liveness_pass_1(TCGContext *s)
2599 int nb_globals = s->nb_globals;
2600 int nb_temps = s->nb_temps;
2601 TCGOp *op, *op_prev;
2605 prefs = tcg_malloc(sizeof(TCGRegSet) * nb_temps);
2606 for (i = 0; i < nb_temps; ++i) {
2607 s->temps[i].state_ptr = prefs + i;
2610 /* ??? Should be redundant with the exit_tb that ends the TB. */
2611 la_func_end(s, nb_globals, nb_temps);
2613 QTAILQ_FOREACH_REVERSE_SAFE(op, &s->ops, link, op_prev) {
2614 int nb_iargs, nb_oargs;
2615 TCGOpcode opc_new, opc_new2;
2617 TCGLifeData arg_life = 0;
2619 TCGOpcode opc = op->opc;
2620 const TCGOpDef *def = &tcg_op_defs[opc];
2628 nb_oargs = TCGOP_CALLO(op);
2629 nb_iargs = TCGOP_CALLI(op);
2630 call_flags = op->args[nb_oargs + nb_iargs + 1];
2632 /* pure functions can be removed if their result is unused */
2633 if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
2634 for (i = 0; i < nb_oargs; i++) {
2635 ts = arg_temp(op->args[i]);
2636 if (ts->state != TS_DEAD) {
2637 goto do_not_remove_call;
2644 /* Output args are dead. */
2645 for (i = 0; i < nb_oargs; i++) {
2646 ts = arg_temp(op->args[i]);
2647 if (ts->state & TS_DEAD) {
2648 arg_life |= DEAD_ARG << i;
2650 if (ts->state & TS_MEM) {
2651 arg_life |= SYNC_ARG << i;
2653 ts->state = TS_DEAD;
2656 /* Not used -- it will be tcg_target_call_oarg_regs[i]. */
2657 op->output_pref[i] = 0;
2660 if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
2661 TCG_CALL_NO_READ_GLOBALS))) {
2662 la_global_kill(s, nb_globals);
2663 } else if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
2664 la_global_sync(s, nb_globals);
2667 /* Record arguments that die in this helper. */
2668 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
2669 ts = arg_temp(op->args[i]);
2670 if (ts && ts->state & TS_DEAD) {
2671 arg_life |= DEAD_ARG << i;
2675 /* For all live registers, remove call-clobbered prefs. */
2676 la_cross_call(s, nb_temps);
2678 nb_call_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
2680 /* Input arguments are live for preceding opcodes. */
2681 for (i = 0; i < nb_iargs; i++) {
2682 ts = arg_temp(op->args[i + nb_oargs]);
2683 if (ts && ts->state & TS_DEAD) {
2684 /* For those arguments that die, and will be allocated
2685 * in registers, clear the register set for that arg,
2686 * to be filled in below. For args that will be on
2687 * the stack, reset to any available reg.
2690 = (i < nb_call_regs ? 0 :
2691 tcg_target_available_regs[ts->type]);
2692 ts->state &= ~TS_DEAD;
2696 /* For each input argument, add its input register to prefs.
2697 If a temp is used once, this produces a single set bit. */
2698 for (i = 0; i < MIN(nb_call_regs, nb_iargs); i++) {
2699 ts = arg_temp(op->args[i + nb_oargs]);
2701 tcg_regset_set_reg(*la_temp_pref(ts),
2702 tcg_target_call_iarg_regs[i]);
2707 case INDEX_op_insn_start:
2709 case INDEX_op_discard:
2710 /* mark the temporary as dead */
2711 ts = arg_temp(op->args[0]);
2712 ts->state = TS_DEAD;
2716 case INDEX_op_add2_i32:
2717 opc_new = INDEX_op_add_i32;
2719 case INDEX_op_sub2_i32:
2720 opc_new = INDEX_op_sub_i32;
2722 case INDEX_op_add2_i64:
2723 opc_new = INDEX_op_add_i64;
2725 case INDEX_op_sub2_i64:
2726 opc_new = INDEX_op_sub_i64;
2730 /* Test if the high part of the operation is dead, but not
2731 the low part. The result can be optimized to a simple
2732 add or sub. This happens often for x86_64 guest when the
2733 cpu mode is set to 32 bit. */
2734 if (arg_temp(op->args[1])->state == TS_DEAD) {
2735 if (arg_temp(op->args[0])->state == TS_DEAD) {
2738 /* Replace the opcode and adjust the args in place,
2739 leaving 3 unused args at the end. */
2740 op->opc = opc = opc_new;
2741 op->args[1] = op->args[2];
2742 op->args[2] = op->args[4];
2743 /* Fall through and mark the single-word operation live. */
2749 case INDEX_op_mulu2_i32:
2750 opc_new = INDEX_op_mul_i32;
2751 opc_new2 = INDEX_op_muluh_i32;
2752 have_opc_new2 = TCG_TARGET_HAS_muluh_i32;
2754 case INDEX_op_muls2_i32:
2755 opc_new = INDEX_op_mul_i32;
2756 opc_new2 = INDEX_op_mulsh_i32;
2757 have_opc_new2 = TCG_TARGET_HAS_mulsh_i32;
2759 case INDEX_op_mulu2_i64:
2760 opc_new = INDEX_op_mul_i64;
2761 opc_new2 = INDEX_op_muluh_i64;
2762 have_opc_new2 = TCG_TARGET_HAS_muluh_i64;
2764 case INDEX_op_muls2_i64:
2765 opc_new = INDEX_op_mul_i64;
2766 opc_new2 = INDEX_op_mulsh_i64;
2767 have_opc_new2 = TCG_TARGET_HAS_mulsh_i64;
2772 if (arg_temp(op->args[1])->state == TS_DEAD) {
2773 if (arg_temp(op->args[0])->state == TS_DEAD) {
2774 /* Both parts of the operation are dead. */
2777 /* The high part of the operation is dead; generate the low. */
2778 op->opc = opc = opc_new;
2779 op->args[1] = op->args[2];
2780 op->args[2] = op->args[3];
2781 } else if (arg_temp(op->args[0])->state == TS_DEAD && have_opc_new2) {
2782 /* The low part of the operation is dead; generate the high. */
2783 op->opc = opc = opc_new2;
2784 op->args[0] = op->args[1];
2785 op->args[1] = op->args[2];
2786 op->args[2] = op->args[3];
2790 /* Mark the single-word operation live. */
2795 /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
2796 nb_iargs = def->nb_iargs;
2797 nb_oargs = def->nb_oargs;
2799 /* Test if the operation can be removed because all
2800 its outputs are dead. We assume that nb_oargs == 0
2801 implies side effects */
2802 if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
2803 for (i = 0; i < nb_oargs; i++) {
2804 if (arg_temp(op->args[i])->state != TS_DEAD) {
2813 tcg_op_remove(s, op);
2817 for (i = 0; i < nb_oargs; i++) {
2818 ts = arg_temp(op->args[i]);
2820 /* Remember the preference of the uses that followed. */
2821 op->output_pref[i] = *la_temp_pref(ts);
2823 /* Output args are dead. */
2824 if (ts->state & TS_DEAD) {
2825 arg_life |= DEAD_ARG << i;
2827 if (ts->state & TS_MEM) {
2828 arg_life |= SYNC_ARG << i;
2830 ts->state = TS_DEAD;
2834 /* If end of basic block, update. */
2835 if (def->flags & TCG_OPF_BB_EXIT) {
2836 la_func_end(s, nb_globals, nb_temps);
2837 } else if (def->flags & TCG_OPF_COND_BRANCH) {
2838 la_bb_sync(s, nb_globals, nb_temps);
2839 } else if (def->flags & TCG_OPF_BB_END) {
2840 la_bb_end(s, nb_globals, nb_temps);
2841 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
2842 la_global_sync(s, nb_globals);
2843 if (def->flags & TCG_OPF_CALL_CLOBBER) {
2844 la_cross_call(s, nb_temps);
2848 /* Record arguments that die in this opcode. */
2849 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
2850 ts = arg_temp(op->args[i]);
2851 if (ts->state & TS_DEAD) {
2852 arg_life |= DEAD_ARG << i;
2856 /* Input arguments are live for preceding opcodes. */
2857 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
2858 ts = arg_temp(op->args[i]);
2859 if (ts->state & TS_DEAD) {
2860 /* For operands that were dead, initially allow
2861 all regs for the type. */
2862 *la_temp_pref(ts) = tcg_target_available_regs[ts->type];
2863 ts->state &= ~TS_DEAD;
2867 /* Incorporate constraints for this operand. */
2869 case INDEX_op_mov_i32:
2870 case INDEX_op_mov_i64:
2871 /* Note that these are TCG_OPF_NOT_PRESENT and do not
2872 have proper constraints. That said, special case
2873 moves to propagate preferences backward. */
2874 if (IS_DEAD_ARG(1)) {
2875 *la_temp_pref(arg_temp(op->args[0]))
2876 = *la_temp_pref(arg_temp(op->args[1]));
2881 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
2882 const TCGArgConstraint *ct = &def->args_ct[i];
2883 TCGRegSet set, *pset;
2885 ts = arg_temp(op->args[i]);
2886 pset = la_temp_pref(ts);
2891 set &= op->output_pref[ct->alias_index];
2893 /* If the combination is not possible, restart. */
2903 op->life = arg_life;
2907 /* Liveness analysis: Convert indirect regs to direct temporaries. */
2908 static bool liveness_pass_2(TCGContext *s)
2910 int nb_globals = s->nb_globals;
2912 bool changes = false;
2913 TCGOp *op, *op_next;
2915 /* Create a temporary for each indirect global. */
2916 for (i = 0; i < nb_globals; ++i) {
2917 TCGTemp *its = &s->temps[i];
2918 if (its->indirect_reg) {
2919 TCGTemp *dts = tcg_temp_alloc(s);
2920 dts->type = its->type;
2921 dts->base_type = its->base_type;
2922 its->state_ptr = dts;
2924 its->state_ptr = NULL;
2926 /* All globals begin dead. */
2927 its->state = TS_DEAD;
2929 for (nb_temps = s->nb_temps; i < nb_temps; ++i) {
2930 TCGTemp *its = &s->temps[i];
2931 its->state_ptr = NULL;
2932 its->state = TS_DEAD;
2935 QTAILQ_FOREACH_SAFE(op, &s->ops, link, op_next) {
2936 TCGOpcode opc = op->opc;
2937 const TCGOpDef *def = &tcg_op_defs[opc];
2938 TCGLifeData arg_life = op->life;
2939 int nb_iargs, nb_oargs, call_flags;
2940 TCGTemp *arg_ts, *dir_ts;
2942 if (opc == INDEX_op_call) {
2943 nb_oargs = TCGOP_CALLO(op);
2944 nb_iargs = TCGOP_CALLI(op);
2945 call_flags = op->args[nb_oargs + nb_iargs + 1];
2947 nb_iargs = def->nb_iargs;
2948 nb_oargs = def->nb_oargs;
2950 /* Set flags similar to how calls require. */
2951 if (def->flags & TCG_OPF_COND_BRANCH) {
2952 /* Like reading globals: sync_globals */
2953 call_flags = TCG_CALL_NO_WRITE_GLOBALS;
2954 } else if (def->flags & TCG_OPF_BB_END) {
2955 /* Like writing globals: save_globals */
2957 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
2958 /* Like reading globals: sync_globals */
2959 call_flags = TCG_CALL_NO_WRITE_GLOBALS;
2961 /* No effect on globals. */
2962 call_flags = (TCG_CALL_NO_READ_GLOBALS |
2963 TCG_CALL_NO_WRITE_GLOBALS);
2967 /* Make sure that input arguments are available. */
2968 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
2969 arg_ts = arg_temp(op->args[i]);
2971 dir_ts = arg_ts->state_ptr;
2972 if (dir_ts && arg_ts->state == TS_DEAD) {
2973 TCGOpcode lopc = (arg_ts->type == TCG_TYPE_I32
2976 TCGOp *lop = tcg_op_insert_before(s, op, lopc);
2978 lop->args[0] = temp_arg(dir_ts);
2979 lop->args[1] = temp_arg(arg_ts->mem_base);
2980 lop->args[2] = arg_ts->mem_offset;
2982 /* Loaded, but synced with memory. */
2983 arg_ts->state = TS_MEM;
2988 /* Perform input replacement, and mark inputs that became dead.
2989 No action is required except keeping temp_state up to date
2990 so that we reload when needed. */
2991 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
2992 arg_ts = arg_temp(op->args[i]);
2994 dir_ts = arg_ts->state_ptr;
2996 op->args[i] = temp_arg(dir_ts);
2998 if (IS_DEAD_ARG(i)) {
2999 arg_ts->state = TS_DEAD;
3005 /* Liveness analysis should ensure that the following are
3006 all correct, for call sites and basic block end points. */
3007 if (call_flags & TCG_CALL_NO_READ_GLOBALS) {
3009 } else if (call_flags & TCG_CALL_NO_WRITE_GLOBALS) {
3010 for (i = 0; i < nb_globals; ++i) {
3011 /* Liveness should see that globals are synced back,
3012 that is, either TS_DEAD or TS_MEM. */
3013 arg_ts = &s->temps[i];
3014 tcg_debug_assert(arg_ts->state_ptr == 0
3015 || arg_ts->state != 0);
3018 for (i = 0; i < nb_globals; ++i) {
3019 /* Liveness should see that globals are saved back,
3020 that is, TS_DEAD, waiting to be reloaded. */
3021 arg_ts = &s->temps[i];
3022 tcg_debug_assert(arg_ts->state_ptr == 0
3023 || arg_ts->state == TS_DEAD);
3027 /* Outputs become available. */
3028 if (opc == INDEX_op_mov_i32 || opc == INDEX_op_mov_i64) {
3029 arg_ts = arg_temp(op->args[0]);
3030 dir_ts = arg_ts->state_ptr;
3032 op->args[0] = temp_arg(dir_ts);
3035 /* The output is now live and modified. */
3038 if (NEED_SYNC_ARG(0)) {
3039 TCGOpcode sopc = (arg_ts->type == TCG_TYPE_I32
3042 TCGOp *sop = tcg_op_insert_after(s, op, sopc);
3043 TCGTemp *out_ts = dir_ts;
3045 if (IS_DEAD_ARG(0)) {
3046 out_ts = arg_temp(op->args[1]);
3047 arg_ts->state = TS_DEAD;
3048 tcg_op_remove(s, op);
3050 arg_ts->state = TS_MEM;
3053 sop->args[0] = temp_arg(out_ts);
3054 sop->args[1] = temp_arg(arg_ts->mem_base);
3055 sop->args[2] = arg_ts->mem_offset;
3057 tcg_debug_assert(!IS_DEAD_ARG(0));
3061 for (i = 0; i < nb_oargs; i++) {
3062 arg_ts = arg_temp(op->args[i]);
3063 dir_ts = arg_ts->state_ptr;
3067 op->args[i] = temp_arg(dir_ts);
3070 /* The output is now live and modified. */
3073 /* Sync outputs upon their last write. */
3074 if (NEED_SYNC_ARG(i)) {
3075 TCGOpcode sopc = (arg_ts->type == TCG_TYPE_I32
3078 TCGOp *sop = tcg_op_insert_after(s, op, sopc);
3080 sop->args[0] = temp_arg(dir_ts);
3081 sop->args[1] = temp_arg(arg_ts->mem_base);
3082 sop->args[2] = arg_ts->mem_offset;
3084 arg_ts->state = TS_MEM;
3086 /* Drop outputs that are dead. */
3087 if (IS_DEAD_ARG(i)) {
3088 arg_ts->state = TS_DEAD;
3097 #ifdef CONFIG_DEBUG_TCG
3098 static void dump_regs(TCGContext *s)
3104 for(i = 0; i < s->nb_temps; i++) {
3106 printf(" %10s: ", tcg_get_arg_str_ptr(s, buf, sizeof(buf), ts));
3107 switch(ts->val_type) {
3109 printf("%s", tcg_target_reg_names[ts->reg]);
3112 printf("%d(%s)", (int)ts->mem_offset,
3113 tcg_target_reg_names[ts->mem_base->reg]);
3115 case TEMP_VAL_CONST:
3116 printf("$0x%" TCG_PRIlx, ts->val);
3128 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
3129 if (s->reg_to_temp[i] != NULL) {
3131 tcg_target_reg_names[i],
3132 tcg_get_arg_str_ptr(s, buf, sizeof(buf), s->reg_to_temp[i]));
3137 static void check_regs(TCGContext *s)
3144 for (reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
3145 ts = s->reg_to_temp[reg];
3147 if (ts->val_type != TEMP_VAL_REG || ts->reg != reg) {
3148 printf("Inconsistency for register %s:\n",
3149 tcg_target_reg_names[reg]);
3154 for (k = 0; k < s->nb_temps; k++) {
3156 if (ts->val_type == TEMP_VAL_REG && !ts->fixed_reg
3157 && s->reg_to_temp[ts->reg] != ts) {
3158 printf("Inconsistency for temp %s:\n",
3159 tcg_get_arg_str_ptr(s, buf, sizeof(buf), ts));
3161 printf("reg state:\n");
3169 static void temp_allocate_frame(TCGContext *s, TCGTemp *ts)
3171 #if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64)
3172 /* Sparc64 stack is accessed with offset of 2047 */
3173 s->current_frame_offset = (s->current_frame_offset +
3174 (tcg_target_long)sizeof(tcg_target_long) - 1) &
3175 ~(sizeof(tcg_target_long) - 1);
3177 if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
3181 ts->mem_offset = s->current_frame_offset;
3182 ts->mem_base = s->frame_temp;
3183 ts->mem_allocated = 1;
3184 s->current_frame_offset += sizeof(tcg_target_long);
3187 static void temp_load(TCGContext *, TCGTemp *, TCGRegSet, TCGRegSet, TCGRegSet);
3189 /* Mark a temporary as free or dead. If 'free_or_dead' is negative,
3190 mark it free; otherwise mark it dead. */
3191 static void temp_free_or_dead(TCGContext *s, TCGTemp *ts, int free_or_dead)
3193 if (ts->fixed_reg) {
3196 if (ts->val_type == TEMP_VAL_REG) {
3197 s->reg_to_temp[ts->reg] = NULL;
3199 ts->val_type = (free_or_dead < 0
3202 ? TEMP_VAL_MEM : TEMP_VAL_DEAD);
3205 /* Mark a temporary as dead. */
3206 static inline void temp_dead(TCGContext *s, TCGTemp *ts)
3208 temp_free_or_dead(s, ts, 1);
3211 /* Sync a temporary to memory. 'allocated_regs' is used in case a temporary
3212 registers needs to be allocated to store a constant. If 'free_or_dead'
3213 is non-zero, subsequently release the temporary; if it is positive, the
3214 temp is dead; if it is negative, the temp is free. */
3215 static void temp_sync(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs,
3216 TCGRegSet preferred_regs, int free_or_dead)
3218 if (ts->fixed_reg) {
3221 if (!ts->mem_coherent) {
3222 if (!ts->mem_allocated) {
3223 temp_allocate_frame(s, ts);
3225 switch (ts->val_type) {
3226 case TEMP_VAL_CONST:
3227 /* If we're going to free the temp immediately, then we won't
3228 require it later in a register, so attempt to store the
3229 constant to memory directly. */
3231 && tcg_out_sti(s, ts->type, ts->val,
3232 ts->mem_base->reg, ts->mem_offset)) {
3235 temp_load(s, ts, tcg_target_available_regs[ts->type],
3236 allocated_regs, preferred_regs);
3240 tcg_out_st(s, ts->type, ts->reg,
3241 ts->mem_base->reg, ts->mem_offset);
3251 ts->mem_coherent = 1;
3254 temp_free_or_dead(s, ts, free_or_dead);
3258 /* free register 'reg' by spilling the corresponding temporary if necessary */
3259 static void tcg_reg_free(TCGContext *s, TCGReg reg, TCGRegSet allocated_regs)
3261 TCGTemp *ts = s->reg_to_temp[reg];
3263 temp_sync(s, ts, allocated_regs, 0, -1);
3269 * @required_regs: Set of registers in which we must allocate.
3270 * @allocated_regs: Set of registers which must be avoided.
3271 * @preferred_regs: Set of registers we should prefer.
3272 * @rev: True if we search the registers in "indirect" order.
3274 * The allocated register must be in @required_regs & ~@allocated_regs,
3275 * but if we can put it in @preferred_regs we may save a move later.
3277 static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet required_regs,
3278 TCGRegSet allocated_regs,
3279 TCGRegSet preferred_regs, bool rev)
3281 int i, j, f, n = ARRAY_SIZE(tcg_target_reg_alloc_order);
3282 TCGRegSet reg_ct[2];
3285 reg_ct[1] = required_regs & ~allocated_regs;
3286 tcg_debug_assert(reg_ct[1] != 0);
3287 reg_ct[0] = reg_ct[1] & preferred_regs;
3289 /* Skip the preferred_regs option if it cannot be satisfied,
3290 or if the preference made no difference. */
3291 f = reg_ct[0] == 0 || reg_ct[0] == reg_ct[1];
3293 order = rev ? indirect_reg_alloc_order : tcg_target_reg_alloc_order;
3295 /* Try free registers, preferences first. */
3296 for (j = f; j < 2; j++) {
3297 TCGRegSet set = reg_ct[j];
3299 if (tcg_regset_single(set)) {
3300 /* One register in the set. */
3301 TCGReg reg = tcg_regset_first(set);
3302 if (s->reg_to_temp[reg] == NULL) {
3306 for (i = 0; i < n; i++) {
3307 TCGReg reg = order[i];
3308 if (s->reg_to_temp[reg] == NULL &&
3309 tcg_regset_test_reg(set, reg)) {
3316 /* We must spill something. */
3317 for (j = f; j < 2; j++) {
3318 TCGRegSet set = reg_ct[j];
3320 if (tcg_regset_single(set)) {
3321 /* One register in the set. */
3322 TCGReg reg = tcg_regset_first(set);
3323 tcg_reg_free(s, reg, allocated_regs);
3326 for (i = 0; i < n; i++) {
3327 TCGReg reg = order[i];
3328 if (tcg_regset_test_reg(set, reg)) {
3329 tcg_reg_free(s, reg, allocated_regs);
3339 /* Make sure the temporary is in a register. If needed, allocate the register
3340 from DESIRED while avoiding ALLOCATED. */
3341 static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs,
3342 TCGRegSet allocated_regs, TCGRegSet preferred_regs)
3346 switch (ts->val_type) {
3349 case TEMP_VAL_CONST:
3350 reg = tcg_reg_alloc(s, desired_regs, allocated_regs,
3351 preferred_regs, ts->indirect_base);
3352 tcg_out_movi(s, ts->type, reg, ts->val);
3353 ts->mem_coherent = 0;
3356 reg = tcg_reg_alloc(s, desired_regs, allocated_regs,
3357 preferred_regs, ts->indirect_base);
3358 tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
3359 ts->mem_coherent = 1;
3366 ts->val_type = TEMP_VAL_REG;
3367 s->reg_to_temp[reg] = ts;
3370 /* Save a temporary to memory. 'allocated_regs' is used in case a
3371 temporary registers needs to be allocated to store a constant. */
3372 static void temp_save(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs)
3374 /* The liveness analysis already ensures that globals are back
3375 in memory. Keep an tcg_debug_assert for safety. */
3376 tcg_debug_assert(ts->val_type == TEMP_VAL_MEM || ts->fixed_reg);
3379 /* save globals to their canonical location and assume they can be
3380 modified be the following code. 'allocated_regs' is used in case a
3381 temporary registers needs to be allocated to store a constant. */
3382 static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
3386 for (i = 0, n = s->nb_globals; i < n; i++) {
3387 temp_save(s, &s->temps[i], allocated_regs);
3391 /* sync globals to their canonical location and assume they can be
3392 read by the following code. 'allocated_regs' is used in case a
3393 temporary registers needs to be allocated to store a constant. */
3394 static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
3398 for (i = 0, n = s->nb_globals; i < n; i++) {
3399 TCGTemp *ts = &s->temps[i];
3400 tcg_debug_assert(ts->val_type != TEMP_VAL_REG
3402 || ts->mem_coherent);
3406 /* at the end of a basic block, we assume all temporaries are dead and
3407 all globals are stored at their canonical location. */
3408 static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
3412 for (i = s->nb_globals; i < s->nb_temps; i++) {
3413 TCGTemp *ts = &s->temps[i];
3414 if (ts->temp_local) {
3415 temp_save(s, ts, allocated_regs);
3417 /* The liveness analysis already ensures that temps are dead.
3418 Keep an tcg_debug_assert for safety. */
3419 tcg_debug_assert(ts->val_type == TEMP_VAL_DEAD);
3423 save_globals(s, allocated_regs);
3427 * At a conditional branch, we assume all temporaries are dead and
3428 * all globals and local temps are synced to their location.
3430 static void tcg_reg_alloc_cbranch(TCGContext *s, TCGRegSet allocated_regs)
3432 sync_globals(s, allocated_regs);
3434 for (int i = s->nb_globals; i < s->nb_temps; i++) {
3435 TCGTemp *ts = &s->temps[i];
3437 * The liveness analysis already ensures that temps are dead.
3438 * Keep tcg_debug_asserts for safety.
3440 if (ts->temp_local) {
3441 tcg_debug_assert(ts->val_type != TEMP_VAL_REG || ts->mem_coherent);
3443 tcg_debug_assert(ts->val_type == TEMP_VAL_DEAD);
3449 * Specialized code generation for INDEX_op_movi_*.
3451 static void tcg_reg_alloc_do_movi(TCGContext *s, TCGTemp *ots,
3452 tcg_target_ulong val, TCGLifeData arg_life,
3453 TCGRegSet preferred_regs)
3455 /* ENV should not be modified. */
3456 tcg_debug_assert(!ots->fixed_reg);
3458 /* The movi is not explicitly generated here. */
3459 if (ots->val_type == TEMP_VAL_REG) {
3460 s->reg_to_temp[ots->reg] = NULL;
3462 ots->val_type = TEMP_VAL_CONST;
3464 ots->mem_coherent = 0;
3465 if (NEED_SYNC_ARG(0)) {
3466 temp_sync(s, ots, s->reserved_regs, preferred_regs, IS_DEAD_ARG(0));
3467 } else if (IS_DEAD_ARG(0)) {
3472 static void tcg_reg_alloc_movi(TCGContext *s, const TCGOp *op)
3474 TCGTemp *ots = arg_temp(op->args[0]);
3475 tcg_target_ulong val = op->args[1];
3477 tcg_reg_alloc_do_movi(s, ots, val, op->life, op->output_pref[0]);
3481 * Specialized code generation for INDEX_op_mov_*.
3483 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp *op)
3485 const TCGLifeData arg_life = op->life;
3486 TCGRegSet allocated_regs, preferred_regs;
3488 TCGType otype, itype;
3490 allocated_regs = s->reserved_regs;
3491 preferred_regs = op->output_pref[0];
3492 ots = arg_temp(op->args[0]);
3493 ts = arg_temp(op->args[1]);
3495 /* ENV should not be modified. */
3496 tcg_debug_assert(!ots->fixed_reg);
3498 /* Note that otype != itype for no-op truncation. */
3502 if (ts->val_type == TEMP_VAL_CONST) {
3503 /* propagate constant or generate sti */
3504 tcg_target_ulong val = ts->val;
3505 if (IS_DEAD_ARG(1)) {
3508 tcg_reg_alloc_do_movi(s, ots, val, arg_life, preferred_regs);
3512 /* If the source value is in memory we're going to be forced
3513 to have it in a register in order to perform the copy. Copy
3514 the SOURCE value into its own register first, that way we
3515 don't have to reload SOURCE the next time it is used. */
3516 if (ts->val_type == TEMP_VAL_MEM) {
3517 temp_load(s, ts, tcg_target_available_regs[itype],
3518 allocated_regs, preferred_regs);
3521 tcg_debug_assert(ts->val_type == TEMP_VAL_REG);
3522 if (IS_DEAD_ARG(0)) {
3523 /* mov to a non-saved dead register makes no sense (even with
3524 liveness analysis disabled). */
3525 tcg_debug_assert(NEED_SYNC_ARG(0));
3526 if (!ots->mem_allocated) {
3527 temp_allocate_frame(s, ots);
3529 tcg_out_st(s, otype, ts->reg, ots->mem_base->reg, ots->mem_offset);
3530 if (IS_DEAD_ARG(1)) {
3535 if (IS_DEAD_ARG(1) && !ts->fixed_reg) {
3536 /* the mov can be suppressed */
3537 if (ots->val_type == TEMP_VAL_REG) {
3538 s->reg_to_temp[ots->reg] = NULL;
3543 if (ots->val_type != TEMP_VAL_REG) {
3544 /* When allocating a new register, make sure to not spill the
3546 tcg_regset_set_reg(allocated_regs, ts->reg);
3547 ots->reg = tcg_reg_alloc(s, tcg_target_available_regs[otype],
3548 allocated_regs, preferred_regs,
3549 ots->indirect_base);
3551 if (!tcg_out_mov(s, otype, ots->reg, ts->reg)) {
3553 * Cross register class move not supported.
3554 * Store the source register into the destination slot
3555 * and leave the destination temp as TEMP_VAL_MEM.
3557 assert(!ots->fixed_reg);
3558 if (!ts->mem_allocated) {
3559 temp_allocate_frame(s, ots);
3561 tcg_out_st(s, ts->type, ts->reg,
3562 ots->mem_base->reg, ots->mem_offset);
3563 ots->mem_coherent = 1;
3564 temp_free_or_dead(s, ots, -1);
3568 ots->val_type = TEMP_VAL_REG;
3569 ots->mem_coherent = 0;
3570 s->reg_to_temp[ots->reg] = ots;
3571 if (NEED_SYNC_ARG(0)) {
3572 temp_sync(s, ots, allocated_regs, 0, 0);
3578 * Specialized code generation for INDEX_op_dup_vec.
3580 static void tcg_reg_alloc_dup(TCGContext *s, const TCGOp *op)
3582 const TCGLifeData arg_life = op->life;
3583 TCGRegSet dup_out_regs, dup_in_regs;
3585 TCGType itype, vtype;
3586 intptr_t endian_fixup;
3590 ots = arg_temp(op->args[0]);
3591 its = arg_temp(op->args[1]);
3593 /* ENV should not be modified. */
3594 tcg_debug_assert(!ots->fixed_reg);
3597 vece = TCGOP_VECE(op);
3598 vtype = TCGOP_VECL(op) + TCG_TYPE_V64;
3600 if (its->val_type == TEMP_VAL_CONST) {
3601 /* Propagate constant via movi -> dupi. */
3602 tcg_target_ulong val = its->val;
3603 if (IS_DEAD_ARG(1)) {
3606 tcg_reg_alloc_do_movi(s, ots, val, arg_life, op->output_pref[0]);
3610 dup_out_regs = tcg_op_defs[INDEX_op_dup_vec].args_ct[0].regs;
3611 dup_in_regs = tcg_op_defs[INDEX_op_dup_vec].args_ct[1].regs;
3613 /* Allocate the output register now. */
3614 if (ots->val_type != TEMP_VAL_REG) {
3615 TCGRegSet allocated_regs = s->reserved_regs;
3617 if (!IS_DEAD_ARG(1) && its->val_type == TEMP_VAL_REG) {
3618 /* Make sure to not spill the input register. */
3619 tcg_regset_set_reg(allocated_regs, its->reg);
3621 ots->reg = tcg_reg_alloc(s, dup_out_regs, allocated_regs,
3622 op->output_pref[0], ots->indirect_base);
3623 ots->val_type = TEMP_VAL_REG;
3624 ots->mem_coherent = 0;
3625 s->reg_to_temp[ots->reg] = ots;
3628 switch (its->val_type) {
3631 * The dup constriaints must be broad, covering all possible VECE.
3632 * However, tcg_op_dup_vec() gets to see the VECE and we allow it
3633 * to fail, indicating that extra moves are required for that case.
3635 if (tcg_regset_test_reg(dup_in_regs, its->reg)) {
3636 if (tcg_out_dup_vec(s, vtype, vece, ots->reg, its->reg)) {
3639 /* Try again from memory or a vector input register. */
3641 if (!its->mem_coherent) {
3643 * The input register is not synced, and so an extra store
3644 * would be required to use memory. Attempt an integer-vector
3645 * register move first. We do not have a TCGRegSet for this.
3647 if (tcg_out_mov(s, itype, ots->reg, its->reg)) {
3650 /* Sync the temp back to its slot and load from there. */
3651 temp_sync(s, its, s->reserved_regs, 0, 0);
3656 #ifdef HOST_WORDS_BIGENDIAN
3657 endian_fixup = itype == TCG_TYPE_I32 ? 4 : 8;
3658 endian_fixup -= 1 << vece;
3662 if (tcg_out_dupm_vec(s, vtype, vece, ots->reg, its->mem_base->reg,
3663 its->mem_offset + endian_fixup)) {
3666 tcg_out_ld(s, itype, ots->reg, its->mem_base->reg, its->mem_offset);
3670 g_assert_not_reached();
3673 /* We now have a vector input register, so dup must succeed. */
3674 ok = tcg_out_dup_vec(s, vtype, vece, ots->reg, ots->reg);
3675 tcg_debug_assert(ok);
3678 if (IS_DEAD_ARG(1)) {
3681 if (NEED_SYNC_ARG(0)) {
3682 temp_sync(s, ots, s->reserved_regs, 0, 0);
3684 if (IS_DEAD_ARG(0)) {
3689 static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
3691 const TCGLifeData arg_life = op->life;
3692 const TCGOpDef * const def = &tcg_op_defs[op->opc];
3693 TCGRegSet i_allocated_regs;
3694 TCGRegSet o_allocated_regs;
3695 int i, k, nb_iargs, nb_oargs;
3698 const TCGArgConstraint *arg_ct;
3700 TCGArg new_args[TCG_MAX_OP_ARGS];
3701 int const_args[TCG_MAX_OP_ARGS];
3703 nb_oargs = def->nb_oargs;
3704 nb_iargs = def->nb_iargs;
3706 /* copy constants */
3707 memcpy(new_args + nb_oargs + nb_iargs,
3708 op->args + nb_oargs + nb_iargs,
3709 sizeof(TCGArg) * def->nb_cargs);
3711 i_allocated_regs = s->reserved_regs;
3712 o_allocated_regs = s->reserved_regs;
3714 /* satisfy input constraints */
3715 for (k = 0; k < nb_iargs; k++) {
3716 TCGRegSet i_preferred_regs, o_preferred_regs;
3718 i = def->args_ct[nb_oargs + k].sort_index;
3720 arg_ct = &def->args_ct[i];
3723 if (ts->val_type == TEMP_VAL_CONST
3724 && tcg_target_const_match(ts->val, ts->type, arg_ct)) {
3725 /* constant is OK for instruction */
3727 new_args[i] = ts->val;
3731 i_preferred_regs = o_preferred_regs = 0;
3732 if (arg_ct->ialias) {
3733 o_preferred_regs = op->output_pref[arg_ct->alias_index];
3734 if (ts->fixed_reg) {
3735 /* if fixed register, we must allocate a new register
3736 if the alias is not the same register */
3737 if (arg != op->args[arg_ct->alias_index]) {
3738 goto allocate_in_reg;
3741 /* if the input is aliased to an output and if it is
3742 not dead after the instruction, we must allocate
3743 a new register and move it */
3744 if (!IS_DEAD_ARG(i)) {
3745 goto allocate_in_reg;
3748 /* check if the current register has already been allocated
3749 for another input aliased to an output */
3750 if (ts->val_type == TEMP_VAL_REG) {
3753 for (k2 = 0 ; k2 < k ; k2++) {
3754 i2 = def->args_ct[nb_oargs + k2].sort_index;
3755 if (def->args_ct[i2].ialias && reg == new_args[i2]) {
3756 goto allocate_in_reg;
3760 i_preferred_regs = o_preferred_regs;
3764 temp_load(s, ts, arg_ct->regs, i_allocated_regs, i_preferred_regs);
3767 if (tcg_regset_test_reg(arg_ct->regs, reg)) {
3768 /* nothing to do : the constraint is satisfied */
3771 /* allocate a new register matching the constraint
3772 and move the temporary register into it */
3773 temp_load(s, ts, tcg_target_available_regs[ts->type],
3774 i_allocated_regs, 0);
3775 reg = tcg_reg_alloc(s, arg_ct->regs, i_allocated_regs,
3776 o_preferred_regs, ts->indirect_base);
3777 if (!tcg_out_mov(s, ts->type, reg, ts->reg)) {
3779 * Cross register class move not supported. Sync the
3780 * temp back to its slot and load from there.
3782 temp_sync(s, ts, i_allocated_regs, 0, 0);
3783 tcg_out_ld(s, ts->type, reg,
3784 ts->mem_base->reg, ts->mem_offset);
3789 tcg_regset_set_reg(i_allocated_regs, reg);
3792 /* mark dead temporaries and free the associated registers */
3793 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
3794 if (IS_DEAD_ARG(i)) {
3795 temp_dead(s, arg_temp(op->args[i]));
3799 if (def->flags & TCG_OPF_COND_BRANCH) {
3800 tcg_reg_alloc_cbranch(s, i_allocated_regs);
3801 } else if (def->flags & TCG_OPF_BB_END) {
3802 tcg_reg_alloc_bb_end(s, i_allocated_regs);
3804 if (def->flags & TCG_OPF_CALL_CLOBBER) {
3805 /* XXX: permit generic clobber register list ? */
3806 for (i = 0; i < TCG_TARGET_NB_REGS; i++) {
3807 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, i)) {
3808 tcg_reg_free(s, i, i_allocated_regs);
3812 if (def->flags & TCG_OPF_SIDE_EFFECTS) {
3813 /* sync globals if the op has side effects and might trigger
3815 sync_globals(s, i_allocated_regs);
3818 /* satisfy the output constraints */
3819 for(k = 0; k < nb_oargs; k++) {
3820 i = def->args_ct[k].sort_index;
3822 arg_ct = &def->args_ct[i];
3825 /* ENV should not be modified. */
3826 tcg_debug_assert(!ts->fixed_reg);
3828 if (arg_ct->oalias && !const_args[arg_ct->alias_index]) {
3829 reg = new_args[arg_ct->alias_index];
3830 } else if (arg_ct->newreg) {
3831 reg = tcg_reg_alloc(s, arg_ct->regs,
3832 i_allocated_regs | o_allocated_regs,
3833 op->output_pref[k], ts->indirect_base);
3835 reg = tcg_reg_alloc(s, arg_ct->regs, o_allocated_regs,
3836 op->output_pref[k], ts->indirect_base);
3838 tcg_regset_set_reg(o_allocated_regs, reg);
3839 if (ts->val_type == TEMP_VAL_REG) {
3840 s->reg_to_temp[ts->reg] = NULL;
3842 ts->val_type = TEMP_VAL_REG;
3845 * Temp value is modified, so the value kept in memory is
3846 * potentially not the same.
3848 ts->mem_coherent = 0;
3849 s->reg_to_temp[reg] = ts;
3854 /* emit instruction */
3855 if (def->flags & TCG_OPF_VECTOR) {
3856 tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op),
3857 new_args, const_args);
3859 tcg_out_op(s, op->opc, new_args, const_args);
3862 /* move the outputs in the correct register if needed */
3863 for(i = 0; i < nb_oargs; i++) {
3864 ts = arg_temp(op->args[i]);
3866 /* ENV should not be modified. */
3867 tcg_debug_assert(!ts->fixed_reg);
3869 if (NEED_SYNC_ARG(i)) {
3870 temp_sync(s, ts, o_allocated_regs, 0, IS_DEAD_ARG(i));
3871 } else if (IS_DEAD_ARG(i)) {
3877 #ifdef TCG_TARGET_STACK_GROWSUP
3878 #define STACK_DIR(x) (-(x))
3880 #define STACK_DIR(x) (x)
3883 static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
3885 const int nb_oargs = TCGOP_CALLO(op);
3886 const int nb_iargs = TCGOP_CALLI(op);
3887 const TCGLifeData arg_life = op->life;
3888 int flags, nb_regs, i;
3892 intptr_t stack_offset;
3893 size_t call_stack_size;
3894 tcg_insn_unit *func_addr;
3896 TCGRegSet allocated_regs;
3898 func_addr = (tcg_insn_unit *)(intptr_t)op->args[nb_oargs + nb_iargs];
3899 flags = op->args[nb_oargs + nb_iargs + 1];
3901 nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
3902 if (nb_regs > nb_iargs) {
3906 /* assign stack slots first */
3907 call_stack_size = (nb_iargs - nb_regs) * sizeof(tcg_target_long);
3908 call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) &
3909 ~(TCG_TARGET_STACK_ALIGN - 1);
3910 allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
3911 if (allocate_args) {
3912 /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
3913 preallocate call stack */
3917 stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
3918 for (i = nb_regs; i < nb_iargs; i++) {
3919 arg = op->args[nb_oargs + i];
3920 #ifdef TCG_TARGET_STACK_GROWSUP
3921 stack_offset -= sizeof(tcg_target_long);
3923 if (arg != TCG_CALL_DUMMY_ARG) {
3925 temp_load(s, ts, tcg_target_available_regs[ts->type],
3926 s->reserved_regs, 0);
3927 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
3929 #ifndef TCG_TARGET_STACK_GROWSUP
3930 stack_offset += sizeof(tcg_target_long);
3934 /* assign input registers */
3935 allocated_regs = s->reserved_regs;
3936 for (i = 0; i < nb_regs; i++) {
3937 arg = op->args[nb_oargs + i];
3938 if (arg != TCG_CALL_DUMMY_ARG) {
3940 reg = tcg_target_call_iarg_regs[i];
3942 if (ts->val_type == TEMP_VAL_REG) {
3943 if (ts->reg != reg) {
3944 tcg_reg_free(s, reg, allocated_regs);
3945 if (!tcg_out_mov(s, ts->type, reg, ts->reg)) {
3947 * Cross register class move not supported. Sync the
3948 * temp back to its slot and load from there.
3950 temp_sync(s, ts, allocated_regs, 0, 0);
3951 tcg_out_ld(s, ts->type, reg,
3952 ts->mem_base->reg, ts->mem_offset);
3956 TCGRegSet arg_set = 0;
3958 tcg_reg_free(s, reg, allocated_regs);
3959 tcg_regset_set_reg(arg_set, reg);
3960 temp_load(s, ts, arg_set, allocated_regs, 0);
3963 tcg_regset_set_reg(allocated_regs, reg);
3967 /* mark dead temporaries and free the associated registers */
3968 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
3969 if (IS_DEAD_ARG(i)) {
3970 temp_dead(s, arg_temp(op->args[i]));
3974 /* clobber call registers */
3975 for (i = 0; i < TCG_TARGET_NB_REGS; i++) {
3976 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, i)) {
3977 tcg_reg_free(s, i, allocated_regs);
3981 /* Save globals if they might be written by the helper, sync them if
3982 they might be read. */
3983 if (flags & TCG_CALL_NO_READ_GLOBALS) {
3985 } else if (flags & TCG_CALL_NO_WRITE_GLOBALS) {
3986 sync_globals(s, allocated_regs);
3988 save_globals(s, allocated_regs);
3991 tcg_out_call(s, func_addr);
3993 /* assign output registers and emit moves if needed */
3994 for(i = 0; i < nb_oargs; i++) {
3998 /* ENV should not be modified. */
3999 tcg_debug_assert(!ts->fixed_reg);
4001 reg = tcg_target_call_oarg_regs[i];
4002 tcg_debug_assert(s->reg_to_temp[reg] == NULL);
4003 if (ts->val_type == TEMP_VAL_REG) {
4004 s->reg_to_temp[ts->reg] = NULL;
4006 ts->val_type = TEMP_VAL_REG;
4008 ts->mem_coherent = 0;
4009 s->reg_to_temp[reg] = ts;
4010 if (NEED_SYNC_ARG(i)) {
4011 temp_sync(s, ts, allocated_regs, 0, IS_DEAD_ARG(i));
4012 } else if (IS_DEAD_ARG(i)) {
4018 #ifdef CONFIG_PROFILER
4020 /* avoid copy/paste errors */
4021 #define PROF_ADD(to, from, field) \
4023 (to)->field += qatomic_read(&((from)->field)); \
4026 #define PROF_MAX(to, from, field) \
4028 typeof((from)->field) val__ = qatomic_read(&((from)->field)); \
4029 if (val__ > (to)->field) { \
4030 (to)->field = val__; \
4034 /* Pass in a zero'ed @prof */
4036 void tcg_profile_snapshot(TCGProfile *prof, bool counters, bool table)
4038 unsigned int n_ctxs = qatomic_read(&n_tcg_ctxs);
4041 for (i = 0; i < n_ctxs; i++) {
4042 TCGContext *s = qatomic_read(&tcg_ctxs[i]);
4043 const TCGProfile *orig = &s->prof;
4046 PROF_ADD(prof, orig, cpu_exec_time);
4047 PROF_ADD(prof, orig, tb_count1);
4048 PROF_ADD(prof, orig, tb_count);
4049 PROF_ADD(prof, orig, op_count);
4050 PROF_MAX(prof, orig, op_count_max);
4051 PROF_ADD(prof, orig, temp_count);
4052 PROF_MAX(prof, orig, temp_count_max);
4053 PROF_ADD(prof, orig, del_op_count);
4054 PROF_ADD(prof, orig, code_in_len);
4055 PROF_ADD(prof, orig, code_out_len);
4056 PROF_ADD(prof, orig, search_out_len);
4057 PROF_ADD(prof, orig, interm_time);
4058 PROF_ADD(prof, orig, code_time);
4059 PROF_ADD(prof, orig, la_time);
4060 PROF_ADD(prof, orig, opt_time);
4061 PROF_ADD(prof, orig, restore_count);
4062 PROF_ADD(prof, orig, restore_time);
4067 for (i = 0; i < NB_OPS; i++) {
4068 PROF_ADD(prof, orig, table_op_count[i]);
4077 static void tcg_profile_snapshot_counters(TCGProfile *prof)
4079 tcg_profile_snapshot(prof, true, false);
4082 static void tcg_profile_snapshot_table(TCGProfile *prof)
4084 tcg_profile_snapshot(prof, false, true);
4087 void tcg_dump_op_count(void)
4089 TCGProfile prof = {};
4092 tcg_profile_snapshot_table(&prof);
4093 for (i = 0; i < NB_OPS; i++) {
4094 qemu_printf("%s %" PRId64 "\n", tcg_op_defs[i].name,
4095 prof.table_op_count[i]);
4099 int64_t tcg_cpu_exec_time(void)
4101 unsigned int n_ctxs = qatomic_read(&n_tcg_ctxs);
4105 for (i = 0; i < n_ctxs; i++) {
4106 const TCGContext *s = qatomic_read(&tcg_ctxs[i]);
4107 const TCGProfile *prof = &s->prof;
4109 ret += qatomic_read(&prof->cpu_exec_time);
4114 void tcg_dump_op_count(void)
4116 qemu_printf("[TCG profiler not compiled]\n");
4119 int64_t tcg_cpu_exec_time(void)
4121 error_report("%s: TCG profiler not compiled", __func__);
4127 int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
4129 #ifdef CONFIG_PROFILER
4130 TCGProfile *prof = &s->prof;
4135 #ifdef CONFIG_PROFILER
4139 QTAILQ_FOREACH(op, &s->ops, link) {
4142 qatomic_set(&prof->op_count, prof->op_count + n);
4143 if (n > prof->op_count_max) {
4144 qatomic_set(&prof->op_count_max, n);
4148 qatomic_set(&prof->temp_count, prof->temp_count + n);
4149 if (n > prof->temp_count_max) {
4150 qatomic_set(&prof->temp_count_max, n);
4156 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)
4157 && qemu_log_in_addr_range(tb->pc))) {
4158 FILE *logfile = qemu_log_lock();
4160 tcg_dump_ops(s, false);
4162 qemu_log_unlock(logfile);
4166 #ifdef CONFIG_DEBUG_TCG
4167 /* Ensure all labels referenced have been emitted. */
4172 QSIMPLEQ_FOREACH(l, &s->labels, next) {
4173 if (unlikely(!l->present) && l->refs) {
4174 qemu_log_mask(CPU_LOG_TB_OP,
4175 "$L%d referenced but not present.\n", l->id);
4183 #ifdef CONFIG_PROFILER
4184 qatomic_set(&prof->opt_time, prof->opt_time - profile_getclock());
4187 #ifdef USE_TCG_OPTIMIZATIONS
4191 #ifdef CONFIG_PROFILER
4192 qatomic_set(&prof->opt_time, prof->opt_time + profile_getclock());
4193 qatomic_set(&prof->la_time, prof->la_time - profile_getclock());
4196 reachable_code_pass(s);
4199 if (s->nb_indirects > 0) {
4201 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_IND)
4202 && qemu_log_in_addr_range(tb->pc))) {
4203 FILE *logfile = qemu_log_lock();
4204 qemu_log("OP before indirect lowering:\n");
4205 tcg_dump_ops(s, false);
4207 qemu_log_unlock(logfile);
4210 /* Replace indirect temps with direct temps. */
4211 if (liveness_pass_2(s)) {
4212 /* If changes were made, re-run liveness. */
4217 #ifdef CONFIG_PROFILER
4218 qatomic_set(&prof->la_time, prof->la_time + profile_getclock());
4222 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT)
4223 && qemu_log_in_addr_range(tb->pc))) {
4224 FILE *logfile = qemu_log_lock();
4225 qemu_log("OP after optimization and liveness analysis:\n");
4226 tcg_dump_ops(s, true);
4228 qemu_log_unlock(logfile);
4232 tcg_reg_alloc_start(s);
4234 s->code_buf = tb->tc.ptr;
4235 s->code_ptr = tb->tc.ptr;
4237 #ifdef TCG_TARGET_NEED_LDST_LABELS
4238 QSIMPLEQ_INIT(&s->ldst_labels);
4240 #ifdef TCG_TARGET_NEED_POOL_LABELS
4241 s->pool_labels = NULL;
4245 QTAILQ_FOREACH(op, &s->ops, link) {
4246 TCGOpcode opc = op->opc;
4248 #ifdef CONFIG_PROFILER
4249 qatomic_set(&prof->table_op_count[opc], prof->table_op_count[opc] + 1);
4253 case INDEX_op_mov_i32:
4254 case INDEX_op_mov_i64:
4255 case INDEX_op_mov_vec:
4256 tcg_reg_alloc_mov(s, op);
4258 case INDEX_op_movi_i32:
4259 case INDEX_op_movi_i64:
4260 case INDEX_op_dupi_vec:
4261 tcg_reg_alloc_movi(s, op);
4263 case INDEX_op_dup_vec:
4264 tcg_reg_alloc_dup(s, op);
4266 case INDEX_op_insn_start:
4267 if (num_insns >= 0) {
4268 size_t off = tcg_current_code_size(s);
4269 s->gen_insn_end_off[num_insns] = off;
4270 /* Assert that we do not overflow our stored offset. */
4271 assert(s->gen_insn_end_off[num_insns] == off);
4274 for (i = 0; i < TARGET_INSN_START_WORDS; ++i) {
4276 #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
4277 a = deposit64(op->args[i * 2], 32, 32, op->args[i * 2 + 1]);
4281 s->gen_insn_data[num_insns][i] = a;
4284 case INDEX_op_discard:
4285 temp_dead(s, arg_temp(op->args[0]));
4287 case INDEX_op_set_label:
4288 tcg_reg_alloc_bb_end(s, s->reserved_regs);
4289 tcg_out_label(s, arg_label(op->args[0]), s->code_ptr);
4292 tcg_reg_alloc_call(s, op);
4295 /* Sanity check that we've not introduced any unhandled opcodes. */
4296 tcg_debug_assert(tcg_op_supported(opc));
4297 /* Note: in order to speed up the code, it would be much
4298 faster to have specialized register allocator functions for
4299 some common argument patterns */
4300 tcg_reg_alloc_op(s, op);
4303 #ifdef CONFIG_DEBUG_TCG
4306 /* Test for (pending) buffer overflow. The assumption is that any
4307 one operation beginning below the high water mark cannot overrun
4308 the buffer completely. Thus we can test for overflow after
4309 generating code without having to check during generation. */
4310 if (unlikely((void *)s->code_ptr > s->code_gen_highwater)) {
4313 /* Test for TB overflow, as seen by gen_insn_end_off. */
4314 if (unlikely(tcg_current_code_size(s) > UINT16_MAX)) {
4318 tcg_debug_assert(num_insns >= 0);
4319 s->gen_insn_end_off[num_insns] = tcg_current_code_size(s);
4321 /* Generate TB finalization at the end of block */
4322 #ifdef TCG_TARGET_NEED_LDST_LABELS
4323 i = tcg_out_ldst_finalize(s);
4328 #ifdef TCG_TARGET_NEED_POOL_LABELS
4329 i = tcg_out_pool_finalize(s);
4334 if (!tcg_resolve_relocs(s)) {
4338 #ifndef CONFIG_TCG_INTERPRETER
4339 /* flush instruction cache */
4340 flush_idcache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_buf,
4341 tcg_ptr_byte_diff(s->code_ptr, s->code_buf));
4344 return tcg_current_code_size(s);
4347 #ifdef CONFIG_PROFILER
4348 void tcg_dump_info(void)
4350 TCGProfile prof = {};
4351 const TCGProfile *s;
4353 int64_t tb_div_count;
4356 tcg_profile_snapshot_counters(&prof);
4358 tb_count = s->tb_count;
4359 tb_div_count = tb_count ? tb_count : 1;
4360 tot = s->interm_time + s->code_time;
4362 qemu_printf("JIT cycles %" PRId64 " (%0.3f s at 2.4 GHz)\n",
4364 qemu_printf("translated TBs %" PRId64 " (aborted=%" PRId64
4366 tb_count, s->tb_count1 - tb_count,
4367 (double)(s->tb_count1 - s->tb_count)
4368 / (s->tb_count1 ? s->tb_count1 : 1) * 100.0);
4369 qemu_printf("avg ops/TB %0.1f max=%d\n",
4370 (double)s->op_count / tb_div_count, s->op_count_max);
4371 qemu_printf("deleted ops/TB %0.2f\n",
4372 (double)s->del_op_count / tb_div_count);
4373 qemu_printf("avg temps/TB %0.2f max=%d\n",
4374 (double)s->temp_count / tb_div_count, s->temp_count_max);
4375 qemu_printf("avg host code/TB %0.1f\n",
4376 (double)s->code_out_len / tb_div_count);
4377 qemu_printf("avg search data/TB %0.1f\n",
4378 (double)s->search_out_len / tb_div_count);
4380 qemu_printf("cycles/op %0.1f\n",
4381 s->op_count ? (double)tot / s->op_count : 0);
4382 qemu_printf("cycles/in byte %0.1f\n",
4383 s->code_in_len ? (double)tot / s->code_in_len : 0);
4384 qemu_printf("cycles/out byte %0.1f\n",
4385 s->code_out_len ? (double)tot / s->code_out_len : 0);
4386 qemu_printf("cycles/search byte %0.1f\n",
4387 s->search_out_len ? (double)tot / s->search_out_len : 0);
4391 qemu_printf(" gen_interm time %0.1f%%\n",
4392 (double)s->interm_time / tot * 100.0);
4393 qemu_printf(" gen_code time %0.1f%%\n",
4394 (double)s->code_time / tot * 100.0);
4395 qemu_printf("optim./code time %0.1f%%\n",
4396 (double)s->opt_time / (s->code_time ? s->code_time : 1)
4398 qemu_printf("liveness/code time %0.1f%%\n",
4399 (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
4400 qemu_printf("cpu_restore count %" PRId64 "\n",
4402 qemu_printf(" avg cycles %0.1f\n",
4403 s->restore_count ? (double)s->restore_time / s->restore_count : 0);
4406 void tcg_dump_info(void)
4408 qemu_printf("[TCG profiler not compiled]\n");
4412 #ifdef ELF_HOST_MACHINE
4413 /* In order to use this feature, the backend needs to do three things:
4415 (1) Define ELF_HOST_MACHINE to indicate both what value to
4416 put into the ELF image and to indicate support for the feature.
4418 (2) Define tcg_register_jit. This should create a buffer containing
4419 the contents of a .debug_frame section that describes the post-
4420 prologue unwind info for the tcg machine.
4422 (3) Call tcg_register_jit_int, with the constructed .debug_frame.
4425 /* Begin GDB interface. THE FOLLOWING MUST MATCH GDB DOCS. */
4432 struct jit_code_entry {
4433 struct jit_code_entry *next_entry;
4434 struct jit_code_entry *prev_entry;
4435 const void *symfile_addr;
4436 uint64_t symfile_size;
4439 struct jit_descriptor {
4441 uint32_t action_flag;
4442 struct jit_code_entry *relevant_entry;
4443 struct jit_code_entry *first_entry;
4446 void __jit_debug_register_code(void) __attribute__((noinline));
4447 void __jit_debug_register_code(void)
4452 /* Must statically initialize the version, because GDB may check
4453 the version before we can set it. */
4454 struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
4456 /* End GDB interface. */
4458 static int find_string(const char *strtab, const char *str)
4460 const char *p = strtab + 1;
4463 if (strcmp(p, str) == 0) {
4470 static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
4471 const void *debug_frame,
4472 size_t debug_frame_size)
4474 struct __attribute__((packed)) DebugInfo {
4481 uintptr_t cu_low_pc;
4482 uintptr_t cu_high_pc;
4485 uintptr_t fn_low_pc;
4486 uintptr_t fn_high_pc;
4495 struct DebugInfo di;
4500 struct ElfImage *img;
4502 static const struct ElfImage img_template = {
4504 .e_ident[EI_MAG0] = ELFMAG0,
4505 .e_ident[EI_MAG1] = ELFMAG1,
4506 .e_ident[EI_MAG2] = ELFMAG2,
4507 .e_ident[EI_MAG3] = ELFMAG3,
4508 .e_ident[EI_CLASS] = ELF_CLASS,
4509 .e_ident[EI_DATA] = ELF_DATA,
4510 .e_ident[EI_VERSION] = EV_CURRENT,
4512 .e_machine = ELF_HOST_MACHINE,
4513 .e_version = EV_CURRENT,
4514 .e_phoff = offsetof(struct ElfImage, phdr),
4515 .e_shoff = offsetof(struct ElfImage, shdr),
4516 .e_ehsize = sizeof(ElfW(Shdr)),
4517 .e_phentsize = sizeof(ElfW(Phdr)),
4519 .e_shentsize = sizeof(ElfW(Shdr)),
4520 .e_shnum = ARRAY_SIZE(img->shdr),
4521 .e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
4522 #ifdef ELF_HOST_FLAGS
4523 .e_flags = ELF_HOST_FLAGS,
4526 .e_ident[EI_OSABI] = ELF_OSABI,
4534 [0] = { .sh_type = SHT_NULL },
4535 /* Trick: The contents of code_gen_buffer are not present in
4536 this fake ELF file; that got allocated elsewhere. Therefore
4537 we mark .text as SHT_NOBITS (similar to .bss) so that readers
4538 will not look for contents. We can record any address. */
4540 .sh_type = SHT_NOBITS,
4541 .sh_flags = SHF_EXECINSTR | SHF_ALLOC,
4543 [2] = { /* .debug_info */
4544 .sh_type = SHT_PROGBITS,
4545 .sh_offset = offsetof(struct ElfImage, di),
4546 .sh_size = sizeof(struct DebugInfo),
4548 [3] = { /* .debug_abbrev */
4549 .sh_type = SHT_PROGBITS,
4550 .sh_offset = offsetof(struct ElfImage, da),
4551 .sh_size = sizeof(img->da),
4553 [4] = { /* .debug_frame */
4554 .sh_type = SHT_PROGBITS,
4555 .sh_offset = sizeof(struct ElfImage),
4557 [5] = { /* .symtab */
4558 .sh_type = SHT_SYMTAB,
4559 .sh_offset = offsetof(struct ElfImage, sym),
4560 .sh_size = sizeof(img->sym),
4562 .sh_link = ARRAY_SIZE(img->shdr) - 1,
4563 .sh_entsize = sizeof(ElfW(Sym)),
4565 [6] = { /* .strtab */
4566 .sh_type = SHT_STRTAB,
4567 .sh_offset = offsetof(struct ElfImage, str),
4568 .sh_size = sizeof(img->str),
4572 [1] = { /* code_gen_buffer */
4573 .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
4578 .len = sizeof(struct DebugInfo) - 4,
4580 .ptr_size = sizeof(void *),
4582 .cu_lang = 0x8001, /* DW_LANG_Mips_Assembler */
4584 .fn_name = "code_gen_buffer"
4587 1, /* abbrev number (the cu) */
4588 0x11, 1, /* DW_TAG_compile_unit, has children */
4589 0x13, 0x5, /* DW_AT_language, DW_FORM_data2 */
4590 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
4591 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
4592 0, 0, /* end of abbrev */
4593 2, /* abbrev number (the fn) */
4594 0x2e, 0, /* DW_TAG_subprogram, no children */
4595 0x3, 0x8, /* DW_AT_name, DW_FORM_string */
4596 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
4597 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
4598 0, 0, /* end of abbrev */
4599 0 /* no more abbrev */
4601 .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
4602 ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
4605 /* We only need a single jit entry; statically allocate it. */
4606 static struct jit_code_entry one_entry;
4608 uintptr_t buf = (uintptr_t)buf_ptr;
4609 size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
4610 DebugFrameHeader *dfh;
4612 img = g_malloc(img_size);
4613 *img = img_template;
4615 img->phdr.p_vaddr = buf;
4616 img->phdr.p_paddr = buf;
4617 img->phdr.p_memsz = buf_size;
4619 img->shdr[1].sh_name = find_string(img->str, ".text");
4620 img->shdr[1].sh_addr = buf;
4621 img->shdr[1].sh_size = buf_size;
4623 img->shdr[2].sh_name = find_string(img->str, ".debug_info");
4624 img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
4626 img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
4627 img->shdr[4].sh_size = debug_frame_size;
4629 img->shdr[5].sh_name = find_string(img->str, ".symtab");
4630 img->shdr[6].sh_name = find_string(img->str, ".strtab");
4632 img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
4633 img->sym[1].st_value = buf;
4634 img->sym[1].st_size = buf_size;
4636 img->di.cu_low_pc = buf;
4637 img->di.cu_high_pc = buf + buf_size;
4638 img->di.fn_low_pc = buf;
4639 img->di.fn_high_pc = buf + buf_size;
4641 dfh = (DebugFrameHeader *)(img + 1);
4642 memcpy(dfh, debug_frame, debug_frame_size);
4643 dfh->fde.func_start = buf;
4644 dfh->fde.func_len = buf_size;
4647 /* Enable this block to be able to debug the ELF image file creation.
4648 One can use readelf, objdump, or other inspection utilities. */
4650 FILE *f = fopen("/tmp/qemu.jit", "w+b");
4652 if (fwrite(img, img_size, 1, f) != img_size) {
4653 /* Avoid stupid unused return value warning for fwrite. */
4660 one_entry.symfile_addr = img;
4661 one_entry.symfile_size = img_size;
4663 __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
4664 __jit_debug_descriptor.relevant_entry = &one_entry;
4665 __jit_debug_descriptor.first_entry = &one_entry;
4666 __jit_debug_register_code();
4669 /* No support for the feature. Provide the entry point expected by exec.c,
4670 and implement the internal function we declared earlier. */
4672 static void tcg_register_jit_int(void *buf, size_t size,
4673 const void *debug_frame,
4674 size_t debug_frame_size)
4678 void tcg_register_jit(void *buf, size_t buf_size)
4681 #endif /* ELF_HOST_MACHINE */
4683 #if !TCG_TARGET_MAYBE_vec
4684 void tcg_expand_vec_op(TCGOpcode o, TCGType t, unsigned e, TCGArg a0, ...)
4686 g_assert_not_reached();