Merge branch 'upstream-merge'
[qemu-kvm.git] / tcg / tcg.c
blob32cd0c6b657a10b905b9dffb2e28c470582d635a
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 "cache-utils.h"
41 #include "host-utils.h"
42 #include "qemu-timer.h"
44 /* Note: the long term plan is to reduce the dependancies on the QEMU
45 CPU definitions. Currently they are used for qemu_ld/st
46 instructions */
47 #define NO_CPU_IO_DEFS
48 #include "cpu.h"
50 #include "tcg-op.h"
52 #if TCG_TARGET_REG_BITS == 64
53 # define ELF_CLASS ELFCLASS64
54 #else
55 # define ELF_CLASS ELFCLASS32
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 #if defined(CONFIG_USE_GUEST_BASE) && !defined(TCG_TARGET_HAS_GUEST_BASE)
66 #error GUEST_BASE not supported on this host.
67 #endif
69 /* Forward declarations for functions declared in tcg-target.c and used here. */
70 static void tcg_target_init(TCGContext *s);
71 static void tcg_target_qemu_prologue(TCGContext *s);
72 static void patch_reloc(uint8_t *code_ptr, int type,
73 tcg_target_long value, tcg_target_long addend);
75 static void tcg_register_jit_int(void *buf, size_t size,
76 void *debug_frame, size_t debug_frame_size)
77 __attribute__((unused));
79 /* Forward declarations for functions declared and used in tcg-target.c. */
80 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str);
81 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
82 tcg_target_long arg2);
83 static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
84 static void tcg_out_movi(TCGContext *s, TCGType type,
85 TCGReg ret, tcg_target_long arg);
86 static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
87 const int *const_args);
88 static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
89 tcg_target_long arg2);
90 static int tcg_target_const_match(tcg_target_long val,
91 const TCGArgConstraint *arg_ct);
93 TCGOpDef tcg_op_defs[] = {
94 #define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags },
95 #include "tcg-opc.h"
96 #undef DEF
98 const size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs);
100 static TCGRegSet tcg_target_available_regs[2];
101 static TCGRegSet tcg_target_call_clobber_regs;
103 /* XXX: move that inside the context */
104 uint16_t *gen_opc_ptr;
105 TCGArg *gen_opparam_ptr;
107 static inline void tcg_out8(TCGContext *s, uint8_t v)
109 *s->code_ptr++ = v;
112 static inline void tcg_out16(TCGContext *s, uint16_t v)
114 *(uint16_t *)s->code_ptr = v;
115 s->code_ptr += 2;
118 static inline void tcg_out32(TCGContext *s, uint32_t v)
120 *(uint32_t *)s->code_ptr = v;
121 s->code_ptr += 4;
124 /* label relocation processing */
126 static void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
127 int label_index, long addend)
129 TCGLabel *l;
130 TCGRelocation *r;
132 l = &s->labels[label_index];
133 if (l->has_value) {
134 /* FIXME: This may break relocations on RISC targets that
135 modify instruction fields in place. The caller may not have
136 written the initial value. */
137 patch_reloc(code_ptr, type, l->u.value, addend);
138 } else {
139 /* add a new relocation entry */
140 r = tcg_malloc(sizeof(TCGRelocation));
141 r->type = type;
142 r->ptr = code_ptr;
143 r->addend = addend;
144 r->next = l->u.first_reloc;
145 l->u.first_reloc = r;
149 static void tcg_out_label(TCGContext *s, int label_index, void *ptr)
151 TCGLabel *l;
152 TCGRelocation *r;
153 tcg_target_long value = (tcg_target_long)ptr;
155 l = &s->labels[label_index];
156 if (l->has_value)
157 tcg_abort();
158 r = l->u.first_reloc;
159 while (r != NULL) {
160 patch_reloc(r->ptr, r->type, value, r->addend);
161 r = r->next;
163 l->has_value = 1;
164 l->u.value = value;
167 int gen_new_label(void)
169 TCGContext *s = &tcg_ctx;
170 int idx;
171 TCGLabel *l;
173 if (s->nb_labels >= TCG_MAX_LABELS)
174 tcg_abort();
175 idx = s->nb_labels++;
176 l = &s->labels[idx];
177 l->has_value = 0;
178 l->u.first_reloc = NULL;
179 return idx;
182 #include "tcg-target.c"
184 /* pool based memory allocation */
185 void *tcg_malloc_internal(TCGContext *s, int size)
187 TCGPool *p;
188 int pool_size;
190 if (size > TCG_POOL_CHUNK_SIZE) {
191 /* big malloc: insert a new pool (XXX: could optimize) */
192 p = g_malloc(sizeof(TCGPool) + size);
193 p->size = size;
194 p->next = s->pool_first_large;
195 s->pool_first_large = p;
196 return p->data;
197 } else {
198 p = s->pool_current;
199 if (!p) {
200 p = s->pool_first;
201 if (!p)
202 goto new_pool;
203 } else {
204 if (!p->next) {
205 new_pool:
206 pool_size = TCG_POOL_CHUNK_SIZE;
207 p = g_malloc(sizeof(TCGPool) + pool_size);
208 p->size = pool_size;
209 p->next = NULL;
210 if (s->pool_current)
211 s->pool_current->next = p;
212 else
213 s->pool_first = p;
214 } else {
215 p = p->next;
219 s->pool_current = p;
220 s->pool_cur = p->data + size;
221 s->pool_end = p->data + p->size;
222 return p->data;
225 void tcg_pool_reset(TCGContext *s)
227 TCGPool *p, *t;
228 for (p = s->pool_first_large; p; p = t) {
229 t = p->next;
230 g_free(p);
232 s->pool_first_large = NULL;
233 s->pool_cur = s->pool_end = NULL;
234 s->pool_current = NULL;
237 void tcg_context_init(TCGContext *s)
239 int op, total_args, n;
240 TCGOpDef *def;
241 TCGArgConstraint *args_ct;
242 int *sorted_args;
244 memset(s, 0, sizeof(*s));
245 s->nb_globals = 0;
247 /* Count total number of arguments and allocate the corresponding
248 space */
249 total_args = 0;
250 for(op = 0; op < NB_OPS; op++) {
251 def = &tcg_op_defs[op];
252 n = def->nb_iargs + def->nb_oargs;
253 total_args += n;
256 args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args);
257 sorted_args = g_malloc(sizeof(int) * total_args);
259 for(op = 0; op < NB_OPS; op++) {
260 def = &tcg_op_defs[op];
261 def->args_ct = args_ct;
262 def->sorted_args = sorted_args;
263 n = def->nb_iargs + def->nb_oargs;
264 sorted_args += n;
265 args_ct += n;
268 tcg_target_init(s);
271 void tcg_prologue_init(TCGContext *s)
273 /* init global prologue and epilogue */
274 s->code_buf = code_gen_prologue;
275 s->code_ptr = s->code_buf;
276 tcg_target_qemu_prologue(s);
277 flush_icache_range((tcg_target_ulong)s->code_buf,
278 (tcg_target_ulong)s->code_ptr);
281 void tcg_set_frame(TCGContext *s, int reg,
282 tcg_target_long start, tcg_target_long size)
284 s->frame_start = start;
285 s->frame_end = start + size;
286 s->frame_reg = reg;
289 void tcg_func_start(TCGContext *s)
291 int i;
292 tcg_pool_reset(s);
293 s->nb_temps = s->nb_globals;
294 for(i = 0; i < (TCG_TYPE_COUNT * 2); i++)
295 s->first_free_temp[i] = -1;
296 s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
297 s->nb_labels = 0;
298 s->current_frame_offset = s->frame_start;
300 #ifdef CONFIG_DEBUG_TCG
301 s->goto_tb_issue_mask = 0;
302 #endif
304 gen_opc_ptr = gen_opc_buf;
305 gen_opparam_ptr = gen_opparam_buf;
308 static inline void tcg_temp_alloc(TCGContext *s, int n)
310 if (n > TCG_MAX_TEMPS)
311 tcg_abort();
314 static inline int tcg_global_reg_new_internal(TCGType type, int reg,
315 const char *name)
317 TCGContext *s = &tcg_ctx;
318 TCGTemp *ts;
319 int idx;
321 #if TCG_TARGET_REG_BITS == 32
322 if (type != TCG_TYPE_I32)
323 tcg_abort();
324 #endif
325 if (tcg_regset_test_reg(s->reserved_regs, reg))
326 tcg_abort();
327 idx = s->nb_globals;
328 tcg_temp_alloc(s, s->nb_globals + 1);
329 ts = &s->temps[s->nb_globals];
330 ts->base_type = type;
331 ts->type = type;
332 ts->fixed_reg = 1;
333 ts->reg = reg;
334 ts->name = name;
335 s->nb_globals++;
336 tcg_regset_set_reg(s->reserved_regs, reg);
337 return idx;
340 TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
342 int idx;
344 idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name);
345 return MAKE_TCGV_I32(idx);
348 TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
350 int idx;
352 idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);
353 return MAKE_TCGV_I64(idx);
356 static inline int tcg_global_mem_new_internal(TCGType type, int reg,
357 tcg_target_long offset,
358 const char *name)
360 TCGContext *s = &tcg_ctx;
361 TCGTemp *ts;
362 int idx;
364 idx = s->nb_globals;
365 #if TCG_TARGET_REG_BITS == 32
366 if (type == TCG_TYPE_I64) {
367 char buf[64];
368 tcg_temp_alloc(s, s->nb_globals + 2);
369 ts = &s->temps[s->nb_globals];
370 ts->base_type = type;
371 ts->type = TCG_TYPE_I32;
372 ts->fixed_reg = 0;
373 ts->mem_allocated = 1;
374 ts->mem_reg = reg;
375 #ifdef TCG_TARGET_WORDS_BIGENDIAN
376 ts->mem_offset = offset + 4;
377 #else
378 ts->mem_offset = offset;
379 #endif
380 pstrcpy(buf, sizeof(buf), name);
381 pstrcat(buf, sizeof(buf), "_0");
382 ts->name = strdup(buf);
383 ts++;
385 ts->base_type = type;
386 ts->type = TCG_TYPE_I32;
387 ts->fixed_reg = 0;
388 ts->mem_allocated = 1;
389 ts->mem_reg = reg;
390 #ifdef TCG_TARGET_WORDS_BIGENDIAN
391 ts->mem_offset = offset;
392 #else
393 ts->mem_offset = offset + 4;
394 #endif
395 pstrcpy(buf, sizeof(buf), name);
396 pstrcat(buf, sizeof(buf), "_1");
397 ts->name = strdup(buf);
399 s->nb_globals += 2;
400 } else
401 #endif
403 tcg_temp_alloc(s, s->nb_globals + 1);
404 ts = &s->temps[s->nb_globals];
405 ts->base_type = type;
406 ts->type = type;
407 ts->fixed_reg = 0;
408 ts->mem_allocated = 1;
409 ts->mem_reg = reg;
410 ts->mem_offset = offset;
411 ts->name = name;
412 s->nb_globals++;
414 return idx;
417 TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
418 const char *name)
420 int idx;
422 idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
423 return MAKE_TCGV_I32(idx);
426 TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
427 const char *name)
429 int idx;
431 idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
432 return MAKE_TCGV_I64(idx);
435 static inline int tcg_temp_new_internal(TCGType type, int temp_local)
437 TCGContext *s = &tcg_ctx;
438 TCGTemp *ts;
439 int idx, k;
441 k = type;
442 if (temp_local)
443 k += TCG_TYPE_COUNT;
444 idx = s->first_free_temp[k];
445 if (idx != -1) {
446 /* There is already an available temp with the
447 right type */
448 ts = &s->temps[idx];
449 s->first_free_temp[k] = ts->next_free_temp;
450 ts->temp_allocated = 1;
451 assert(ts->temp_local == temp_local);
452 } else {
453 idx = s->nb_temps;
454 #if TCG_TARGET_REG_BITS == 32
455 if (type == TCG_TYPE_I64) {
456 tcg_temp_alloc(s, s->nb_temps + 2);
457 ts = &s->temps[s->nb_temps];
458 ts->base_type = type;
459 ts->type = TCG_TYPE_I32;
460 ts->temp_allocated = 1;
461 ts->temp_local = temp_local;
462 ts->name = NULL;
463 ts++;
464 ts->base_type = TCG_TYPE_I32;
465 ts->type = TCG_TYPE_I32;
466 ts->temp_allocated = 1;
467 ts->temp_local = temp_local;
468 ts->name = NULL;
469 s->nb_temps += 2;
470 } else
471 #endif
473 tcg_temp_alloc(s, s->nb_temps + 1);
474 ts = &s->temps[s->nb_temps];
475 ts->base_type = type;
476 ts->type = type;
477 ts->temp_allocated = 1;
478 ts->temp_local = temp_local;
479 ts->name = NULL;
480 s->nb_temps++;
484 #if defined(CONFIG_DEBUG_TCG)
485 s->temps_in_use++;
486 #endif
487 return idx;
490 TCGv_i32 tcg_temp_new_internal_i32(int temp_local)
492 int idx;
494 idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
495 return MAKE_TCGV_I32(idx);
498 TCGv_i64 tcg_temp_new_internal_i64(int temp_local)
500 int idx;
502 idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
503 return MAKE_TCGV_I64(idx);
506 static inline void tcg_temp_free_internal(int idx)
508 TCGContext *s = &tcg_ctx;
509 TCGTemp *ts;
510 int k;
512 #if defined(CONFIG_DEBUG_TCG)
513 s->temps_in_use--;
514 if (s->temps_in_use < 0) {
515 fprintf(stderr, "More temporaries freed than allocated!\n");
517 #endif
519 assert(idx >= s->nb_globals && idx < s->nb_temps);
520 ts = &s->temps[idx];
521 assert(ts->temp_allocated != 0);
522 ts->temp_allocated = 0;
523 k = ts->base_type;
524 if (ts->temp_local)
525 k += TCG_TYPE_COUNT;
526 ts->next_free_temp = s->first_free_temp[k];
527 s->first_free_temp[k] = idx;
530 void tcg_temp_free_i32(TCGv_i32 arg)
532 tcg_temp_free_internal(GET_TCGV_I32(arg));
535 void tcg_temp_free_i64(TCGv_i64 arg)
537 tcg_temp_free_internal(GET_TCGV_I64(arg));
540 TCGv_i32 tcg_const_i32(int32_t val)
542 TCGv_i32 t0;
543 t0 = tcg_temp_new_i32();
544 tcg_gen_movi_i32(t0, val);
545 return t0;
548 TCGv_i64 tcg_const_i64(int64_t val)
550 TCGv_i64 t0;
551 t0 = tcg_temp_new_i64();
552 tcg_gen_movi_i64(t0, val);
553 return t0;
556 TCGv_i32 tcg_const_local_i32(int32_t val)
558 TCGv_i32 t0;
559 t0 = tcg_temp_local_new_i32();
560 tcg_gen_movi_i32(t0, val);
561 return t0;
564 TCGv_i64 tcg_const_local_i64(int64_t val)
566 TCGv_i64 t0;
567 t0 = tcg_temp_local_new_i64();
568 tcg_gen_movi_i64(t0, val);
569 return t0;
572 #if defined(CONFIG_DEBUG_TCG)
573 void tcg_clear_temp_count(void)
575 TCGContext *s = &tcg_ctx;
576 s->temps_in_use = 0;
579 int tcg_check_temp_count(void)
581 TCGContext *s = &tcg_ctx;
582 if (s->temps_in_use) {
583 /* Clear the count so that we don't give another
584 * warning immediately next time around.
586 s->temps_in_use = 0;
587 return 1;
589 return 0;
591 #endif
593 void tcg_register_helper(void *func, const char *name)
595 TCGContext *s = &tcg_ctx;
596 int n;
597 if ((s->nb_helpers + 1) > s->allocated_helpers) {
598 n = s->allocated_helpers;
599 if (n == 0) {
600 n = 4;
601 } else {
602 n *= 2;
604 s->helpers = realloc(s->helpers, n * sizeof(TCGHelperInfo));
605 s->allocated_helpers = n;
607 s->helpers[s->nb_helpers].func = (tcg_target_ulong)func;
608 s->helpers[s->nb_helpers].name = name;
609 s->nb_helpers++;
612 /* Note: we convert the 64 bit args to 32 bit and do some alignment
613 and endian swap. Maybe it would be better to do the alignment
614 and endian swap in tcg_reg_alloc_call(). */
615 void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
616 int sizemask, TCGArg ret, int nargs, TCGArg *args)
618 int i;
619 int real_args;
620 int nb_rets;
621 TCGArg *nparam;
623 #if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
624 for (i = 0; i < nargs; ++i) {
625 int is_64bit = sizemask & (1 << (i+1)*2);
626 int is_signed = sizemask & (2 << (i+1)*2);
627 if (!is_64bit) {
628 TCGv_i64 temp = tcg_temp_new_i64();
629 TCGv_i64 orig = MAKE_TCGV_I64(args[i]);
630 if (is_signed) {
631 tcg_gen_ext32s_i64(temp, orig);
632 } else {
633 tcg_gen_ext32u_i64(temp, orig);
635 args[i] = GET_TCGV_I64(temp);
638 #endif /* TCG_TARGET_EXTEND_ARGS */
640 *gen_opc_ptr++ = INDEX_op_call;
641 nparam = gen_opparam_ptr++;
642 if (ret != TCG_CALL_DUMMY_ARG) {
643 #if TCG_TARGET_REG_BITS < 64
644 if (sizemask & 1) {
645 #ifdef TCG_TARGET_WORDS_BIGENDIAN
646 *gen_opparam_ptr++ = ret + 1;
647 *gen_opparam_ptr++ = ret;
648 #else
649 *gen_opparam_ptr++ = ret;
650 *gen_opparam_ptr++ = ret + 1;
651 #endif
652 nb_rets = 2;
653 } else
654 #endif
656 *gen_opparam_ptr++ = ret;
657 nb_rets = 1;
659 } else {
660 nb_rets = 0;
662 real_args = 0;
663 for (i = 0; i < nargs; i++) {
664 #if TCG_TARGET_REG_BITS < 64
665 int is_64bit = sizemask & (1 << (i+1)*2);
666 if (is_64bit) {
667 #ifdef TCG_TARGET_CALL_ALIGN_ARGS
668 /* some targets want aligned 64 bit args */
669 if (real_args & 1) {
670 *gen_opparam_ptr++ = TCG_CALL_DUMMY_ARG;
671 real_args++;
673 #endif
674 /* If stack grows up, then we will be placing successive
675 arguments at lower addresses, which means we need to
676 reverse the order compared to how we would normally
677 treat either big or little-endian. For those arguments
678 that will wind up in registers, this still works for
679 HPPA (the only current STACK_GROWSUP target) since the
680 argument registers are *also* allocated in decreasing
681 order. If another such target is added, this logic may
682 have to get more complicated to differentiate between
683 stack arguments and register arguments. */
684 #if defined(TCG_TARGET_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
685 *gen_opparam_ptr++ = args[i] + 1;
686 *gen_opparam_ptr++ = args[i];
687 #else
688 *gen_opparam_ptr++ = args[i];
689 *gen_opparam_ptr++ = args[i] + 1;
690 #endif
691 real_args += 2;
692 continue;
694 #endif /* TCG_TARGET_REG_BITS < 64 */
696 *gen_opparam_ptr++ = args[i];
697 real_args++;
699 *gen_opparam_ptr++ = GET_TCGV_PTR(func);
701 *gen_opparam_ptr++ = flags;
703 *nparam = (nb_rets << 16) | (real_args + 1);
705 /* total parameters, needed to go backward in the instruction stream */
706 *gen_opparam_ptr++ = 1 + nb_rets + real_args + 3;
708 #if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
709 for (i = 0; i < nargs; ++i) {
710 int is_64bit = sizemask & (1 << (i+1)*2);
711 if (!is_64bit) {
712 TCGv_i64 temp = MAKE_TCGV_I64(args[i]);
713 tcg_temp_free_i64(temp);
716 #endif /* TCG_TARGET_EXTEND_ARGS */
719 #if TCG_TARGET_REG_BITS == 32
720 void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
721 int c, int right, int arith)
723 if (c == 0) {
724 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
725 tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
726 } else if (c >= 32) {
727 c -= 32;
728 if (right) {
729 if (arith) {
730 tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
731 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
732 } else {
733 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
734 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
736 } else {
737 tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
738 tcg_gen_movi_i32(TCGV_LOW(ret), 0);
740 } else {
741 TCGv_i32 t0, t1;
743 t0 = tcg_temp_new_i32();
744 t1 = tcg_temp_new_i32();
745 if (right) {
746 tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c);
747 if (arith)
748 tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c);
749 else
750 tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c);
751 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
752 tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t0);
753 tcg_gen_mov_i32(TCGV_HIGH(ret), t1);
754 } else {
755 tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
756 /* Note: ret can be the same as arg1, so we use t1 */
757 tcg_gen_shli_i32(t1, TCGV_LOW(arg1), c);
758 tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
759 tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
760 tcg_gen_mov_i32(TCGV_LOW(ret), t1);
762 tcg_temp_free_i32(t0);
763 tcg_temp_free_i32(t1);
766 #endif
769 static void tcg_reg_alloc_start(TCGContext *s)
771 int i;
772 TCGTemp *ts;
773 for(i = 0; i < s->nb_globals; i++) {
774 ts = &s->temps[i];
775 if (ts->fixed_reg) {
776 ts->val_type = TEMP_VAL_REG;
777 } else {
778 ts->val_type = TEMP_VAL_MEM;
781 for(i = s->nb_globals; i < s->nb_temps; i++) {
782 ts = &s->temps[i];
783 ts->val_type = TEMP_VAL_DEAD;
784 ts->mem_allocated = 0;
785 ts->fixed_reg = 0;
787 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
788 s->reg_to_temp[i] = -1;
792 static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
793 int idx)
795 TCGTemp *ts;
797 assert(idx >= 0 && idx < s->nb_temps);
798 ts = &s->temps[idx];
799 assert(ts);
800 if (idx < s->nb_globals) {
801 pstrcpy(buf, buf_size, ts->name);
802 } else {
803 if (ts->temp_local)
804 snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
805 else
806 snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
808 return buf;
811 char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg)
813 return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg));
816 char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg)
818 return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg));
821 static int helper_cmp(const void *p1, const void *p2)
823 const TCGHelperInfo *th1 = p1;
824 const TCGHelperInfo *th2 = p2;
825 if (th1->func < th2->func)
826 return -1;
827 else if (th1->func == th2->func)
828 return 0;
829 else
830 return 1;
833 /* find helper definition (Note: A hash table would be better) */
834 static TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val)
836 int m, m_min, m_max;
837 TCGHelperInfo *th;
838 tcg_target_ulong v;
840 if (unlikely(!s->helpers_sorted)) {
841 qsort(s->helpers, s->nb_helpers, sizeof(TCGHelperInfo),
842 helper_cmp);
843 s->helpers_sorted = 1;
846 /* binary search */
847 m_min = 0;
848 m_max = s->nb_helpers - 1;
849 while (m_min <= m_max) {
850 m = (m_min + m_max) >> 1;
851 th = &s->helpers[m];
852 v = th->func;
853 if (v == val)
854 return th;
855 else if (val < v) {
856 m_max = m - 1;
857 } else {
858 m_min = m + 1;
861 return NULL;
864 static const char * const cond_name[] =
866 [TCG_COND_NEVER] = "never",
867 [TCG_COND_ALWAYS] = "always",
868 [TCG_COND_EQ] = "eq",
869 [TCG_COND_NE] = "ne",
870 [TCG_COND_LT] = "lt",
871 [TCG_COND_GE] = "ge",
872 [TCG_COND_LE] = "le",
873 [TCG_COND_GT] = "gt",
874 [TCG_COND_LTU] = "ltu",
875 [TCG_COND_GEU] = "geu",
876 [TCG_COND_LEU] = "leu",
877 [TCG_COND_GTU] = "gtu"
880 void tcg_dump_ops(TCGContext *s)
882 const uint16_t *opc_ptr;
883 const TCGArg *args;
884 TCGArg arg;
885 TCGOpcode c;
886 int i, k, nb_oargs, nb_iargs, nb_cargs, first_insn;
887 const TCGOpDef *def;
888 char buf[128];
890 first_insn = 1;
891 opc_ptr = gen_opc_buf;
892 args = gen_opparam_buf;
893 while (opc_ptr < gen_opc_ptr) {
894 c = *opc_ptr++;
895 def = &tcg_op_defs[c];
896 if (c == INDEX_op_debug_insn_start) {
897 uint64_t pc;
898 #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
899 pc = ((uint64_t)args[1] << 32) | args[0];
900 #else
901 pc = args[0];
902 #endif
903 if (!first_insn) {
904 qemu_log("\n");
906 qemu_log(" ---- 0x%" PRIx64, pc);
907 first_insn = 0;
908 nb_oargs = def->nb_oargs;
909 nb_iargs = def->nb_iargs;
910 nb_cargs = def->nb_cargs;
911 } else if (c == INDEX_op_call) {
912 TCGArg arg;
914 /* variable number of arguments */
915 arg = *args++;
916 nb_oargs = arg >> 16;
917 nb_iargs = arg & 0xffff;
918 nb_cargs = def->nb_cargs;
920 qemu_log(" %s ", def->name);
922 /* function name */
923 qemu_log("%s",
924 tcg_get_arg_str_idx(s, buf, sizeof(buf),
925 args[nb_oargs + nb_iargs - 1]));
926 /* flags */
927 qemu_log(",$0x%" TCG_PRIlx, args[nb_oargs + nb_iargs]);
928 /* nb out args */
929 qemu_log(",$%d", nb_oargs);
930 for(i = 0; i < nb_oargs; i++) {
931 qemu_log(",");
932 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
933 args[i]));
935 for(i = 0; i < (nb_iargs - 1); i++) {
936 qemu_log(",");
937 if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) {
938 qemu_log("<dummy>");
939 } else {
940 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
941 args[nb_oargs + i]));
944 } else if (c == INDEX_op_movi_i32 || c == INDEX_op_movi_i64) {
945 tcg_target_ulong val;
946 TCGHelperInfo *th;
948 nb_oargs = def->nb_oargs;
949 nb_iargs = def->nb_iargs;
950 nb_cargs = def->nb_cargs;
951 qemu_log(" %s %s,$", def->name,
952 tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
953 val = args[1];
954 th = tcg_find_helper(s, val);
955 if (th) {
956 qemu_log("%s", th->name);
957 } else {
958 if (c == INDEX_op_movi_i32) {
959 qemu_log("0x%x", (uint32_t)val);
960 } else {
961 qemu_log("0x%" PRIx64 , (uint64_t)val);
964 } else {
965 qemu_log(" %s ", def->name);
966 if (c == INDEX_op_nopn) {
967 /* variable number of arguments */
968 nb_cargs = *args;
969 nb_oargs = 0;
970 nb_iargs = 0;
971 } else {
972 nb_oargs = def->nb_oargs;
973 nb_iargs = def->nb_iargs;
974 nb_cargs = def->nb_cargs;
977 k = 0;
978 for(i = 0; i < nb_oargs; i++) {
979 if (k != 0) {
980 qemu_log(",");
982 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
983 args[k++]));
985 for(i = 0; i < nb_iargs; i++) {
986 if (k != 0) {
987 qemu_log(",");
989 qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
990 args[k++]));
992 switch (c) {
993 case INDEX_op_brcond_i32:
994 case INDEX_op_setcond_i32:
995 case INDEX_op_movcond_i32:
996 case INDEX_op_brcond2_i32:
997 case INDEX_op_setcond2_i32:
998 case INDEX_op_brcond_i64:
999 case INDEX_op_setcond_i64:
1000 case INDEX_op_movcond_i64:
1001 if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) {
1002 qemu_log(",%s", cond_name[args[k++]]);
1003 } else {
1004 qemu_log(",$0x%" TCG_PRIlx, args[k++]);
1006 i = 1;
1007 break;
1008 default:
1009 i = 0;
1010 break;
1012 for(; i < nb_cargs; i++) {
1013 if (k != 0) {
1014 qemu_log(",");
1016 arg = args[k++];
1017 qemu_log("$0x%" TCG_PRIlx, arg);
1020 qemu_log("\n");
1021 args += nb_iargs + nb_oargs + nb_cargs;
1025 /* we give more priority to constraints with less registers */
1026 static int get_constraint_priority(const TCGOpDef *def, int k)
1028 const TCGArgConstraint *arg_ct;
1030 int i, n;
1031 arg_ct = &def->args_ct[k];
1032 if (arg_ct->ct & TCG_CT_ALIAS) {
1033 /* an alias is equivalent to a single register */
1034 n = 1;
1035 } else {
1036 if (!(arg_ct->ct & TCG_CT_REG))
1037 return 0;
1038 n = 0;
1039 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1040 if (tcg_regset_test_reg(arg_ct->u.regs, i))
1041 n++;
1044 return TCG_TARGET_NB_REGS - n + 1;
1047 /* sort from highest priority to lowest */
1048 static void sort_constraints(TCGOpDef *def, int start, int n)
1050 int i, j, p1, p2, tmp;
1052 for(i = 0; i < n; i++)
1053 def->sorted_args[start + i] = start + i;
1054 if (n <= 1)
1055 return;
1056 for(i = 0; i < n - 1; i++) {
1057 for(j = i + 1; j < n; j++) {
1058 p1 = get_constraint_priority(def, def->sorted_args[start + i]);
1059 p2 = get_constraint_priority(def, def->sorted_args[start + j]);
1060 if (p1 < p2) {
1061 tmp = def->sorted_args[start + i];
1062 def->sorted_args[start + i] = def->sorted_args[start + j];
1063 def->sorted_args[start + j] = tmp;
1069 void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
1071 TCGOpcode op;
1072 TCGOpDef *def;
1073 const char *ct_str;
1074 int i, nb_args;
1076 for(;;) {
1077 if (tdefs->op == (TCGOpcode)-1)
1078 break;
1079 op = tdefs->op;
1080 assert((unsigned)op < NB_OPS);
1081 def = &tcg_op_defs[op];
1082 #if defined(CONFIG_DEBUG_TCG)
1083 /* Duplicate entry in op definitions? */
1084 assert(!def->used);
1085 def->used = 1;
1086 #endif
1087 nb_args = def->nb_iargs + def->nb_oargs;
1088 for(i = 0; i < nb_args; i++) {
1089 ct_str = tdefs->args_ct_str[i];
1090 /* Incomplete TCGTargetOpDef entry? */
1091 assert(ct_str != NULL);
1092 tcg_regset_clear(def->args_ct[i].u.regs);
1093 def->args_ct[i].ct = 0;
1094 if (ct_str[0] >= '0' && ct_str[0] <= '9') {
1095 int oarg;
1096 oarg = ct_str[0] - '0';
1097 assert(oarg < def->nb_oargs);
1098 assert(def->args_ct[oarg].ct & TCG_CT_REG);
1099 /* TCG_CT_ALIAS is for the output arguments. The input
1100 argument is tagged with TCG_CT_IALIAS. */
1101 def->args_ct[i] = def->args_ct[oarg];
1102 def->args_ct[oarg].ct = TCG_CT_ALIAS;
1103 def->args_ct[oarg].alias_index = i;
1104 def->args_ct[i].ct |= TCG_CT_IALIAS;
1105 def->args_ct[i].alias_index = oarg;
1106 } else {
1107 for(;;) {
1108 if (*ct_str == '\0')
1109 break;
1110 switch(*ct_str) {
1111 case 'i':
1112 def->args_ct[i].ct |= TCG_CT_CONST;
1113 ct_str++;
1114 break;
1115 default:
1116 if (target_parse_constraint(&def->args_ct[i], &ct_str) < 0) {
1117 fprintf(stderr, "Invalid constraint '%s' for arg %d of operation '%s'\n",
1118 ct_str, i, def->name);
1119 exit(1);
1126 /* TCGTargetOpDef entry with too much information? */
1127 assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL);
1129 /* sort the constraints (XXX: this is just an heuristic) */
1130 sort_constraints(def, 0, def->nb_oargs);
1131 sort_constraints(def, def->nb_oargs, def->nb_iargs);
1133 #if 0
1135 int i;
1137 printf("%s: sorted=", def->name);
1138 for(i = 0; i < def->nb_oargs + def->nb_iargs; i++)
1139 printf(" %d", def->sorted_args[i]);
1140 printf("\n");
1142 #endif
1143 tdefs++;
1146 #if defined(CONFIG_DEBUG_TCG)
1147 i = 0;
1148 for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) {
1149 const TCGOpDef *def = &tcg_op_defs[op];
1150 if (op < INDEX_op_call
1151 || op == INDEX_op_debug_insn_start
1152 || (def->flags & TCG_OPF_NOT_PRESENT)) {
1153 /* Wrong entry in op definitions? */
1154 if (def->used) {
1155 fprintf(stderr, "Invalid op definition for %s\n", def->name);
1156 i = 1;
1158 } else {
1159 /* Missing entry in op definitions? */
1160 if (!def->used) {
1161 fprintf(stderr, "Missing op definition for %s\n", def->name);
1162 i = 1;
1166 if (i == 1) {
1167 tcg_abort();
1169 #endif
1172 #ifdef USE_LIVENESS_ANALYSIS
1174 /* set a nop for an operation using 'nb_args' */
1175 static inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr,
1176 TCGArg *args, int nb_args)
1178 if (nb_args == 0) {
1179 *opc_ptr = INDEX_op_nop;
1180 } else {
1181 *opc_ptr = INDEX_op_nopn;
1182 args[0] = nb_args;
1183 args[nb_args - 1] = nb_args;
1187 /* liveness analysis: end of function: globals are live, temps are
1188 dead. */
1189 /* XXX: at this stage, not used as there would be little gains because
1190 most TBs end with a conditional jump. */
1191 static inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps)
1193 memset(dead_temps, 0, s->nb_globals);
1194 memset(dead_temps + s->nb_globals, 1, s->nb_temps - s->nb_globals);
1197 /* liveness analysis: end of basic block: globals are live, temps are
1198 dead, local temps are live. */
1199 static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps)
1201 int i;
1202 TCGTemp *ts;
1204 memset(dead_temps, 0, s->nb_globals);
1205 ts = &s->temps[s->nb_globals];
1206 for(i = s->nb_globals; i < s->nb_temps; i++) {
1207 if (ts->temp_local)
1208 dead_temps[i] = 0;
1209 else
1210 dead_temps[i] = 1;
1211 ts++;
1215 /* Liveness analysis : update the opc_dead_args array to tell if a
1216 given input arguments is dead. Instructions updating dead
1217 temporaries are removed. */
1218 static void tcg_liveness_analysis(TCGContext *s)
1220 int i, op_index, nb_args, nb_iargs, nb_oargs, arg, nb_ops;
1221 TCGOpcode op;
1222 TCGArg *args;
1223 const TCGOpDef *def;
1224 uint8_t *dead_temps;
1225 unsigned int dead_args;
1227 gen_opc_ptr++; /* skip end */
1229 nb_ops = gen_opc_ptr - gen_opc_buf;
1231 s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1233 dead_temps = tcg_malloc(s->nb_temps);
1234 memset(dead_temps, 1, s->nb_temps);
1236 args = gen_opparam_ptr;
1237 op_index = nb_ops - 1;
1238 while (op_index >= 0) {
1239 op = gen_opc_buf[op_index];
1240 def = &tcg_op_defs[op];
1241 switch(op) {
1242 case INDEX_op_call:
1244 int call_flags;
1246 nb_args = args[-1];
1247 args -= nb_args;
1248 nb_iargs = args[0] & 0xffff;
1249 nb_oargs = args[0] >> 16;
1250 args++;
1251 call_flags = args[nb_oargs + nb_iargs];
1253 /* pure functions can be removed if their result is not
1254 used */
1255 if (call_flags & TCG_CALL_PURE) {
1256 for(i = 0; i < nb_oargs; i++) {
1257 arg = args[i];
1258 if (!dead_temps[arg])
1259 goto do_not_remove_call;
1261 tcg_set_nop(s, gen_opc_buf + op_index,
1262 args - 1, nb_args);
1263 } else {
1264 do_not_remove_call:
1266 /* output args are dead */
1267 dead_args = 0;
1268 for(i = 0; i < nb_oargs; i++) {
1269 arg = args[i];
1270 if (dead_temps[arg]) {
1271 dead_args |= (1 << i);
1273 dead_temps[arg] = 1;
1276 if (!(call_flags & TCG_CALL_CONST)) {
1277 /* globals are live (they may be used by the call) */
1278 memset(dead_temps, 0, s->nb_globals);
1281 /* input args are live */
1282 for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1283 arg = args[i];
1284 if (arg != TCG_CALL_DUMMY_ARG) {
1285 if (dead_temps[arg]) {
1286 dead_args |= (1 << i);
1288 dead_temps[arg] = 0;
1291 s->op_dead_args[op_index] = dead_args;
1293 args--;
1295 break;
1296 case INDEX_op_debug_insn_start:
1297 args -= def->nb_args;
1298 break;
1299 case INDEX_op_nopn:
1300 nb_args = args[-1];
1301 args -= nb_args;
1302 break;
1303 case INDEX_op_discard:
1304 args--;
1305 /* mark the temporary as dead */
1306 dead_temps[args[0]] = 1;
1307 break;
1308 case INDEX_op_end:
1309 break;
1310 /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
1311 default:
1312 args -= def->nb_args;
1313 nb_iargs = def->nb_iargs;
1314 nb_oargs = def->nb_oargs;
1316 /* Test if the operation can be removed because all
1317 its outputs are dead. We assume that nb_oargs == 0
1318 implies side effects */
1319 if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
1320 for(i = 0; i < nb_oargs; i++) {
1321 arg = args[i];
1322 if (!dead_temps[arg])
1323 goto do_not_remove;
1325 tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
1326 #ifdef CONFIG_PROFILER
1327 s->del_op_count++;
1328 #endif
1329 } else {
1330 do_not_remove:
1332 /* output args are dead */
1333 dead_args = 0;
1334 for(i = 0; i < nb_oargs; i++) {
1335 arg = args[i];
1336 if (dead_temps[arg]) {
1337 dead_args |= (1 << i);
1339 dead_temps[arg] = 1;
1342 /* if end of basic block, update */
1343 if (def->flags & TCG_OPF_BB_END) {
1344 tcg_la_bb_end(s, dead_temps);
1345 } else if (def->flags & TCG_OPF_CALL_CLOBBER) {
1346 /* globals are live */
1347 memset(dead_temps, 0, s->nb_globals);
1350 /* input args are live */
1351 for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1352 arg = args[i];
1353 if (dead_temps[arg]) {
1354 dead_args |= (1 << i);
1356 dead_temps[arg] = 0;
1358 s->op_dead_args[op_index] = dead_args;
1360 break;
1362 op_index--;
1365 if (args != gen_opparam_buf)
1366 tcg_abort();
1368 #else
1369 /* dummy liveness analysis */
1370 static void tcg_liveness_analysis(TCGContext *s)
1372 int nb_ops;
1373 nb_ops = gen_opc_ptr - gen_opc_buf;
1375 s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1376 memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
1378 #endif
1380 #ifndef NDEBUG
1381 static void dump_regs(TCGContext *s)
1383 TCGTemp *ts;
1384 int i;
1385 char buf[64];
1387 for(i = 0; i < s->nb_temps; i++) {
1388 ts = &s->temps[i];
1389 printf(" %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
1390 switch(ts->val_type) {
1391 case TEMP_VAL_REG:
1392 printf("%s", tcg_target_reg_names[ts->reg]);
1393 break;
1394 case TEMP_VAL_MEM:
1395 printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
1396 break;
1397 case TEMP_VAL_CONST:
1398 printf("$0x%" TCG_PRIlx, ts->val);
1399 break;
1400 case TEMP_VAL_DEAD:
1401 printf("D");
1402 break;
1403 default:
1404 printf("???");
1405 break;
1407 printf("\n");
1410 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
1411 if (s->reg_to_temp[i] >= 0) {
1412 printf("%s: %s\n",
1413 tcg_target_reg_names[i],
1414 tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
1419 static void check_regs(TCGContext *s)
1421 int reg, k;
1422 TCGTemp *ts;
1423 char buf[64];
1425 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1426 k = s->reg_to_temp[reg];
1427 if (k >= 0) {
1428 ts = &s->temps[k];
1429 if (ts->val_type != TEMP_VAL_REG ||
1430 ts->reg != reg) {
1431 printf("Inconsistency for register %s:\n",
1432 tcg_target_reg_names[reg]);
1433 goto fail;
1437 for(k = 0; k < s->nb_temps; k++) {
1438 ts = &s->temps[k];
1439 if (ts->val_type == TEMP_VAL_REG &&
1440 !ts->fixed_reg &&
1441 s->reg_to_temp[ts->reg] != k) {
1442 printf("Inconsistency for temp %s:\n",
1443 tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
1444 fail:
1445 printf("reg state:\n");
1446 dump_regs(s);
1447 tcg_abort();
1451 #endif
1453 static void temp_allocate_frame(TCGContext *s, int temp)
1455 TCGTemp *ts;
1456 ts = &s->temps[temp];
1457 #if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64)
1458 /* Sparc64 stack is accessed with offset of 2047 */
1459 s->current_frame_offset = (s->current_frame_offset +
1460 (tcg_target_long)sizeof(tcg_target_long) - 1) &
1461 ~(sizeof(tcg_target_long) - 1);
1462 #endif
1463 if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
1464 s->frame_end) {
1465 tcg_abort();
1467 ts->mem_offset = s->current_frame_offset;
1468 ts->mem_reg = s->frame_reg;
1469 ts->mem_allocated = 1;
1470 s->current_frame_offset += (tcg_target_long)sizeof(tcg_target_long);
1473 /* free register 'reg' by spilling the corresponding temporary if necessary */
1474 static void tcg_reg_free(TCGContext *s, int reg)
1476 TCGTemp *ts;
1477 int temp;
1479 temp = s->reg_to_temp[reg];
1480 if (temp != -1) {
1481 ts = &s->temps[temp];
1482 assert(ts->val_type == TEMP_VAL_REG);
1483 if (!ts->mem_coherent) {
1484 if (!ts->mem_allocated)
1485 temp_allocate_frame(s, temp);
1486 tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1488 ts->val_type = TEMP_VAL_MEM;
1489 s->reg_to_temp[reg] = -1;
1493 /* Allocate a register belonging to reg1 & ~reg2 */
1494 static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1496 int i, reg;
1497 TCGRegSet reg_ct;
1499 tcg_regset_andnot(reg_ct, reg1, reg2);
1501 /* first try free registers */
1502 for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1503 reg = tcg_target_reg_alloc_order[i];
1504 if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
1505 return reg;
1508 /* XXX: do better spill choice */
1509 for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
1510 reg = tcg_target_reg_alloc_order[i];
1511 if (tcg_regset_test_reg(reg_ct, reg)) {
1512 tcg_reg_free(s, reg);
1513 return reg;
1517 tcg_abort();
1520 /* save a temporary to memory. 'allocated_regs' is used in case a
1521 temporary registers needs to be allocated to store a constant. */
1522 static void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
1524 TCGTemp *ts;
1525 int reg;
1527 ts = &s->temps[temp];
1528 if (!ts->fixed_reg) {
1529 switch(ts->val_type) {
1530 case TEMP_VAL_REG:
1531 tcg_reg_free(s, ts->reg);
1532 break;
1533 case TEMP_VAL_DEAD:
1534 ts->val_type = TEMP_VAL_MEM;
1535 break;
1536 case TEMP_VAL_CONST:
1537 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1538 allocated_regs);
1539 if (!ts->mem_allocated)
1540 temp_allocate_frame(s, temp);
1541 tcg_out_movi(s, ts->type, reg, ts->val);
1542 tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1543 ts->val_type = TEMP_VAL_MEM;
1544 break;
1545 case TEMP_VAL_MEM:
1546 break;
1547 default:
1548 tcg_abort();
1553 /* save globals to their canonical location and assume they can be
1554 modified be the following code. 'allocated_regs' is used in case a
1555 temporary registers needs to be allocated to store a constant. */
1556 static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
1558 int i;
1560 for(i = 0; i < s->nb_globals; i++) {
1561 temp_save(s, i, allocated_regs);
1565 /* at the end of a basic block, we assume all temporaries are dead and
1566 all globals are stored at their canonical location. */
1567 static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
1569 TCGTemp *ts;
1570 int i;
1572 for(i = s->nb_globals; i < s->nb_temps; i++) {
1573 ts = &s->temps[i];
1574 if (ts->temp_local) {
1575 temp_save(s, i, allocated_regs);
1576 } else {
1577 if (ts->val_type == TEMP_VAL_REG) {
1578 s->reg_to_temp[ts->reg] = -1;
1580 ts->val_type = TEMP_VAL_DEAD;
1584 save_globals(s, allocated_regs);
1587 #define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
1589 static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args)
1591 TCGTemp *ots;
1592 tcg_target_ulong val;
1594 ots = &s->temps[args[0]];
1595 val = args[1];
1597 if (ots->fixed_reg) {
1598 /* for fixed registers, we do not do any constant
1599 propagation */
1600 tcg_out_movi(s, ots->type, ots->reg, val);
1601 } else {
1602 /* The movi is not explicitly generated here */
1603 if (ots->val_type == TEMP_VAL_REG)
1604 s->reg_to_temp[ots->reg] = -1;
1605 ots->val_type = TEMP_VAL_CONST;
1606 ots->val = val;
1610 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
1611 const TCGArg *args,
1612 unsigned int dead_args)
1614 TCGTemp *ts, *ots;
1615 int reg;
1616 const TCGArgConstraint *arg_ct;
1618 ots = &s->temps[args[0]];
1619 ts = &s->temps[args[1]];
1620 arg_ct = &def->args_ct[0];
1622 /* XXX: always mark arg dead if IS_DEAD_ARG(1) */
1623 if (ts->val_type == TEMP_VAL_REG) {
1624 if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
1625 /* the mov can be suppressed */
1626 if (ots->val_type == TEMP_VAL_REG)
1627 s->reg_to_temp[ots->reg] = -1;
1628 reg = ts->reg;
1629 s->reg_to_temp[reg] = -1;
1630 ts->val_type = TEMP_VAL_DEAD;
1631 } else {
1632 if (ots->val_type == TEMP_VAL_REG) {
1633 reg = ots->reg;
1634 } else {
1635 reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
1637 if (ts->reg != reg) {
1638 tcg_out_mov(s, ots->type, reg, ts->reg);
1641 } else if (ts->val_type == TEMP_VAL_MEM) {
1642 if (ots->val_type == TEMP_VAL_REG) {
1643 reg = ots->reg;
1644 } else {
1645 reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
1647 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1648 } else if (ts->val_type == TEMP_VAL_CONST) {
1649 if (ots->fixed_reg) {
1650 reg = ots->reg;
1651 tcg_out_movi(s, ots->type, reg, ts->val);
1652 } else {
1653 /* propagate constant */
1654 if (ots->val_type == TEMP_VAL_REG)
1655 s->reg_to_temp[ots->reg] = -1;
1656 ots->val_type = TEMP_VAL_CONST;
1657 ots->val = ts->val;
1658 return;
1660 } else {
1661 tcg_abort();
1663 s->reg_to_temp[reg] = args[0];
1664 ots->reg = reg;
1665 ots->val_type = TEMP_VAL_REG;
1666 ots->mem_coherent = 0;
1669 static void tcg_reg_alloc_op(TCGContext *s,
1670 const TCGOpDef *def, TCGOpcode opc,
1671 const TCGArg *args,
1672 unsigned int dead_args)
1674 TCGRegSet allocated_regs;
1675 int i, k, nb_iargs, nb_oargs, reg;
1676 TCGArg arg;
1677 const TCGArgConstraint *arg_ct;
1678 TCGTemp *ts;
1679 TCGArg new_args[TCG_MAX_OP_ARGS];
1680 int const_args[TCG_MAX_OP_ARGS];
1682 nb_oargs = def->nb_oargs;
1683 nb_iargs = def->nb_iargs;
1685 /* copy constants */
1686 memcpy(new_args + nb_oargs + nb_iargs,
1687 args + nb_oargs + nb_iargs,
1688 sizeof(TCGArg) * def->nb_cargs);
1690 /* satisfy input constraints */
1691 tcg_regset_set(allocated_regs, s->reserved_regs);
1692 for(k = 0; k < nb_iargs; k++) {
1693 i = def->sorted_args[nb_oargs + k];
1694 arg = args[i];
1695 arg_ct = &def->args_ct[i];
1696 ts = &s->temps[arg];
1697 if (ts->val_type == TEMP_VAL_MEM) {
1698 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1699 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1700 ts->val_type = TEMP_VAL_REG;
1701 ts->reg = reg;
1702 ts->mem_coherent = 1;
1703 s->reg_to_temp[reg] = arg;
1704 } else if (ts->val_type == TEMP_VAL_CONST) {
1705 if (tcg_target_const_match(ts->val, arg_ct)) {
1706 /* constant is OK for instruction */
1707 const_args[i] = 1;
1708 new_args[i] = ts->val;
1709 goto iarg_end;
1710 } else {
1711 /* need to move to a register */
1712 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1713 tcg_out_movi(s, ts->type, reg, ts->val);
1714 ts->val_type = TEMP_VAL_REG;
1715 ts->reg = reg;
1716 ts->mem_coherent = 0;
1717 s->reg_to_temp[reg] = arg;
1720 assert(ts->val_type == TEMP_VAL_REG);
1721 if (arg_ct->ct & TCG_CT_IALIAS) {
1722 if (ts->fixed_reg) {
1723 /* if fixed register, we must allocate a new register
1724 if the alias is not the same register */
1725 if (arg != args[arg_ct->alias_index])
1726 goto allocate_in_reg;
1727 } else {
1728 /* if the input is aliased to an output and if it is
1729 not dead after the instruction, we must allocate
1730 a new register and move it */
1731 if (!IS_DEAD_ARG(i)) {
1732 goto allocate_in_reg;
1736 reg = ts->reg;
1737 if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1738 /* nothing to do : the constraint is satisfied */
1739 } else {
1740 allocate_in_reg:
1741 /* allocate a new register matching the constraint
1742 and move the temporary register into it */
1743 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1744 tcg_out_mov(s, ts->type, reg, ts->reg);
1746 new_args[i] = reg;
1747 const_args[i] = 0;
1748 tcg_regset_set_reg(allocated_regs, reg);
1749 iarg_end: ;
1752 if (def->flags & TCG_OPF_BB_END) {
1753 tcg_reg_alloc_bb_end(s, allocated_regs);
1754 } else {
1755 /* mark dead temporaries and free the associated registers */
1756 for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1757 arg = args[i];
1758 if (IS_DEAD_ARG(i)) {
1759 ts = &s->temps[arg];
1760 if (!ts->fixed_reg) {
1761 if (ts->val_type == TEMP_VAL_REG)
1762 s->reg_to_temp[ts->reg] = -1;
1763 ts->val_type = TEMP_VAL_DEAD;
1768 if (def->flags & TCG_OPF_CALL_CLOBBER) {
1769 /* XXX: permit generic clobber register list ? */
1770 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1771 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1772 tcg_reg_free(s, reg);
1775 /* XXX: for load/store we could do that only for the slow path
1776 (i.e. when a memory callback is called) */
1778 /* store globals and free associated registers (we assume the insn
1779 can modify any global. */
1780 save_globals(s, allocated_regs);
1783 /* satisfy the output constraints */
1784 tcg_regset_set(allocated_regs, s->reserved_regs);
1785 for(k = 0; k < nb_oargs; k++) {
1786 i = def->sorted_args[k];
1787 arg = args[i];
1788 arg_ct = &def->args_ct[i];
1789 ts = &s->temps[arg];
1790 if (arg_ct->ct & TCG_CT_ALIAS) {
1791 reg = new_args[arg_ct->alias_index];
1792 } else {
1793 /* if fixed register, we try to use it */
1794 reg = ts->reg;
1795 if (ts->fixed_reg &&
1796 tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1797 goto oarg_end;
1799 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1801 tcg_regset_set_reg(allocated_regs, reg);
1802 /* if a fixed register is used, then a move will be done afterwards */
1803 if (!ts->fixed_reg) {
1804 if (ts->val_type == TEMP_VAL_REG)
1805 s->reg_to_temp[ts->reg] = -1;
1806 if (IS_DEAD_ARG(i)) {
1807 ts->val_type = TEMP_VAL_DEAD;
1808 } else {
1809 ts->val_type = TEMP_VAL_REG;
1810 ts->reg = reg;
1811 /* temp value is modified, so the value kept in memory is
1812 potentially not the same */
1813 ts->mem_coherent = 0;
1814 s->reg_to_temp[reg] = arg;
1817 oarg_end:
1818 new_args[i] = reg;
1822 /* emit instruction */
1823 tcg_out_op(s, opc, new_args, const_args);
1825 /* move the outputs in the correct register if needed */
1826 for(i = 0; i < nb_oargs; i++) {
1827 ts = &s->temps[args[i]];
1828 reg = new_args[i];
1829 if (ts->fixed_reg && ts->reg != reg) {
1830 tcg_out_mov(s, ts->type, ts->reg, reg);
1835 #ifdef TCG_TARGET_STACK_GROWSUP
1836 #define STACK_DIR(x) (-(x))
1837 #else
1838 #define STACK_DIR(x) (x)
1839 #endif
1841 static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1842 TCGOpcode opc, const TCGArg *args,
1843 unsigned int dead_args)
1845 int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
1846 TCGArg arg, func_arg;
1847 TCGTemp *ts;
1848 tcg_target_long stack_offset, call_stack_size, func_addr;
1849 int const_func_arg, allocate_args;
1850 TCGRegSet allocated_regs;
1851 const TCGArgConstraint *arg_ct;
1853 arg = *args++;
1855 nb_oargs = arg >> 16;
1856 nb_iargs = arg & 0xffff;
1857 nb_params = nb_iargs - 1;
1859 flags = args[nb_oargs + nb_iargs];
1861 nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
1862 if (nb_regs > nb_params)
1863 nb_regs = nb_params;
1865 /* assign stack slots first */
1866 call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
1867 call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) &
1868 ~(TCG_TARGET_STACK_ALIGN - 1);
1869 allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
1870 if (allocate_args) {
1871 /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
1872 preallocate call stack */
1873 tcg_abort();
1876 stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
1877 for(i = nb_regs; i < nb_params; i++) {
1878 arg = args[nb_oargs + i];
1879 #ifdef TCG_TARGET_STACK_GROWSUP
1880 stack_offset -= sizeof(tcg_target_long);
1881 #endif
1882 if (arg != TCG_CALL_DUMMY_ARG) {
1883 ts = &s->temps[arg];
1884 if (ts->val_type == TEMP_VAL_REG) {
1885 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
1886 } else if (ts->val_type == TEMP_VAL_MEM) {
1887 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1888 s->reserved_regs);
1889 /* XXX: not correct if reading values from the stack */
1890 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1891 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
1892 } else if (ts->val_type == TEMP_VAL_CONST) {
1893 reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
1894 s->reserved_regs);
1895 /* XXX: sign extend may be needed on some targets */
1896 tcg_out_movi(s, ts->type, reg, ts->val);
1897 tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
1898 } else {
1899 tcg_abort();
1902 #ifndef TCG_TARGET_STACK_GROWSUP
1903 stack_offset += sizeof(tcg_target_long);
1904 #endif
1907 /* assign input registers */
1908 tcg_regset_set(allocated_regs, s->reserved_regs);
1909 for(i = 0; i < nb_regs; i++) {
1910 arg = args[nb_oargs + i];
1911 if (arg != TCG_CALL_DUMMY_ARG) {
1912 ts = &s->temps[arg];
1913 reg = tcg_target_call_iarg_regs[i];
1914 tcg_reg_free(s, reg);
1915 if (ts->val_type == TEMP_VAL_REG) {
1916 if (ts->reg != reg) {
1917 tcg_out_mov(s, ts->type, reg, ts->reg);
1919 } else if (ts->val_type == TEMP_VAL_MEM) {
1920 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1921 } else if (ts->val_type == TEMP_VAL_CONST) {
1922 /* XXX: sign extend ? */
1923 tcg_out_movi(s, ts->type, reg, ts->val);
1924 } else {
1925 tcg_abort();
1927 tcg_regset_set_reg(allocated_regs, reg);
1931 /* assign function address */
1932 func_arg = args[nb_oargs + nb_iargs - 1];
1933 arg_ct = &def->args_ct[0];
1934 ts = &s->temps[func_arg];
1935 func_addr = ts->val;
1936 const_func_arg = 0;
1937 if (ts->val_type == TEMP_VAL_MEM) {
1938 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1939 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1940 func_arg = reg;
1941 tcg_regset_set_reg(allocated_regs, reg);
1942 } else if (ts->val_type == TEMP_VAL_REG) {
1943 reg = ts->reg;
1944 if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1945 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1946 tcg_out_mov(s, ts->type, reg, ts->reg);
1948 func_arg = reg;
1949 tcg_regset_set_reg(allocated_regs, reg);
1950 } else if (ts->val_type == TEMP_VAL_CONST) {
1951 if (tcg_target_const_match(func_addr, arg_ct)) {
1952 const_func_arg = 1;
1953 func_arg = func_addr;
1954 } else {
1955 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1956 tcg_out_movi(s, ts->type, reg, func_addr);
1957 func_arg = reg;
1958 tcg_regset_set_reg(allocated_regs, reg);
1960 } else {
1961 tcg_abort();
1965 /* mark dead temporaries and free the associated registers */
1966 for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1967 arg = args[i];
1968 if (IS_DEAD_ARG(i)) {
1969 ts = &s->temps[arg];
1970 if (!ts->fixed_reg) {
1971 if (ts->val_type == TEMP_VAL_REG)
1972 s->reg_to_temp[ts->reg] = -1;
1973 ts->val_type = TEMP_VAL_DEAD;
1978 /* clobber call registers */
1979 for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1980 if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1981 tcg_reg_free(s, reg);
1985 /* store globals and free associated registers (we assume the call
1986 can modify any global. */
1987 if (!(flags & TCG_CALL_CONST)) {
1988 save_globals(s, allocated_regs);
1991 tcg_out_op(s, opc, &func_arg, &const_func_arg);
1993 /* assign output registers and emit moves if needed */
1994 for(i = 0; i < nb_oargs; i++) {
1995 arg = args[i];
1996 ts = &s->temps[arg];
1997 reg = tcg_target_call_oarg_regs[i];
1998 assert(s->reg_to_temp[reg] == -1);
1999 if (ts->fixed_reg) {
2000 if (ts->reg != reg) {
2001 tcg_out_mov(s, ts->type, ts->reg, reg);
2003 } else {
2004 if (ts->val_type == TEMP_VAL_REG)
2005 s->reg_to_temp[ts->reg] = -1;
2006 if (IS_DEAD_ARG(i)) {
2007 ts->val_type = TEMP_VAL_DEAD;
2008 } else {
2009 ts->val_type = TEMP_VAL_REG;
2010 ts->reg = reg;
2011 ts->mem_coherent = 0;
2012 s->reg_to_temp[reg] = arg;
2017 return nb_iargs + nb_oargs + def->nb_cargs + 1;
2020 #ifdef CONFIG_PROFILER
2022 static int64_t tcg_table_op_count[NB_OPS];
2024 static void dump_op_count(void)
2026 int i;
2027 FILE *f;
2028 f = fopen("/tmp/op.log", "w");
2029 for(i = INDEX_op_end; i < NB_OPS; i++) {
2030 fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
2032 fclose(f);
2034 #endif
2037 static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
2038 long search_pc)
2040 TCGOpcode opc;
2041 int op_index;
2042 const TCGOpDef *def;
2043 unsigned int dead_args;
2044 const TCGArg *args;
2046 #ifdef DEBUG_DISAS
2047 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2048 qemu_log("OP:\n");
2049 tcg_dump_ops(s);
2050 qemu_log("\n");
2052 #endif
2054 #ifdef CONFIG_PROFILER
2055 s->opt_time -= profile_getclock();
2056 #endif
2058 #ifdef USE_TCG_OPTIMIZATIONS
2059 gen_opparam_ptr =
2060 tcg_optimize(s, gen_opc_ptr, gen_opparam_buf, tcg_op_defs);
2061 #endif
2063 #ifdef CONFIG_PROFILER
2064 s->opt_time += profile_getclock();
2065 s->la_time -= profile_getclock();
2066 #endif
2068 tcg_liveness_analysis(s);
2070 #ifdef CONFIG_PROFILER
2071 s->la_time += profile_getclock();
2072 #endif
2074 #ifdef DEBUG_DISAS
2075 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
2076 qemu_log("OP after optimization and liveness analysis:\n");
2077 tcg_dump_ops(s);
2078 qemu_log("\n");
2080 #endif
2082 tcg_reg_alloc_start(s);
2084 s->code_buf = gen_code_buf;
2085 s->code_ptr = gen_code_buf;
2087 args = gen_opparam_buf;
2088 op_index = 0;
2090 for(;;) {
2091 opc = gen_opc_buf[op_index];
2092 #ifdef CONFIG_PROFILER
2093 tcg_table_op_count[opc]++;
2094 #endif
2095 def = &tcg_op_defs[opc];
2096 #if 0
2097 printf("%s: %d %d %d\n", def->name,
2098 def->nb_oargs, def->nb_iargs, def->nb_cargs);
2099 // dump_regs(s);
2100 #endif
2101 switch(opc) {
2102 case INDEX_op_mov_i32:
2103 case INDEX_op_mov_i64:
2104 dead_args = s->op_dead_args[op_index];
2105 tcg_reg_alloc_mov(s, def, args, dead_args);
2106 break;
2107 case INDEX_op_movi_i32:
2108 case INDEX_op_movi_i64:
2109 tcg_reg_alloc_movi(s, args);
2110 break;
2111 case INDEX_op_debug_insn_start:
2112 /* debug instruction */
2113 break;
2114 case INDEX_op_nop:
2115 case INDEX_op_nop1:
2116 case INDEX_op_nop2:
2117 case INDEX_op_nop3:
2118 break;
2119 case INDEX_op_nopn:
2120 args += args[0];
2121 goto next;
2122 case INDEX_op_discard:
2124 TCGTemp *ts;
2125 ts = &s->temps[args[0]];
2126 /* mark the temporary as dead */
2127 if (!ts->fixed_reg) {
2128 if (ts->val_type == TEMP_VAL_REG)
2129 s->reg_to_temp[ts->reg] = -1;
2130 ts->val_type = TEMP_VAL_DEAD;
2133 break;
2134 case INDEX_op_set_label:
2135 tcg_reg_alloc_bb_end(s, s->reserved_regs);
2136 tcg_out_label(s, args[0], s->code_ptr);
2137 break;
2138 case INDEX_op_call:
2139 dead_args = s->op_dead_args[op_index];
2140 args += tcg_reg_alloc_call(s, def, opc, args, dead_args);
2141 goto next;
2142 case INDEX_op_end:
2143 goto the_end;
2144 default:
2145 /* Sanity check that we've not introduced any unhandled opcodes. */
2146 if (def->flags & TCG_OPF_NOT_PRESENT) {
2147 tcg_abort();
2149 /* Note: in order to speed up the code, it would be much
2150 faster to have specialized register allocator functions for
2151 some common argument patterns */
2152 dead_args = s->op_dead_args[op_index];
2153 tcg_reg_alloc_op(s, def, opc, args, dead_args);
2154 break;
2156 args += def->nb_args;
2157 next:
2158 if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
2159 return op_index;
2161 op_index++;
2162 #ifndef NDEBUG
2163 check_regs(s);
2164 #endif
2166 the_end:
2167 return -1;
2170 int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
2172 #ifdef CONFIG_PROFILER
2174 int n;
2175 n = (gen_opc_ptr - gen_opc_buf);
2176 s->op_count += n;
2177 if (n > s->op_count_max)
2178 s->op_count_max = n;
2180 s->temp_count += s->nb_temps;
2181 if (s->nb_temps > s->temp_count_max)
2182 s->temp_count_max = s->nb_temps;
2184 #endif
2186 tcg_gen_code_common(s, gen_code_buf, -1);
2188 /* flush instruction cache */
2189 flush_icache_range((tcg_target_ulong)gen_code_buf,
2190 (tcg_target_ulong)s->code_ptr);
2192 return s->code_ptr - gen_code_buf;
2195 /* Return the index of the micro operation such as the pc after is <
2196 offset bytes from the start of the TB. The contents of gen_code_buf must
2197 not be changed, though writing the same values is ok.
2198 Return -1 if not found. */
2199 int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
2201 return tcg_gen_code_common(s, gen_code_buf, offset);
2204 #ifdef CONFIG_PROFILER
2205 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2207 TCGContext *s = &tcg_ctx;
2208 int64_t tot;
2210 tot = s->interm_time + s->code_time;
2211 cpu_fprintf(f, "JIT cycles %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2212 tot, tot / 2.4e9);
2213 cpu_fprintf(f, "translated TBs %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n",
2214 s->tb_count,
2215 s->tb_count1 - s->tb_count,
2216 s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
2217 cpu_fprintf(f, "avg ops/TB %0.1f max=%d\n",
2218 s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
2219 cpu_fprintf(f, "deleted ops/TB %0.2f\n",
2220 s->tb_count ?
2221 (double)s->del_op_count / s->tb_count : 0);
2222 cpu_fprintf(f, "avg temps/TB %0.2f max=%d\n",
2223 s->tb_count ?
2224 (double)s->temp_count / s->tb_count : 0,
2225 s->temp_count_max);
2227 cpu_fprintf(f, "cycles/op %0.1f\n",
2228 s->op_count ? (double)tot / s->op_count : 0);
2229 cpu_fprintf(f, "cycles/in byte %0.1f\n",
2230 s->code_in_len ? (double)tot / s->code_in_len : 0);
2231 cpu_fprintf(f, "cycles/out byte %0.1f\n",
2232 s->code_out_len ? (double)tot / s->code_out_len : 0);
2233 if (tot == 0)
2234 tot = 1;
2235 cpu_fprintf(f, " gen_interm time %0.1f%%\n",
2236 (double)s->interm_time / tot * 100.0);
2237 cpu_fprintf(f, " gen_code time %0.1f%%\n",
2238 (double)s->code_time / tot * 100.0);
2239 cpu_fprintf(f, "optim./code time %0.1f%%\n",
2240 (double)s->opt_time / (s->code_time ? s->code_time : 1)
2241 * 100.0);
2242 cpu_fprintf(f, "liveness/code time %0.1f%%\n",
2243 (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
2244 cpu_fprintf(f, "cpu_restore count %" PRId64 "\n",
2245 s->restore_count);
2246 cpu_fprintf(f, " avg cycles %0.1f\n",
2247 s->restore_count ? (double)s->restore_time / s->restore_count : 0);
2249 dump_op_count();
2251 #else
2252 void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
2254 cpu_fprintf(f, "[TCG profiler not compiled]\n");
2256 #endif
2258 #ifdef ELF_HOST_MACHINE
2259 /* In order to use this feature, the backend needs to do three things:
2261 (1) Define ELF_HOST_MACHINE to indicate both what value to
2262 put into the ELF image and to indicate support for the feature.
2264 (2) Define tcg_register_jit. This should create a buffer containing
2265 the contents of a .debug_frame section that describes the post-
2266 prologue unwind info for the tcg machine.
2268 (3) Call tcg_register_jit_int, with the constructed .debug_frame.
2271 /* Begin GDB interface. THE FOLLOWING MUST MATCH GDB DOCS. */
2272 typedef enum {
2273 JIT_NOACTION = 0,
2274 JIT_REGISTER_FN,
2275 JIT_UNREGISTER_FN
2276 } jit_actions_t;
2278 struct jit_code_entry {
2279 struct jit_code_entry *next_entry;
2280 struct jit_code_entry *prev_entry;
2281 const void *symfile_addr;
2282 uint64_t symfile_size;
2285 struct jit_descriptor {
2286 uint32_t version;
2287 uint32_t action_flag;
2288 struct jit_code_entry *relevant_entry;
2289 struct jit_code_entry *first_entry;
2292 void __jit_debug_register_code(void) __attribute__((noinline));
2293 void __jit_debug_register_code(void)
2295 asm("");
2298 /* Must statically initialize the version, because GDB may check
2299 the version before we can set it. */
2300 struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
2302 /* End GDB interface. */
2304 static int find_string(const char *strtab, const char *str)
2306 const char *p = strtab + 1;
2308 while (1) {
2309 if (strcmp(p, str) == 0) {
2310 return p - strtab;
2312 p += strlen(p) + 1;
2316 static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
2317 void *debug_frame, size_t debug_frame_size)
2319 struct __attribute__((packed)) DebugInfo {
2320 uint32_t len;
2321 uint16_t version;
2322 uint32_t abbrev;
2323 uint8_t ptr_size;
2324 uint8_t cu_die;
2325 uint16_t cu_lang;
2326 uintptr_t cu_low_pc;
2327 uintptr_t cu_high_pc;
2328 uint8_t fn_die;
2329 char fn_name[16];
2330 uintptr_t fn_low_pc;
2331 uintptr_t fn_high_pc;
2332 uint8_t cu_eoc;
2335 struct ElfImage {
2336 ElfW(Ehdr) ehdr;
2337 ElfW(Phdr) phdr;
2338 ElfW(Shdr) shdr[7];
2339 ElfW(Sym) sym[2];
2340 struct DebugInfo di;
2341 uint8_t da[24];
2342 char str[80];
2345 struct ElfImage *img;
2347 static const struct ElfImage img_template = {
2348 .ehdr = {
2349 .e_ident[EI_MAG0] = ELFMAG0,
2350 .e_ident[EI_MAG1] = ELFMAG1,
2351 .e_ident[EI_MAG2] = ELFMAG2,
2352 .e_ident[EI_MAG3] = ELFMAG3,
2353 .e_ident[EI_CLASS] = ELF_CLASS,
2354 .e_ident[EI_DATA] = ELF_DATA,
2355 .e_ident[EI_VERSION] = EV_CURRENT,
2356 .e_type = ET_EXEC,
2357 .e_machine = ELF_HOST_MACHINE,
2358 .e_version = EV_CURRENT,
2359 .e_phoff = offsetof(struct ElfImage, phdr),
2360 .e_shoff = offsetof(struct ElfImage, shdr),
2361 .e_ehsize = sizeof(ElfW(Shdr)),
2362 .e_phentsize = sizeof(ElfW(Phdr)),
2363 .e_phnum = 1,
2364 .e_shentsize = sizeof(ElfW(Shdr)),
2365 .e_shnum = ARRAY_SIZE(img->shdr),
2366 .e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
2367 #ifdef ELF_HOST_FLAGS
2368 .e_flags = ELF_HOST_FLAGS,
2369 #endif
2370 #ifdef ELF_OSABI
2371 .e_ident[EI_OSABI] = ELF_OSABI,
2372 #endif
2374 .phdr = {
2375 .p_type = PT_LOAD,
2376 .p_flags = PF_X,
2378 .shdr = {
2379 [0] = { .sh_type = SHT_NULL },
2380 /* Trick: The contents of code_gen_buffer are not present in
2381 this fake ELF file; that got allocated elsewhere. Therefore
2382 we mark .text as SHT_NOBITS (similar to .bss) so that readers
2383 will not look for contents. We can record any address. */
2384 [1] = { /* .text */
2385 .sh_type = SHT_NOBITS,
2386 .sh_flags = SHF_EXECINSTR | SHF_ALLOC,
2388 [2] = { /* .debug_info */
2389 .sh_type = SHT_PROGBITS,
2390 .sh_offset = offsetof(struct ElfImage, di),
2391 .sh_size = sizeof(struct DebugInfo),
2393 [3] = { /* .debug_abbrev */
2394 .sh_type = SHT_PROGBITS,
2395 .sh_offset = offsetof(struct ElfImage, da),
2396 .sh_size = sizeof(img->da),
2398 [4] = { /* .debug_frame */
2399 .sh_type = SHT_PROGBITS,
2400 .sh_offset = sizeof(struct ElfImage),
2402 [5] = { /* .symtab */
2403 .sh_type = SHT_SYMTAB,
2404 .sh_offset = offsetof(struct ElfImage, sym),
2405 .sh_size = sizeof(img->sym),
2406 .sh_info = 1,
2407 .sh_link = ARRAY_SIZE(img->shdr) - 1,
2408 .sh_entsize = sizeof(ElfW(Sym)),
2410 [6] = { /* .strtab */
2411 .sh_type = SHT_STRTAB,
2412 .sh_offset = offsetof(struct ElfImage, str),
2413 .sh_size = sizeof(img->str),
2416 .sym = {
2417 [1] = { /* code_gen_buffer */
2418 .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
2419 .st_shndx = 1,
2422 .di = {
2423 .len = sizeof(struct DebugInfo) - 4,
2424 .version = 2,
2425 .ptr_size = sizeof(void *),
2426 .cu_die = 1,
2427 .cu_lang = 0x8001, /* DW_LANG_Mips_Assembler */
2428 .fn_die = 2,
2429 .fn_name = "code_gen_buffer"
2431 .da = {
2432 1, /* abbrev number (the cu) */
2433 0x11, 1, /* DW_TAG_compile_unit, has children */
2434 0x13, 0x5, /* DW_AT_language, DW_FORM_data2 */
2435 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
2436 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
2437 0, 0, /* end of abbrev */
2438 2, /* abbrev number (the fn) */
2439 0x2e, 0, /* DW_TAG_subprogram, no children */
2440 0x3, 0x8, /* DW_AT_name, DW_FORM_string */
2441 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
2442 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
2443 0, 0, /* end of abbrev */
2444 0 /* no more abbrev */
2446 .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
2447 ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
2450 /* We only need a single jit entry; statically allocate it. */
2451 static struct jit_code_entry one_entry;
2453 uintptr_t buf = (uintptr_t)buf_ptr;
2454 size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
2456 img = g_malloc(img_size);
2457 *img = img_template;
2458 memcpy(img + 1, debug_frame, debug_frame_size);
2460 img->phdr.p_vaddr = buf;
2461 img->phdr.p_paddr = buf;
2462 img->phdr.p_memsz = buf_size;
2464 img->shdr[1].sh_name = find_string(img->str, ".text");
2465 img->shdr[1].sh_addr = buf;
2466 img->shdr[1].sh_size = buf_size;
2468 img->shdr[2].sh_name = find_string(img->str, ".debug_info");
2469 img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
2471 img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
2472 img->shdr[4].sh_size = debug_frame_size;
2474 img->shdr[5].sh_name = find_string(img->str, ".symtab");
2475 img->shdr[6].sh_name = find_string(img->str, ".strtab");
2477 img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
2478 img->sym[1].st_value = buf;
2479 img->sym[1].st_size = buf_size;
2481 img->di.cu_low_pc = buf;
2482 img->di.cu_high_pc = buf_size;
2483 img->di.fn_low_pc = buf;
2484 img->di.fn_high_pc = buf_size;
2486 #ifdef DEBUG_JIT
2487 /* Enable this block to be able to debug the ELF image file creation.
2488 One can use readelf, objdump, or other inspection utilities. */
2490 FILE *f = fopen("/tmp/qemu.jit", "w+b");
2491 if (f) {
2492 if (fwrite(img, img_size, 1, f) != img_size) {
2493 /* Avoid stupid unused return value warning for fwrite. */
2495 fclose(f);
2498 #endif
2500 one_entry.symfile_addr = img;
2501 one_entry.symfile_size = img_size;
2503 __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
2504 __jit_debug_descriptor.relevant_entry = &one_entry;
2505 __jit_debug_descriptor.first_entry = &one_entry;
2506 __jit_debug_register_code();
2508 #else
2509 /* No support for the feature. Provide the entry point expected by exec.c,
2510 and implement the internal function we declared earlier. */
2512 static void tcg_register_jit_int(void *buf, size_t size,
2513 void *debug_frame, size_t debug_frame_size)
2517 void tcg_register_jit(void *buf, size_t buf_size)
2520 #endif /* ELF_HOST_MACHINE */