aboutsummaryrefslogtreecommitdiffstats
path: root/tcg/tcg.c
diff options
context:
space:
mode:
Diffstat (limited to 'tcg/tcg.c')
-rw-r--r--tcg/tcg.c99
1 files changed, 65 insertions, 34 deletions
diff --git a/tcg/tcg.c b/tcg/tcg.c
index c63168b..77bd545 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -27,7 +27,7 @@
#include "config.h"
-#ifndef DEBUG_TCG
+#ifndef CONFIG_DEBUG_TCG
/* define it to suppress various consistency checks (faster) */
#define NDEBUG
#endif
@@ -46,6 +46,7 @@
#include "qemu-common.h"
#include "cache-utils.h"
+#include "host-utils.h"
/* Note: the long term plan is to reduce the dependancies on the QEMU
CPU definitions. Currently they are used for qemu_ld/st
@@ -57,12 +58,16 @@
#include "tcg-op.h"
#include "elf.h"
-static void patch_reloc(uint8_t *code_ptr, int type,
+#if defined(CONFIG_USE_GUEST_BASE) && !defined(TCG_TARGET_HAS_GUEST_BASE)
+#error GUEST_BASE not supported on this host.
+#endif
+
+static void patch_reloc(uint8_t *code_ptr, int type,
tcg_target_long value, tcg_target_long addend);
static TCGOpDef tcg_op_defs[] = {
#define DEF(s, n, copy_size) { #s, 0, 0, n, n, 0, copy_size },
-#define DEF2(s, iargs, oargs, cargs, flags) { #s, iargs, oargs, cargs, iargs + oargs + cargs, flags, 0 },
+#define DEF2(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags, 0 },
#include "tcg-opc.h"
#undef DEF
#undef DEF2
@@ -104,7 +109,7 @@ static inline void tcg_out32(TCGContext *s, uint32_t v)
/* label relocation processing */
-void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
+void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
int label_index, long addend)
{
TCGLabel *l;
@@ -113,7 +118,7 @@ void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
l = &s->labels[label_index];
if (l->has_value) {
/* FIXME: This may break relocations on RISC targets that
- modify instruction fields in place. The caller may not have
+ modify instruction fields in place. The caller may not have
written the initial value. */
patch_reloc(code_ptr, type, l->u.value, addend);
} else {
@@ -127,7 +132,7 @@ void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
}
}
-static void tcg_out_label(TCGContext *s, int label_index,
+static void tcg_out_label(TCGContext *s, int label_index,
tcg_target_long value)
{
TCGLabel *l;
@@ -167,7 +172,7 @@ void *tcg_malloc_internal(TCGContext *s, int size)
{
TCGPool *p;
int pool_size;
-
+
if (size > TCG_POOL_CHUNK_SIZE) {
/* big malloc: insert a new pool (XXX: could optimize) */
p = qemu_malloc(sizeof(TCGPool) + size);
@@ -190,7 +195,7 @@ void *tcg_malloc_internal(TCGContext *s, int size)
p = qemu_malloc(sizeof(TCGPool) + pool_size);
p->size = pool_size;
p->next = NULL;
- if (s->pool_current)
+ if (s->pool_current)
s->pool_current->next = p;
else
s->pool_first = p;
@@ -221,7 +226,7 @@ void tcg_context_init(TCGContext *s)
memset(s, 0, sizeof(*s));
s->temps = s->static_temps;
s->nb_globals = 0;
-
+
/* Count total number of arguments and allocate the corresponding
space */
total_args = 0;
@@ -242,14 +247,14 @@ void tcg_context_init(TCGContext *s)
sorted_args += n;
args_ct += n;
}
-
+
tcg_target_init(s);
/* init global prologue and epilogue */
s->code_buf = code_gen_prologue;
s->code_ptr = s->code_buf;
tcg_target_qemu_prologue(s);
- flush_icache_range((unsigned long)s->code_buf,
+ flush_icache_range((unsigned long)s->code_buf,
(unsigned long)s->code_ptr);
}
@@ -707,7 +712,7 @@ static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
if (idx < s->nb_globals) {
pstrcpy(buf, buf_size, ts->name);
} else {
- if (ts->temp_local)
+ if (ts->temp_local)
snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
else
snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
@@ -745,7 +750,7 @@ static TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val)
tcg_target_ulong v;
if (unlikely(!s->helpers_sorted)) {
- qsort(s->helpers, s->nb_helpers, sizeof(TCGHelperInfo),
+ qsort(s->helpers, s->nb_helpers, sizeof(TCGHelperInfo),
helper_cmp);
s->helpers_sorted = 1;
}
@@ -804,7 +809,7 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile)
#else
pc = args[0];
#endif
- if (!first_insn)
+ if (!first_insn)
fprintf(outfile, "\n");
fprintf(outfile, " ---- 0x%" PRIx64, pc);
first_insn = 0;
@@ -844,7 +849,7 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile)
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + i]));
}
}
- } else if (c == INDEX_op_movi_i32
+ } else if (c == INDEX_op_movi_i32
#if TCG_TARGET_REG_BITS == 64
|| c == INDEX_op_movi_i64
#endif
@@ -855,7 +860,7 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile)
nb_oargs = def->nb_oargs;
nb_iargs = def->nb_iargs;
nb_cargs = def->nb_cargs;
- fprintf(outfile, " %s %s,$", def->name,
+ fprintf(outfile, " %s %s,$", def->name,
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
val = args[1];
th = tcg_find_helper(s, val);
@@ -879,7 +884,7 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile)
nb_iargs = def->nb_iargs;
nb_cargs = def->nb_cargs;
}
-
+
k = 0;
for(i = 0; i < nb_oargs; i++) {
if (k != 0)
@@ -893,21 +898,29 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile)
fprintf(outfile, "%s",
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
}
- if (c == INDEX_op_brcond_i32
+ switch (c) {
+ case INDEX_op_brcond_i32:
#if TCG_TARGET_REG_BITS == 32
- || c == INDEX_op_brcond2_i32
+ case INDEX_op_brcond2_i32:
#elif TCG_TARGET_REG_BITS == 64
- || c == INDEX_op_brcond_i64
+ case INDEX_op_brcond_i64:
+#endif
+ case INDEX_op_setcond_i32:
+#if TCG_TARGET_REG_BITS == 32
+ case INDEX_op_setcond2_i32:
+#elif TCG_TARGET_REG_BITS == 64
+ case INDEX_op_setcond_i64:
#endif
- ) {
if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]])
fprintf(outfile, ",%s", cond_name[args[k++]]);
else
fprintf(outfile, ",$0x%" TCG_PRIlx, args[k++]);
i = 1;
- }
- else
+ break;
+ default:
i = 0;
+ break;
+ }
for(; i < nb_cargs; i++) {
if (k != 0)
fprintf(outfile, ",");
@@ -977,9 +990,16 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
op = tdefs->op;
assert(op >= 0 && op < NB_OPS);
def = &tcg_op_defs[op];
+#if defined(CONFIG_DEBUG_TCG)
+ /* Duplicate entry in op definitions? */
+ assert(!def->used);
+ def->used = 1;
+#endif
nb_args = def->nb_iargs + def->nb_oargs;
for(i = 0; i < nb_args; i++) {
ct_str = tdefs->args_ct_str[i];
+ /* Incomplete TCGTargetOpDef entry? */
+ assert(ct_str != NULL);
tcg_regset_clear(def->args_ct[i].u.regs);
def->args_ct[i].ct = 0;
if (ct_str[0] >= '0' && ct_str[0] <= '9') {
@@ -1014,6 +1034,9 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
}
}
+ /* TCGTargetOpDef entry with too much information? */
+ assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL);
+
/* sort the constraints (XXX: this is just an heuristic) */
sort_constraints(def, 0, def->nb_oargs);
sort_constraints(def, def->nb_oargs, def->nb_iargs);
@@ -1031,12 +1054,23 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
tdefs++;
}
+#if defined(CONFIG_DEBUG_TCG)
+ for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) {
+ if (op < INDEX_op_call || op == INDEX_op_debug_insn_start) {
+ /* Wrong entry in op definitions? */
+ assert(!tcg_op_defs[op].used);
+ } else {
+ /* Missing entry in op definitions? */
+ assert(tcg_op_defs[op].used);
+ }
+ }
+#endif
}
#ifdef USE_LIVENESS_ANALYSIS
/* set a nop for an operation using 'nb_args' */
-static inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr,
+static inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr,
TCGArg *args, int nb_args)
{
if (nb_args == 0) {
@@ -1098,9 +1132,8 @@ static void tcg_liveness_analysis(TCGContext *s)
nb_ops = gen_opc_ptr - gen_opc_buf;
- /* XXX: make it really dynamic */
- s->op_dead_iargs = tcg_malloc(OPC_BUF_SIZE * sizeof(uint16_t));
-
+ s->op_dead_iargs = tcg_malloc(nb_ops * sizeof(uint16_t));
+
dead_temps = tcg_malloc(s->nb_temps);
memset(dead_temps, 1, s->nb_temps);
@@ -1129,7 +1162,7 @@ static void tcg_liveness_analysis(TCGContext *s)
if (!dead_temps[arg])
goto do_not_remove_call;
}
- tcg_set_nop(s, gen_opc_buf + op_index,
+ tcg_set_nop(s, gen_opc_buf + op_index,
args - 1, nb_args);
} else {
do_not_remove_call:
@@ -1139,7 +1172,7 @@ static void tcg_liveness_analysis(TCGContext *s)
arg = args[i];
dead_temps[arg] = 1;
}
-
+
if (!(call_flags & TCG_CALL_CONST)) {
/* globals are live (they may be used by the call) */
memset(dead_temps, 0, s->nb_globals);
@@ -1920,7 +1953,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
#ifdef DEBUG_DISAS
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
- qemu_log("OP after la:\n");
+ qemu_log("OP after liveness analysis:\n");
tcg_dump_ops(s, logfile);
qemu_log("\n");
}
@@ -2116,10 +2149,8 @@ void tcg_dump_info(FILE *f,
s->restore_count);
cpu_fprintf(f, " avg cycles %0.1f\n",
s->restore_count ? (double)s->restore_time / s->restore_count : 0);
- {
- extern void dump_op_count(void);
- dump_op_count();
- }
+
+ dump_op_count();
}
#else
void tcg_dump_info(FILE *f,