Merge remote-tracking branch 'qemu/master'
[qemu/ar7.git] / tcg / tcg.c
blobd68d21fff5a62b173a5fbb835b0b2d31ee2e981e
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/host-utils.h"
41 #include "qemu/timer.h"
43 /* Note: the long term plan is to reduce the dependencies on the QEMU
44 CPU definitions. Currently they are used for qemu_ld/st
45 instructions */
46 #define NO_CPU_IO_DEFS
47 #include "cpu.h"
49 #include "tcg-op.h"
51 #if UINTPTR_MAX == UINT32_MAX
52 # define ELF_CLASS ELFCLASS32
53 #else
54 # define ELF_CLASS ELFCLASS64
55 #endif
56 #ifdef HOST_WORDS_BIGENDIAN
57 # define ELF_DATA ELFDATA2MSB
58 #else
59 # define ELF_DATA ELFDATA2LSB
60 #endif
62 #include "elf.h"
64 /* Forward declarations for functions declared in tcg-target.c and used here. */
65 static void tcg_target_init(TCGContext *s);
66 static void tcg_target_qemu_prologue(TCGContext *s);
67 static void patch_reloc(tcg_insn_unit *code_ptr, int type,
68 intptr_t value, intptr_t addend);
70 /* The CIE and FDE header definitions will be common to all hosts. */
71 typedef struct {
72 uint32_t len __attribute__((aligned((sizeof(void *)))));
73 uint32_t id;
74 uint8_t version;
75 char augmentation[1];
76 uint8_t code_align;
77 uint8_t data_align;
78 uint8_t return_column;
79 } DebugFrameCIE;
81 typedef struct QEMU_PACKED {
82 uint32_t len __attribute__((aligned((sizeof(void *)))));
83 uint32_t cie_offset;
84 uintptr_t func_start;
85 uintptr_t func_len;
86 } DebugFrameFDEHeader;
88 typedef struct QEMU_PACKED {
89 DebugFrameCIE cie;
90 DebugFrameFDEHeader fde;
91 } DebugFrameHeader;
93 static void tcg_register_jit_int(void *buf, size_t size,
94 const void *debug_frame,
95 size_t debug_frame_size)
96 __attribute__((unused));
98 /* Forward declarations for functions declared and used in tcg-target.c. */
99 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str);
100 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
101 intptr_t arg2);
102 static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
103 static void tcg_out_movi(TCGContext *s, TCGType type,
104 TCGReg ret, tcg_target_long arg);
105 static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
106 const int *const_args);
107 static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
108 intptr_t arg2);
109 static void tcg_out_call(TCGContext *s, tcg_insn_unit *target);
110 static int tcg_target_const_match(tcg_target_long val, TCGType type,
111 const TCGArgConstraint *arg_ct);
112 static void tcg_out_tb_init(TCGContext *s);
113 static void tcg_out_tb_finalize(TCGContext *s);
116 /* Forward declarations for functions which may be used in tcg-target.c. */
117 static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
118 int idx);
120 TCGOpDef tcg_op_defs[] = {
121 #define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags },
122 #include "tcg-opc.h"
123 #undef DEF
125 const size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs);
127 static TCGRegSet tcg_target_available_regs[2];
128 static TCGRegSet tcg_target_call_clobber_regs;
130 #if TCG_TARGET_INSN_UNIT_SIZE == 1
131 static __attribute__((unused)) inline void tcg_out8(TCGContext *s, uint8_t v)
133 *s->code_ptr++ = v;
136 static __attribute__((unused)) inline void tcg_patch8(tcg_insn_unit *p,
137 uint8_t v)
139 *p = v;
141 #endif
143 #if TCG_TARGET_INSN_UNIT_SIZE <= 2
144 static __attribute__((unused)) inline void tcg_out16(TCGContext *s, uint16_t v)
146 if (TCG_TARGET_INSN_UNIT_SIZE == 2) {
147 *s->code_ptr++ = v;
148 } else {
149 tcg_insn_unit *p = s->code_ptr;
150 memcpy(p, &v, sizeof(v));
151 s->code_ptr = p + (2 / TCG_TARGET_INSN_UNIT_SIZE);
155 static __attribute__((unused)) inline void tcg_patch16(tcg_insn_unit *p,
156 uint16_t v)
158 if (TCG_TARGET_INSN_UNIT_SIZE == 2) {
159 *p = v;
160 } else {
161 memcpy(p, &v, sizeof(v));
164 #endif
166 #if TCG_TARGET_INSN_UNIT_SIZE <= 4
167 static __attribute__((unused)) inline void tcg_out32(TCGContext *s, uint32_t v)
169 if (TCG_TARGET_INSN_UNIT_SIZE == 4) {
170 *s->code_ptr++ = v;
171 } else {
172 tcg_insn_unit *p = s->code_ptr;
173 memcpy(p, &v, sizeof(v));
174 s->code_ptr = p + (4 / TCG_TARGET_INSN_UNIT_SIZE);
178 static __attribute__((unused)) inline void tcg_patch32(tcg_insn_unit *p,
179 uint32_t v)
181 if (TCG_TARGET_INSN_UNIT_SIZE == 4) {
182 *p = v;
183 } else {
184 memcpy(p, &v, sizeof(v));
187 #endif
189 #if TCG_TARGET_INSN_UNIT_SIZE <= 8
190 static __attribute__((unused)) inline void tcg_out64(TCGContext *s, uint64_t v)
192 if (TCG_TARGET_INSN_UNIT_SIZE == 8) {
193 *s->code_ptr++ = v;
194 } else {
195 tcg_insn_unit *p = s->code_ptr;
196 memcpy(p, &v, sizeof(v));
197 s->code_ptr = p + (8 / TCG_TARGET_INSN_UNIT_SIZE);
201 static __attribute__((unused)) inline void tcg_patch64(tcg_insn_unit *p,
202 uint64_t v)
204 if (TCG_TARGET_INSN_UNIT_SIZE == 8) {
205 *p = v;
206 } else {
207 memcpy(p, &v, sizeof(v));
210 #endif
212 /* label relocation processing */
214 static void tcg_out_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
215 int label_index, intptr_t addend)
217 TCGLabel *l;
218 TCGRelocation *r;
220 l = &s->labels[label_index];
221 if (l->has_value) {
222 /* FIXME: This may break relocations on RISC targets that
223 modify instruction fields in place. The caller may not have
224 written the initial value. */
225 patch_reloc(code_ptr, type, l->u.value, addend);
226 } else {
227 /* add a new relocation entry */
228 r = tcg_malloc(sizeof(TCGRelocation));
229 r->type = type;
230 r->ptr = code_ptr;
231 r->addend = addend;
232 r->next = l->u.first_reloc;
233 l->u.first_reloc = r;
237 static void tcg_out_label(TCGContext *s, int label_index, tcg_insn_unit *ptr)
239 TCGLabel *l = &s->labels[label_index];
240 intptr_t value = (intptr_t)ptr;
241 TCGRelocation *r;
243 assert(!l->has_value);
245 for (r = l->u.first_reloc; r != NULL; r = r->next) {
246 patch_reloc(r->ptr, r->type, value, r->addend);
249 l->has_value = 1;
250 l->u.value_ptr = ptr;
253 int gen_new_label(void)
255 TCGContext *s = &tcg_ctx;
256 int idx;
257 TCGLabel *l;
259 if (s->nb_labels >= TCG_MAX_LABELS)
260 tcg_abort();
261 idx = s->nb_labels++;
262 l = &s->labels[idx];
263 l->has_value = 0;
264 l->u.first_reloc = NULL;
265 return idx;
268 #include "tcg-target.c"
270 /* pool based memory allocation */
271 void *tcg_malloc_internal(TCGContext *s, int size)
273 TCGPool *p;
274 int pool_size;
276 if (size > TCG_POOL_CHUNK_SIZE) {
277 /* big malloc: insert a new pool (XXX: could optimize) */
278 p = g_malloc(sizeof(TCGPool) + size);
279 p->size = size;
280 p->next = s->pool_first_large;
281 s->pool_first_large = p;
282 return p->data;
283 } else {
284 p = s->pool_current;
285 if (!p) {
286 p = s->pool_first;
287 if (!p)
288 goto new_pool;
289 } else {
290 if (!p->next) {
291 new_pool:
292 pool_size = TCG_POOL_CHUNK_SIZE;
293 p = g_malloc(sizeof(TCGPool) + pool_size);
294 p->size = pool_size;
295 p->next = NULL;
296 if (s->pool_current)
297 s->pool_current->next = p;
298 else
299 s->pool_first = p;
300 } else {
301 p = p->next;
305 s->pool_current = p;
306 s->pool_cur = p->data + size;
307 s->pool_end = p->data + p->size;
308 return p->data;
311 void tcg_pool_reset(TCGContext *s)
313 TCGPool *p, *t;
314 for (p = s->pool_first_large; p; p = t) {
315 t = p->next;
316 g_free(p);
318 s->pool_first_large = NULL;
319 s->pool_cur = s->pool_end = NULL;
320 s->pool_current = NULL;
323 typedef struct TCGHelperInfo {
324 void *func;
325 const char *name;
326 unsigned flags;
327 unsigned sizemask;
328 } TCGHelperInfo;
330 #include "exec/helper-proto.h"
332 static const TCGHelperInfo all_helpers[] = {
333 #include "exec/helper-tcg.h"
336 void tcg_context_init(TCGContext *s)
338 int op, total_args, n, i;
339 TCGOpDef *def;
340 TCGArgConstraint *args_ct;
341 int *sorted_args;
342 GHashTable *helper_table;
344 memset(s, 0, sizeof(*s));
345 s->nb_globals = 0;
347 /* Count total number of arguments and allocate the corresponding
348 space */
349 total_args = 0;
350 for(op = 0; op < NB_OPS; op++) {
351 def = &tcg_op_defs[op];
352 n = def->nb_iargs + def->nb_oargs;
353 total_args += n;
356 args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args);
357 sorted_args = g_malloc(sizeof(int) * total_args);
359 for(op = 0; op < NB_OPS; op++) {
360 def = &tcg_op_defs[op];
361 def->args_ct = args_ct;
362 def->sorted_args = sorted_args;
363 n = def->nb_iargs + def->nb_oargs;
364 sorted_args += n;
365 args_ct += n;
368 /* Register helpers. */
369 /* Use g_direct_hash/equal for direct pointer comparisons on func. */
370 s->helpers = helper_table = g_hash_table_new(NULL, NULL);
372 for (i = 0; i < ARRAY_SIZE(all_helpers); ++i) {
373 g_hash_table_insert(helper_table, (gpointer)all_helpers[i].func,
374 (gpointer)&all_helpers[i]);
377 tcg_target_init(s);
380 void tcg_prologue_init(TCGContext *s)
382 /* init global prologue and epilogue */
383 s->code_buf = s->code_gen_prologue;
384 s->code_ptr = s->code_buf;
385 tcg_target_qemu_prologue(s);
386 flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);
388 #ifdef DEBUG_DISAS
389 if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
390 size_t size = tcg_current_code_size(s);
391 qemu_log("PROLOGUE: [size=%zu]\n", size);
392 log_disas(s->code_buf, size);
393 qemu_log("\n");
394 qemu_log_flush();
396 #endif
399 void tcg_set_frame(TCGContext *s, int reg, intptr_t start, intptr_t size)
401 s->frame_start = start;
402 s->frame_end = start + size;
403 s->frame_reg = reg;
406 void tcg_func_start(TCGContext *s)
408 tcg_pool_reset(s);
409 s->nb_temps = s->nb_globals;
411 /* No temps have been previously allocated for size or locality. */
412 memset(s->free_temps, 0, sizeof(s->free_temps));
414 s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
415 s->nb_labels = 0;
416 s->current_frame_offset = s->frame_start;
418 #ifdef CONFIG_DEBUG_TCG
419 s->goto_tb_issue_mask = 0;
420 #endif
422 s->gen_opc_ptr = s->gen_opc_buf;
423 s->gen_opparam_ptr = s->gen_opparam_buf;
425 s->be = tcg_malloc(sizeof(TCGBackendData));
428 static inline void tcg_temp_alloc(TCGContext *s, int n)
430 if (n > TCG_MAX_TEMPS)
431 tcg_abort();
434 static inline int tcg_global_reg_new_internal(TCGType type, int reg,
435 const char *name)
437 TCGContext *s = &tcg_ctx;
438 TCGTemp *ts;
439 int idx;
441 #if TCG_TARGET_REG_BITS == 32
442 if (type != TCG_TYPE_I32)
443 tcg_abort();
444 #endif
445 if (tcg_regset_test_reg(s->reserved_regs, reg))
446 tcg_abort();
447 idx = s->nb_globals;
448 tcg_temp_alloc(s, s->nb_globals + 1);
449 ts = &s->temps[s->nb_globals];
450 ts->base_type = type;
451 ts->type = type;
452 ts->fixed_reg = 1;
453 ts->reg = reg;
454 ts->name = name;
455 s->nb_globals++;
456 tcg_regset_set_reg(s->reserved_regs, reg);
457 return idx;
460 TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
462 int idx;
464 idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name);
465 return MAKE_TCGV_I32(idx);
468 TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
470 int idx;
472 idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);
473 return MAKE_TCGV_I64(idx);
476 static inline int tcg_global_mem_new_internal(TCGType type, int reg,
477 intptr_t offset,
478 const char *name)
480 TCGContext *s = &tcg_ctx;
481 TCGTemp *ts;
482 int idx;
484 idx = s->nb_globals;
485 #if TCG_TARGET_REG_BITS == 32
486 if (type == TCG_TYPE_I64) {
487 char buf[64];
488 tcg_temp_alloc(s, s->nb_globals + 2);
489 ts = &s->temps[s->nb_globals];
490 ts->base_type = type;
491 ts->type = TCG_TYPE_I32;
492 ts->fixed_reg = 0;
493 ts->mem_allocated = 1;
494 ts->mem_reg = reg;
495 #ifdef HOST_WORDS_BIGENDIAN
496 ts->mem_offset = offset + 4;
497 #else
498 ts->mem_offset = offset;
499 #endif
500 pstrcpy(buf, sizeof(buf), name);
501 pstrcat(buf, sizeof(buf), "_0");
502 ts->name = strdup(buf);
503 ts++;
505 ts->base_type = type;
506 ts->type = TCG_TYPE_I32;
507 ts->fixed_reg = 0;
508 ts->mem_allocated = 1;
509 ts->mem_reg = reg;
510 #ifdef HOST_WORDS_BIGENDIAN
511 ts->mem_offset = offset;
512 #else
513 ts->mem_offset = offset + 4;
514 #endif
515 pstrcpy(buf, sizeof(buf), name);
516 pstrcat(buf, sizeof(buf), "_1");
517 ts->name = strdup(buf);
519 s->nb_globals += 2;
520 } else
521 #endif
523 tcg_temp_alloc(s, s->nb_globals + 1);
524 ts = &s->temps[s->nb_globals];
525 ts->base_type = type;
526 ts->type = type;
527 ts->fixed_reg = 0;
528 ts->mem_allocated = 1;
529 ts->mem_reg = reg;
530 ts->mem_offset = offset;
531 ts->name = name;
532 s->nb_globals++;
534 return idx;
537 TCGv_i32 tcg_global_mem_new_i32(int reg, intptr_t offset, const char *name)
539 int idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
540 return MAKE_TCGV_I32(idx);
543 TCGv_i64 tcg_global_mem_new_i64(int reg, intptr_t offset, const char *name)
545 int idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
546 return MAKE_TCGV_I64(idx);
549 static inline int tcg_temp_new_internal(TCGType type, int temp_local)
551 TCGContext *s = &tcg_ctx;
552 TCGTemp *ts;
553 int idx, k;
555 k = type + (temp_local ? TCG_TYPE_COUNT : 0);
556 idx = find_first_bit(s->free_temps[k].l, TCG_MAX_TEMPS);
557 if (idx < TCG_MAX_TEMPS) {
558 /* There is already an available temp with the right type. */
559 clear_bit(idx, s->free_temps[k].l);
561 ts = &s->temps[idx];
562 ts->temp_allocated = 1;
563 assert(ts->base_type == type);
564 assert(ts->temp_local == temp_local);
565 } else {
566 idx = s->nb_temps;
567 #if TCG_TARGET_REG_BITS == 32
568 if (type == TCG_TYPE_I64) {
569 tcg_temp_alloc(s, s->nb_temps + 2);
570 ts = &s->temps[s->nb_temps];
571 ts->base_type = type;
572 ts->type = TCG_TYPE_I32;
573 ts->temp_allocated = 1;
574 ts->temp_local = temp_local;
575 ts->name = NULL;
576 ts++;
577 ts->base_type = type;
578 ts->type = TCG_TYPE_I32;
579 ts->temp_allocated = 1;
580 ts->temp_local = temp_local;
581 ts->name = NULL;
582 s->nb_temps += 2;
583 } else
584 #endif
586 tcg_temp_alloc(s, s->nb_temps + 1);
587 ts = &s->temps[s->nb_temps];
588 ts->base_type = type;
589 ts->type = type;
590 ts->temp_allocated = 1;
591 ts->temp_local = temp_local;
592 ts->name = NULL;
593 s->nb_temps++;
597 #if defined(CONFIG_DEBUG_TCG)
598 s->temps_in_use++;
599 #endif
600 return idx;
603 TCGv_i32 tcg_temp_new_internal_i32(int temp_local)
605 int idx;
607 idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
608 return MAKE_TCGV_I32(idx);
611 TCGv_i64 tcg_temp_new_internal_i64(int temp_local)
613 int idx;
615 idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
616 return MAKE_TCGV_I64(idx);
619 static void tcg_temp_free_internal(int idx)
621 TCGContext *s = &tcg_ctx;
622 TCGTemp *ts;
623 int k;
625 #if defined(CONFIG_DEBUG_TCG)
626 s->temps_in_use--;
627 if (s->temps_in_use < 0) {
628 fprintf(stderr, "More temporaries freed than allocated!\n");
630 #endif
632 assert(idx >= s->nb_globals && idx < s->nb_temps);
633 ts = &s->temps[idx];
634 assert(ts->temp_allocated != 0);
635 ts->temp_allocated = 0;
637 k = ts->base_type + (ts->temp_local ? TCG_TYPE_COUNT : 0);
638 set_bit(idx, s->free_temps[k].l);
641 void tcg_temp_free_i32(TCGv_i32 arg)
643 tcg_temp_free_internal(GET_TCGV_I32(arg));
646 void tcg_temp_free_i64(TCGv_i64 arg)
648 tcg_temp_free_internal(GET_TCGV_I64(arg));
651 TCGv_i32 tcg_const_i32(int32_t val)
653 TCGv_i32 t0;
654 t0 = tcg_temp_new_i32();
655 tcg_gen_movi_i32(t0, val);
656 return t0;
659 TCGv_i64 tcg_const_i64(int64_t val)
661 TCGv_i64 t0;
662 t0 = tcg_temp_new_i64();
663 tcg_gen_movi_i64(t0, val);
664 return t0;
667 TCGv_i32 tcg_const_local_i32(int32_t val)
669 TCGv_i32 t0;
670 t0 = tcg_temp_local_new_i32();
671 tcg_gen_movi_i32(t0, val);
672 return t0;
675 TCGv_i64 tcg_const_local_i64(int64_t val)
677 TCGv_i64 t0;
678 t0 = tcg_temp_local_new_i64();
679 tcg_gen_movi_i64(t0, val);
680 return t0;
683 #if defined(CONFIG_DEBUG_TCG)
684 void tcg_clear_temp_count(void)
686 TCGContext *s = &tcg_ctx;
687 s->temps_in_use = 0;
690 int tcg_check_temp_count(void)
692 TCGContext *s = &tcg_ctx;
693 if (s->temps_in_use) {
694 /* Clear the count so that we don't give another
695 * warning immediately next time around.
697 s->temps_in_use = 0;
698 return 1;
700 return 0;
702 #endif
704 /* Note: we convert the 64 bit args to 32 bit and do some alignment
705 and endian swap. Maybe it would be better to do the alignment
706 and endian swap in tcg_reg_alloc_call(). */
707 void tcg_gen_callN(TCGContext *s, void *func, TCGArg ret,
708 int nargs, TCGArg *args)
710 int i, real_args, nb_rets;
711 unsigned sizemask, flags;
712 TCGArg *nparam;
713 TCGHelperInfo *info;
715 info = g_hash_table_lookup(s->helpers, (gpointer)func);
716 flags = info->flags;
717 sizemask = info->sizemask;
719 #if defined(__sparc__) && !defined(__arch64__) \
720 && !defined(CONFIG_TCG_INTERPRETER)
721 /* We have 64-bit values in one register, but need to pass as two
722 separate parameters. Split them. */
723 int orig_sizemask = sizemask;
724 int orig_nargs = nargs;
725 TCGv_i64 retl, reth;
727 TCGV_UNUSED_I64(retl);
728 TCGV_UNUSED_I64(reth);
729 if (sizemask != 0) {
730 TCGArg *split_args = __builtin_alloca(sizeof(TCGArg) * nargs * 2);
731 for (i = real_args = 0; i < nargs; ++i) {
732 int is_64bit = sizemask & (1 << (i+1)*2);
733 if (is_64bit) {
734 TCGv_i64 orig = MAKE_TCGV_I64(args[i]);
735 TCGv_i32 h = tcg_temp_new_i32();
736 TCGv_i32 l = tcg_temp_new_i32();
737 tcg_gen_extr_i64_i32(l, h, orig);
738 split_args[real_args++] = GET_TCGV_I32(h);
739 split_args[real_args++] = GET_TCGV_I32(l);
740 } else {
741 split_args[real_args++] = args[i];
744 nargs = real_args;
745 args = split_args;
746 sizemask = 0;
748 #elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
749 for (i = 0; i < nargs; ++i) {
750 int is_64bit = sizemask & (1 << (i+1)*2);
751 int is_signed = sizemask & (2 << (i+1)*2);
752 if (!is_64bit) {
753 TCGv_i64 temp = tcg_temp_new_i64();
754 TCGv_i64 orig = MAKE_TCGV_I64(args[i]);
755 if (is_signed) {
756 tcg_gen_ext32s_i64(temp, orig);
757 } else {
758 tcg_gen_ext32u_i64(temp, orig);
760 args[i] = GET_TCGV_I64(temp);
763 #endif /* TCG_TARGET_EXTEND_ARGS */
765 *s->gen_opc_ptr++ = INDEX_op_call;
766 nparam = s->gen_opparam_ptr++;
767 if (ret != TCG_CALL_DUMMY_ARG) {
768 #if defined(__sparc__) && !defined(__arch64__) \
769 && !defined(CONFIG_TCG_INTERPRETER)
770 if (orig_sizemask & 1) {
771 /* The 32-bit ABI is going to return the 64-bit value in
772 the %o0/%o1 register pair. Prepare for this by using
773 two return temporaries, and reassemble below. */
774 retl = tcg_temp_new_i64();
775 reth = tcg_temp_new_i64();
776 *s->gen_opparam_ptr++ = GET_TCGV_I64(reth);
777 *s->gen_opparam_ptr++ = GET_TCGV_I64(retl);
778 nb_rets = 2;
779 } else {
780 *s->gen_opparam_ptr++ = ret;
781 nb_rets = 1;
783 #else
784 if (TCG_TARGET_REG_BITS < 64 && (sizemask & 1)) {
785 #ifdef HOST_WORDS_BIGENDIAN
786 *s->gen_opparam_ptr++ = ret + 1;
787 *s->gen_opparam_ptr++ = ret;
788 #else
789 *s->gen_opparam_ptr++ = ret;
790 *s->gen_opparam_ptr++ = ret + 1;
791 #endif
792 nb_rets = 2;
793 } else {
794 *s->gen_opparam_ptr++ = ret;
795 nb_rets = 1;
797 #endif
798 } else {
799 nb_rets = 0;
801 real_args = 0;
802 for (i = 0; i < nargs; i++) {
803 int is_64bit = sizemask & (1 << (i+1)*2);
804 if (TCG_TARGET_REG_BITS < 64 && is_64bit) {
805 #ifdef TCG_TARGET_CALL_ALIGN_ARGS
806 /* some targets want aligned 64 bit args */
807 if (real_args & 1) {
808 *s->gen_opparam_ptr++ = TCG_CALL_DUMMY_ARG;
809 real_args++;
811 #endif
812 /* If stack grows up, then we will be placing successive
813 arguments at lower addresses, which means we need to
814 reverse the order compared to how we would normally
815 treat either big or little-endian. For those arguments
816 that will wind up in registers, this still works for
817 HPPA (the only current STACK_GROWSUP target) since the
818 argument registers are *also* allocated in decreasing
819 order. If another such target is added, this logic may
820 have to get more complicated to differentiate between
821 stack arguments and register arguments. */
822 #if defined(HOST_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
823 *s->gen_opparam_ptr++ = args[i] + 1;
824 *s->gen_opparam_ptr++ = args[i];
825 #else
826 *s->gen_opparam_ptr++ = args[i];
827 *s->gen_opparam_ptr++ = args[i] + 1;
828 #endif
829 real_args += 2;
830 continue;
833 *s->gen_opparam_ptr++ = args[i];
834 real_args++;
836 *s->gen_opparam_ptr++ = (uintptr_t)func;
837 *s->gen_opparam_ptr++ = flags;
839 *nparam = (nb_rets << 16) | real_args;
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 void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop)
953 memop = tcg_canonicalize_memop(memop, 0, 0);
955 *tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_ld_i32;
956 tcg_add_param_i32(val);
957 tcg_add_param_tl(addr);
958 *tcg_ctx.gen_opparam_ptr++ = memop;
959 *tcg_ctx.gen_opparam_ptr++ = idx;
962 void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop)
964 memop = tcg_canonicalize_memop(memop, 0, 1);
966 *tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_st_i32;
967 tcg_add_param_i32(val);
968 tcg_add_param_tl(addr);
969 *tcg_ctx.gen_opparam_ptr++ = memop;
970 *tcg_ctx.gen_opparam_ptr++ = idx;
973 void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop)
975 memop = tcg_canonicalize_memop(memop, 1, 0);
977 #if TCG_TARGET_REG_BITS == 32
978 if ((memop & MO_SIZE) < MO_64) {
979 tcg_gen_qemu_ld_i32(TCGV_LOW(val), addr, idx, memop);
980 if (memop & MO_SIGN) {
981 tcg_gen_sari_i32(TCGV_HIGH(val), TCGV_LOW(val), 31);
982 } else {
983 tcg_gen_movi_i32(TCGV_HIGH(val), 0);
985 return;
987 #endif
989 *tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_ld_i64;
990 tcg_add_param_i64(val);
991 tcg_add_param_tl(addr);
992 *tcg_ctx.gen_opparam_ptr++ = memop;
993 *tcg_ctx.gen_opparam_ptr++ = idx;
996 void tcg_gen_qemu_st_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop)
998 memop = tcg_canonicalize_memop(memop, 1, 1);
1000 #if TCG_TARGET_REG_BITS == 32
1001 if ((memop & MO_SIZE) < MO_64) {
1002 tcg_gen_qemu_st_i32(TCGV_LOW(val), addr, idx, memop);
1003 return;
1005 #endif
1007 *tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_st_i64;
1008 tcg_add_param_i64(val);
1009 tcg_add_param_tl(addr);
1010 *tcg_ctx.gen_opparam_ptr++ = memop;
1011 *tcg_ctx.gen_opparam_ptr++ = idx;
1014 static void tcg_reg_alloc_start(TCGContext *s)
1016 int i;
1017 TCGTemp *ts;
1018 for(i = 0; i < s->nb_globals; i++) {
1019 ts = &s->temps[i];
1020 if (ts->fixed_reg) {
1021 ts->val_type = TEMP_VAL_REG;
1022 } else {
1023 ts->val_type = TEMP_VAL_MEM;
1026 for(i = s->nb_globals; i < s->nb_temps; i++) {
1027 ts = &s->temps[i];
1028 if (ts->temp_local) {
1029 ts->val_type = TEMP_VAL_MEM;
1030 } else {
1031 ts->val_type = TEMP_VAL_DEAD;
1033 ts->mem_allocated = 0;
1034 ts->fixed_reg = 0;
1036 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1037 s->reg_to_temp[i] = -1;
1041 static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
1042 int idx)
1044 TCGTemp *ts = NULL;
1046 assert(idx >= 0 && idx < s->nb_temps);
1047 ts = &s->temps[idx];
1048 if (idx < s->nb_globals) {
1049 pstrcpy(buf, buf_size, ts->name);
1050 } else {
1051 if (ts && ts->temp_local)
1052 snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
1053 else
1054 snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
1056 return buf;
1059 char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg)
1061 return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg));
1064 char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg)
1066 return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg));
1069 /* Find helper name. */
1070 static inline const char *tcg_find_helper(TCGContext *s, uintptr_t val)
1072 const char *ret = NULL;
1073 if (s->helpers) {
1074 TCGHelperInfo *info = g_hash_table_lookup(s->helpers, (gpointer)val);
1075 if (info) {
1076 ret = info->name;
1079 return ret;
1082 static const char * const cond_name[] =
1084 [TCG_COND_NEVER] = "never",
1085 [TCG_COND_ALWAYS] = "always",
1086 [TCG_COND_EQ] = "eq",
1087 [TCG_COND_NE] = "ne",
1088 [TCG_COND_LT] = "lt",
1089 [TCG_COND_GE] = "ge",
1090 [TCG_COND_LE] = "le",
1091 [TCG_COND_GT] = "gt",
1092 [TCG_COND_LTU] = "ltu",
1093 [TCG_COND_GEU] = "geu",
1094 [TCG_COND_LEU] = "leu",
1095 [TCG_COND_GTU] = "gtu"
1098 static const char * const ldst_name[] =
1100 [MO_UB] = "ub",
1101 [MO_SB] = "sb",
1102 [MO_LEUW] = "leuw",
1103 [MO_LESW] = "lesw",
1104 [MO_LEUL] = "leul",
1105 [MO_LESL] = "lesl",
1106 [MO_LEQ] = "leq",
1107 [MO_BEUW] = "beuw",
1108 [MO_BESW] = "besw",
1109 [MO_BEUL] = "beul",
1110 [MO_BESL] = "besl",
1111 [MO_BEQ] = "beq",
1114 void tcg_dump_ops(TCGContext *s)
1116 const uint16_t *opc_ptr;
1117 const TCGArg *args;
1118 TCGArg arg;
1119 TCGOpcode c;
1120 int i, k, nb_oargs, nb_iargs, nb_cargs, first_insn;
1121 const TCGOpDef *def;
1122 char buf[128];
1124 first_insn = 1;
1125 opc_ptr = s->gen_opc_buf;
1126 args = s->gen_opparam_buf;
1127 while (opc_ptr < s->gen_opc_ptr) {
1128 c = *opc_ptr++;
1129 def = &tcg_op_defs[c];
1130 if (c == INDEX_op_debug_insn_start) {
1131 uint64_t pc;
1132 #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
1133 pc = ((uint64_t)args[1] << 32) | args[0];
1134 #else
1135 pc = args[0];
1136 #endif
1137 if (!first_insn) {
1138 qemu_log("\n");
1140 qemu_log(" ---- 0x%" PRIx64, pc);
1141 first_insn = 0;
1142 nb_oargs = def->nb_oargs;
1143 nb_iargs = def->nb_iargs;
1144 nb_cargs = def->nb_cargs;
1145 } else if (c == INDEX_op_call) {
1146 TCGArg arg;
1148 /* variable number of arguments */
1149 arg = *args++;
1150 nb_oargs = arg >> 16;
1151 nb_iargs = arg & 0xffff;
1152 nb_cargs = def->nb_cargs;
1154 /* function name, flags, out args */
1155 qemu_log(" %s %s,$0x%" TCG_PRIlx ",$%d", def->name,
1156 tcg_find_helper(s, args[nb_oargs + nb_iargs]),
1157 args[nb_oargs + nb_iargs + 1], nb_oargs);
1158 for (i = 0; i < nb_oargs; i++) {
1159 qemu_log(",%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
1160 args[i]));
1162 for (i = 0; i < nb_iargs; i++) {
1163 TCGArg arg = args[nb_oargs + i];
1164 const char *t = "<dummy>";
1165 if (arg != TCG_CALL_DUMMY_ARG) {
1166 t = tcg_get_arg_str_idx(s, buf, sizeof(buf), arg);
1168 qemu_log(",%s", t);
1170 } else {
1171 qemu_log(" %s ", def->name);
1172 if (c == INDEX_op_nopn) {
1173 /* variable number of arguments */
1174 nb_cargs = *args;
1175 nb_oargs = 0;
1176 nb_iargs = 0;
1177 } else {
1178 nb_oargs = def->nb_oargs;
1179 nb_iargs = def->nb_iargs;
1180 nb_cargs = def->nb_cargs;
1183 k = 0;
1184 for(i = 0; i < nb_oargs; i++) {
1185 if (k != 0) {
1186 qemu_log(",");
1188 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
1189 args[k++]));
1191 for(i = 0; i < nb_iargs; i++) {
1192 if (k != 0) {
1193 qemu_log(",");
1195 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
1196 args[k++]));
1198 switch (c) {
1199 case INDEX_op_brcond_i32:
1200 case INDEX_op_setcond_i32:
1201 case INDEX_op_movcond_i32:
1202 case INDEX_op_brcond2_i32:
1203 case INDEX_op_setcond2_i32:
1204 case INDEX_op_brcond_i64:
1205 case INDEX_op_setcond_i64:
1206 case INDEX_op_movcond_i64:
1207 if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) {
1208 qemu_log(",%s", cond_name[args[k++]]);
1209 } else {
1210 qemu_log(",$0x%" TCG_PRIlx, args[k++]);
1212 i = 1;
1213 break;
1214 case INDEX_op_qemu_ld_i32:
1215 case INDEX_op_qemu_st_i32:
1216 case INDEX_op_qemu_ld_i64:
1217 case INDEX_op_qemu_st_i64:
1218 if (args[k] < ARRAY_SIZE(ldst_name) && ldst_name[args[k]]) {
1219 qemu_log(",%s", ldst_name[args[k++]]);
1220 } else {
1221 qemu_log(",$0x%" TCG_PRIlx, args[k++]);
1223 i = 1;
1224 break;
1225 default:
1226 i = 0;
1227 break;
1229 for(; i < nb_cargs; i++) {
1230 if (k != 0) {
1231 qemu_log(",");
1233 arg = args[k++];
1234 qemu_log("$0x%" TCG_PRIlx, arg);
1237 qemu_log("\n");
1238 args += nb_iargs + nb_oargs + nb_cargs;
1242 /* we give more priority to constraints with less registers */
1243 static int get_constraint_priority(const TCGOpDef *def, int k)
1245 const TCGArgConstraint *arg_ct;
1247 int i, n;
1248 arg_ct = &def->args_ct[k];
1249 if (arg_ct->ct & TCG_CT_ALIAS) {
1250 /* an alias is equivalent to a single register */
1251 n = 1;
1252 } else {
1253 if (!(arg_ct->ct & TCG_CT_REG))
1254 return 0;
1255 n = 0;
1256 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1257 if (tcg_regset_test_reg(arg_ct->u.regs, i))
1258 n++;
1261 return TCG_TARGET_NB_REGS - n + 1;
1264 /* sort from highest priority to lowest */
1265 static void sort_constraints(TCGOpDef *def, int start, int n)
1267 int i, j, p1, p2, tmp;
1269 for(i = 0; i < n; i++)
1270 def->sorted_args[start + i] = start + i;
1271 if (n <= 1)
1272 return;
1273 for(i = 0; i < n - 1; i++) {
1274 for(j = i + 1; j < n; j++) {
1275 p1 = get_constraint_priority(def, def->sorted_args[start + i]);
1276 p2 = get_constraint_priority(def, def->sorted_args[start + j]);
1277 if (p1 < p2) {
1278 tmp = def->sorted_args[start + i];
1279 def->sorted_args[start + i] = def->sorted_args[start + j];
1280 def->sorted_args[start + j] = tmp;
1286 void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
1288 TCGOpcode op;
1289 TCGOpDef *def;
1290 const char *ct_str;
1291 int i, nb_args;
1293 for(;;) {
1294 if (tdefs->op == (TCGOpcode)-1)
1295 break;
1296 op = tdefs->op;
1297 assert((unsigned)op < NB_OPS);
1298 def = &tcg_op_defs[op];
1299 #if defined(CONFIG_DEBUG_TCG)
1300 /* Duplicate entry in op definitions? */
1301 assert(!def->used);
1302 def->used = 1;
1303 #endif
1304 nb_args = def->nb_iargs + def->nb_oargs;
1305 for(i = 0; i < nb_args; i++) {
1306 ct_str = tdefs->args_ct_str[i];
1307 /* Incomplete TCGTargetOpDef entry? */
1308 assert(ct_str != NULL);
1309 tcg_regset_clear(def->args_ct[i].u.regs);
1310 def->args_ct[i].ct = 0;
1311 if (ct_str[0] >= '0' && ct_str[0] <= '9') {
1312 int oarg;
1313 oarg = ct_str[0] - '0';
1314 assert(oarg < def->nb_oargs);
1315 assert(def->args_ct[oarg].ct & TCG_CT_REG);
1316 /* TCG_CT_ALIAS is for the output arguments. The input
1317 argument is tagged with TCG_CT_IALIAS. */
1318 def->args_ct[i] = def->args_ct[oarg];
1319 def->args_ct[oarg].ct = TCG_CT_ALIAS;
1320 def->args_ct[oarg].alias_index = i;
1321 def->args_ct[i].ct |= TCG_CT_IALIAS;
1322 def->args_ct[i].alias_index = oarg;
1323 } else {
1324 for(;;) {
1325 if (*ct_str == '\0')
1326 break;
1327 switch(*ct_str) {
1328 case 'i':
1329 def->args_ct[i].ct |= TCG_CT_CONST;
1330 ct_str++;
1331 break;
1332 default:
1333 if (target_parse_constraint(&def->args_ct[i], &ct_str) < 0) {
1334 fprintf(stderr, "Invalid constraint '%s' for arg %d of operation '%s'\n",
1335 ct_str, i, def->name);
1336 exit(1);
1343 /* TCGTargetOpDef entry with too much information? */
1344 assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL);
1346 /* sort the constraints (XXX: this is just an heuristic) */
1347 sort_constraints(def, 0, def->nb_oargs);
1348 sort_constraints(def, def->nb_oargs, def->nb_iargs);
1350 #if 0
1352 int i;
1354 printf("%s: sorted=", def->name);
1355 for(i = 0; i < def->nb_oargs + def->nb_iargs; i++)
1356 printf(" %d", def->sorted_args[i]);
1357 printf("\n");
1359 #endif
1360 tdefs++;
1363 #if defined(CONFIG_DEBUG_TCG)
1364 i = 0;
1365 for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) {
1366 const TCGOpDef *def = &tcg_op_defs[op];
1367 if (def->flags & TCG_OPF_NOT_PRESENT) {
1368 /* Wrong entry in op definitions? */
1369 if (def->used) {
1370 fprintf(stderr, "Invalid op definition for %s\n", def->name);
1371 i = 1;
1373 } else {
1374 /* Missing entry in op definitions? */
1375 if (!def->used) {
1376 fprintf(stderr, "Missing op definition for %s\n", def->name);
1377 i = 1;
1381 if (i == 1) {
1382 tcg_abort();
1384 #endif
1387 #ifdef USE_LIVENESS_ANALYSIS
1389 /* set a nop for an operation using 'nb_args' */
1390 static inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr,
1391 TCGArg *args, int nb_args)
1393 if (nb_args == 0) {
1394 *opc_ptr = INDEX_op_nop;
1395 } else {
1396 *opc_ptr = INDEX_op_nopn;
1397 args[0] = nb_args;
1398 args[nb_args - 1] = nb_args;
1402 /* liveness analysis: end of function: all temps are dead, and globals
1403 should be in memory. */
1404 static inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps,
1405 uint8_t *mem_temps)
1407 memset(dead_temps, 1, s->nb_temps);
1408 memset(mem_temps, 1, s->nb_globals);
1409 memset(mem_temps + s->nb_globals, 0, s->nb_temps - s->nb_globals);
1412 /* liveness analysis: end of basic block: all temps are dead, globals
1413 and local temps should be in memory. */
1414 static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps,
1415 uint8_t *mem_temps)
1417 int i;
1419 memset(dead_temps, 1, s->nb_temps);
1420 memset(mem_temps, 1, s->nb_globals);
1421 for(i = s->nb_globals; i < s->nb_temps; i++) {
1422 mem_temps[i] = s->temps[i].temp_local;
1426 /* Liveness analysis : update the opc_dead_args array to tell if a
1427 given input arguments is dead. Instructions updating dead
1428 temporaries are removed. */
1429 static void tcg_liveness_analysis(TCGContext *s)
1431 int i, op_index, nb_args, nb_iargs, nb_oargs, nb_ops;
1432 TCGOpcode op, op_new, op_new2;
1433 TCGArg *args, arg;
1434 const TCGOpDef *def;
1435 uint8_t *dead_temps, *mem_temps;
1436 uint16_t dead_args;
1437 uint8_t sync_args;
1438 bool have_op_new2;
1440 s->gen_opc_ptr++; /* skip end */
1442 nb_ops = s->gen_opc_ptr - s->gen_opc_buf;
1444 s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1445 s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
1447 dead_temps = tcg_malloc(s->nb_temps);
1448 mem_temps = tcg_malloc(s->nb_temps);
1449 tcg_la_func_end(s, dead_temps, mem_temps);
1451 args = s->gen_opparam_ptr;
1452 op_index = nb_ops - 1;
1453 while (op_index >= 0) {
1454 op = s->gen_opc_buf[op_index];
1455 def = &tcg_op_defs[op];
1456 switch(op) {
1457 case INDEX_op_call:
1459 int call_flags;
1461 nb_args = args[-1];
1462 args -= nb_args;
1463 arg = *args++;
1464 nb_iargs = arg & 0xffff;
1465 nb_oargs = arg >> 16;
1466 call_flags = args[nb_oargs + nb_iargs + 1];
1468 /* pure functions can be removed if their result is not
1469 used */
1470 if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
1471 for (i = 0; i < nb_oargs; i++) {
1472 arg = args[i];
1473 if (!dead_temps[arg] || mem_temps[arg]) {
1474 goto do_not_remove_call;
1477 tcg_set_nop(s, s->gen_opc_buf + op_index,
1478 args - 1, nb_args);
1479 } else {
1480 do_not_remove_call:
1482 /* output args are dead */
1483 dead_args = 0;
1484 sync_args = 0;
1485 for (i = 0; i < nb_oargs; i++) {
1486 arg = args[i];
1487 if (dead_temps[arg]) {
1488 dead_args |= (1 << i);
1490 if (mem_temps[arg]) {
1491 sync_args |= (1 << i);
1493 dead_temps[arg] = 1;
1494 mem_temps[arg] = 0;
1497 if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
1498 /* globals should be synced to memory */
1499 memset(mem_temps, 1, s->nb_globals);
1501 if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
1502 TCG_CALL_NO_READ_GLOBALS))) {
1503 /* globals should go back to memory */
1504 memset(dead_temps, 1, s->nb_globals);
1507 /* input args are live */
1508 for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1509 arg = args[i];
1510 if (arg != TCG_CALL_DUMMY_ARG) {
1511 if (dead_temps[arg]) {
1512 dead_args |= (1 << i);
1514 dead_temps[arg] = 0;
1517 s->op_dead_args[op_index] = dead_args;
1518 s->op_sync_args[op_index] = sync_args;
1520 args--;
1522 break;
1523 case INDEX_op_debug_insn_start:
1524 args -= def->nb_args;
1525 break;
1526 case INDEX_op_nopn:
1527 nb_args = args[-1];
1528 args -= nb_args;
1529 break;
1530 case INDEX_op_discard:
1531 args--;
1532 /* mark the temporary as dead */
1533 dead_temps[args[0]] = 1;
1534 mem_temps[args[0]] = 0;
1535 break;
1536 case INDEX_op_end:
1537 break;
1539 case INDEX_op_add2_i32:
1540 op_new = INDEX_op_add_i32;
1541 goto do_addsub2;
1542 case INDEX_op_sub2_i32:
1543 op_new = INDEX_op_sub_i32;
1544 goto do_addsub2;
1545 case INDEX_op_add2_i64:
1546 op_new = INDEX_op_add_i64;
1547 goto do_addsub2;
1548 case INDEX_op_sub2_i64:
1549 op_new = INDEX_op_sub_i64;
1550 do_addsub2:
1551 args -= 6;
1552 nb_iargs = 4;
1553 nb_oargs = 2;
1554 /* Test if the high part of the operation is dead, but not
1555 the low part. The result can be optimized to a simple
1556 add or sub. This happens often for x86_64 guest when the
1557 cpu mode is set to 32 bit. */
1558 if (dead_temps[args[1]] && !mem_temps[args[1]]) {
1559 if (dead_temps[args[0]] && !mem_temps[args[0]]) {
1560 goto do_remove;
1562 /* Create the single operation plus nop. */
1563 s->gen_opc_buf[op_index] = op = op_new;
1564 args[1] = args[2];
1565 args[2] = args[4];
1566 assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
1567 tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 3);
1568 /* Fall through and mark the single-word operation live. */
1569 nb_iargs = 2;
1570 nb_oargs = 1;
1572 goto do_not_remove;
1574 case INDEX_op_mulu2_i32:
1575 op_new = INDEX_op_mul_i32;
1576 op_new2 = INDEX_op_muluh_i32;
1577 have_op_new2 = TCG_TARGET_HAS_muluh_i32;
1578 goto do_mul2;
1579 case INDEX_op_muls2_i32:
1580 op_new = INDEX_op_mul_i32;
1581 op_new2 = INDEX_op_mulsh_i32;
1582 have_op_new2 = TCG_TARGET_HAS_mulsh_i32;
1583 goto do_mul2;
1584 case INDEX_op_mulu2_i64:
1585 op_new = INDEX_op_mul_i64;
1586 op_new2 = INDEX_op_muluh_i64;
1587 have_op_new2 = TCG_TARGET_HAS_muluh_i64;
1588 goto do_mul2;
1589 case INDEX_op_muls2_i64:
1590 op_new = INDEX_op_mul_i64;
1591 op_new2 = INDEX_op_mulsh_i64;
1592 have_op_new2 = TCG_TARGET_HAS_mulsh_i64;
1593 goto do_mul2;
1594 do_mul2:
1595 args -= 4;
1596 nb_iargs = 2;
1597 nb_oargs = 2;
1598 if (dead_temps[args[1]] && !mem_temps[args[1]]) {
1599 if (dead_temps[args[0]] && !mem_temps[args[0]]) {
1600 /* Both parts of the operation are dead. */
1601 goto do_remove;
1603 /* The high part of the operation is dead; generate the low. */
1604 s->gen_opc_buf[op_index] = op = op_new;
1605 args[1] = args[2];
1606 args[2] = args[3];
1607 } else if (have_op_new2 && dead_temps[args[0]]
1608 && !mem_temps[args[0]]) {
1609 /* The low part of the operation is dead; generate the high. */
1610 s->gen_opc_buf[op_index] = op = op_new2;
1611 args[0] = args[1];
1612 args[1] = args[2];
1613 args[2] = args[3];
1614 } else {
1615 goto do_not_remove;
1617 assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
1618 tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 1);
1619 /* Mark the single-word operation live. */
1620 nb_oargs = 1;
1621 goto do_not_remove;
1623 default:
1624 /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
1625 args -= def->nb_args;
1626 nb_iargs = def->nb_iargs;
1627 nb_oargs = def->nb_oargs;
1629 /* Test if the operation can be removed because all
1630 its outputs are dead. We assume that nb_oargs == 0
1631 implies side effects */
1632 if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
1633 for(i = 0; i < nb_oargs; i++) {
1634 arg = args[i];
1635 if (!dead_temps[arg] || mem_temps[arg]) {
1636 goto do_not_remove;
1639 do_remove:
1640 tcg_set_nop(s, s->gen_opc_buf + op_index, args, def->nb_args);
1641 #ifdef CONFIG_PROFILER
1642 s->del_op_count++;
1643 #endif
1644 } else {
1645 do_not_remove:
1647 /* output args are dead */
1648 dead_args = 0;
1649 sync_args = 0;
1650 for(i = 0; i < nb_oargs; i++) {
1651 arg = args[i];
1652 if (dead_temps[arg]) {
1653 dead_args |= (1 << i);
1655 if (mem_temps[arg]) {
1656 sync_args |= (1 << i);
1658 dead_temps[arg] = 1;
1659 mem_temps[arg] = 0;
1662 /* if end of basic block, update */
1663 if (def->flags & TCG_OPF_BB_END) {
1664 tcg_la_bb_end(s, dead_temps, mem_temps);
1665 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
1666 /* globals should be synced to memory */
1667 memset(mem_temps, 1, s->nb_globals);
1670 /* input args are live */
1671 for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1672 arg = args[i];
1673 if (dead_temps[arg]) {
1674 dead_args |= (1 << i);
1676 dead_temps[arg] = 0;
1678 s->op_dead_args[op_index] = dead_args;
1679 s->op_sync_args[op_index] = sync_args;
1681 break;
1683 op_index--;
1686 if (args != s->gen_opparam_buf) {
1687 tcg_abort();
1690 #else
1691 /* dummy liveness analysis */
1692 static void tcg_liveness_analysis(TCGContext *s)
1694 int nb_ops;
1695 nb_ops = s->gen_opc_ptr - s->gen_opc_buf;
1697 s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1698 memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
1699 s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
1700 memset(s->op_sync_args, 0, nb_ops * sizeof(uint8_t));
1702 #endif
1704 #ifndef NDEBUG
1705 static void dump_regs(TCGContext *s)
1707 TCGTemp *ts;
1708 int i;
1709 char buf[64];
1711 for(i = 0; i < s->nb_temps; i++) {
1712 ts = &s->temps[i];
1713 printf(" %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
1714 switch(ts->val_type) {
1715 case TEMP_VAL_REG:
1716 printf("%s", tcg_target_reg_names[ts->reg]);
1717 break;
1718 case TEMP_VAL_MEM:
1719 printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
1720 break;
1721 case TEMP_VAL_CONST:
1722 printf("$0x%" TCG_PRIlx, ts->val);
1723 break;
1724 case TEMP_VAL_DEAD:
1725 printf("D");
1726 break;
1727 default:
1728 printf("???");
1729 break;
1731 printf("\n");
1734 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1735 if (s->reg_to_temp[i] >= 0) {
1736 printf("%s: %s\n",
1737 tcg_target_reg_names[i],
1738 tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
1743 static void check_regs(TCGContext *s)
1745 int reg, k;
1746 TCGTemp *ts;
1747 char buf[64];
1749 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1750 k = s->reg_to_temp[reg];
1751 if (k >= 0) {
1752 ts = &s->temps[k];
1753 if (ts->val_type != TEMP_VAL_REG ||
1754 ts->reg != reg) {
1755 printf("Inconsistency for register %s:\n",
1756 tcg_target_reg_names[reg]);
1757 goto fail;
1761 for(k = 0; k < s->nb_temps; k++) {
1762 ts = &s->temps[k];
1763 if (ts->val_type == TEMP_VAL_REG &&
1764 !ts->fixed_reg &&
1765 s->reg_to_temp[ts->reg] != k) {
1766 printf("Inconsistency for temp %s:\n",
1767 tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
1768 fail:
1769 printf("reg state:\n");
1770 dump_regs(s);
1771 tcg_abort();
1775 #endif
1777 static void temp_allocate_frame(TCGContext *s, int temp)
1779 TCGTemp *ts;
1780 ts = &s->temps[temp];
1781 #if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64)
1782 /* Sparc64 stack is accessed with offset of 2047 */
1783 s->current_frame_offset = (s->current_frame_offset +
1784 (tcg_target_long)sizeof(tcg_target_long) - 1) &
1785 ~(sizeof(tcg_target_long) - 1);
1786 #endif
1787 if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
1788 s->frame_end) {
1789 tcg_abort();
1791 ts->mem_offset = s->current_frame_offset;
1792 ts->mem_reg = s->frame_reg;
1793 ts->mem_allocated = 1;
1794 s->current_frame_offset += sizeof(tcg_target_long);
1797 /* sync register 'reg' by saving it to the corresponding temporary */
1798 static inline void tcg_reg_sync(TCGContext *s, int reg)
1800 TCGTemp *ts;
1801 int temp;
1803 temp = s->reg_to_temp[reg];
1804 ts = &s->temps[temp];
1805 assert(ts->val_type == TEMP_VAL_REG);
1806 if (!ts->mem_coherent && !ts->fixed_reg) {
1807 if (!ts->mem_allocated) {
1808 temp_allocate_frame(s, temp);
1810 tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1812 ts->mem_coherent = 1;
1815 /* free register 'reg' by spilling the corresponding temporary if necessary */
1816 static void tcg_reg_free(TCGContext *s, int reg)
1818 int temp;
1820 temp = s->reg_to_temp[reg];
1821 if (temp != -1) {
1822 tcg_reg_sync(s, reg);
1823 s->temps[temp].val_type = TEMP_VAL_MEM;
1824 s->reg_to_temp[reg] = -1;
1828 /* Allocate a register belonging to reg1 & ~reg2 */
1829 static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1831 int i, reg;
1832 TCGRegSet reg_ct;
1834 tcg_regset_andnot(reg_ct, reg1, reg2);
1836 /* first try free registers */
1837 for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1838 reg = tcg_target_reg_alloc_order[i];
1839 if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
1840 return reg;
1843 /* XXX: do better spill choice */
1844 for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1845 reg = tcg_target_reg_alloc_order[i];
1846 if (tcg_regset_test_reg(reg_ct, reg)) {
1847 tcg_reg_free(s, reg);
1848 return reg;
1852 tcg_abort();
1855 /* mark a temporary as dead. */
1856 static inline void temp_dead(TCGContext *s, int temp)
1858 TCGTemp *ts;
1860 ts = &s->temps[temp];
1861 if (!ts->fixed_reg) {
1862 if (ts->val_type == TEMP_VAL_REG) {
1863 s->reg_to_temp[ts->reg] = -1;
1865 if (temp < s->nb_globals || ts->temp_local) {
1866 ts->val_type = TEMP_VAL_MEM;
1867 } else {
1868 ts->val_type = TEMP_VAL_DEAD;
1873 /* sync a temporary to memory. 'allocated_regs' is used in case a
1874 temporary registers needs to be allocated to store a constant. */
1875 static inline void temp_sync(TCGContext *s, int temp, TCGRegSet allocated_regs)
1877 TCGTemp *ts;
1879 ts = &s->temps[temp];
1880 if (!ts->fixed_reg) {
1881 switch(ts->val_type) {
1882 case TEMP_VAL_CONST:
1883 ts->reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1884 allocated_regs);
1885 ts->val_type = TEMP_VAL_REG;
1886 s->reg_to_temp[ts->reg] = temp;
1887 ts->mem_coherent = 0;
1888 tcg_out_movi(s, ts->type, ts->reg, ts->val);
1889 /* fallthrough*/
1890 case TEMP_VAL_REG:
1891 tcg_reg_sync(s, ts->reg);
1892 break;
1893 case TEMP_VAL_DEAD:
1894 case TEMP_VAL_MEM:
1895 break;
1896 default:
1897 tcg_abort();
1902 /* save a temporary to memory. 'allocated_regs' is used in case a
1903 temporary registers needs to be allocated to store a constant. */
1904 static inline void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
1906 #ifdef USE_LIVENESS_ANALYSIS
1907 /* The liveness analysis already ensures that globals are back
1908 in memory. Keep an assert for safety. */
1909 assert(s->temps[temp].val_type == TEMP_VAL_MEM || s->temps[temp].fixed_reg);
1910 #else
1911 temp_sync(s, temp, allocated_regs);
1912 temp_dead(s, temp);
1913 #endif
1916 /* save globals to their canonical location and assume they can be
1917 modified be the following code. 'allocated_regs' is used in case a
1918 temporary registers needs to be allocated to store a constant. */
1919 static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
1921 int i;
1923 for(i = 0; i < s->nb_globals; i++) {
1924 temp_save(s, i, allocated_regs);
1928 /* sync globals to their canonical location and assume they can be
1929 read by the following code. 'allocated_regs' is used in case a
1930 temporary registers needs to be allocated to store a constant. */
1931 static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
1933 int i;
1935 for (i = 0; i < s->nb_globals; i++) {
1936 #ifdef USE_LIVENESS_ANALYSIS
1937 assert(s->temps[i].val_type != TEMP_VAL_REG || s->temps[i].fixed_reg ||
1938 s->temps[i].mem_coherent);
1939 #else
1940 temp_sync(s, i, allocated_regs);
1941 #endif
1945 /* at the end of a basic block, we assume all temporaries are dead and
1946 all globals are stored at their canonical location. */
1947 static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
1949 TCGTemp *ts;
1950 int i;
1952 for(i = s->nb_globals; i < s->nb_temps; i++) {
1953 ts = &s->temps[i];
1954 if (ts->temp_local) {
1955 temp_save(s, i, allocated_regs);
1956 } else {
1957 #ifdef USE_LIVENESS_ANALYSIS
1958 /* The liveness analysis already ensures that temps are dead.
1959 Keep an assert for safety. */
1960 assert(ts->val_type == TEMP_VAL_DEAD);
1961 #else
1962 temp_dead(s, i);
1963 #endif
1967 save_globals(s, allocated_regs);
1970 #define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
1971 #define NEED_SYNC_ARG(n) ((sync_args >> (n)) & 1)
1973 static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
1974 uint16_t dead_args, uint8_t sync_args)
1976 TCGTemp *ots;
1977 tcg_target_ulong val;
1979 ots = &s->temps[args[0]];
1980 val = args[1];
1982 if (ots->fixed_reg) {
1983 /* for fixed registers, we do not do any constant
1984 propagation */
1985 tcg_out_movi(s, ots->type, ots->reg, val);
1986 } else {
1987 /* The movi is not explicitly generated here */
1988 if (ots->val_type == TEMP_VAL_REG)
1989 s->reg_to_temp[ots->reg] = -1;
1990 ots->val_type = TEMP_VAL_CONST;
1991 ots->val = val;
1993 if (NEED_SYNC_ARG(0)) {
1994 temp_sync(s, args[0], s->reserved_regs);
1996 if (IS_DEAD_ARG(0)) {
1997 temp_dead(s, args[0]);
2001 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
2002 const TCGArg *args, uint16_t dead_args,
2003 uint8_t sync_args)
2005 TCGRegSet allocated_regs;
2006 TCGTemp *ts, *ots;
2007 TCGType otype, itype;
2009 tcg_regset_set(allocated_regs, s->reserved_regs);
2010 ots = &s->temps[args[0]];
2011 ts = &s->temps[args[1]];
2013 /* Note that otype != itype for no-op truncation. */
2014 otype = ots->type;
2015 itype = ts->type;
2017 /* If the source value is not in a register, and we're going to be
2018 forced to have it in a register in order to perform the copy,
2019 then copy the SOURCE value into its own register first. That way
2020 we don't have to reload SOURCE the next time it is used. */
2021 if (((NEED_SYNC_ARG(0) || ots->fixed_reg) && ts->val_type != TEMP_VAL_REG)
2022 || ts->val_type == TEMP_VAL_MEM) {
2023 ts->reg = tcg_reg_alloc(s, tcg_target_available_regs[itype],
2024 allocated_regs);
2025 if (ts->val_type == TEMP_VAL_MEM) {
2026 tcg_out_ld(s, itype, ts->reg, ts->mem_reg, ts->mem_offset);
2027 ts->mem_coherent = 1;
2028 } else if (ts->val_type == TEMP_VAL_CONST) {
2029 tcg_out_movi(s, itype, ts->reg, ts->val);
2031 s->reg_to_temp[ts->reg] = args[1];
2032 ts->val_type = TEMP_VAL_REG;
2035 if (IS_DEAD_ARG(0) && !ots->fixed_reg) {
2036 /* mov to a non-saved dead register makes no sense (even with
2037 liveness analysis disabled). */
2038 assert(NEED_SYNC_ARG(0));
2039 /* The code above should have moved the temp to a register. */
2040 assert(ts->val_type == TEMP_VAL_REG);
2041 if (!ots->mem_allocated) {
2042 temp_allocate_frame(s, args[0]);
2044 tcg_out_st(s, otype, ts->reg, ots->mem_reg, ots->mem_offset);
2045 if (IS_DEAD_ARG(1)) {
2046 temp_dead(s, args[1]);
2048 temp_dead(s, args[0]);
2049 } else if (ts->val_type == TEMP_VAL_CONST) {
2050 /* propagate constant */
2051 if (ots->val_type == TEMP_VAL_REG) {
2052 s->reg_to_temp[ots->reg] = -1;
2054 ots->val_type = TEMP_VAL_CONST;
2055 ots->val = ts->val;
2056 } else {
2057 /* The code in the first if block should have moved the
2058 temp to a register. */
2059 assert(ts->val_type == TEMP_VAL_REG);
2060 if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
2061 /* the mov can be suppressed */
2062 if (ots->val_type == TEMP_VAL_REG) {
2063 s->reg_to_temp[ots->reg] = -1;
2065 ots->reg = ts->reg;
2066 temp_dead(s, args[1]);
2067 } else {
2068 if (ots->val_type != TEMP_VAL_REG) {
2069 /* When allocating a new register, make sure to not spill the
2070 input one. */
2071 tcg_regset_set_reg(allocated_regs, ts->reg);
2072 ots->reg = tcg_reg_alloc(s, tcg_target_available_regs[otype],
2073 allocated_regs);
2075 tcg_out_mov(s, otype, ots->reg, ts->reg);
2077 ots->val_type = TEMP_VAL_REG;
2078 ots->mem_coherent = 0;
2079 s->reg_to_temp[ots->reg] = args[0];
2080 if (NEED_SYNC_ARG(0)) {
2081 tcg_reg_sync(s, ots->reg);
2086 static void tcg_reg_alloc_op(TCGContext *s,
2087 const TCGOpDef *def, TCGOpcode opc,
2088 const TCGArg *args, uint16_t dead_args,
2089 uint8_t sync_args)
2091 TCGRegSet allocated_regs;
2092 int i, k, nb_iargs, nb_oargs, reg;
2093 TCGArg arg;
2094 const TCGArgConstraint *arg_ct;
2095 TCGTemp *ts;
2096 TCGArg new_args[TCG_MAX_OP_ARGS];
2097 int const_args[TCG_MAX_OP_ARGS];
2099 nb_oargs = def->nb_oargs;
2100 nb_iargs = def->nb_iargs;
2102 /* copy constants */
2103 memcpy(new_args + nb_oargs + nb_iargs,
2104 args + nb_oargs + nb_iargs,
2105 sizeof(TCGArg) * def->nb_cargs);
2107 /* satisfy input constraints */
2108 tcg_regset_set(allocated_regs, s->reserved_regs);
2109 for(k = 0; k < nb_iargs; k++) {
2110 i = def->sorted_args[nb_oargs + k];
2111 arg = args[i];
2112 arg_ct = &def->args_ct[i];
2113 ts = &s->temps[arg];
2114 if (ts->val_type == TEMP_VAL_MEM) {
2115 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2116 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2117 ts->val_type = TEMP_VAL_REG;
2118 ts->reg = reg;
2119 ts->mem_coherent = 1;
2120 s->reg_to_temp[reg] = arg;
2121 } else if (ts->val_type == TEMP_VAL_CONST) {
2122 if (tcg_target_const_match(ts->val, ts->type, arg_ct)) {
2123 /* constant is OK for instruction */
2124 const_args[i] = 1;
2125 new_args[i] = ts->val;
2126 goto iarg_end;
2127 } else {
2128 /* need to move to a register */
2129 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2130 tcg_out_movi(s, ts->type, reg, ts->val);
2131 ts->val_type = TEMP_VAL_REG;
2132 ts->reg = reg;
2133 ts->mem_coherent = 0;
2134 s->reg_to_temp[reg] = arg;
2137 assert(ts->val_type == TEMP_VAL_REG);
2138 if (arg_ct->ct & TCG_CT_IALIAS) {
2139 if (ts->fixed_reg) {
2140 /* if fixed register, we must allocate a new register
2141 if the alias is not the same register */
2142 if (arg != args[arg_ct->alias_index])
2143 goto allocate_in_reg;
2144 } else {
2145 /* if the input is aliased to an output and if it is
2146 not dead after the instruction, we must allocate
2147 a new register and move it */
2148 if (!IS_DEAD_ARG(i)) {
2149 goto allocate_in_reg;
2153 reg = ts->reg;
2154 if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
2155 /* nothing to do : the constraint is satisfied */
2156 } else {
2157 allocate_in_reg:
2158 /* allocate a new register matching the constraint
2159 and move the temporary register into it */
2160 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2161 tcg_out_mov(s, ts->type, reg, ts->reg);
2163 new_args[i] = reg;
2164 const_args[i] = 0;
2165 tcg_regset_set_reg(allocated_regs, reg);
2166 iarg_end: ;
2169 /* mark dead temporaries and free the associated registers */
2170 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
2171 if (IS_DEAD_ARG(i)) {
2172 temp_dead(s, args[i]);
2176 if (def->flags & TCG_OPF_BB_END) {
2177 tcg_reg_alloc_bb_end(s, allocated_regs);
2178 } else {
2179 if (def->flags & TCG_OPF_CALL_CLOBBER) {
2180 /* XXX: permit generic clobber register list ? */
2181 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
2182 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
2183 tcg_reg_free(s, reg);
2187 if (def->flags & TCG_OPF_SIDE_EFFECTS) {
2188 /* sync globals if the op has side effects and might trigger
2189 an exception. */
2190 sync_globals(s, allocated_regs);
2193 /* satisfy the output constraints */
2194 tcg_regset_set(allocated_regs, s->reserved_regs);
2195 for(k = 0; k < nb_oargs; k++) {
2196 i = def->sorted_args[k];
2197 arg = args[i];
2198 arg_ct = &def->args_ct[i];
2199 ts = &s->temps[arg];
2200 if (arg_ct->ct & TCG_CT_ALIAS) {
2201 reg = new_args[arg_ct->alias_index];
2202 } else {
2203 /* if fixed register, we try to use it */
2204 reg = ts->reg;
2205 if (ts->fixed_reg &&
2206 tcg_regset_test_reg(arg_ct->u.regs, reg)) {
2207 goto oarg_end;
2209 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
2211 tcg_regset_set_reg(allocated_regs, reg);
2212 /* if a fixed register is used, then a move will be done afterwards */
2213 if (!ts->fixed_reg) {
2214 if (ts->val_type == TEMP_VAL_REG) {
2215 s->reg_to_temp[ts->reg] = -1;
2217 ts->val_type = TEMP_VAL_REG;
2218 ts->reg = reg;
2219 /* temp value is modified, so the value kept in memory is
2220 potentially not the same */
2221 ts->mem_coherent = 0;
2222 s->reg_to_temp[reg] = arg;
2224 oarg_end:
2225 new_args[i] = reg;
2229 /* emit instruction */
2230 tcg_out_op(s, opc, new_args, const_args);
2232 /* move the outputs in the correct register if needed */
2233 for(i = 0; i < nb_oargs; i++) {
2234 ts = &s->temps[args[i]];
2235 reg = new_args[i];
2236 if (ts->fixed_reg && ts->reg != reg) {
2237 tcg_out_mov(s, ts->type, ts->reg, reg);
2239 if (NEED_SYNC_ARG(i)) {
2240 tcg_reg_sync(s, reg);
2242 if (IS_DEAD_ARG(i)) {
2243 temp_dead(s, args[i]);
2248 #ifdef TCG_TARGET_STACK_GROWSUP
2249 #define STACK_DIR(x) (-(x))
2250 #else
2251 #define STACK_DIR(x) (x)
2252 #endif
2254 static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
2255 TCGOpcode opc, const TCGArg *args,
2256 uint16_t dead_args, uint8_t sync_args)
2258 int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
2259 TCGArg arg;
2260 TCGTemp *ts;
2261 intptr_t stack_offset;
2262 size_t call_stack_size;
2263 tcg_insn_unit *func_addr;
2264 int allocate_args;
2265 TCGRegSet allocated_regs;
2267 arg = *args++;
2269 nb_oargs = arg >> 16;
2270 nb_iargs = arg & 0xffff;
2271 nb_params = nb_iargs;
2273 func_addr = (tcg_insn_unit *)(intptr_t)args[nb_oargs + nb_iargs];
2274 flags = args[nb_oargs + nb_iargs + 1];
2276 nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
2277 if (nb_regs > nb_params) {
2278 nb_regs = nb_params;
2281 /* assign stack slots first */
2282 call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
2283 call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) &
2284 ~(TCG_TARGET_STACK_ALIGN - 1);
2285 allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
2286 if (allocate_args) {
2287 /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
2288 preallocate call stack */
2289 tcg_abort();
2292 stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
2293 for(i = nb_regs; i < nb_params; i++) {
2294 arg = args[nb_oargs + i];
2295 #ifdef TCG_TARGET_STACK_GROWSUP
2296 stack_offset -= sizeof(tcg_target_long);
2297 #endif
2298 if (arg != TCG_CALL_DUMMY_ARG) {
2299 ts = &s->temps[arg];
2300 if (ts->val_type == TEMP_VAL_REG) {
2301 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
2302 } else if (ts->val_type == TEMP_VAL_MEM) {
2303 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
2304 s->reserved_regs);
2305 /* XXX: not correct if reading values from the stack */
2306 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2307 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
2308 } else if (ts->val_type == TEMP_VAL_CONST) {
2309 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
2310 s->reserved_regs);
2311 /* XXX: sign extend may be needed on some targets */
2312 tcg_out_movi(s, ts->type, reg, ts->val);
2313 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
2314 } else {
2315 tcg_abort();
2318 #ifndef TCG_TARGET_STACK_GROWSUP
2319 stack_offset += sizeof(tcg_target_long);
2320 #endif
2323 /* assign input registers */
2324 tcg_regset_set(allocated_regs, s->reserved_regs);
2325 for(i = 0; i < nb_regs; i++) {
2326 arg = args[nb_oargs + i];
2327 if (arg != TCG_CALL_DUMMY_ARG) {
2328 ts = &s->temps[arg];
2329 reg = tcg_target_call_iarg_regs[i];
2330 tcg_reg_free(s, reg);
2331 if (ts->val_type == TEMP_VAL_REG) {
2332 if (ts->reg != reg) {
2333 tcg_out_mov(s, ts->type, reg, ts->reg);
2335 } else if (ts->val_type == TEMP_VAL_MEM) {
2336 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
2337 } else if (ts->val_type == TEMP_VAL_CONST) {
2338 /* XXX: sign extend ? */
2339 tcg_out_movi(s, ts->type, reg, ts->val);
2340 } else {
2341 tcg_abort();
2343 tcg_regset_set_reg(allocated_regs, reg);
2347 /* mark dead temporaries and free the associated registers */
2348 for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
2349 if (IS_DEAD_ARG(i)) {
2350 temp_dead(s, args[i]);
2354 /* clobber call registers */
2355 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
2356 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
2357 tcg_reg_free(s, reg);
2361 /* Save globals if they might be written by the helper, sync them if
2362 they might be read. */
2363 if (flags & TCG_CALL_NO_READ_GLOBALS) {
2364 /* Nothing to do */
2365 } else if (flags & TCG_CALL_NO_WRITE_GLOBALS) {
2366 sync_globals(s, allocated_regs);
2367 } else {
2368 save_globals(s, allocated_regs);
2371 tcg_out_call(s, func_addr);
2373 /* assign output registers and emit moves if needed */
2374 for(i = 0; i < nb_oargs; i++) {
2375 arg = args[i];
2376 ts = &s->temps[arg];
2377 reg = tcg_target_call_oarg_regs[i];
2378 assert(s->reg_to_temp[reg] == -1);
2380 if (ts->fixed_reg) {
2381 if (ts->reg != reg) {
2382 tcg_out_mov(s, ts->type, ts->reg, reg);
2384 } else {
2385 if (ts->val_type == TEMP_VAL_REG) {
2386 s->reg_to_temp[ts->reg] = -1;
2388 ts->val_type = TEMP_VAL_REG;
2389 ts->reg = reg;
2390 ts->mem_coherent = 0;
2391 s->reg_to_temp[reg] = arg;
2392 if (NEED_SYNC_ARG(i)) {
2393 tcg_reg_sync(s, reg);
2395 if (IS_DEAD_ARG(i)) {
2396 temp_dead(s, args[i]);
2401 return nb_iargs + nb_oargs + def->nb_cargs + 1;
2404 #ifdef CONFIG_PROFILER
2406 static int64_t tcg_table_op_count[NB_OPS];
2408 void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf)
2410 int i;
2412 for(i = INDEX_op_end; i < NB_OPS; i++) {
2413 cpu_fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name,
2414 tcg_table_op_count[i]);
2417 #else
2418 void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf)
2420 cpu_fprintf(f, "[TCG profiler not compiled]\n");
2422 #endif
2425 static inline int tcg_gen_code_common(TCGContext *s,
2426 tcg_insn_unit *gen_code_buf,
2427 long search_pc)
2429 TCGOpcode opc;
2430 int op_index;
2431 const TCGOpDef *def;
2432 const TCGArg *args;
2434 #ifdef DEBUG_DISAS
2435 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2436 qemu_log("OP:\n");
2437 tcg_dump_ops(s);
2438 qemu_log("\n");
2440 #endif
2442 #ifdef CONFIG_PROFILER
2443 s->opt_time -= profile_getclock();
2444 #endif
2446 #ifdef USE_TCG_OPTIMIZATIONS
2447 s->gen_opparam_ptr =
2448 tcg_optimize(s, s->gen_opc_ptr, s->gen_opparam_buf, tcg_op_defs);
2449 #endif
2451 #ifdef CONFIG_PROFILER
2452 s->opt_time += profile_getclock();
2453 s->la_time -= profile_getclock();
2454 #endif
2456 tcg_liveness_analysis(s);
2458 #ifdef CONFIG_PROFILER
2459 s->la_time += profile_getclock();
2460 #endif
2462 #ifdef DEBUG_DISAS
2463 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
2464 qemu_log("OP after optimization and liveness analysis:\n");
2465 tcg_dump_ops(s);
2466 qemu_log("\n");
2468 #endif
2470 tcg_reg_alloc_start(s);
2472 s->code_buf = gen_code_buf;
2473 s->code_ptr = gen_code_buf;
2475 tcg_out_tb_init(s);
2477 args = s->gen_opparam_buf;
2478 op_index = 0;
2480 for(;;) {
2481 opc = s->gen_opc_buf[op_index];
2482 #ifdef CONFIG_PROFILER
2483 tcg_table_op_count[opc]++;
2484 #endif
2485 def = &tcg_op_defs[opc];
2486 #if 0
2487 printf("%s: %d %d %d\n", def->name,
2488 def->nb_oargs, def->nb_iargs, def->nb_cargs);
2489 // dump_regs(s);
2490 #endif
2491 switch(opc) {
2492 case INDEX_op_mov_i32:
2493 case INDEX_op_mov_i64:
2494 tcg_reg_alloc_mov(s, def, args, s->op_dead_args[op_index],
2495 s->op_sync_args[op_index]);
2496 break;
2497 case INDEX_op_movi_i32:
2498 case INDEX_op_movi_i64:
2499 tcg_reg_alloc_movi(s, args, s->op_dead_args[op_index],
2500 s->op_sync_args[op_index]);
2501 break;
2502 case INDEX_op_debug_insn_start:
2503 /* debug instruction */
2504 break;
2505 case INDEX_op_nop:
2506 case INDEX_op_nop1:
2507 case INDEX_op_nop2:
2508 case INDEX_op_nop3:
2509 break;
2510 case INDEX_op_nopn:
2511 args += args[0];
2512 goto next;
2513 case INDEX_op_discard:
2514 temp_dead(s, args[0]);
2515 break;
2516 case INDEX_op_set_label:
2517 tcg_reg_alloc_bb_end(s, s->reserved_regs);
2518 tcg_out_label(s, args[0], s->code_ptr);
2519 break;
2520 case INDEX_op_call:
2521 args += tcg_reg_alloc_call(s, def, opc, args,
2522 s->op_dead_args[op_index],
2523 s->op_sync_args[op_index]);
2524 goto next;
2525 case INDEX_op_end:
2526 goto the_end;
2527 default:
2528 /* Sanity check that we've not introduced any unhandled opcodes. */
2529 if (def->flags & TCG_OPF_NOT_PRESENT) {
2530 tcg_abort();
2532 /* Note: in order to speed up the code, it would be much
2533 faster to have specialized register allocator functions for
2534 some common argument patterns */
2535 tcg_reg_alloc_op(s, def, opc, args, s->op_dead_args[op_index],
2536 s->op_sync_args[op_index]);
2537 break;
2539 args += def->nb_args;
2540 next:
2541 if (search_pc >= 0 && search_pc < tcg_current_code_size(s)) {
2542 return op_index;
2544 op_index++;
2545 #ifndef NDEBUG
2546 check_regs(s);
2547 #endif
2549 the_end:
2550 /* Generate TB finalization at the end of block */
2551 tcg_out_tb_finalize(s);
2552 return -1;
2555 int tcg_gen_code(TCGContext *s, tcg_insn_unit *gen_code_buf)
2557 #ifdef CONFIG_PROFILER
2559 int n;
2560 n = (s->gen_opc_ptr - s->gen_opc_buf);
2561 s->op_count += n;
2562 if (n > s->op_count_max)
2563 s->op_count_max = n;
2565 s->temp_count += s->nb_temps;
2566 if (s->nb_temps > s->temp_count_max)
2567 s->temp_count_max = s->nb_temps;
2569 #endif
2571 tcg_gen_code_common(s, gen_code_buf, -1);
2573 /* flush instruction cache */
2574 flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);
2576 return tcg_current_code_size(s);
2579 /* Return the index of the micro operation such as the pc after is <
2580 offset bytes from the start of the TB. The contents of gen_code_buf must
2581 not be changed, though writing the same values is ok.
2582 Return -1 if not found. */
2583 int tcg_gen_code_search_pc(TCGContext *s, tcg_insn_unit *gen_code_buf,
2584 long offset)
2586 return tcg_gen_code_common(s, gen_code_buf, offset);
2589 #ifdef CONFIG_PROFILER
2590 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2592 TCGContext *s = &tcg_ctx;
2593 int64_t tot;
2595 tot = s->interm_time + s->code_time;
2596 cpu_fprintf(f, "JIT cycles %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2597 tot, tot / 2.4e9);
2598 cpu_fprintf(f, "translated TBs %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n",
2599 s->tb_count,
2600 s->tb_count1 - s->tb_count,
2601 s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
2602 cpu_fprintf(f, "avg ops/TB %0.1f max=%d\n",
2603 s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
2604 cpu_fprintf(f, "deleted ops/TB %0.2f\n",
2605 s->tb_count ?
2606 (double)s->del_op_count / s->tb_count : 0);
2607 cpu_fprintf(f, "avg temps/TB %0.2f max=%d\n",
2608 s->tb_count ?
2609 (double)s->temp_count / s->tb_count : 0,
2610 s->temp_count_max);
2612 cpu_fprintf(f, "cycles/op %0.1f\n",
2613 s->op_count ? (double)tot / s->op_count : 0);
2614 cpu_fprintf(f, "cycles/in byte %0.1f\n",
2615 s->code_in_len ? (double)tot / s->code_in_len : 0);
2616 cpu_fprintf(f, "cycles/out byte %0.1f\n",
2617 s->code_out_len ? (double)tot / s->code_out_len : 0);
2618 if (tot == 0)
2619 tot = 1;
2620 cpu_fprintf(f, " gen_interm time %0.1f%%\n",
2621 (double)s->interm_time / tot * 100.0);
2622 cpu_fprintf(f, " gen_code time %0.1f%%\n",
2623 (double)s->code_time / tot * 100.0);
2624 cpu_fprintf(f, "optim./code time %0.1f%%\n",
2625 (double)s->opt_time / (s->code_time ? s->code_time : 1)
2626 * 100.0);
2627 cpu_fprintf(f, "liveness/code time %0.1f%%\n",
2628 (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2629 cpu_fprintf(f, "cpu_restore count %" PRId64 "\n",
2630 s->restore_count);
2631 cpu_fprintf(f, " avg cycles %0.1f\n",
2632 s->restore_count ? (double)s->restore_time / s->restore_count : 0);
2634 #else
2635 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2637 cpu_fprintf(f, "[TCG profiler not compiled]\n");
2639 #endif
2641 #ifdef ELF_HOST_MACHINE
2642 /* In order to use this feature, the backend needs to do three things:
2644 (1) Define ELF_HOST_MACHINE to indicate both what value to
2645 put into the ELF image and to indicate support for the feature.
2647 (2) Define tcg_register_jit. This should create a buffer containing
2648 the contents of a .debug_frame section that describes the post-
2649 prologue unwind info for the tcg machine.
2651 (3) Call tcg_register_jit_int, with the constructed .debug_frame.
2654 /* Begin GDB interface. THE FOLLOWING MUST MATCH GDB DOCS. */
2655 typedef enum {
2656 JIT_NOACTION = 0,
2657 JIT_REGISTER_FN,
2658 JIT_UNREGISTER_FN
2659 } jit_actions_t;
2661 struct jit_code_entry {
2662 struct jit_code_entry *next_entry;
2663 struct jit_code_entry *prev_entry;
2664 const void *symfile_addr;
2665 uint64_t symfile_size;
2668 struct jit_descriptor {
2669 uint32_t version;
2670 uint32_t action_flag;
2671 struct jit_code_entry *relevant_entry;
2672 struct jit_code_entry *first_entry;
2675 void __jit_debug_register_code(void) __attribute__((noinline));
2676 void __jit_debug_register_code(void)
2678 asm("");
2681 /* Must statically initialize the version, because GDB may check
2682 the version before we can set it. */
2683 struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
2685 /* End GDB interface. */
2687 static int find_string(const char *strtab, const char *str)
2689 const char *p = strtab + 1;
2691 while (1) {
2692 if (strcmp(p, str) == 0) {
2693 return p - strtab;
2695 p += strlen(p) + 1;
2699 static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
2700 const void *debug_frame,
2701 size_t debug_frame_size)
2703 struct __attribute__((packed)) DebugInfo {
2704 uint32_t len;
2705 uint16_t version;
2706 uint32_t abbrev;
2707 uint8_t ptr_size;
2708 uint8_t cu_die;
2709 uint16_t cu_lang;
2710 uintptr_t cu_low_pc;
2711 uintptr_t cu_high_pc;
2712 uint8_t fn_die;
2713 char fn_name[16];
2714 uintptr_t fn_low_pc;
2715 uintptr_t fn_high_pc;
2716 uint8_t cu_eoc;
2719 struct ElfImage {
2720 ElfW(Ehdr) ehdr;
2721 ElfW(Phdr) phdr;
2722 ElfW(Shdr) shdr[7];
2723 ElfW(Sym) sym[2];
2724 struct DebugInfo di;
2725 uint8_t da[24];
2726 char str[80];
2729 struct ElfImage *img;
2731 static const struct ElfImage img_template = {
2732 .ehdr = {
2733 .e_ident[EI_MAG0] = ELFMAG0,
2734 .e_ident[EI_MAG1] = ELFMAG1,
2735 .e_ident[EI_MAG2] = ELFMAG2,
2736 .e_ident[EI_MAG3] = ELFMAG3,
2737 .e_ident[EI_CLASS] = ELF_CLASS,
2738 .e_ident[EI_DATA] = ELF_DATA,
2739 .e_ident[EI_VERSION] = EV_CURRENT,
2740 .e_type = ET_EXEC,
2741 .e_machine = ELF_HOST_MACHINE,
2742 .e_version = EV_CURRENT,
2743 .e_phoff = offsetof(struct ElfImage, phdr),
2744 .e_shoff = offsetof(struct ElfImage, shdr),
2745 .e_ehsize = sizeof(ElfW(Shdr)),
2746 .e_phentsize = sizeof(ElfW(Phdr)),
2747 .e_phnum = 1,
2748 .e_shentsize = sizeof(ElfW(Shdr)),
2749 .e_shnum = ARRAY_SIZE(img->shdr),
2750 .e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
2751 #ifdef ELF_HOST_FLAGS
2752 .e_flags = ELF_HOST_FLAGS,
2753 #endif
2754 #ifdef ELF_OSABI
2755 .e_ident[EI_OSABI] = ELF_OSABI,
2756 #endif
2758 .phdr = {
2759 .p_type = PT_LOAD,
2760 .p_flags = PF_X,
2762 .shdr = {
2763 [0] = { .sh_type = SHT_NULL },
2764 /* Trick: The contents of code_gen_buffer are not present in
2765 this fake ELF file; that got allocated elsewhere. Therefore
2766 we mark .text as SHT_NOBITS (similar to .bss) so that readers
2767 will not look for contents. We can record any address. */
2768 [1] = { /* .text */
2769 .sh_type = SHT_NOBITS,
2770 .sh_flags = SHF_EXECINSTR | SHF_ALLOC,
2772 [2] = { /* .debug_info */
2773 .sh_type = SHT_PROGBITS,
2774 .sh_offset = offsetof(struct ElfImage, di),
2775 .sh_size = sizeof(struct DebugInfo),
2777 [3] = { /* .debug_abbrev */
2778 .sh_type = SHT_PROGBITS,
2779 .sh_offset = offsetof(struct ElfImage, da),
2780 .sh_size = sizeof(img->da),
2782 [4] = { /* .debug_frame */
2783 .sh_type = SHT_PROGBITS,
2784 .sh_offset = sizeof(struct ElfImage),
2786 [5] = { /* .symtab */
2787 .sh_type = SHT_SYMTAB,
2788 .sh_offset = offsetof(struct ElfImage, sym),
2789 .sh_size = sizeof(img->sym),
2790 .sh_info = 1,
2791 .sh_link = ARRAY_SIZE(img->shdr) - 1,
2792 .sh_entsize = sizeof(ElfW(Sym)),
2794 [6] = { /* .strtab */
2795 .sh_type = SHT_STRTAB,
2796 .sh_offset = offsetof(struct ElfImage, str),
2797 .sh_size = sizeof(img->str),
2800 .sym = {
2801 [1] = { /* code_gen_buffer */
2802 .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
2803 .st_shndx = 1,
2806 .di = {
2807 .len = sizeof(struct DebugInfo) - 4,
2808 .version = 2,
2809 .ptr_size = sizeof(void *),
2810 .cu_die = 1,
2811 .cu_lang = 0x8001, /* DW_LANG_Mips_Assembler */
2812 .fn_die = 2,
2813 .fn_name = "code_gen_buffer"
2815 .da = {
2816 1, /* abbrev number (the cu) */
2817 0x11, 1, /* DW_TAG_compile_unit, has children */
2818 0x13, 0x5, /* DW_AT_language, DW_FORM_data2 */
2819 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
2820 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
2821 0, 0, /* end of abbrev */
2822 2, /* abbrev number (the fn) */
2823 0x2e, 0, /* DW_TAG_subprogram, no children */
2824 0x3, 0x8, /* DW_AT_name, DW_FORM_string */
2825 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
2826 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
2827 0, 0, /* end of abbrev */
2828 0 /* no more abbrev */
2830 .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
2831 ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
2834 /* We only need a single jit entry; statically allocate it. */
2835 static struct jit_code_entry one_entry;
2837 uintptr_t buf = (uintptr_t)buf_ptr;
2838 size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
2839 DebugFrameHeader *dfh;
2841 img = g_malloc(img_size);
2842 *img = img_template;
2844 img->phdr.p_vaddr = buf;
2845 img->phdr.p_paddr = buf;
2846 img->phdr.p_memsz = buf_size;
2848 img->shdr[1].sh_name = find_string(img->str, ".text");
2849 img->shdr[1].sh_addr = buf;
2850 img->shdr[1].sh_size = buf_size;
2852 img->shdr[2].sh_name = find_string(img->str, ".debug_info");
2853 img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
2855 img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
2856 img->shdr[4].sh_size = debug_frame_size;
2858 img->shdr[5].sh_name = find_string(img->str, ".symtab");
2859 img->shdr[6].sh_name = find_string(img->str, ".strtab");
2861 img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
2862 img->sym[1].st_value = buf;
2863 img->sym[1].st_size = buf_size;
2865 img->di.cu_low_pc = buf;
2866 img->di.cu_high_pc = buf + buf_size;
2867 img->di.fn_low_pc = buf;
2868 img->di.fn_high_pc = buf + buf_size;
2870 dfh = (DebugFrameHeader *)(img + 1);
2871 memcpy(dfh, debug_frame, debug_frame_size);
2872 dfh->fde.func_start = buf;
2873 dfh->fde.func_len = buf_size;
2875 #ifdef DEBUG_JIT
2876 /* Enable this block to be able to debug the ELF image file creation.
2877 One can use readelf, objdump, or other inspection utilities. */
2879 FILE *f = fopen("/tmp/qemu.jit", "w+b");
2880 if (f) {
2881 if (fwrite(img, img_size, 1, f) != img_size) {
2882 /* Avoid stupid unused return value warning for fwrite. */
2884 fclose(f);
2887 #endif
2889 one_entry.symfile_addr = img;
2890 one_entry.symfile_size = img_size;
2892 __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
2893 __jit_debug_descriptor.relevant_entry = &one_entry;
2894 __jit_debug_descriptor.first_entry = &one_entry;
2895 __jit_debug_register_code();
2897 #else
2898 /* No support for the feature. Provide the entry point expected by exec.c,
2899 and implement the internal function we declared earlier. */
2901 static void tcg_register_jit_int(void *buf, size_t size,
2902 const void *debug_frame,
2903 size_t debug_frame_size)
2907 void tcg_register_jit(void *buf, size_t buf_size)
2910 #endif /* ELF_HOST_MACHINE */