/*
* Tiny Code Interpreter for QEMU
*
- * Copyright (c) 2009, 2011 Stefan Weil
+ * Copyright (c) 2009, 2011, 2016 Stefan Weil
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "qemu/osdep.h"
-/* Defining NDEBUG disables assertions (which makes the code faster). */
-#if !defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG)
-# define NDEBUG
+/* Enable TCI assertions only when debugging TCG (and without NDEBUG defined).
+ * Without assertions, the interpreter runs much faster. */
+#if defined(CONFIG_DEBUG_TCG)
+# define tci_assert(cond) assert(cond)
+#else
+# define tci_assert(cond) ((void)0)
#endif
#include "qemu-common.h"
static tcg_target_ulong tci_read_reg(TCGReg index)
{
- assert(index < ARRAY_SIZE(tci_reg));
+ tci_assert(index < ARRAY_SIZE(tci_reg));
return tci_reg[index];
}
static void tci_write_reg(TCGReg index, tcg_target_ulong value)
{
- assert(index < ARRAY_SIZE(tci_reg));
- assert(index != TCG_AREG0);
- assert(index != TCG_REG_CALL_STACK);
+ tci_assert(index < ARRAY_SIZE(tci_reg));
+ tci_assert(index != TCG_AREG0);
+ tci_assert(index != TCG_REG_CALL_STACK);
tci_reg[index] = value;
}
static tcg_target_ulong tci_read_label(uint8_t **tb_ptr)
{
tcg_target_ulong label = tci_read_i(tb_ptr);
- assert(label != 0);
+ tci_assert(label != 0);
return label;
}
tci_reg[TCG_AREG0] = (tcg_target_ulong)env;
tci_reg[TCG_REG_CALL_STACK] = sp_value;
- assert(tb_ptr);
+ tci_assert(tb_ptr);
for (;;) {
TCGOpcode opc = tb_ptr[0];
-#if !defined(NDEBUG)
+#if defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG)
uint8_t op_size = tb_ptr[1];
uint8_t *old_code_ptr = tb_ptr;
#endif
break;
case INDEX_op_br:
label = tci_read_label(&tb_ptr);
- assert(tb_ptr == old_code_ptr + op_size);
+ tci_assert(tb_ptr == old_code_ptr + op_size);
tb_ptr = (uint8_t *)label;
continue;
case INDEX_op_setcond_i32:
t0 = tci_read_r32(&tb_ptr);
t1 = tci_read_r(&tb_ptr);
t2 = tci_read_s32(&tb_ptr);
- assert(t1 != sp_value || (int32_t)t2 < 0);
+ tci_assert(t1 != sp_value || (int32_t)t2 < 0);
*(uint32_t *)(t1 + t2) = t0;
break;
condition = *tb_ptr++;
label = tci_read_label(&tb_ptr);
if (tci_compare32(t0, t1, condition)) {
- assert(tb_ptr == old_code_ptr + op_size);
+ tci_assert(tb_ptr == old_code_ptr + op_size);
tb_ptr = (uint8_t *)label;
continue;
}
condition = *tb_ptr++;
label = tci_read_label(&tb_ptr);
if (tci_compare64(tmp64, v64, condition)) {
- assert(tb_ptr == old_code_ptr + op_size);
+ tci_assert(tb_ptr == old_code_ptr + op_size);
tb_ptr = (uint8_t *)label;
continue;
}
t0 = tci_read_r64(&tb_ptr);
t1 = tci_read_r(&tb_ptr);
t2 = tci_read_s32(&tb_ptr);
- assert(t1 != sp_value || (int32_t)t2 < 0);
+ tci_assert(t1 != sp_value || (int32_t)t2 < 0);
*(uint64_t *)(t1 + t2) = t0;
break;
condition = *tb_ptr++;
label = tci_read_label(&tb_ptr);
if (tci_compare64(t0, t1, condition)) {
- assert(tb_ptr == old_code_ptr + op_size);
+ tci_assert(tb_ptr == old_code_ptr + op_size);
tb_ptr = (uint8_t *)label;
continue;
}
break;
case INDEX_op_goto_tb:
t0 = tci_read_i32(&tb_ptr);
- assert(tb_ptr == old_code_ptr + op_size);
+ tci_assert(tb_ptr == old_code_ptr + op_size);
tb_ptr += (int32_t)t0;
continue;
case INDEX_op_qemu_ld_i32:
TODO();
break;
}
- assert(tb_ptr == old_code_ptr + op_size);
+ tci_assert(tb_ptr == old_code_ptr + op_size);
}
exit:
return next_tb;