mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-09-06 18:05:37 +00:00
tcg/tci: Hoist op_size checking into tci_args_*
This performs the size check while reading the arguments, which means that we don't have to arrange for it to be done after the operation. Which tidies all of the branches. Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
63041ed25f
commit
92bc4fad82
87
tcg/tci.c
87
tcg/tci.c
|
@ -24,7 +24,7 @@
|
||||||
#if defined(CONFIG_DEBUG_TCG)
|
#if defined(CONFIG_DEBUG_TCG)
|
||||||
# define tci_assert(cond) assert(cond)
|
# define tci_assert(cond) assert(cond)
|
||||||
#else
|
#else
|
||||||
# define tci_assert(cond) ((void)0)
|
# define tci_assert(cond) ((void)(cond))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
|
@ -137,146 +137,217 @@ static tcg_target_ulong tci_read_label(const uint8_t **tb_ptr)
|
||||||
* s = signed ldst offset
|
* s = signed ldst offset
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static void check_size(const uint8_t *start, const uint8_t **tb_ptr)
|
||||||
|
{
|
||||||
|
const uint8_t *old_code_ptr = start - 2;
|
||||||
|
uint8_t op_size = old_code_ptr[1];
|
||||||
|
tci_assert(*tb_ptr == old_code_ptr + op_size);
|
||||||
|
}
|
||||||
|
|
||||||
static void tci_args_l(const uint8_t **tb_ptr, void **l0)
|
static void tci_args_l(const uint8_t **tb_ptr, void **l0)
|
||||||
{
|
{
|
||||||
|
const uint8_t *start = *tb_ptr;
|
||||||
|
|
||||||
*l0 = (void *)tci_read_label(tb_ptr);
|
*l0 = (void *)tci_read_label(tb_ptr);
|
||||||
|
|
||||||
|
check_size(start, tb_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tci_args_rr(const uint8_t **tb_ptr,
|
static void tci_args_rr(const uint8_t **tb_ptr,
|
||||||
TCGReg *r0, TCGReg *r1)
|
TCGReg *r0, TCGReg *r1)
|
||||||
{
|
{
|
||||||
|
const uint8_t *start = *tb_ptr;
|
||||||
|
|
||||||
*r0 = tci_read_r(tb_ptr);
|
*r0 = tci_read_r(tb_ptr);
|
||||||
*r1 = tci_read_r(tb_ptr);
|
*r1 = tci_read_r(tb_ptr);
|
||||||
|
|
||||||
|
check_size(start, tb_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tci_args_ri(const uint8_t **tb_ptr,
|
static void tci_args_ri(const uint8_t **tb_ptr,
|
||||||
TCGReg *r0, tcg_target_ulong *i1)
|
TCGReg *r0, tcg_target_ulong *i1)
|
||||||
{
|
{
|
||||||
|
const uint8_t *start = *tb_ptr;
|
||||||
|
|
||||||
*r0 = tci_read_r(tb_ptr);
|
*r0 = tci_read_r(tb_ptr);
|
||||||
*i1 = tci_read_i32(tb_ptr);
|
*i1 = tci_read_i32(tb_ptr);
|
||||||
|
|
||||||
|
check_size(start, tb_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TCG_TARGET_REG_BITS == 64
|
#if TCG_TARGET_REG_BITS == 64
|
||||||
static void tci_args_rI(const uint8_t **tb_ptr,
|
static void tci_args_rI(const uint8_t **tb_ptr,
|
||||||
TCGReg *r0, tcg_target_ulong *i1)
|
TCGReg *r0, tcg_target_ulong *i1)
|
||||||
{
|
{
|
||||||
|
const uint8_t *start = *tb_ptr;
|
||||||
|
|
||||||
*r0 = tci_read_r(tb_ptr);
|
*r0 = tci_read_r(tb_ptr);
|
||||||
*i1 = tci_read_i(tb_ptr);
|
*i1 = tci_read_i(tb_ptr);
|
||||||
|
|
||||||
|
check_size(start, tb_ptr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void tci_args_rrm(const uint8_t **tb_ptr,
|
static void tci_args_rrm(const uint8_t **tb_ptr,
|
||||||
TCGReg *r0, TCGReg *r1, TCGMemOpIdx *m2)
|
TCGReg *r0, TCGReg *r1, TCGMemOpIdx *m2)
|
||||||
{
|
{
|
||||||
|
const uint8_t *start = *tb_ptr;
|
||||||
|
|
||||||
*r0 = tci_read_r(tb_ptr);
|
*r0 = tci_read_r(tb_ptr);
|
||||||
*r1 = tci_read_r(tb_ptr);
|
*r1 = tci_read_r(tb_ptr);
|
||||||
*m2 = tci_read_i32(tb_ptr);
|
*m2 = tci_read_i32(tb_ptr);
|
||||||
|
|
||||||
|
check_size(start, tb_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tci_args_rrr(const uint8_t **tb_ptr,
|
static void tci_args_rrr(const uint8_t **tb_ptr,
|
||||||
TCGReg *r0, TCGReg *r1, TCGReg *r2)
|
TCGReg *r0, TCGReg *r1, TCGReg *r2)
|
||||||
{
|
{
|
||||||
|
const uint8_t *start = *tb_ptr;
|
||||||
|
|
||||||
*r0 = tci_read_r(tb_ptr);
|
*r0 = tci_read_r(tb_ptr);
|
||||||
*r1 = tci_read_r(tb_ptr);
|
*r1 = tci_read_r(tb_ptr);
|
||||||
*r2 = tci_read_r(tb_ptr);
|
*r2 = tci_read_r(tb_ptr);
|
||||||
|
|
||||||
|
check_size(start, tb_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tci_args_rrs(const uint8_t **tb_ptr,
|
static void tci_args_rrs(const uint8_t **tb_ptr,
|
||||||
TCGReg *r0, TCGReg *r1, int32_t *i2)
|
TCGReg *r0, TCGReg *r1, int32_t *i2)
|
||||||
{
|
{
|
||||||
|
const uint8_t *start = *tb_ptr;
|
||||||
|
|
||||||
*r0 = tci_read_r(tb_ptr);
|
*r0 = tci_read_r(tb_ptr);
|
||||||
*r1 = tci_read_r(tb_ptr);
|
*r1 = tci_read_r(tb_ptr);
|
||||||
*i2 = tci_read_s32(tb_ptr);
|
*i2 = tci_read_s32(tb_ptr);
|
||||||
|
|
||||||
|
check_size(start, tb_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tci_args_rrcl(const uint8_t **tb_ptr,
|
static void tci_args_rrcl(const uint8_t **tb_ptr,
|
||||||
TCGReg *r0, TCGReg *r1, TCGCond *c2, void **l3)
|
TCGReg *r0, TCGReg *r1, TCGCond *c2, void **l3)
|
||||||
{
|
{
|
||||||
|
const uint8_t *start = *tb_ptr;
|
||||||
|
|
||||||
*r0 = tci_read_r(tb_ptr);
|
*r0 = tci_read_r(tb_ptr);
|
||||||
*r1 = tci_read_r(tb_ptr);
|
*r1 = tci_read_r(tb_ptr);
|
||||||
*c2 = tci_read_b(tb_ptr);
|
*c2 = tci_read_b(tb_ptr);
|
||||||
*l3 = (void *)tci_read_label(tb_ptr);
|
*l3 = (void *)tci_read_label(tb_ptr);
|
||||||
|
|
||||||
|
check_size(start, tb_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tci_args_rrrc(const uint8_t **tb_ptr,
|
static void tci_args_rrrc(const uint8_t **tb_ptr,
|
||||||
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGCond *c3)
|
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGCond *c3)
|
||||||
{
|
{
|
||||||
|
const uint8_t *start = *tb_ptr;
|
||||||
|
|
||||||
*r0 = tci_read_r(tb_ptr);
|
*r0 = tci_read_r(tb_ptr);
|
||||||
*r1 = tci_read_r(tb_ptr);
|
*r1 = tci_read_r(tb_ptr);
|
||||||
*r2 = tci_read_r(tb_ptr);
|
*r2 = tci_read_r(tb_ptr);
|
||||||
*c3 = tci_read_b(tb_ptr);
|
*c3 = tci_read_b(tb_ptr);
|
||||||
|
|
||||||
|
check_size(start, tb_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tci_args_rrrm(const uint8_t **tb_ptr,
|
static void tci_args_rrrm(const uint8_t **tb_ptr,
|
||||||
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGMemOpIdx *m3)
|
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGMemOpIdx *m3)
|
||||||
{
|
{
|
||||||
|
const uint8_t *start = *tb_ptr;
|
||||||
|
|
||||||
*r0 = tci_read_r(tb_ptr);
|
*r0 = tci_read_r(tb_ptr);
|
||||||
*r1 = tci_read_r(tb_ptr);
|
*r1 = tci_read_r(tb_ptr);
|
||||||
*r2 = tci_read_r(tb_ptr);
|
*r2 = tci_read_r(tb_ptr);
|
||||||
*m3 = tci_read_i32(tb_ptr);
|
*m3 = tci_read_i32(tb_ptr);
|
||||||
|
|
||||||
|
check_size(start, tb_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tci_args_rrrbb(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
|
static void tci_args_rrrbb(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
|
||||||
TCGReg *r2, uint8_t *i3, uint8_t *i4)
|
TCGReg *r2, uint8_t *i3, uint8_t *i4)
|
||||||
{
|
{
|
||||||
|
const uint8_t *start = *tb_ptr;
|
||||||
|
|
||||||
*r0 = tci_read_r(tb_ptr);
|
*r0 = tci_read_r(tb_ptr);
|
||||||
*r1 = tci_read_r(tb_ptr);
|
*r1 = tci_read_r(tb_ptr);
|
||||||
*r2 = tci_read_r(tb_ptr);
|
*r2 = tci_read_r(tb_ptr);
|
||||||
*i3 = tci_read_b(tb_ptr);
|
*i3 = tci_read_b(tb_ptr);
|
||||||
*i4 = tci_read_b(tb_ptr);
|
*i4 = tci_read_b(tb_ptr);
|
||||||
|
|
||||||
|
check_size(start, tb_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tci_args_rrrrm(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
|
static void tci_args_rrrrm(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
|
||||||
TCGReg *r2, TCGReg *r3, TCGMemOpIdx *m4)
|
TCGReg *r2, TCGReg *r3, TCGMemOpIdx *m4)
|
||||||
{
|
{
|
||||||
|
const uint8_t *start = *tb_ptr;
|
||||||
|
|
||||||
*r0 = tci_read_r(tb_ptr);
|
*r0 = tci_read_r(tb_ptr);
|
||||||
*r1 = tci_read_r(tb_ptr);
|
*r1 = tci_read_r(tb_ptr);
|
||||||
*r2 = tci_read_r(tb_ptr);
|
*r2 = tci_read_r(tb_ptr);
|
||||||
*r3 = tci_read_r(tb_ptr);
|
*r3 = tci_read_r(tb_ptr);
|
||||||
*m4 = tci_read_i32(tb_ptr);
|
*m4 = tci_read_i32(tb_ptr);
|
||||||
|
|
||||||
|
check_size(start, tb_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TCG_TARGET_REG_BITS == 32
|
#if TCG_TARGET_REG_BITS == 32
|
||||||
static void tci_args_rrrr(const uint8_t **tb_ptr,
|
static void tci_args_rrrr(const uint8_t **tb_ptr,
|
||||||
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGReg *r3)
|
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGReg *r3)
|
||||||
{
|
{
|
||||||
|
const uint8_t *start = *tb_ptr;
|
||||||
|
|
||||||
*r0 = tci_read_r(tb_ptr);
|
*r0 = tci_read_r(tb_ptr);
|
||||||
*r1 = tci_read_r(tb_ptr);
|
*r1 = tci_read_r(tb_ptr);
|
||||||
*r2 = tci_read_r(tb_ptr);
|
*r2 = tci_read_r(tb_ptr);
|
||||||
*r3 = tci_read_r(tb_ptr);
|
*r3 = tci_read_r(tb_ptr);
|
||||||
|
|
||||||
|
check_size(start, tb_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tci_args_rrrrcl(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
|
static void tci_args_rrrrcl(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
|
||||||
TCGReg *r2, TCGReg *r3, TCGCond *c4, void **l5)
|
TCGReg *r2, TCGReg *r3, TCGCond *c4, void **l5)
|
||||||
{
|
{
|
||||||
|
const uint8_t *start = *tb_ptr;
|
||||||
|
|
||||||
*r0 = tci_read_r(tb_ptr);
|
*r0 = tci_read_r(tb_ptr);
|
||||||
*r1 = tci_read_r(tb_ptr);
|
*r1 = tci_read_r(tb_ptr);
|
||||||
*r2 = tci_read_r(tb_ptr);
|
*r2 = tci_read_r(tb_ptr);
|
||||||
*r3 = tci_read_r(tb_ptr);
|
*r3 = tci_read_r(tb_ptr);
|
||||||
*c4 = tci_read_b(tb_ptr);
|
*c4 = tci_read_b(tb_ptr);
|
||||||
*l5 = (void *)tci_read_label(tb_ptr);
|
*l5 = (void *)tci_read_label(tb_ptr);
|
||||||
|
|
||||||
|
check_size(start, tb_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tci_args_rrrrrc(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
|
static void tci_args_rrrrrc(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
|
||||||
TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGCond *c5)
|
TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGCond *c5)
|
||||||
{
|
{
|
||||||
|
const uint8_t *start = *tb_ptr;
|
||||||
|
|
||||||
*r0 = tci_read_r(tb_ptr);
|
*r0 = tci_read_r(tb_ptr);
|
||||||
*r1 = tci_read_r(tb_ptr);
|
*r1 = tci_read_r(tb_ptr);
|
||||||
*r2 = tci_read_r(tb_ptr);
|
*r2 = tci_read_r(tb_ptr);
|
||||||
*r3 = tci_read_r(tb_ptr);
|
*r3 = tci_read_r(tb_ptr);
|
||||||
*r4 = tci_read_r(tb_ptr);
|
*r4 = tci_read_r(tb_ptr);
|
||||||
*c5 = tci_read_b(tb_ptr);
|
*c5 = tci_read_b(tb_ptr);
|
||||||
|
|
||||||
|
check_size(start, tb_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tci_args_rrrrrr(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
|
static void tci_args_rrrrrr(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
|
||||||
TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGReg *r5)
|
TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGReg *r5)
|
||||||
{
|
{
|
||||||
|
const uint8_t *start = *tb_ptr;
|
||||||
|
|
||||||
*r0 = tci_read_r(tb_ptr);
|
*r0 = tci_read_r(tb_ptr);
|
||||||
*r1 = tci_read_r(tb_ptr);
|
*r1 = tci_read_r(tb_ptr);
|
||||||
*r2 = tci_read_r(tb_ptr);
|
*r2 = tci_read_r(tb_ptr);
|
||||||
*r3 = tci_read_r(tb_ptr);
|
*r3 = tci_read_r(tb_ptr);
|
||||||
*r4 = tci_read_r(tb_ptr);
|
*r4 = tci_read_r(tb_ptr);
|
||||||
*r5 = tci_read_r(tb_ptr);
|
*r5 = tci_read_r(tb_ptr);
|
||||||
|
|
||||||
|
check_size(start, tb_ptr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -425,10 +496,6 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
TCGOpcode opc = tb_ptr[0];
|
TCGOpcode opc = tb_ptr[0];
|
||||||
#if defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG)
|
|
||||||
uint8_t op_size = tb_ptr[1];
|
|
||||||
const uint8_t *old_code_ptr = tb_ptr;
|
|
||||||
#endif
|
|
||||||
TCGReg r0, r1, r2, r3;
|
TCGReg r0, r1, r2, r3;
|
||||||
tcg_target_ulong t1;
|
tcg_target_ulong t1;
|
||||||
TCGCond condition;
|
TCGCond condition;
|
||||||
|
@ -478,7 +545,6 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
|
||||||
break;
|
break;
|
||||||
case INDEX_op_br:
|
case INDEX_op_br:
|
||||||
tci_args_l(&tb_ptr, &ptr);
|
tci_args_l(&tb_ptr, &ptr);
|
||||||
tci_assert(tb_ptr == old_code_ptr + op_size);
|
|
||||||
tb_ptr = ptr;
|
tb_ptr = ptr;
|
||||||
continue;
|
continue;
|
||||||
case INDEX_op_setcond_i32:
|
case INDEX_op_setcond_i32:
|
||||||
|
@ -631,9 +697,7 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
|
||||||
case INDEX_op_brcond_i32:
|
case INDEX_op_brcond_i32:
|
||||||
tci_args_rrcl(&tb_ptr, &r0, &r1, &condition, &ptr);
|
tci_args_rrcl(&tb_ptr, &r0, &r1, &condition, &ptr);
|
||||||
if (tci_compare32(regs[r0], regs[r1], condition)) {
|
if (tci_compare32(regs[r0], regs[r1], condition)) {
|
||||||
tci_assert(tb_ptr == old_code_ptr + op_size);
|
|
||||||
tb_ptr = ptr;
|
tb_ptr = ptr;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#if TCG_TARGET_REG_BITS == 32
|
#if TCG_TARGET_REG_BITS == 32
|
||||||
|
@ -654,7 +718,6 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
|
||||||
T1 = tci_uint64(regs[r1], regs[r0]);
|
T1 = tci_uint64(regs[r1], regs[r0]);
|
||||||
T2 = tci_uint64(regs[r3], regs[r2]);
|
T2 = tci_uint64(regs[r3], regs[r2]);
|
||||||
if (tci_compare64(T1, T2, condition)) {
|
if (tci_compare64(T1, T2, condition)) {
|
||||||
tci_assert(tb_ptr == old_code_ptr + op_size);
|
|
||||||
tb_ptr = ptr;
|
tb_ptr = ptr;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -788,9 +851,7 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
|
||||||
case INDEX_op_brcond_i64:
|
case INDEX_op_brcond_i64:
|
||||||
tci_args_rrcl(&tb_ptr, &r0, &r1, &condition, &ptr);
|
tci_args_rrcl(&tb_ptr, &r0, &r1, &condition, &ptr);
|
||||||
if (tci_compare64(regs[r0], regs[r1], condition)) {
|
if (tci_compare64(regs[r0], regs[r1], condition)) {
|
||||||
tci_assert(tb_ptr == old_code_ptr + op_size);
|
|
||||||
tb_ptr = ptr;
|
tb_ptr = ptr;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INDEX_op_ext32s_i64:
|
case INDEX_op_ext32s_i64:
|
||||||
|
@ -819,9 +880,8 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
|
||||||
|
|
||||||
case INDEX_op_goto_tb:
|
case INDEX_op_goto_tb:
|
||||||
tci_args_l(&tb_ptr, &ptr);
|
tci_args_l(&tb_ptr, &ptr);
|
||||||
tci_assert(tb_ptr == old_code_ptr + op_size);
|
|
||||||
tb_ptr = *(void **)ptr;
|
tb_ptr = *(void **)ptr;
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
|
if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
|
||||||
|
@ -999,6 +1059,5 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
tci_assert(tb_ptr == old_code_ptr + op_size);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue