tcg: Define tcg_insn_unit for code pointers
[qemu/ar7.git] / tcg / tcg.c
blob0b0be454df8b13aeafa6cc6107ae0703442df3d4
1 /*
2 * Tiny Code Generator for QEMU
4 * Copyright (c) 2008 Fabrice Bellard
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
25 /* define it to use liveness analysis (better code) */
26 #define USE_LIVENESS_ANALYSIS
27 #define USE_TCG_OPTIMIZATIONS
29 #include "config.h"
31 /* Define to jump the ELF file used to communicate with GDB. */
32 #undef DEBUG_JIT
34 #if !defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG)
35 /* define it to suppress various consistency checks (faster) */
36 #define NDEBUG
37 #endif
39 #include "qemu-common.h"
40 #include "qemu/cache-utils.h"
41 #include "qemu/host-utils.h"
42 #include "qemu/timer.h"
44 /* Note: the long term plan is to reduce the dependencies on the QEMU
45 CPU definitions. Currently they are used for qemu_ld/st
46 instructions */
47 #define NO_CPU_IO_DEFS
48 #include "cpu.h"
50 #include "tcg-op.h"
52 #if UINTPTR_MAX == UINT32_MAX
53 # define ELF_CLASS ELFCLASS32
54 #else
55 # define ELF_CLASS ELFCLASS64
56 #endif
57 #ifdef HOST_WORDS_BIGENDIAN
58 # define ELF_DATA ELFDATA2MSB
59 #else
60 # define ELF_DATA ELFDATA2LSB
61 #endif
63 #include "elf.h"
65 /* Forward declarations for functions declared in tcg-target.c and used here. */
66 static void tcg_target_init(TCGContext *s);
67 static void tcg_target_qemu_prologue(TCGContext *s);
68 static void patch_reloc(tcg_insn_unit *code_ptr, int type,
69 intptr_t value, intptr_t addend);
71 /* The CIE and FDE header definitions will be common to all hosts. */
72 typedef struct {
73 uint32_t len __attribute__((aligned((sizeof(void *)))));
74 uint32_t id;
75 uint8_t version;
76 char augmentation[1];
77 uint8_t code_align;
78 uint8_t data_align;
79 uint8_t return_column;
80 } DebugFrameCIE;
82 typedef struct QEMU_PACKED {
83 uint32_t len __attribute__((aligned((sizeof(void *)))));
84 uint32_t cie_offset;
85 uintptr_t func_start;
86 uintptr_t func_len;
87 } DebugFrameFDEHeader;
89 static void tcg_register_jit_int(void *buf, size_t size,
90 void *debug_frame, size_t debug_frame_size)
91 __attribute__((unused));
93 /* Forward declarations for functions declared and used in tcg-target.c. */
94 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str);
95 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
96 intptr_t arg2);
97 static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
98 static void tcg_out_movi(TCGContext *s, TCGType type,
99 TCGReg ret, tcg_target_long arg);
100 static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
101 const int *const_args);
102 static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
103 intptr_t arg2);
104 static int tcg_target_const_match(tcg_target_long val, TCGType type,
105 const TCGArgConstraint *arg_ct);
106 static void tcg_out_tb_init(TCGContext *s);
107 static void tcg_out_tb_finalize(TCGContext *s);
110 TCGOpDef tcg_op_defs[] = {
111 #define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags },
112 #include "tcg-opc.h"
113 #undef DEF
115 const size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs);
117 static TCGRegSet tcg_target_available_regs[2];
118 static TCGRegSet tcg_target_call_clobber_regs;
120 #if TCG_TARGET_INSN_UNIT_SIZE == 1
121 static inline void tcg_out8(TCGContext *s, uint8_t v)
123 *s->code_ptr++ = v;
126 static inline void tcg_patch8(tcg_insn_unit *p, uint8_t v)
128 *p = v;
130 #endif
132 #if TCG_TARGET_INSN_UNIT_SIZE <= 2
133 static inline void tcg_out16(TCGContext *s, uint16_t v)
135 if (TCG_TARGET_INSN_UNIT_SIZE == 2) {
136 *s->code_ptr++ = v;
137 } else {
138 tcg_insn_unit *p = s->code_ptr;
139 memcpy(p, &v, sizeof(v));
140 s->code_ptr = p + (2 / TCG_TARGET_INSN_UNIT_SIZE);
144 static inline void tcg_patch16(tcg_insn_unit *p, uint16_t v)
146 if (TCG_TARGET_INSN_UNIT_SIZE == 2) {
147 *p = v;
148 } else {
149 memcpy(p, &v, sizeof(v));
152 #endif
154 #if TCG_TARGET_INSN_UNIT_SIZE <= 4
155 static inline void tcg_out32(TCGContext *s, uint32_t v)
157 if (TCG_TARGET_INSN_UNIT_SIZE == 4) {
158 *s->code_ptr++ = v;
159 } else {
160 tcg_insn_unit *p = s->code_ptr;
161 memcpy(p, &v, sizeof(v));
162 s->code_ptr = p + (4 / TCG_TARGET_INSN_UNIT_SIZE);
166 static inline void tcg_patch32(tcg_insn_unit *p, uint32_t v)
168 if (TCG_TARGET_INSN_UNIT_SIZE == 4) {
169 *p = v;
170 } else {
171 memcpy(p, &v, sizeof(v));
174 #endif
176 #if TCG_TARGET_INSN_UNIT_SIZE <= 8
177 static inline void tcg_out64(TCGContext *s, uint64_t v)
179 if (TCG_TARGET_INSN_UNIT_SIZE == 8) {
180 *s->code_ptr++ = v;
181 } else {
182 tcg_insn_unit *p = s->code_ptr;
183 memcpy(p, &v, sizeof(v));
184 s->code_ptr = p + (8 / TCG_TARGET_INSN_UNIT_SIZE);
188 static inline void tcg_patch64(tcg_insn_unit *p, uint64_t v)
190 if (TCG_TARGET_INSN_UNIT_SIZE == 8) {
191 *p = v;
192 } else {
193 memcpy(p, &v, sizeof(v));
196 #endif
198 /* label relocation processing */
200 static void tcg_out_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
201 int label_index, intptr_t addend)
203 TCGLabel *l;
204 TCGRelocation *r;
206 l = &s->labels[label_index];
207 if (l->has_value) {
208 /* FIXME: This may break relocations on RISC targets that
209 modify instruction fields in place. The caller may not have
210 written the initial value. */
211 patch_reloc(code_ptr, type, l->u.value, addend);
212 } else {
213 /* add a new relocation entry */
214 r = tcg_malloc(sizeof(TCGRelocation));
215 r->type = type;
216 r->ptr = code_ptr;
217 r->addend = addend;
218 r->next = l->u.first_reloc;
219 l->u.first_reloc = r;
223 static void tcg_out_label(TCGContext *s, int label_index, tcg_insn_unit *ptr)
225 TCGLabel *l = &s->labels[label_index];
226 intptr_t value = (intptr_t)ptr;
227 TCGRelocation *r;
229 assert(!l->has_value);
231 for (r = l->u.first_reloc; r != NULL; r = r->next) {
232 patch_reloc(r->ptr, r->type, value, r->addend);
235 l->has_value = 1;
236 l->u.value_ptr = ptr;
239 int gen_new_label(void)
241 TCGContext *s = &tcg_ctx;
242 int idx;
243 TCGLabel *l;
245 if (s->nb_labels >= TCG_MAX_LABELS)
246 tcg_abort();
247 idx = s->nb_labels++;
248 l = &s->labels[idx];
249 l->has_value = 0;
250 l->u.first_reloc = NULL;
251 return idx;
254 #include "tcg-target.c"
256 /* pool based memory allocation */
257 void *tcg_malloc_internal(TCGContext *s, int size)
259 TCGPool *p;
260 int pool_size;
262 if (size > TCG_POOL_CHUNK_SIZE) {
263 /* big malloc: insert a new pool (XXX: could optimize) */
264 p = g_malloc(sizeof(TCGPool) + size);
265 p->size = size;
266 p->next = s->pool_first_large;
267 s->pool_first_large = p;
268 return p->data;
269 } else {
270 p = s->pool_current;
271 if (!p) {
272 p = s->pool_first;
273 if (!p)
274 goto new_pool;
275 } else {
276 if (!p->next) {
277 new_pool:
278 pool_size = TCG_POOL_CHUNK_SIZE;
279 p = g_malloc(sizeof(TCGPool) + pool_size);
280 p->size = pool_size;
281 p->next = NULL;
282 if (s->pool_current)
283 s->pool_current->next = p;
284 else
285 s->pool_first = p;
286 } else {
287 p = p->next;
291 s->pool_current = p;
292 s->pool_cur = p->data + size;
293 s->pool_end = p->data + p->size;
294 return p->data;
297 void tcg_pool_reset(TCGContext *s)
299 TCGPool *p, *t;
300 for (p = s->pool_first_large; p; p = t) {
301 t = p->next;
302 g_free(p);
304 s->pool_first_large = NULL;
305 s->pool_cur = s->pool_end = NULL;
306 s->pool_current = NULL;
309 #include "helper.h"
311 typedef struct TCGHelperInfo {
312 void *func;
313 const char *name;
314 } TCGHelperInfo;
316 static const TCGHelperInfo all_helpers[] = {
317 #define GEN_HELPER 2
318 #include "helper.h"
320 /* Include tcg-runtime.c functions. */
321 { tcg_helper_div_i32, "div_i32" },
322 { tcg_helper_rem_i32, "rem_i32" },
323 { tcg_helper_divu_i32, "divu_i32" },
324 { tcg_helper_remu_i32, "remu_i32" },
326 { tcg_helper_shl_i64, "shl_i64" },
327 { tcg_helper_shr_i64, "shr_i64" },
328 { tcg_helper_sar_i64, "sar_i64" },
329 { tcg_helper_div_i64, "div_i64" },
330 { tcg_helper_rem_i64, "rem_i64" },
331 { tcg_helper_divu_i64, "divu_i64" },
332 { tcg_helper_remu_i64, "remu_i64" },
333 { tcg_helper_mulsh_i64, "mulsh_i64" },
334 { tcg_helper_muluh_i64, "muluh_i64" },
337 void tcg_context_init(TCGContext *s)
339 int op, total_args, n, i;
340 TCGOpDef *def;
341 TCGArgConstraint *args_ct;
342 int *sorted_args;
343 GHashTable *helper_table;
345 memset(s, 0, sizeof(*s));
346 s->nb_globals = 0;
348 /* Count total number of arguments and allocate the corresponding
349 space */
350 total_args = 0;
351 for(op = 0; op < NB_OPS; op++) {
352 def = &tcg_op_defs[op];
353 n = def->nb_iargs + def->nb_oargs;
354 total_args += n;
357 args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args);
358 sorted_args = g_malloc(sizeof(int) * total_args);
360 for(op = 0; op < NB_OPS; op++) {
361 def = &tcg_op_defs[op];
362 def->args_ct = args_ct;
363 def->sorted_args = sorted_args;
364 n = def->nb_iargs + def->nb_oargs;
365 sorted_args += n;
366 args_ct += n;
369 /* Register helpers. */
370 /* Use g_direct_hash/equal for direct pointer comparisons on func. */
371 s->helpers = helper_table = g_hash_table_new(NULL, NULL);
373 for (i = 0; i < ARRAY_SIZE(all_helpers); ++i) {
374 g_hash_table_insert(helper_table, (gpointer)all_helpers[i].func,
375 (gpointer)all_helpers[i].name);
378 tcg_target_init(s);
381 void tcg_prologue_init(TCGContext *s)
383 /* init global prologue and epilogue */
384 s->code_buf = s->code_gen_prologue;
385 s->code_ptr = s->code_buf;
386 tcg_target_qemu_prologue(s);
387 flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);
389 #ifdef DEBUG_DISAS
390 if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
391 size_t size = tcg_current_code_size(s);
392 qemu_log("PROLOGUE: [size=%zu]\n", size);
393 log_disas(s->code_buf, size);
394 qemu_log("\n");
395 qemu_log_flush();
397 #endif
400 void tcg_set_frame(TCGContext *s, int reg, intptr_t start, intptr_t size)
402 s->frame_start = start;
403 s->frame_end = start + size;
404 s->frame_reg = reg;
407 void tcg_func_start(TCGContext *s)
409 tcg_pool_reset(s);
410 s->nb_temps = s->nb_globals;
412 /* No temps have been previously allocated for size or locality. */
413 memset(s->free_temps, 0, sizeof(s->free_temps));
415 s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
416 s->nb_labels = 0;
417 s->current_frame_offset = s->frame_start;
419 #ifdef CONFIG_DEBUG_TCG
420 s->goto_tb_issue_mask = 0;
421 #endif
423 s->gen_opc_ptr = s->gen_opc_buf;
424 s->gen_opparam_ptr = s->gen_opparam_buf;
426 s->be = tcg_malloc(sizeof(TCGBackendData));
429 static inline void tcg_temp_alloc(TCGContext *s, int n)
431 if (n > TCG_MAX_TEMPS)
432 tcg_abort();
435 static inline int tcg_global_reg_new_internal(TCGType type, int reg,
436 const char *name)
438 TCGContext *s = &tcg_ctx;
439 TCGTemp *ts;
440 int idx;
442 #if TCG_TARGET_REG_BITS == 32
443 if (type != TCG_TYPE_I32)
444 tcg_abort();
445 #endif
446 if (tcg_regset_test_reg(s->reserved_regs, reg))
447 tcg_abort();
448 idx = s->nb_globals;
449 tcg_temp_alloc(s, s->nb_globals + 1);
450 ts = &s->temps[s->nb_globals];
451 ts->base_type = type;
452 ts->type = type;
453 ts->fixed_reg = 1;
454 ts->reg = reg;
455 ts->name = name;
456 s->nb_globals++;
457 tcg_regset_set_reg(s->reserved_regs, reg);
458 return idx;
461 TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
463 int idx;
465 idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name);
466 return MAKE_TCGV_I32(idx);
469 TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
471 int idx;
473 idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);
474 return MAKE_TCGV_I64(idx);
477 static inline int tcg_global_mem_new_internal(TCGType type, int reg,
478 intptr_t offset,
479 const char *name)
481 TCGContext *s = &tcg_ctx;
482 TCGTemp *ts;
483 int idx;
485 idx = s->nb_globals;
486 #if TCG_TARGET_REG_BITS == 32
487 if (type == TCG_TYPE_I64) {
488 char buf[64];
489 tcg_temp_alloc(s, s->nb_globals + 2);
490 ts = &s->temps[s->nb_globals];
491 ts->base_type = type;
492 ts->type = TCG_TYPE_I32;
493 ts->fixed_reg = 0;
494 ts->mem_allocated = 1;
495 ts->mem_reg = reg;
496 #ifdef HOST_WORDS_BIGENDIAN
497 ts->mem_offset = offset + 4;
498 #else
499 ts->mem_offset = offset;
500 #endif
501 pstrcpy(buf, sizeof(buf), name);
502 pstrcat(buf, sizeof(buf), "_0");
503 ts->name = strdup(buf);
504 ts++;
506 ts->base_type = type;
507 ts->type = TCG_TYPE_I32;
508 ts->fixed_reg = 0;
509 ts->mem_allocated = 1;
510 ts->mem_reg = reg;
511 #ifdef HOST_WORDS_BIGENDIAN
512 ts->mem_offset = offset;
513 #else
514 ts->mem_offset = offset + 4;
515 #endif
516 pstrcpy(buf, sizeof(buf), name);
517 pstrcat(buf, sizeof(buf), "_1");
518 ts->name = strdup(buf);
520 s->nb_globals += 2;
521 } else
522 #endif
524 tcg_temp_alloc(s, s->nb_globals + 1);
525 ts = &s->temps[s->nb_globals];
526 ts->base_type = type;
527 ts->type = type;
528 ts->fixed_reg = 0;
529 ts->mem_allocated = 1;
530 ts->mem_reg = reg;
531 ts->mem_offset = offset;
532 ts->name = name;
533 s->nb_globals++;
535 return idx;
538 TCGv_i32 tcg_global_mem_new_i32(int reg, intptr_t offset, const char *name)
540 int idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
541 return MAKE_TCGV_I32(idx);
544 TCGv_i64 tcg_global_mem_new_i64(int reg, intptr_t offset, const char *name)
546 int idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
547 return MAKE_TCGV_I64(idx);
550 static inline int tcg_temp_new_internal(TCGType type, int temp_local)
552 TCGContext *s = &tcg_ctx;
553 TCGTemp *ts;
554 int idx, k;
556 k = type + (temp_local ? TCG_TYPE_COUNT : 0);
557 idx = find_first_bit(s->free_temps[k].l, TCG_MAX_TEMPS);
558 if (idx < TCG_MAX_TEMPS) {
559 /* There is already an available temp with the right type. */
560 clear_bit(idx, s->free_temps[k].l);
562 ts = &s->temps[idx];
563 ts->temp_allocated = 1;
564 assert(ts->base_type == type);
565 assert(ts->temp_local == temp_local);
566 } else {
567 idx = s->nb_temps;
568 #if TCG_TARGET_REG_BITS == 32
569 if (type == TCG_TYPE_I64) {
570 tcg_temp_alloc(s, s->nb_temps + 2);
571 ts = &s->temps[s->nb_temps];
572 ts->base_type = type;
573 ts->type = TCG_TYPE_I32;
574 ts->temp_allocated = 1;
575 ts->temp_local = temp_local;
576 ts->name = NULL;
577 ts++;
578 ts->base_type = type;
579 ts->type = TCG_TYPE_I32;
580 ts->temp_allocated = 1;
581 ts->temp_local = temp_local;
582 ts->name = NULL;
583 s->nb_temps += 2;
584 } else
585 #endif
587 tcg_temp_alloc(s, s->nb_temps + 1);
588 ts = &s->temps[s->nb_temps];
589 ts->base_type = type;
590 ts->type = type;
591 ts->temp_allocated = 1;
592 ts->temp_local = temp_local;
593 ts->name = NULL;
594 s->nb_temps++;
598 #if defined(CONFIG_DEBUG_TCG)
599 s->temps_in_use++;
600 #endif
601 return idx;
604 TCGv_i32 tcg_temp_new_internal_i32(int temp_local)
606 int idx;
608 idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
609 return MAKE_TCGV_I32(idx);
612 TCGv_i64 tcg_temp_new_internal_i64(int temp_local)
614 int idx;
616 idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
617 return MAKE_TCGV_I64(idx);
620 static void tcg_temp_free_internal(int idx)
622 TCGContext *s = &tcg_ctx;
623 TCGTemp *ts;
624 int k;
626 #if defined(CONFIG_DEBUG_TCG)
627 s->temps_in_use--;
628 if (s->temps_in_use < 0) {
629 fprintf(stderr, "More temporaries freed than allocated!\n");
631 #endif
633 assert(idx >= s->nb_globals && idx < s->nb_temps);
634 ts = &s->temps[idx];
635 assert(ts->temp_allocated != 0);
636 ts->temp_allocated = 0;
638 k = ts->base_type + (ts->temp_local ? TCG_TYPE_COUNT : 0);
639 set_bit(idx, s->free_temps[k].l);
642 void tcg_temp_free_i32(TCGv_i32 arg)
644 tcg_temp_free_internal(GET_TCGV_I32(arg));
647 void tcg_temp_free_i64(TCGv_i64 arg)
649 tcg_temp_free_internal(GET_TCGV_I64(arg));
652 TCGv_i32 tcg_const_i32(int32_t val)
654 TCGv_i32 t0;
655 t0 = tcg_temp_new_i32();
656 tcg_gen_movi_i32(t0, val);
657 return t0;
660 TCGv_i64 tcg_const_i64(int64_t val)
662 TCGv_i64 t0;
663 t0 = tcg_temp_new_i64();
664 tcg_gen_movi_i64(t0, val);
665 return t0;
668 TCGv_i32 tcg_const_local_i32(int32_t val)
670 TCGv_i32 t0;
671 t0 = tcg_temp_local_new_i32();
672 tcg_gen_movi_i32(t0, val);
673 return t0;
676 TCGv_i64 tcg_const_local_i64(int64_t val)
678 TCGv_i64 t0;
679 t0 = tcg_temp_local_new_i64();
680 tcg_gen_movi_i64(t0, val);
681 return t0;
684 #if defined(CONFIG_DEBUG_TCG)
685 void tcg_clear_temp_count(void)
687 TCGContext *s = &tcg_ctx;
688 s->temps_in_use = 0;
691 int tcg_check_temp_count(void)
693 TCGContext *s = &tcg_ctx;
694 if (s->temps_in_use) {
695 /* Clear the count so that we don't give another
696 * warning immediately next time around.
698 s->temps_in_use = 0;
699 return 1;
701 return 0;
703 #endif
705 /* Note: we convert the 64 bit args to 32 bit and do some alignment
706 and endian swap. Maybe it would be better to do the alignment
707 and endian swap in tcg_reg_alloc_call(). */
708 void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
709 int sizemask, TCGArg ret, int nargs, TCGArg *args)
711 int i;
712 int real_args;
713 int nb_rets;
714 TCGArg *nparam;
716 #if defined(__sparc__) && !defined(__arch64__) \
717 && !defined(CONFIG_TCG_INTERPRETER)
718 /* We have 64-bit values in one register, but need to pass as two
719 separate parameters. Split them. */
720 int orig_sizemask = sizemask;
721 int orig_nargs = nargs;
722 TCGv_i64 retl, reth;
724 TCGV_UNUSED_I64(retl);
725 TCGV_UNUSED_I64(reth);
726 if (sizemask != 0) {
727 TCGArg *split_args = __builtin_alloca(sizeof(TCGArg) * nargs * 2);
728 for (i = real_args = 0; i < nargs; ++i) {
729 int is_64bit = sizemask & (1 << (i+1)*2);
730 if (is_64bit) {
731 TCGv_i64 orig = MAKE_TCGV_I64(args[i]);
732 TCGv_i32 h = tcg_temp_new_i32();
733 TCGv_i32 l = tcg_temp_new_i32();
734 tcg_gen_extr_i64_i32(l, h, orig);
735 split_args[real_args++] = GET_TCGV_I32(h);
736 split_args[real_args++] = GET_TCGV_I32(l);
737 } else {
738 split_args[real_args++] = args[i];
741 nargs = real_args;
742 args = split_args;
743 sizemask = 0;
745 #elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
746 for (i = 0; i < nargs; ++i) {
747 int is_64bit = sizemask & (1 << (i+1)*2);
748 int is_signed = sizemask & (2 << (i+1)*2);
749 if (!is_64bit) {
750 TCGv_i64 temp = tcg_temp_new_i64();
751 TCGv_i64 orig = MAKE_TCGV_I64(args[i]);
752 if (is_signed) {
753 tcg_gen_ext32s_i64(temp, orig);
754 } else {
755 tcg_gen_ext32u_i64(temp, orig);
757 args[i] = GET_TCGV_I64(temp);
760 #endif /* TCG_TARGET_EXTEND_ARGS */
762 *s->gen_opc_ptr++ = INDEX_op_call;
763 nparam = s->gen_opparam_ptr++;
764 if (ret != TCG_CALL_DUMMY_ARG) {
765 #if defined(__sparc__) && !defined(__arch64__) \
766 && !defined(CONFIG_TCG_INTERPRETER)
767 if (orig_sizemask & 1) {
768 /* The 32-bit ABI is going to return the 64-bit value in
769 the %o0/%o1 register pair. Prepare for this by using
770 two return temporaries, and reassemble below. */
771 retl = tcg_temp_new_i64();
772 reth = tcg_temp_new_i64();
773 *s->gen_opparam_ptr++ = GET_TCGV_I64(reth);
774 *s->gen_opparam_ptr++ = GET_TCGV_I64(retl);
775 nb_rets = 2;
776 } else {
777 *s->gen_opparam_ptr++ = ret;
778 nb_rets = 1;
780 #else
781 if (TCG_TARGET_REG_BITS < 64 && (sizemask & 1)) {
782 #ifdef HOST_WORDS_BIGENDIAN
783 *s->gen_opparam_ptr++ = ret + 1;
784 *s->gen_opparam_ptr++ = ret;
785 #else
786 *s->gen_opparam_ptr++ = ret;
787 *s->gen_opparam_ptr++ = ret + 1;
788 #endif
789 nb_rets = 2;
790 } else {
791 *s->gen_opparam_ptr++ = ret;
792 nb_rets = 1;
794 #endif
795 } else {
796 nb_rets = 0;
798 real_args = 0;
799 for (i = 0; i < nargs; i++) {
800 #if TCG_TARGET_REG_BITS < 64
801 int is_64bit = sizemask & (1 << (i+1)*2);
802 if (is_64bit) {
803 #ifdef TCG_TARGET_CALL_ALIGN_ARGS
804 /* some targets want aligned 64 bit args */
805 if (real_args & 1) {
806 *s->gen_opparam_ptr++ = TCG_CALL_DUMMY_ARG;
807 real_args++;
809 #endif
810 /* If stack grows up, then we will be placing successive
811 arguments at lower addresses, which means we need to
812 reverse the order compared to how we would normally
813 treat either big or little-endian. For those arguments
814 that will wind up in registers, this still works for
815 HPPA (the only current STACK_GROWSUP target) since the
816 argument registers are *also* allocated in decreasing
817 order. If another such target is added, this logic may
818 have to get more complicated to differentiate between
819 stack arguments and register arguments. */
820 #if defined(HOST_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
821 *s->gen_opparam_ptr++ = args[i] + 1;
822 *s->gen_opparam_ptr++ = args[i];
823 #else
824 *s->gen_opparam_ptr++ = args[i];
825 *s->gen_opparam_ptr++ = args[i] + 1;
826 #endif
827 real_args += 2;
828 continue;
830 #endif /* TCG_TARGET_REG_BITS < 64 */
832 *s->gen_opparam_ptr++ = args[i];
833 real_args++;
835 *s->gen_opparam_ptr++ = GET_TCGV_PTR(func);
837 *s->gen_opparam_ptr++ = flags;
839 *nparam = (nb_rets << 16) | (real_args + 1);
841 /* total parameters, needed to go backward in the instruction stream */
842 *s->gen_opparam_ptr++ = 1 + nb_rets + real_args + 3;
844 #if defined(__sparc__) && !defined(__arch64__) \
845 && !defined(CONFIG_TCG_INTERPRETER)
846 /* Free all of the parts we allocated above. */
847 for (i = real_args = 0; i < orig_nargs; ++i) {
848 int is_64bit = orig_sizemask & (1 << (i+1)*2);
849 if (is_64bit) {
850 TCGv_i32 h = MAKE_TCGV_I32(args[real_args++]);
851 TCGv_i32 l = MAKE_TCGV_I32(args[real_args++]);
852 tcg_temp_free_i32(h);
853 tcg_temp_free_i32(l);
854 } else {
855 real_args++;
858 if (orig_sizemask & 1) {
859 /* The 32-bit ABI returned two 32-bit pieces. Re-assemble them.
860 Note that describing these as TCGv_i64 eliminates an unnecessary
861 zero-extension that tcg_gen_concat_i32_i64 would create. */
862 tcg_gen_concat32_i64(MAKE_TCGV_I64(ret), retl, reth);
863 tcg_temp_free_i64(retl);
864 tcg_temp_free_i64(reth);
866 #elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
867 for (i = 0; i < nargs; ++i) {
868 int is_64bit = sizemask & (1 << (i+1)*2);
869 if (!is_64bit) {
870 TCGv_i64 temp = MAKE_TCGV_I64(args[i]);
871 tcg_temp_free_i64(temp);
874 #endif /* TCG_TARGET_EXTEND_ARGS */
877 #if TCG_TARGET_REG_BITS == 32
878 void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
879 int c, int right, int arith)
881 if (c == 0) {
882 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
883 tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
884 } else if (c >= 32) {
885 c -= 32;
886 if (right) {
887 if (arith) {
888 tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
889 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
890 } else {
891 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
892 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
894 } else {
895 tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
896 tcg_gen_movi_i32(TCGV_LOW(ret), 0);
898 } else {
899 TCGv_i32 t0, t1;
901 t0 = tcg_temp_new_i32();
902 t1 = tcg_temp_new_i32();
903 if (right) {
904 tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c);
905 if (arith)
906 tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c);
907 else
908 tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c);
909 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
910 tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t0);
911 tcg_gen_mov_i32(TCGV_HIGH(ret), t1);
912 } else {
913 tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
914 /* Note: ret can be the same as arg1, so we use t1 */
915 tcg_gen_shli_i32(t1, TCGV_LOW(arg1), c);
916 tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
917 tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
918 tcg_gen_mov_i32(TCGV_LOW(ret), t1);
920 tcg_temp_free_i32(t0);
921 tcg_temp_free_i32(t1);
924 #endif
926 static inline TCGMemOp tcg_canonicalize_memop(TCGMemOp op, bool is64, bool st)
928 switch (op & MO_SIZE) {
929 case MO_8:
930 op &= ~MO_BSWAP;
931 break;
932 case MO_16:
933 break;
934 case MO_32:
935 if (!is64) {
936 op &= ~MO_SIGN;
938 break;
939 case MO_64:
940 if (!is64) {
941 tcg_abort();
943 break;
945 if (st) {
946 op &= ~MO_SIGN;
948 return op;
951 static const TCGOpcode old_ld_opc[8] = {
952 [MO_UB] = INDEX_op_qemu_ld8u,
953 [MO_SB] = INDEX_op_qemu_ld8s,
954 [MO_UW] = INDEX_op_qemu_ld16u,
955 [MO_SW] = INDEX_op_qemu_ld16s,
956 #if TCG_TARGET_REG_BITS == 32
957 [MO_UL] = INDEX_op_qemu_ld32,
958 [MO_SL] = INDEX_op_qemu_ld32,
959 #else
960 [MO_UL] = INDEX_op_qemu_ld32u,
961 [MO_SL] = INDEX_op_qemu_ld32s,
962 #endif
963 [MO_Q] = INDEX_op_qemu_ld64,
966 static const TCGOpcode old_st_opc[4] = {
967 [MO_UB] = INDEX_op_qemu_st8,
968 [MO_UW] = INDEX_op_qemu_st16,
969 [MO_UL] = INDEX_op_qemu_st32,
970 [MO_Q] = INDEX_op_qemu_st64,
973 void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop)
975 memop = tcg_canonicalize_memop(memop, 0, 0);
977 if (TCG_TARGET_HAS_new_ldst) {
978 *tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_ld_i32;
979 tcg_add_param_i32(val);
980 tcg_add_param_tl(addr);
981 *tcg_ctx.gen_opparam_ptr++ = memop;
982 *tcg_ctx.gen_opparam_ptr++ = idx;
983 return;
986 /* The old opcodes only support target-endian memory operations. */
987 assert((memop & MO_BSWAP) == MO_TE || (memop & MO_SIZE) == MO_8);
988 assert(old_ld_opc[memop & MO_SSIZE] != 0);
990 if (TCG_TARGET_REG_BITS == 32) {
991 *tcg_ctx.gen_opc_ptr++ = old_ld_opc[memop & MO_SSIZE];
992 tcg_add_param_i32(val);
993 tcg_add_param_tl(addr);
994 *tcg_ctx.gen_opparam_ptr++ = idx;
995 } else {
996 TCGv_i64 val64 = tcg_temp_new_i64();
998 *tcg_ctx.gen_opc_ptr++ = old_ld_opc[memop & MO_SSIZE];
999 tcg_add_param_i64(val64);
1000 tcg_add_param_tl(addr);
1001 *tcg_ctx.gen_opparam_ptr++ = idx;
1003 tcg_gen_trunc_i64_i32(val, val64);
1004 tcg_temp_free_i64(val64);
1008 void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop)
1010 memop = tcg_canonicalize_memop(memop, 0, 1);
1012 if (TCG_TARGET_HAS_new_ldst) {
1013 *tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_st_i32;
1014 tcg_add_param_i32(val);
1015 tcg_add_param_tl(addr);
1016 *tcg_ctx.gen_opparam_ptr++ = memop;
1017 *tcg_ctx.gen_opparam_ptr++ = idx;
1018 return;
1021 /* The old opcodes only support target-endian memory operations. */
1022 assert((memop & MO_BSWAP) == MO_TE || (memop & MO_SIZE) == MO_8);
1023 assert(old_st_opc[memop & MO_SIZE] != 0);
1025 if (TCG_TARGET_REG_BITS == 32) {
1026 *tcg_ctx.gen_opc_ptr++ = old_st_opc[memop & MO_SIZE];
1027 tcg_add_param_i32(val);
1028 tcg_add_param_tl(addr);
1029 *tcg_ctx.gen_opparam_ptr++ = idx;
1030 } else {
1031 TCGv_i64 val64 = tcg_temp_new_i64();
1033 tcg_gen_extu_i32_i64(val64, val);
1035 *tcg_ctx.gen_opc_ptr++ = old_st_opc[memop & MO_SIZE];
1036 tcg_add_param_i64(val64);
1037 tcg_add_param_tl(addr);
1038 *tcg_ctx.gen_opparam_ptr++ = idx;
1040 tcg_temp_free_i64(val64);
1044 void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop)
1046 memop = tcg_canonicalize_memop(memop, 1, 0);
1048 #if TCG_TARGET_REG_BITS == 32
1049 if ((memop & MO_SIZE) < MO_64) {
1050 tcg_gen_qemu_ld_i32(TCGV_LOW(val), addr, idx, memop);
1051 if (memop & MO_SIGN) {
1052 tcg_gen_sari_i32(TCGV_HIGH(val), TCGV_LOW(val), 31);
1053 } else {
1054 tcg_gen_movi_i32(TCGV_HIGH(val), 0);
1056 return;
1058 #endif
1060 if (TCG_TARGET_HAS_new_ldst) {
1061 *tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_ld_i64;
1062 tcg_add_param_i64(val);
1063 tcg_add_param_tl(addr);
1064 *tcg_ctx.gen_opparam_ptr++ = memop;
1065 *tcg_ctx.gen_opparam_ptr++ = idx;
1066 return;
1069 /* The old opcodes only support target-endian memory operations. */
1070 assert((memop & MO_BSWAP) == MO_TE || (memop & MO_SIZE) == MO_8);
1071 assert(old_ld_opc[memop & MO_SSIZE] != 0);
1073 *tcg_ctx.gen_opc_ptr++ = old_ld_opc[memop & MO_SSIZE];
1074 tcg_add_param_i64(val);
1075 tcg_add_param_tl(addr);
1076 *tcg_ctx.gen_opparam_ptr++ = idx;
1079 void tcg_gen_qemu_st_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop)
1081 memop = tcg_canonicalize_memop(memop, 1, 1);
1083 #if TCG_TARGET_REG_BITS == 32
1084 if ((memop & MO_SIZE) < MO_64) {
1085 tcg_gen_qemu_st_i32(TCGV_LOW(val), addr, idx, memop);
1086 return;
1088 #endif
1090 if (TCG_TARGET_HAS_new_ldst) {
1091 *tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_st_i64;
1092 tcg_add_param_i64(val);
1093 tcg_add_param_tl(addr);
1094 *tcg_ctx.gen_opparam_ptr++ = memop;
1095 *tcg_ctx.gen_opparam_ptr++ = idx;
1096 return;
1099 /* The old opcodes only support target-endian memory operations. */
1100 assert((memop & MO_BSWAP) == MO_TE || (memop & MO_SIZE) == MO_8);
1101 assert(old_st_opc[memop & MO_SIZE] != 0);
1103 *tcg_ctx.gen_opc_ptr++ = old_st_opc[memop & MO_SIZE];
1104 tcg_add_param_i64(val);
1105 tcg_add_param_tl(addr);
1106 *tcg_ctx.gen_opparam_ptr++ = idx;
1109 static void tcg_reg_alloc_start(TCGContext *s)
1111 int i;
1112 TCGTemp *ts;
1113 for(i = 0; i < s->nb_globals; i++) {
1114 ts = &s->temps[i];
1115 if (ts->fixed_reg) {
1116 ts->val_type = TEMP_VAL_REG;
1117 } else {
1118 ts->val_type = TEMP_VAL_MEM;
1121 for(i = s->nb_globals; i < s->nb_temps; i++) {
1122 ts = &s->temps[i];
1123 if (ts->temp_local) {
1124 ts->val_type = TEMP_VAL_MEM;
1125 } else {
1126 ts->val_type = TEMP_VAL_DEAD;
1128 ts->mem_allocated = 0;
1129 ts->fixed_reg = 0;
1131 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1132 s->reg_to_temp[i] = -1;
1136 static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
1137 int idx)
1139 TCGTemp *ts;
1141 assert(idx >= 0 && idx < s->nb_temps);
1142 ts = &s->temps[idx];
1143 if (idx < s->nb_globals) {
1144 pstrcpy(buf, buf_size, ts->name);
1145 } else {
1146 if (ts->temp_local)
1147 snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
1148 else
1149 snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
1151 return buf;
1154 char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg)
1156 return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg));
1159 char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg)
1161 return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg));
1164 /* Find helper name. */
1165 static inline const char *tcg_find_helper(TCGContext *s, uintptr_t val)
1167 const char *ret = NULL;
1168 if (s->helpers) {
1169 ret = g_hash_table_lookup(s->helpers, (gpointer)val);
1171 return ret;
1174 static const char * const cond_name[] =
1176 [TCG_COND_NEVER] = "never",
1177 [TCG_COND_ALWAYS] = "always",
1178 [TCG_COND_EQ] = "eq",
1179 [TCG_COND_NE] = "ne",
1180 [TCG_COND_LT] = "lt",
1181 [TCG_COND_GE] = "ge",
1182 [TCG_COND_LE] = "le",
1183 [TCG_COND_GT] = "gt",
1184 [TCG_COND_LTU] = "ltu",
1185 [TCG_COND_GEU] = "geu",
1186 [TCG_COND_LEU] = "leu",
1187 [TCG_COND_GTU] = "gtu"
1190 static const char * const ldst_name[] =
1192 [MO_UB] = "ub",
1193 [MO_SB] = "sb",
1194 [MO_LEUW] = "leuw",
1195 [MO_LESW] = "lesw",
1196 [MO_LEUL] = "leul",
1197 [MO_LESL] = "lesl",
1198 [MO_LEQ] = "leq",
1199 [MO_BEUW] = "beuw",
1200 [MO_BESW] = "besw",
1201 [MO_BEUL] = "beul",
1202 [MO_BESL] = "besl",
1203 [MO_BEQ] = "beq",
1206 void tcg_dump_ops(TCGContext *s)
1208 const uint16_t *opc_ptr;
1209 const TCGArg *args;
1210 TCGArg arg;
1211 TCGOpcode c;
1212 int i, k, nb_oargs, nb_iargs, nb_cargs, first_insn;
1213 const TCGOpDef *def;
1214 char buf[128];
1216 first_insn = 1;
1217 opc_ptr = s->gen_opc_buf;
1218 args = s->gen_opparam_buf;
1219 while (opc_ptr < s->gen_opc_ptr) {
1220 c = *opc_ptr++;
1221 def = &tcg_op_defs[c];
1222 if (c == INDEX_op_debug_insn_start) {
1223 uint64_t pc;
1224 #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
1225 pc = ((uint64_t)args[1] << 32) | args[0];
1226 #else
1227 pc = args[0];
1228 #endif
1229 if (!first_insn) {
1230 qemu_log("\n");
1232 qemu_log(" ---- 0x%" PRIx64, pc);
1233 first_insn = 0;
1234 nb_oargs = def->nb_oargs;
1235 nb_iargs = def->nb_iargs;
1236 nb_cargs = def->nb_cargs;
1237 } else if (c == INDEX_op_call) {
1238 TCGArg arg;
1240 /* variable number of arguments */
1241 arg = *args++;
1242 nb_oargs = arg >> 16;
1243 nb_iargs = arg & 0xffff;
1244 nb_cargs = def->nb_cargs;
1246 qemu_log(" %s ", def->name);
1248 /* function name */
1249 qemu_log("%s",
1250 tcg_get_arg_str_idx(s, buf, sizeof(buf),
1251 args[nb_oargs + nb_iargs - 1]));
1252 /* flags */
1253 qemu_log(",$0x%" TCG_PRIlx, args[nb_oargs + nb_iargs]);
1254 /* nb out args */
1255 qemu_log(",$%d", nb_oargs);
1256 for(i = 0; i < nb_oargs; i++) {
1257 qemu_log(",");
1258 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
1259 args[i]));
1261 for(i = 0; i < (nb_iargs - 1); i++) {
1262 qemu_log(",");
1263 if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) {
1264 qemu_log("<dummy>");
1265 } else {
1266 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
1267 args[nb_oargs + i]));
1270 } else if (c == INDEX_op_movi_i32 || c == INDEX_op_movi_i64) {
1271 tcg_target_ulong val;
1272 const char *name;
1274 nb_oargs = def->nb_oargs;
1275 nb_iargs = def->nb_iargs;
1276 nb_cargs = def->nb_cargs;
1277 qemu_log(" %s %s,$", def->name,
1278 tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
1279 val = args[1];
1280 name = tcg_find_helper(s, val);
1281 if (name) {
1282 qemu_log("%s", name);
1283 } else {
1284 if (c == INDEX_op_movi_i32) {
1285 qemu_log("0x%x", (uint32_t)val);
1286 } else {
1287 qemu_log("0x%" PRIx64 , (uint64_t)val);
1290 } else {
1291 qemu_log(" %s ", def->name);
1292 if (c == INDEX_op_nopn) {
1293 /* variable number of arguments */
1294 nb_cargs = *args;
1295 nb_oargs = 0;
1296 nb_iargs = 0;
1297 } else {
1298 nb_oargs = def->nb_oargs;
1299 nb_iargs = def->nb_iargs;
1300 nb_cargs = def->nb_cargs;
1303 k = 0;
1304 for(i = 0; i < nb_oargs; i++) {
1305 if (k != 0) {
1306 qemu_log(",");
1308 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
1309 args[k++]));
1311 for(i = 0; i < nb_iargs; i++) {
1312 if (k != 0) {
1313 qemu_log(",");
1315 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
1316 args[k++]));
1318 switch (c) {
1319 case INDEX_op_brcond_i32:
1320 case INDEX_op_setcond_i32:
1321 case INDEX_op_movcond_i32:
1322 case INDEX_op_brcond2_i32:
1323 case INDEX_op_setcond2_i32:
1324 case INDEX_op_brcond_i64:
1325 case INDEX_op_setcond_i64:
1326 case INDEX_op_movcond_i64:
1327 if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) {
1328 qemu_log(",%s", cond_name[args[k++]]);
1329 } else {
1330 qemu_log(",$0x%" TCG_PRIlx, args[k++]);
1332 i = 1;
1333 break;
1334 case INDEX_op_qemu_ld_i32:
1335 case INDEX_op_qemu_st_i32:
1336 case INDEX_op_qemu_ld_i64:
1337 case INDEX_op_qemu_st_i64:
1338 if (args[k] < ARRAY_SIZE(ldst_name) && ldst_name[args[k]]) {
1339 qemu_log(",%s", ldst_name[args[k++]]);
1340 } else {
1341 qemu_log(",$0x%" TCG_PRIlx, args[k++]);
1343 i = 1;
1344 break;
1345 default:
1346 i = 0;
1347 break;
1349 for(; i < nb_cargs; i++) {
1350 if (k != 0) {
1351 qemu_log(",");
1353 arg = args[k++];
1354 qemu_log("$0x%" TCG_PRIlx, arg);
1357 qemu_log("\n");
1358 args += nb_iargs + nb_oargs + nb_cargs;
1362 /* we give more priority to constraints with less registers */
1363 static int get_constraint_priority(const TCGOpDef *def, int k)
1365 const TCGArgConstraint *arg_ct;
1367 int i, n;
1368 arg_ct = &def->args_ct[k];
1369 if (arg_ct->ct & TCG_CT_ALIAS) {
1370 /* an alias is equivalent to a single register */
1371 n = 1;
1372 } else {
1373 if (!(arg_ct->ct & TCG_CT_REG))
1374 return 0;
1375 n = 0;
1376 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1377 if (tcg_regset_test_reg(arg_ct->u.regs, i))
1378 n++;
1381 return TCG_TARGET_NB_REGS - n + 1;
1384 /* sort from highest priority to lowest */
1385 static void sort_constraints(TCGOpDef *def, int start, int n)
1387 int i, j, p1, p2, tmp;
1389 for(i = 0; i < n; i++)
1390 def->sorted_args[start + i] = start + i;
1391 if (n <= 1)
1392 return;
1393 for(i = 0; i < n - 1; i++) {
1394 for(j = i + 1; j < n; j++) {
1395 p1 = get_constraint_priority(def, def->sorted_args[start + i]);
1396 p2 = get_constraint_priority(def, def->sorted_args[start + j]);
1397 if (p1 < p2) {
1398 tmp = def->sorted_args[start + i];
1399 def->sorted_args[start + i] = def->sorted_args[start + j];
1400 def->sorted_args[start + j] = tmp;
1406 void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
1408 TCGOpcode op;
1409 TCGOpDef *def;
1410 const char *ct_str;
1411 int i, nb_args;
1413 for(;;) {
1414 if (tdefs->op == (TCGOpcode)-1)
1415 break;
1416 op = tdefs->op;
1417 assert((unsigned)op < NB_OPS);
1418 def = &tcg_op_defs[op];
1419 #if defined(CONFIG_DEBUG_TCG)
1420 /* Duplicate entry in op definitions? */
1421 assert(!def->used);
1422 def->used = 1;
1423 #endif
1424 nb_args = def->nb_iargs + def->nb_oargs;
1425 for(i = 0; i < nb_args; i++) {
1426 ct_str = tdefs->args_ct_str[i];
1427 /* Incomplete TCGTargetOpDef entry? */
1428 assert(ct_str != NULL);
1429 tcg_regset_clear(def->args_ct[i].u.regs);
1430 def->args_ct[i].ct = 0;
1431 if (ct_str[0] >= '0' && ct_str[0] <= '9') {
1432 int oarg;
1433 oarg = ct_str[0] - '0';
1434 assert(oarg < def->nb_oargs);
1435 assert(def->args_ct[oarg].ct & TCG_CT_REG);
1436 /* TCG_CT_ALIAS is for the output arguments. The input
1437 argument is tagged with TCG_CT_IALIAS. */
1438 def->args_ct[i] = def->args_ct[oarg];
1439 def->args_ct[oarg].ct = TCG_CT_ALIAS;
1440 def->args_ct[oarg].alias_index = i;
1441 def->args_ct[i].ct |= TCG_CT_IALIAS;
1442 def->args_ct[i].alias_index = oarg;
1443 } else {
1444 for(;;) {
1445 if (*ct_str == '\0')
1446 break;
1447 switch(*ct_str) {
1448 case 'i':
1449 def->args_ct[i].ct |= TCG_CT_CONST;
1450 ct_str++;
1451 break;
1452 default:
1453 if (target_parse_constraint(&def->args_ct[i], &ct_str) < 0) {
1454 fprintf(stderr, "Invalid constraint '%s' for arg %d of operation '%s'\n",
1455 ct_str, i, def->name);
1456 exit(1);
1463 /* TCGTargetOpDef entry with too much information? */
1464 assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL);
1466 /* sort the constraints (XXX: this is just an heuristic) */
1467 sort_constraints(def, 0, def->nb_oargs);
1468 sort_constraints(def, def->nb_oargs, def->nb_iargs);
1470 #if 0
1472 int i;
1474 printf("%s: sorted=", def->name);
1475 for(i = 0; i < def->nb_oargs + def->nb_iargs; i++)
1476 printf(" %d", def->sorted_args[i]);
1477 printf("\n");
1479 #endif
1480 tdefs++;
1483 #if defined(CONFIG_DEBUG_TCG)
1484 i = 0;
1485 for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) {
1486 const TCGOpDef *def = &tcg_op_defs[op];
1487 if (def->flags & TCG_OPF_NOT_PRESENT) {
1488 /* Wrong entry in op definitions? */
1489 if (def->used) {
1490 fprintf(stderr, "Invalid op definition for %s\n", def->name);
1491 i = 1;
1493 } else {
1494 /* Missing entry in op definitions? */
1495 if (!def->used) {
1496 fprintf(stderr, "Missing op definition for %s\n", def->name);
1497 i = 1;
1501 if (i == 1) {
1502 tcg_abort();
1504 #endif
1507 #ifdef USE_LIVENESS_ANALYSIS
1509 /* set a nop for an operation using 'nb_args' */
1510 static inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr,
1511 TCGArg *args, int nb_args)
1513 if (nb_args == 0) {
1514 *opc_ptr = INDEX_op_nop;
1515 } else {
1516 *opc_ptr = INDEX_op_nopn;
1517 args[0] = nb_args;
1518 args[nb_args - 1] = nb_args;
1522 /* liveness analysis: end of function: all temps are dead, and globals
1523 should be in memory. */
1524 static inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps,
1525 uint8_t *mem_temps)
1527 memset(dead_temps, 1, s->nb_temps);
1528 memset(mem_temps, 1, s->nb_globals);
1529 memset(mem_temps + s->nb_globals, 0, s->nb_temps - s->nb_globals);
1532 /* liveness analysis: end of basic block: all temps are dead, globals
1533 and local temps should be in memory. */
1534 static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps,
1535 uint8_t *mem_temps)
1537 int i;
1539 memset(dead_temps, 1, s->nb_temps);
1540 memset(mem_temps, 1, s->nb_globals);
1541 for(i = s->nb_globals; i < s->nb_temps; i++) {
1542 mem_temps[i] = s->temps[i].temp_local;
1546 /* Liveness analysis : update the opc_dead_args array to tell if a
1547 given input arguments is dead. Instructions updating dead
1548 temporaries are removed. */
1549 static void tcg_liveness_analysis(TCGContext *s)
1551 int i, op_index, nb_args, nb_iargs, nb_oargs, arg, nb_ops;
1552 TCGOpcode op, op_new, op_new2;
1553 TCGArg *args;
1554 const TCGOpDef *def;
1555 uint8_t *dead_temps, *mem_temps;
1556 uint16_t dead_args;
1557 uint8_t sync_args;
1558 bool have_op_new2;
1560 s->gen_opc_ptr++; /* skip end */
1562 nb_ops = s->gen_opc_ptr - s->gen_opc_buf;
1564 s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1565 s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
1567 dead_temps = tcg_malloc(s->nb_temps);
1568 mem_temps = tcg_malloc(s->nb_temps);
1569 tcg_la_func_end(s, dead_temps, mem_temps);
1571 args = s->gen_opparam_ptr;
1572 op_index = nb_ops - 1;
1573 while (op_index >= 0) {
1574 op = s->gen_opc_buf[op_index];
1575 def = &tcg_op_defs[op];
1576 switch(op) {
1577 case INDEX_op_call:
1579 int call_flags;
1581 nb_args = args[-1];
1582 args -= nb_args;
1583 nb_iargs = args[0] & 0xffff;
1584 nb_oargs = args[0] >> 16;
1585 args++;
1586 call_flags = args[nb_oargs + nb_iargs];
1588 /* pure functions can be removed if their result is not
1589 used */
1590 if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
1591 for(i = 0; i < nb_oargs; i++) {
1592 arg = args[i];
1593 if (!dead_temps[arg] || mem_temps[arg]) {
1594 goto do_not_remove_call;
1597 tcg_set_nop(s, s->gen_opc_buf + op_index,
1598 args - 1, nb_args);
1599 } else {
1600 do_not_remove_call:
1602 /* output args are dead */
1603 dead_args = 0;
1604 sync_args = 0;
1605 for(i = 0; i < nb_oargs; i++) {
1606 arg = args[i];
1607 if (dead_temps[arg]) {
1608 dead_args |= (1 << i);
1610 if (mem_temps[arg]) {
1611 sync_args |= (1 << i);
1613 dead_temps[arg] = 1;
1614 mem_temps[arg] = 0;
1617 if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
1618 /* globals should be synced to memory */
1619 memset(mem_temps, 1, s->nb_globals);
1621 if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
1622 TCG_CALL_NO_READ_GLOBALS))) {
1623 /* globals should go back to memory */
1624 memset(dead_temps, 1, s->nb_globals);
1627 /* input args are live */
1628 for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1629 arg = args[i];
1630 if (arg != TCG_CALL_DUMMY_ARG) {
1631 if (dead_temps[arg]) {
1632 dead_args |= (1 << i);
1634 dead_temps[arg] = 0;
1637 s->op_dead_args[op_index] = dead_args;
1638 s->op_sync_args[op_index] = sync_args;
1640 args--;
1642 break;
1643 case INDEX_op_debug_insn_start:
1644 args -= def->nb_args;
1645 break;
1646 case INDEX_op_nopn:
1647 nb_args = args[-1];
1648 args -= nb_args;
1649 break;
1650 case INDEX_op_discard:
1651 args--;
1652 /* mark the temporary as dead */
1653 dead_temps[args[0]] = 1;
1654 mem_temps[args[0]] = 0;
1655 break;
1656 case INDEX_op_end:
1657 break;
1659 case INDEX_op_add2_i32:
1660 op_new = INDEX_op_add_i32;
1661 goto do_addsub2;
1662 case INDEX_op_sub2_i32:
1663 op_new = INDEX_op_sub_i32;
1664 goto do_addsub2;
1665 case INDEX_op_add2_i64:
1666 op_new = INDEX_op_add_i64;
1667 goto do_addsub2;
1668 case INDEX_op_sub2_i64:
1669 op_new = INDEX_op_sub_i64;
1670 do_addsub2:
1671 args -= 6;
1672 nb_iargs = 4;
1673 nb_oargs = 2;
1674 /* Test if the high part of the operation is dead, but not
1675 the low part. The result can be optimized to a simple
1676 add or sub. This happens often for x86_64 guest when the
1677 cpu mode is set to 32 bit. */
1678 if (dead_temps[args[1]] && !mem_temps[args[1]]) {
1679 if (dead_temps[args[0]] && !mem_temps[args[0]]) {
1680 goto do_remove;
1682 /* Create the single operation plus nop. */
1683 s->gen_opc_buf[op_index] = op = op_new;
1684 args[1] = args[2];
1685 args[2] = args[4];
1686 assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
1687 tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 3);
1688 /* Fall through and mark the single-word operation live. */
1689 nb_iargs = 2;
1690 nb_oargs = 1;
1692 goto do_not_remove;
1694 case INDEX_op_mulu2_i32:
1695 op_new = INDEX_op_mul_i32;
1696 op_new2 = INDEX_op_muluh_i32;
1697 have_op_new2 = TCG_TARGET_HAS_muluh_i32;
1698 goto do_mul2;
1699 case INDEX_op_muls2_i32:
1700 op_new = INDEX_op_mul_i32;
1701 op_new2 = INDEX_op_mulsh_i32;
1702 have_op_new2 = TCG_TARGET_HAS_mulsh_i32;
1703 goto do_mul2;
1704 case INDEX_op_mulu2_i64:
1705 op_new = INDEX_op_mul_i64;
1706 op_new2 = INDEX_op_muluh_i64;
1707 have_op_new2 = TCG_TARGET_HAS_muluh_i64;
1708 goto do_mul2;
1709 case INDEX_op_muls2_i64:
1710 op_new = INDEX_op_mul_i64;
1711 op_new2 = INDEX_op_mulsh_i64;
1712 have_op_new2 = TCG_TARGET_HAS_mulsh_i64;
1713 goto do_mul2;
1714 do_mul2:
1715 args -= 4;
1716 nb_iargs = 2;
1717 nb_oargs = 2;
1718 if (dead_temps[args[1]] && !mem_temps[args[1]]) {
1719 if (dead_temps[args[0]] && !mem_temps[args[0]]) {
1720 /* Both parts of the operation are dead. */
1721 goto do_remove;
1723 /* The high part of the operation is dead; generate the low. */
1724 s->gen_opc_buf[op_index] = op = op_new;
1725 args[1] = args[2];
1726 args[2] = args[3];
1727 } else if (have_op_new2 && dead_temps[args[0]]
1728 && !mem_temps[args[0]]) {
1729 /* The low part of the operation is dead; generate the high. */
1730 s->gen_opc_buf[op_index] = op = op_new2;
1731 args[0] = args[1];
1732 args[1] = args[2];
1733 args[2] = args[3];
1734 } else {
1735 goto do_not_remove;
1737 assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
1738 tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 1);
1739 /* Mark the single-word operation live. */
1740 nb_oargs = 1;
1741 goto do_not_remove;
1743 default:
1744 /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
1745 args -= def->nb_args;
1746 nb_iargs = def->nb_iargs;
1747 nb_oargs = def->nb_oargs;
1749 /* Test if the operation can be removed because all
1750 its outputs are dead. We assume that nb_oargs == 0
1751 implies side effects */
1752 if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
1753 for(i = 0; i < nb_oargs; i++) {
1754 arg = args[i];
1755 if (!dead_temps[arg] || mem_temps[arg]) {
1756 goto do_not_remove;
1759 do_remove:
1760 tcg_set_nop(s, s->gen_opc_buf + op_index, args, def->nb_args);
1761 #ifdef CONFIG_PROFILER
1762 s->del_op_count++;
1763 #endif
1764 } else {
1765 do_not_remove:
1767 /* output args are dead */
1768 dead_args = 0;
1769 sync_args = 0;
1770 for(i = 0; i < nb_oargs; i++) {
1771 arg = args[i];
1772 if (dead_temps[arg]) {
1773 dead_args |= (1 << i);
1775 if (mem_temps[arg]) {
1776 sync_args |= (1 << i);
1778 dead_temps[arg] = 1;
1779 mem_temps[arg] = 0;
1782 /* if end of basic block, update */
1783 if (def->flags & TCG_OPF_BB_END) {
1784 tcg_la_bb_end(s, dead_temps, mem_temps);
1785 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
1786 /* globals should be synced to memory */
1787 memset(mem_temps, 1, s->nb_globals);
1790 /* input args are live */
1791 for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1792 arg = args[i];
1793 if (dead_temps[arg]) {
1794 dead_args |= (1 << i);
1796 dead_temps[arg] = 0;
1798 s->op_dead_args[op_index] = dead_args;
1799 s->op_sync_args[op_index] = sync_args;
1801 break;
1803 op_index--;
1806 if (args != s->gen_opparam_buf) {
1807 tcg_abort();
1810 #else
1811 /* dummy liveness analysis */
1812 static void tcg_liveness_analysis(TCGContext *s)
1814 int nb_ops;
1815 nb_ops = s->gen_opc_ptr - s->gen_opc_buf;
1817 s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1818 memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
1819 s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
1820 memset(s->op_sync_args, 0, nb_ops * sizeof(uint8_t));
1822 #endif
1824 #ifndef NDEBUG
1825 static void dump_regs(TCGContext *s)
1827 TCGTemp *ts;
1828 int i;
1829 char buf[64];
1831 for(i = 0; i < s->nb_temps; i++) {
1832 ts = &s->temps[i];
1833 printf(" %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
1834 switch(ts->val_type) {
1835 case TEMP_VAL_REG:
1836 printf("%s", tcg_target_reg_names[ts->reg]);
1837 break;
1838 case TEMP_VAL_MEM:
1839 printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
1840 break;
1841 case TEMP_VAL_CONST:
1842 printf("$0x%" TCG_PRIlx, ts->val);
1843 break;
1844 case TEMP_VAL_DEAD:
1845 printf("D");
1846 break;
1847 default:
1848 printf("???");
1849 break;
1851 printf("\n");
1854 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1855 if (s->reg_to_temp[i] >= 0) {
1856 printf("%s: %s\n",
1857 tcg_target_reg_names[i],
1858 tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
1863 static void check_regs(TCGContext *s)
1865 int reg, k;
1866 TCGTemp *ts;
1867 char buf[64];
1869 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1870 k = s->reg_to_temp[reg];
1871 if (k >= 0) {
1872 ts = &s->temps[k];
1873 if (ts->val_type != TEMP_VAL_REG ||
1874 ts->reg != reg) {
1875 printf("Inconsistency for register %s:\n",
1876 tcg_target_reg_names[reg]);
1877 goto fail;
1881 for(k = 0; k < s->nb_temps; k++) {
1882 ts = &s->temps[k];
1883 if (ts->val_type == TEMP_VAL_REG &&
1884 !ts->fixed_reg &&
1885 s->reg_to_temp[ts->reg] != k) {
1886 printf("Inconsistency for temp %s:\n",
1887 tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
1888 fail:
1889 printf("reg state:\n");
1890 dump_regs(s);
1891 tcg_abort();
1895 #endif
1897 static void temp_allocate_frame(TCGContext *s, int temp)
1899 TCGTemp *ts;
1900 ts = &s->temps[temp];
1901 #if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64)
1902 /* Sparc64 stack is accessed with offset of 2047 */
1903 s->current_frame_offset = (s->current_frame_offset +
1904 (tcg_target_long)sizeof(tcg_target_long) - 1) &
1905 ~(sizeof(tcg_target_long) - 1);
1906 #endif
1907 if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
1908 s->frame_end) {
1909 tcg_abort();
1911 ts->mem_offset = s->current_frame_offset;
1912 ts->mem_reg = s->frame_reg;
1913 ts->mem_allocated = 1;
1914 s->current_frame_offset += sizeof(tcg_target_long);
1917 /* sync register 'reg' by saving it to the corresponding temporary */
1918 static inline void tcg_reg_sync(TCGContext *s, int reg)
1920 TCGTemp *ts;
1921 int temp;
1923 temp = s->reg_to_temp[reg];
1924 ts = &s->temps[temp];
1925 assert(ts->val_type == TEMP_VAL_REG);
1926 if (!ts->mem_coherent && !ts->fixed_reg) {
1927 if (!ts->mem_allocated) {
1928 temp_allocate_frame(s, temp);
1930 tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1932 ts->mem_coherent = 1;
1935 /* free register 'reg' by spilling the corresponding temporary if necessary */
1936 static void tcg_reg_free(TCGContext *s, int reg)
1938 int temp;
1940 temp = s->reg_to_temp[reg];
1941 if (temp != -1) {
1942 tcg_reg_sync(s, reg);
1943 s->temps[temp].val_type = TEMP_VAL_MEM;
1944 s->reg_to_temp[reg] = -1;
1948 /* Allocate a register belonging to reg1 & ~reg2 */
1949 static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1951 int i, reg;
1952 TCGRegSet reg_ct;
1954 tcg_regset_andnot(reg_ct, reg1, reg2);
1956 /* first try free registers */
1957 for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1958 reg = tcg_target_reg_alloc_order[i];
1959 if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
1960 return reg;
1963 /* XXX: do better spill choice */
1964 for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1965 reg = tcg_target_reg_alloc_order[i];
1966 if (tcg_regset_test_reg(reg_ct, reg)) {
1967 tcg_reg_free(s, reg);
1968 return reg;
1972 tcg_abort();
1975 /* mark a temporary as dead. */
1976 static inline void temp_dead(TCGContext *s, int temp)
1978 TCGTemp *ts;
1980 ts = &s->temps[temp];
1981 if (!ts->fixed_reg) {
1982 if (ts->val_type == TEMP_VAL_REG) {
1983 s->reg_to_temp[ts->reg] = -1;
1985 if (temp < s->nb_globals || ts->temp_local) {
1986 ts->val_type = TEMP_VAL_MEM;
1987 } else {
1988 ts->val_type = TEMP_VAL_DEAD;
1993 /* sync a temporary to memory. 'allocated_regs' is used in case a
1994 temporary registers needs to be allocated to store a constant. */
1995 static inline void temp_sync(TCGContext *s, int temp, TCGRegSet allocated_regs)
1997 TCGTemp *ts;
1999 ts = &s->temps[temp];
2000 if (!ts->fixed_reg) {
2001 switch(ts->val_type) {
2002 case TEMP_VAL_CONST:
2003 ts->reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
2004 allocated_regs);
2005 ts->val_type = TEMP_VAL_REG;
2006 s->reg_to_temp[ts->reg] = temp;
2007 ts->mem_coherent = 0;
2008 tcg_out_movi(s, ts->type, ts->reg, ts->val);
2009 /* fallthrough*/
2010 case TEMP_VAL_REG:
2011 tcg_reg_sync(s, ts->reg);
2012 break;
2013 case TEMP_VAL_DEAD:
2014 case TEMP_VAL_MEM:
2015 break;
2016 default:
2017 tcg_abort();
2022 /* save a temporary to memory. 'allocated_regs' is used in case a
2023 temporary registers needs to be allocated to store a constant. */
2024 static inline void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
2026 #ifdef USE_LIVENESS_ANALYSIS
2027 /* The liveness analysis already ensures that globals are back
2028 in memory. Keep an assert for safety. */
2029 assert(s->temps[temp].val_type == TEMP_VAL_MEM || s->temps[temp].fixed_reg);
2030 #else
2031 temp_sync(s, temp, allocated_regs);
2032 temp_dead(s, temp);
2033 #endif
2036 /* save globals to their canonical location and assume they can be
2037 modified be the following code. 'allocated_regs' is used in case a
2038 temporary registers needs to be allocated to store a constant. */
2039 static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
2041 int i;
2043 for(i = 0; i < s->nb_globals; i++) {
2044 temp_save(s, i, allocated_regs);
2048 /* sync globals to their canonical location and assume they can be
2049 read by the following code. 'allocated_regs' is used in case a
2050 temporary registers needs to be allocated to store a constant. */
2051 static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
2053 int i;
2055 for (i = 0; i < s->nb_globals; i++) {
2056 #ifdef USE_LIVENESS_ANALYSIS
2057 assert(s->temps[i].val_type != TEMP_VAL_REG || s->temps[i].fixed_reg ||
2058 s->temps[i].mem_coherent);
2059 #else
2060 temp_sync(s, i, allocated_regs);
2061 #endif
2065 /* at the end of a basic block, we assume all temporaries are dead and
2066 all globals are stored at their canonical location. */
2067 static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
2069 TCGTemp *ts;
2070 int i;
2072 for(i = s->nb_globals; i < s->nb_temps; i++) {
2073 ts = &s->temps[i];
2074 if (ts->temp_local) {
2075 temp_save(s, i, allocated_regs);
2076 } else {
2077 #ifdef USE_LIVENESS_ANALYSIS
2078 /* The liveness analysis already ensures that temps are dead.
2079 Keep an assert for safety. */
2080 assert(ts->val_type == TEMP_VAL_DEAD);
2081 #else
2082 temp_dead(s, i);
2083 #endif
2087 save_globals(s, allocated_regs);
2090 #define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
2091 #define NEED_SYNC_ARG(n) ((sync_args >> (n)) & 1)
2093 static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
2094 uint16_t dead_args, uint8_t sync_args)
2096 TCGTemp *ots;
2097 tcg_target_ulong val;
2099 ots = &s->temps[args[0]];
2100 val = args[1];
2102 if (ots->fixed_reg) {
2103 /* for fixed registers, we do not do any constant
2104 propagation */
2105 tcg_out_movi(s, ots->type, ots->reg, val);
2106 } else {
2107 /* The movi is not explicitly generated here */
2108 if (ots->val_type == TEMP_VAL_REG)
2109 s->reg_to_temp[ots->reg] = -1;
2110 ots->val_type = TEMP_VAL_CONST;
2111 ots->val = val;
2113 if (NEED_SYNC_ARG(0)) {
2114 temp_sync(s, args[0], s->reserved_regs);
2116 if (IS_DEAD_ARG(0)) {
2117 temp_dead(s, args[0]);
2121 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
2122 const TCGArg *args, uint16_t dead_args,
2123 uint8_t sync_args)
2125 TCGRegSet allocated_regs;
2126 TCGTemp *ts, *ots;
2127 const TCGArgConstraint *arg_ct, *oarg_ct;
2129 tcg_regset_set(allocated_regs, s->reserved_regs);
2130 ots = &s->temps[args[0]];
2131 ts = &s->temps[args[1]];
2132 oarg_ct = &def->args_ct[0];
2133 arg_ct = &def->args_ct[1];
2135 /* If the source value is not in a register, and we're going to be
2136 forced to have it in a register in order to perform the copy,
2137 then copy the SOURCE value into its own register first. That way
2138 we don't have to reload SOURCE the next time it is used. */
2139 if (((NEED_SYNC_ARG(0) || ots->fixed_reg) && ts->val_type != TEMP_VAL_REG)
2140 || ts->val_type == TEMP_VAL_MEM) {
2141 ts->reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2142 if (ts->val_type == TEMP_VAL_MEM) {
2143 tcg_out_ld(s, ts->type, ts->reg, ts->mem_reg, ts->mem_offset);
2144 ts->mem_coherent = 1;
2145 } else if (ts->val_type == TEMP_VAL_CONST) {
2146 tcg_out_movi(s, ts->type, ts->reg, ts->val);
2148 s->reg_to_temp[ts->reg] = args[1];
2149 ts->val_type = TEMP_VAL_REG;
2152 if (IS_DEAD_ARG(0) && !ots->fixed_reg) {
2153 /* mov to a non-saved dead register makes no sense (even with
2154 liveness analysis disabled). */
2155 assert(NEED_SYNC_ARG(0));
2156 /* The code above should have moved the temp to a register. */
2157 assert(ts->val_type == TEMP_VAL_REG);
2158 if (!ots->mem_allocated) {
2159 temp_allocate_frame(s, args[0]);
2161 tcg_out_st(s, ots->type, ts->reg, ots->mem_reg, ots->mem_offset);
2162 if (IS_DEAD_ARG(1)) {
2163 temp_dead(s, args[1]);
2165 temp_dead(s, args[0]);
2166 } else if (ts->val_type == TEMP_VAL_CONST) {
2167 /* propagate constant */
2168 if (ots->val_type == TEMP_VAL_REG) {
2169 s->reg_to_temp[ots->reg] = -1;
2171 ots->val_type = TEMP_VAL_CONST;
2172 ots->val = ts->val;
2173 } else {
2174 /* The code in the first if block should have moved the
2175 temp to a register. */
2176 assert(ts->val_type == TEMP_VAL_REG);
2177 if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
2178 /* the mov can be suppressed */
2179 if (ots->val_type == TEMP_VAL_REG) {
2180 s->reg_to_temp[ots->reg] = -1;
2182 ots->reg = ts->reg;
2183 temp_dead(s, args[1]);
2184 } else {
2185 if (ots->val_type != TEMP_VAL_REG) {
2186 /* When allocating a new register, make sure to not spill the
2187 input one. */
2188 tcg_regset_set_reg(allocated_regs, ts->reg);
2189 ots->reg = tcg_reg_alloc(s, oarg_ct->u.regs, allocated_regs);
2191 tcg_out_mov(s, ots->type, ots->reg, ts->reg);
2193 ots->val_type = TEMP_VAL_REG;
2194 ots->mem_coherent = 0;
2195 s->reg_to_temp[ots->reg] = args[0];
2196 if (NEED_SYNC_ARG(0)) {
2197 tcg_reg_sync(s, ots->reg);
2202 static void tcg_reg_alloc_op(TCGContext *s,
2203 const TCGOpDef *def, TCGOpcode opc,
2204 const TCGArg *args, uint16_t dead_args,
2205 uint8_t sync_args)
2207 TCGRegSet allocated_regs;
2208 int i, k, nb_iargs, nb_oargs, reg;
2209 TCGArg arg;
2210 const TCGArgConstraint *arg_ct;
2211 TCGTemp *ts;
2212 TCGArg new_args[TCG_MAX_OP_ARGS];
2213 int const_args[TCG_MAX_OP_ARGS];
2215 nb_oargs = def->nb_oargs;
2216 nb_iargs = def->nb_iargs;
2218 /* copy constants */
2219 memcpy(new_args + nb_oargs + nb_iargs,
2220 args + nb_oargs + nb_iargs,
2221 sizeof(TCGArg) * def->nb_cargs);
2223 /* satisfy input constraints */
2224 tcg_regset_set(allocated_regs, s->reserved_regs);
2225 for(k = 0; k < nb_iargs; k++) {
2226 i = def->sorted_args[nb_oargs + k];
2227 arg = args[i];
2228 arg_ct = &def->args_ct[i];
2229 ts = &s->temps[arg];
2230 if (ts->val_type == TEMP_VAL_MEM) {
2231 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2232 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2233 ts->val_type = TEMP_VAL_REG;
2234 ts->reg = reg;
2235 ts->mem_coherent = 1;
2236 s->reg_to_temp[reg] = arg;
2237 } else if (ts->val_type == TEMP_VAL_CONST) {
2238 if (tcg_target_const_match(ts->val, ts->type, arg_ct)) {
2239 /* constant is OK for instruction */
2240 const_args[i] = 1;
2241 new_args[i] = ts->val;
2242 goto iarg_end;
2243 } else {
2244 /* need to move to a register */
2245 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2246 tcg_out_movi(s, ts->type, reg, ts->val);
2247 ts->val_type = TEMP_VAL_REG;
2248 ts->reg = reg;
2249 ts->mem_coherent = 0;
2250 s->reg_to_temp[reg] = arg;
2253 assert(ts->val_type == TEMP_VAL_REG);
2254 if (arg_ct->ct & TCG_CT_IALIAS) {
2255 if (ts->fixed_reg) {
2256 /* if fixed register, we must allocate a new register
2257 if the alias is not the same register */
2258 if (arg != args[arg_ct->alias_index])
2259 goto allocate_in_reg;
2260 } else {
2261 /* if the input is aliased to an output and if it is
2262 not dead after the instruction, we must allocate
2263 a new register and move it */
2264 if (!IS_DEAD_ARG(i)) {
2265 goto allocate_in_reg;
2269 reg = ts->reg;
2270 if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
2271 /* nothing to do : the constraint is satisfied */
2272 } else {
2273 allocate_in_reg:
2274 /* allocate a new register matching the constraint
2275 and move the temporary register into it */
2276 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2277 tcg_out_mov(s, ts->type, reg, ts->reg);
2279 new_args[i] = reg;
2280 const_args[i] = 0;
2281 tcg_regset_set_reg(allocated_regs, reg);
2282 iarg_end: ;
2285 /* mark dead temporaries and free the associated registers */
2286 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
2287 if (IS_DEAD_ARG(i)) {
2288 temp_dead(s, args[i]);
2292 if (def->flags & TCG_OPF_BB_END) {
2293 tcg_reg_alloc_bb_end(s, allocated_regs);
2294 } else {
2295 if (def->flags & TCG_OPF_CALL_CLOBBER) {
2296 /* XXX: permit generic clobber register list ? */
2297 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
2298 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
2299 tcg_reg_free(s, reg);
2303 if (def->flags & TCG_OPF_SIDE_EFFECTS) {
2304 /* sync globals if the op has side effects and might trigger
2305 an exception. */
2306 sync_globals(s, allocated_regs);
2309 /* satisfy the output constraints */
2310 tcg_regset_set(allocated_regs, s->reserved_regs);
2311 for(k = 0; k < nb_oargs; k++) {
2312 i = def->sorted_args[k];
2313 arg = args[i];
2314 arg_ct = &def->args_ct[i];
2315 ts = &s->temps[arg];
2316 if (arg_ct->ct & TCG_CT_ALIAS) {
2317 reg = new_args[arg_ct->alias_index];
2318 } else {
2319 /* if fixed register, we try to use it */
2320 reg = ts->reg;
2321 if (ts->fixed_reg &&
2322 tcg_regset_test_reg(arg_ct->u.regs, reg)) {
2323 goto oarg_end;
2325 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2327 tcg_regset_set_reg(allocated_regs, reg);
2328 /* if a fixed register is used, then a move will be done afterwards */
2329 if (!ts->fixed_reg) {
2330 if (ts->val_type == TEMP_VAL_REG) {
2331 s->reg_to_temp[ts->reg] = -1;
2333 ts->val_type = TEMP_VAL_REG;
2334 ts->reg = reg;
2335 /* temp value is modified, so the value kept in memory is
2336 potentially not the same */
2337 ts->mem_coherent = 0;
2338 s->reg_to_temp[reg] = arg;
2340 oarg_end:
2341 new_args[i] = reg;
2345 /* emit instruction */
2346 tcg_out_op(s, opc, new_args, const_args);
2348 /* move the outputs in the correct register if needed */
2349 for(i = 0; i < nb_oargs; i++) {
2350 ts = &s->temps[args[i]];
2351 reg = new_args[i];
2352 if (ts->fixed_reg && ts->reg != reg) {
2353 tcg_out_mov(s, ts->type, ts->reg, reg);
2355 if (NEED_SYNC_ARG(i)) {
2356 tcg_reg_sync(s, reg);
2358 if (IS_DEAD_ARG(i)) {
2359 temp_dead(s, args[i]);
2364 #ifdef TCG_TARGET_STACK_GROWSUP
2365 #define STACK_DIR(x) (-(x))
2366 #else
2367 #define STACK_DIR(x) (x)
2368 #endif
2370 static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
2371 TCGOpcode opc, const TCGArg *args,
2372 uint16_t dead_args, uint8_t sync_args)
2374 int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
2375 TCGArg arg, func_arg;
2376 TCGTemp *ts;
2377 intptr_t stack_offset;
2378 size_t call_stack_size;
2379 uintptr_t func_addr;
2380 int const_func_arg, allocate_args;
2381 TCGRegSet allocated_regs;
2382 const TCGArgConstraint *arg_ct;
2384 arg = *args++;
2386 nb_oargs = arg >> 16;
2387 nb_iargs = arg & 0xffff;
2388 nb_params = nb_iargs - 1;
2390 flags = args[nb_oargs + nb_iargs];
2392 nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
2393 if (nb_regs > nb_params)
2394 nb_regs = nb_params;
2396 /* assign stack slots first */
2397 call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
2398 call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) &
2399 ~(TCG_TARGET_STACK_ALIGN - 1);
2400 allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
2401 if (allocate_args) {
2402 /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
2403 preallocate call stack */
2404 tcg_abort();
2407 stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
2408 for(i = nb_regs; i < nb_params; i++) {
2409 arg = args[nb_oargs + i];
2410 #ifdef TCG_TARGET_STACK_GROWSUP
2411 stack_offset -= sizeof(tcg_target_long);
2412 #endif
2413 if (arg != TCG_CALL_DUMMY_ARG) {
2414 ts = &s->temps[arg];
2415 if (ts->val_type == TEMP_VAL_REG) {
2416 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
2417 } else if (ts->val_type == TEMP_VAL_MEM) {
2418 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
2419 s->reserved_regs);
2420 /* XXX: not correct if reading values from the stack */
2421 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2422 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
2423 } else if (ts->val_type == TEMP_VAL_CONST) {
2424 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
2425 s->reserved_regs);
2426 /* XXX: sign extend may be needed on some targets */
2427 tcg_out_movi(s, ts->type, reg, ts->val);
2428 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
2429 } else {
2430 tcg_abort();
2433 #ifndef TCG_TARGET_STACK_GROWSUP
2434 stack_offset += sizeof(tcg_target_long);
2435 #endif
2438 /* assign input registers */
2439 tcg_regset_set(allocated_regs, s->reserved_regs);
2440 for(i = 0; i < nb_regs; i++) {
2441 arg = args[nb_oargs + i];
2442 if (arg != TCG_CALL_DUMMY_ARG) {
2443 ts = &s->temps[arg];
2444 reg = tcg_target_call_iarg_regs[i];
2445 tcg_reg_free(s, reg);
2446 if (ts->val_type == TEMP_VAL_REG) {
2447 if (ts->reg != reg) {
2448 tcg_out_mov(s, ts->type, reg, ts->reg);
2450 } else if (ts->val_type == TEMP_VAL_MEM) {
2451 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2452 } else if (ts->val_type == TEMP_VAL_CONST) {
2453 /* XXX: sign extend ? */
2454 tcg_out_movi(s, ts->type, reg, ts->val);
2455 } else {
2456 tcg_abort();
2458 tcg_regset_set_reg(allocated_regs, reg);
2462 /* assign function address */
2463 func_arg = args[nb_oargs + nb_iargs - 1];
2464 arg_ct = &def->args_ct[0];
2465 ts = &s->temps[func_arg];
2466 func_addr = ts->val;
2467 const_func_arg = 0;
2468 if (ts->val_type == TEMP_VAL_MEM) {
2469 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2470 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2471 func_arg = reg;
2472 tcg_regset_set_reg(allocated_regs, reg);
2473 } else if (ts->val_type == TEMP_VAL_REG) {
2474 reg = ts->reg;
2475 if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
2476 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2477 tcg_out_mov(s, ts->type, reg, ts->reg);
2479 func_arg = reg;
2480 tcg_regset_set_reg(allocated_regs, reg);
2481 } else if (ts->val_type == TEMP_VAL_CONST) {
2482 if (tcg_target_const_match(func_addr, ts->type, arg_ct)) {
2483 const_func_arg = 1;
2484 func_arg = func_addr;
2485 } else {
2486 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2487 tcg_out_movi(s, ts->type, reg, func_addr);
2488 func_arg = reg;
2489 tcg_regset_set_reg(allocated_regs, reg);
2491 } else {
2492 tcg_abort();
2496 /* mark dead temporaries and free the associated registers */
2497 for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
2498 if (IS_DEAD_ARG(i)) {
2499 temp_dead(s, args[i]);
2503 /* clobber call registers */
2504 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
2505 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
2506 tcg_reg_free(s, reg);
2510 /* Save globals if they might be written by the helper, sync them if
2511 they might be read. */
2512 if (flags & TCG_CALL_NO_READ_GLOBALS) {
2513 /* Nothing to do */
2514 } else if (flags & TCG_CALL_NO_WRITE_GLOBALS) {
2515 sync_globals(s, allocated_regs);
2516 } else {
2517 save_globals(s, allocated_regs);
2520 tcg_out_op(s, opc, &func_arg, &const_func_arg);
2522 /* assign output registers and emit moves if needed */
2523 for(i = 0; i < nb_oargs; i++) {
2524 arg = args[i];
2525 ts = &s->temps[arg];
2526 reg = tcg_target_call_oarg_regs[i];
2527 assert(s->reg_to_temp[reg] == -1);
2529 if (ts->fixed_reg) {
2530 if (ts->reg != reg) {
2531 tcg_out_mov(s, ts->type, ts->reg, reg);
2533 } else {
2534 if (ts->val_type == TEMP_VAL_REG) {
2535 s->reg_to_temp[ts->reg] = -1;
2537 ts->val_type = TEMP_VAL_REG;
2538 ts->reg = reg;
2539 ts->mem_coherent = 0;
2540 s->reg_to_temp[reg] = arg;
2541 if (NEED_SYNC_ARG(i)) {
2542 tcg_reg_sync(s, reg);
2544 if (IS_DEAD_ARG(i)) {
2545 temp_dead(s, args[i]);
2550 return nb_iargs + nb_oargs + def->nb_cargs + 1;
2553 #ifdef CONFIG_PROFILER
2555 static int64_t tcg_table_op_count[NB_OPS];
2557 static void dump_op_count(void)
2559 int i;
2560 FILE *f;
2561 f = fopen("/tmp/op.log", "w");
2562 for(i = INDEX_op_end; i < NB_OPS; i++) {
2563 fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
2565 fclose(f);
2567 #endif
2570 static inline int tcg_gen_code_common(TCGContext *s,
2571 tcg_insn_unit *gen_code_buf,
2572 long search_pc)
2574 TCGOpcode opc;
2575 int op_index;
2576 const TCGOpDef *def;
2577 const TCGArg *args;
2579 #ifdef DEBUG_DISAS
2580 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2581 qemu_log("OP:\n");
2582 tcg_dump_ops(s);
2583 qemu_log("\n");
2585 #endif
2587 #ifdef CONFIG_PROFILER
2588 s->opt_time -= profile_getclock();
2589 #endif
2591 #ifdef USE_TCG_OPTIMIZATIONS
2592 s->gen_opparam_ptr =
2593 tcg_optimize(s, s->gen_opc_ptr, s->gen_opparam_buf, tcg_op_defs);
2594 #endif
2596 #ifdef CONFIG_PROFILER
2597 s->opt_time += profile_getclock();
2598 s->la_time -= profile_getclock();
2599 #endif
2601 tcg_liveness_analysis(s);
2603 #ifdef CONFIG_PROFILER
2604 s->la_time += profile_getclock();
2605 #endif
2607 #ifdef DEBUG_DISAS
2608 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
2609 qemu_log("OP after optimization and liveness analysis:\n");
2610 tcg_dump_ops(s);
2611 qemu_log("\n");
2613 #endif
2615 tcg_reg_alloc_start(s);
2617 s->code_buf = gen_code_buf;
2618 s->code_ptr = gen_code_buf;
2620 tcg_out_tb_init(s);
2622 args = s->gen_opparam_buf;
2623 op_index = 0;
2625 for(;;) {
2626 opc = s->gen_opc_buf[op_index];
2627 #ifdef CONFIG_PROFILER
2628 tcg_table_op_count[opc]++;
2629 #endif
2630 def = &tcg_op_defs[opc];
2631 #if 0
2632 printf("%s: %d %d %d\n", def->name,
2633 def->nb_oargs, def->nb_iargs, def->nb_cargs);
2634 // dump_regs(s);
2635 #endif
2636 switch(opc) {
2637 case INDEX_op_mov_i32:
2638 case INDEX_op_mov_i64:
2639 tcg_reg_alloc_mov(s, def, args, s->op_dead_args[op_index],
2640 s->op_sync_args[op_index]);
2641 break;
2642 case INDEX_op_movi_i32:
2643 case INDEX_op_movi_i64:
2644 tcg_reg_alloc_movi(s, args, s->op_dead_args[op_index],
2645 s->op_sync_args[op_index]);
2646 break;
2647 case INDEX_op_debug_insn_start:
2648 /* debug instruction */
2649 break;
2650 case INDEX_op_nop:
2651 case INDEX_op_nop1:
2652 case INDEX_op_nop2:
2653 case INDEX_op_nop3:
2654 break;
2655 case INDEX_op_nopn:
2656 args += args[0];
2657 goto next;
2658 case INDEX_op_discard:
2659 temp_dead(s, args[0]);
2660 break;
2661 case INDEX_op_set_label:
2662 tcg_reg_alloc_bb_end(s, s->reserved_regs);
2663 tcg_out_label(s, args[0], s->code_ptr);
2664 break;
2665 case INDEX_op_call:
2666 args += tcg_reg_alloc_call(s, def, opc, args,
2667 s->op_dead_args[op_index],
2668 s->op_sync_args[op_index]);
2669 goto next;
2670 case INDEX_op_end:
2671 goto the_end;
2672 default:
2673 /* Sanity check that we've not introduced any unhandled opcodes. */
2674 if (def->flags & TCG_OPF_NOT_PRESENT) {
2675 tcg_abort();
2677 /* Note: in order to speed up the code, it would be much
2678 faster to have specialized register allocator functions for
2679 some common argument patterns */
2680 tcg_reg_alloc_op(s, def, opc, args, s->op_dead_args[op_index],
2681 s->op_sync_args[op_index]);
2682 break;
2684 args += def->nb_args;
2685 next:
2686 if (search_pc >= 0 && search_pc < tcg_current_code_size(s)) {
2687 return op_index;
2689 op_index++;
2690 #ifndef NDEBUG
2691 check_regs(s);
2692 #endif
2694 the_end:
2695 /* Generate TB finalization at the end of block */
2696 tcg_out_tb_finalize(s);
2697 return -1;
2700 int tcg_gen_code(TCGContext *s, tcg_insn_unit *gen_code_buf)
2702 #ifdef CONFIG_PROFILER
2704 int n;
2705 n = (s->gen_opc_ptr - s->gen_opc_buf);
2706 s->op_count += n;
2707 if (n > s->op_count_max)
2708 s->op_count_max = n;
2710 s->temp_count += s->nb_temps;
2711 if (s->nb_temps > s->temp_count_max)
2712 s->temp_count_max = s->nb_temps;
2714 #endif
2716 tcg_gen_code_common(s, gen_code_buf, -1);
2718 /* flush instruction cache */
2719 flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);
2721 return tcg_current_code_size(s);
2724 /* Return the index of the micro operation such as the pc after is <
2725 offset bytes from the start of the TB. The contents of gen_code_buf must
2726 not be changed, though writing the same values is ok.
2727 Return -1 if not found. */
2728 int tcg_gen_code_search_pc(TCGContext *s, tcg_insn_unit *gen_code_buf,
2729 long offset)
2731 return tcg_gen_code_common(s, gen_code_buf, offset);
2734 #ifdef CONFIG_PROFILER
2735 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2737 TCGContext *s = &tcg_ctx;
2738 int64_t tot;
2740 tot = s->interm_time + s->code_time;
2741 cpu_fprintf(f, "JIT cycles %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2742 tot, tot / 2.4e9);
2743 cpu_fprintf(f, "translated TBs %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n",
2744 s->tb_count,
2745 s->tb_count1 - s->tb_count,
2746 s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
2747 cpu_fprintf(f, "avg ops/TB %0.1f max=%d\n",
2748 s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
2749 cpu_fprintf(f, "deleted ops/TB %0.2f\n",
2750 s->tb_count ?
2751 (double)s->del_op_count / s->tb_count : 0);
2752 cpu_fprintf(f, "avg temps/TB %0.2f max=%d\n",
2753 s->tb_count ?
2754 (double)s->temp_count / s->tb_count : 0,
2755 s->temp_count_max);
2757 cpu_fprintf(f, "cycles/op %0.1f\n",
2758 s->op_count ? (double)tot / s->op_count : 0);
2759 cpu_fprintf(f, "cycles/in byte %0.1f\n",
2760 s->code_in_len ? (double)tot / s->code_in_len : 0);
2761 cpu_fprintf(f, "cycles/out byte %0.1f\n",
2762 s->code_out_len ? (double)tot / s->code_out_len : 0);
2763 if (tot == 0)
2764 tot = 1;
2765 cpu_fprintf(f, " gen_interm time %0.1f%%\n",
2766 (double)s->interm_time / tot * 100.0);
2767 cpu_fprintf(f, " gen_code time %0.1f%%\n",
2768 (double)s->code_time / tot * 100.0);
2769 cpu_fprintf(f, "optim./code time %0.1f%%\n",
2770 (double)s->opt_time / (s->code_time ? s->code_time : 1)
2771 * 100.0);
2772 cpu_fprintf(f, "liveness/code time %0.1f%%\n",
2773 (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2774 cpu_fprintf(f, "cpu_restore count %" PRId64 "\n",
2775 s->restore_count);
2776 cpu_fprintf(f, " avg cycles %0.1f\n",
2777 s->restore_count ? (double)s->restore_time / s->restore_count : 0);
2779 dump_op_count();
2781 #else
2782 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2784 cpu_fprintf(f, "[TCG profiler not compiled]\n");
2786 #endif
2788 #ifdef ELF_HOST_MACHINE
2789 /* In order to use this feature, the backend needs to do three things:
2791 (1) Define ELF_HOST_MACHINE to indicate both what value to
2792 put into the ELF image and to indicate support for the feature.
2794 (2) Define tcg_register_jit. This should create a buffer containing
2795 the contents of a .debug_frame section that describes the post-
2796 prologue unwind info for the tcg machine.
2798 (3) Call tcg_register_jit_int, with the constructed .debug_frame.
2801 /* Begin GDB interface. THE FOLLOWING MUST MATCH GDB DOCS. */
2802 typedef enum {
2803 JIT_NOACTION = 0,
2804 JIT_REGISTER_FN,
2805 JIT_UNREGISTER_FN
2806 } jit_actions_t;
2808 struct jit_code_entry {
2809 struct jit_code_entry *next_entry;
2810 struct jit_code_entry *prev_entry;
2811 const void *symfile_addr;
2812 uint64_t symfile_size;
2815 struct jit_descriptor {
2816 uint32_t version;
2817 uint32_t action_flag;
2818 struct jit_code_entry *relevant_entry;
2819 struct jit_code_entry *first_entry;
2822 void __jit_debug_register_code(void) __attribute__((noinline));
2823 void __jit_debug_register_code(void)
2825 asm("");
2828 /* Must statically initialize the version, because GDB may check
2829 the version before we can set it. */
2830 struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
2832 /* End GDB interface. */
2834 static int find_string(const char *strtab, const char *str)
2836 const char *p = strtab + 1;
2838 while (1) {
2839 if (strcmp(p, str) == 0) {
2840 return p - strtab;
2842 p += strlen(p) + 1;
2846 static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
2847 void *debug_frame, size_t debug_frame_size)
2849 struct __attribute__((packed)) DebugInfo {
2850 uint32_t len;
2851 uint16_t version;
2852 uint32_t abbrev;
2853 uint8_t ptr_size;
2854 uint8_t cu_die;
2855 uint16_t cu_lang;
2856 uintptr_t cu_low_pc;
2857 uintptr_t cu_high_pc;
2858 uint8_t fn_die;
2859 char fn_name[16];
2860 uintptr_t fn_low_pc;
2861 uintptr_t fn_high_pc;
2862 uint8_t cu_eoc;
2865 struct ElfImage {
2866 ElfW(Ehdr) ehdr;
2867 ElfW(Phdr) phdr;
2868 ElfW(Shdr) shdr[7];
2869 ElfW(Sym) sym[2];
2870 struct DebugInfo di;
2871 uint8_t da[24];
2872 char str[80];
2875 struct ElfImage *img;
2877 static const struct ElfImage img_template = {
2878 .ehdr = {
2879 .e_ident[EI_MAG0] = ELFMAG0,
2880 .e_ident[EI_MAG1] = ELFMAG1,
2881 .e_ident[EI_MAG2] = ELFMAG2,
2882 .e_ident[EI_MAG3] = ELFMAG3,
2883 .e_ident[EI_CLASS] = ELF_CLASS,
2884 .e_ident[EI_DATA] = ELF_DATA,
2885 .e_ident[EI_VERSION] = EV_CURRENT,
2886 .e_type = ET_EXEC,
2887 .e_machine = ELF_HOST_MACHINE,
2888 .e_version = EV_CURRENT,
2889 .e_phoff = offsetof(struct ElfImage, phdr),
2890 .e_shoff = offsetof(struct ElfImage, shdr),
2891 .e_ehsize = sizeof(ElfW(Shdr)),
2892 .e_phentsize = sizeof(ElfW(Phdr)),
2893 .e_phnum = 1,
2894 .e_shentsize = sizeof(ElfW(Shdr)),
2895 .e_shnum = ARRAY_SIZE(img->shdr),
2896 .e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
2897 #ifdef ELF_HOST_FLAGS
2898 .e_flags = ELF_HOST_FLAGS,
2899 #endif
2900 #ifdef ELF_OSABI
2901 .e_ident[EI_OSABI] = ELF_OSABI,
2902 #endif
2904 .phdr = {
2905 .p_type = PT_LOAD,
2906 .p_flags = PF_X,
2908 .shdr = {
2909 [0] = { .sh_type = SHT_NULL },
2910 /* Trick: The contents of code_gen_buffer are not present in
2911 this fake ELF file; that got allocated elsewhere. Therefore
2912 we mark .text as SHT_NOBITS (similar to .bss) so that readers
2913 will not look for contents. We can record any address. */
2914 [1] = { /* .text */
2915 .sh_type = SHT_NOBITS,
2916 .sh_flags = SHF_EXECINSTR | SHF_ALLOC,
2918 [2] = { /* .debug_info */
2919 .sh_type = SHT_PROGBITS,
2920 .sh_offset = offsetof(struct ElfImage, di),
2921 .sh_size = sizeof(struct DebugInfo),
2923 [3] = { /* .debug_abbrev */
2924 .sh_type = SHT_PROGBITS,
2925 .sh_offset = offsetof(struct ElfImage, da),
2926 .sh_size = sizeof(img->da),
2928 [4] = { /* .debug_frame */
2929 .sh_type = SHT_PROGBITS,
2930 .sh_offset = sizeof(struct ElfImage),
2932 [5] = { /* .symtab */
2933 .sh_type = SHT_SYMTAB,
2934 .sh_offset = offsetof(struct ElfImage, sym),
2935 .sh_size = sizeof(img->sym),
2936 .sh_info = 1,
2937 .sh_link = ARRAY_SIZE(img->shdr) - 1,
2938 .sh_entsize = sizeof(ElfW(Sym)),
2940 [6] = { /* .strtab */
2941 .sh_type = SHT_STRTAB,
2942 .sh_offset = offsetof(struct ElfImage, str),
2943 .sh_size = sizeof(img->str),
2946 .sym = {
2947 [1] = { /* code_gen_buffer */
2948 .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
2949 .st_shndx = 1,
2952 .di = {
2953 .len = sizeof(struct DebugInfo) - 4,
2954 .version = 2,
2955 .ptr_size = sizeof(void *),
2956 .cu_die = 1,
2957 .cu_lang = 0x8001, /* DW_LANG_Mips_Assembler */
2958 .fn_die = 2,
2959 .fn_name = "code_gen_buffer"
2961 .da = {
2962 1, /* abbrev number (the cu) */
2963 0x11, 1, /* DW_TAG_compile_unit, has children */
2964 0x13, 0x5, /* DW_AT_language, DW_FORM_data2 */
2965 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
2966 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
2967 0, 0, /* end of abbrev */
2968 2, /* abbrev number (the fn) */
2969 0x2e, 0, /* DW_TAG_subprogram, no children */
2970 0x3, 0x8, /* DW_AT_name, DW_FORM_string */
2971 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
2972 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
2973 0, 0, /* end of abbrev */
2974 0 /* no more abbrev */
2976 .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
2977 ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
2980 /* We only need a single jit entry; statically allocate it. */
2981 static struct jit_code_entry one_entry;
2983 uintptr_t buf = (uintptr_t)buf_ptr;
2984 size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
2986 img = g_malloc(img_size);
2987 *img = img_template;
2988 memcpy(img + 1, debug_frame, debug_frame_size);
2990 img->phdr.p_vaddr = buf;
2991 img->phdr.p_paddr = buf;
2992 img->phdr.p_memsz = buf_size;
2994 img->shdr[1].sh_name = find_string(img->str, ".text");
2995 img->shdr[1].sh_addr = buf;
2996 img->shdr[1].sh_size = buf_size;
2998 img->shdr[2].sh_name = find_string(img->str, ".debug_info");
2999 img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
3001 img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
3002 img->shdr[4].sh_size = debug_frame_size;
3004 img->shdr[5].sh_name = find_string(img->str, ".symtab");
3005 img->shdr[6].sh_name = find_string(img->str, ".strtab");
3007 img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
3008 img->sym[1].st_value = buf;
3009 img->sym[1].st_size = buf_size;
3011 img->di.cu_low_pc = buf;
3012 img->di.cu_high_pc = buf + buf_size;
3013 img->di.fn_low_pc = buf;
3014 img->di.fn_high_pc = buf + buf_size;
3016 #ifdef DEBUG_JIT
3017 /* Enable this block to be able to debug the ELF image file creation.
3018 One can use readelf, objdump, or other inspection utilities. */
3020 FILE *f = fopen("/tmp/qemu.jit", "w+b");
3021 if (f) {
3022 if (fwrite(img, img_size, 1, f) != img_size) {
3023 /* Avoid stupid unused return value warning for fwrite. */
3025 fclose(f);
3028 #endif
3030 one_entry.symfile_addr = img;
3031 one_entry.symfile_size = img_size;
3033 __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
3034 __jit_debug_descriptor.relevant_entry = &one_entry;
3035 __jit_debug_descriptor.first_entry = &one_entry;
3036 __jit_debug_register_code();
3038 #else
3039 /* No support for the feature. Provide the entry point expected by exec.c,
3040 and implement the internal function we declared earlier. */
3042 static void tcg_register_jit_int(void *buf, size_t size,
3043 void *debug_frame, size_t debug_frame_size)
3047 void tcg_register_jit(void *buf, size_t buf_size)
3050 #endif /* ELF_HOST_MACHINE */