@@ -83,6 +83,20 @@ static uint64_t tci_uint64(uint32_t high, uint32_t low)
}
#endif
+/* Read constant byte from bytecode. */
+static uint8_t tci_read_b(const uint8_t **tb_ptr)
+{
+ return *(tb_ptr[0]++);
+}
+
+/* Read register number from bytecode. */
+static TCGReg tci_read_r(const uint8_t **tb_ptr)
+{
+ uint8_t regno = tci_read_b(tb_ptr);
+ tci_assert(regno < TCG_TARGET_NB_REGS);
+ return regno;
+}
+
/* Read constant (native size) from bytecode. */
static tcg_target_ulong tci_read_i(const uint8_t **tb_ptr)
{
@@ -161,6 +175,23 @@ static tcg_target_ulong tci_read_label(const uint8_t **tb_ptr)
return label;
}
+/*
+ * Load sets of arguments all at once. The naming convention is:
+ * tci_args_<arguments>
+ * where arguments is a sequence of
+ *
+ * r = register
+ * s = signed ldst offset
+ */
+
+static void tci_args_rrs(const uint8_t **tb_ptr,
+ TCGReg *r0, TCGReg *r1, int32_t *i2)
+{
+ *r0 = tci_read_r(tb_ptr);
+ *r1 = tci_read_r(tb_ptr);
+ *i2 = tci_read_s32(tb_ptr);
+}
+
static bool tci_compare32(uint32_t u0, uint32_t u1, TCGCond condition)
{
bool result = false;
@@ -311,6 +342,7 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
uint8_t op_size = tb_ptr[1];
const uint8_t *old_code_ptr = tb_ptr;
#endif
+ TCGReg r0, r1;
tcg_target_ulong t0;
tcg_target_ulong t1;
tcg_target_ulong t2;
@@ -325,6 +357,8 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
uint64_t v64;
#endif
TCGMemOpIdx oi;
+ int32_t ofs;
+ void *ptr;
/* Skip opcode and size entry. */
tb_ptr += 2;
@@ -401,54 +435,46 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
/* Load/store operations (32 bit). */
CASE_32_64(ld8u)
- t0 = *tb_ptr++;
- t1 = tci_read_rval(regs, &tb_ptr);
- t2 = tci_read_s32(&tb_ptr);
- tci_write_reg(regs, t0, *(uint8_t *)(t1 + t2));
+ tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ ptr = (void *)(regs[r1] + ofs);
+ regs[r0] = *(uint8_t *)ptr;
break;
CASE_32_64(ld8s)
- t0 = *tb_ptr++;
- t1 = tci_read_rval(regs, &tb_ptr);
- t2 = tci_read_s32(&tb_ptr);
- tci_write_reg(regs, t0, *(int8_t *)(t1 + t2));
+ tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ ptr = (void *)(regs[r1] + ofs);
+ regs[r0] = *(int8_t *)ptr;
break;
CASE_32_64(ld16u)
- t0 = *tb_ptr++;
- t1 = tci_read_rval(regs, &tb_ptr);
- t2 = tci_read_s32(&tb_ptr);
- tci_write_reg(regs, t0, *(uint16_t *)(t1 + t2));
+ tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ ptr = (void *)(regs[r1] + ofs);
+ regs[r0] = *(uint16_t *)ptr;
break;
CASE_32_64(ld16s)
- t0 = *tb_ptr++;
- t1 = tci_read_rval(regs, &tb_ptr);
- t2 = tci_read_s32(&tb_ptr);
- tci_write_reg(regs, t0, *(int16_t *)(t1 + t2));
+ tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ ptr = (void *)(regs[r1] + ofs);
+ regs[r0] = *(int16_t *)ptr;
break;
case INDEX_op_ld_i32:
CASE_64(ld32u)
- t0 = *tb_ptr++;
- t1 = tci_read_rval(regs, &tb_ptr);
- t2 = tci_read_s32(&tb_ptr);
- tci_write_reg(regs, t0, *(uint32_t *)(t1 + t2));
+ tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ ptr = (void *)(regs[r1] + ofs);
+ regs[r0] = *(uint32_t *)ptr;
break;
CASE_32_64(st8)
- t0 = tci_read_rval(regs, &tb_ptr);
- t1 = tci_read_rval(regs, &tb_ptr);
- t2 = tci_read_s32(&tb_ptr);
- *(uint8_t *)(t1 + t2) = t0;
+ tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ ptr = (void *)(regs[r1] + ofs);
+ *(uint8_t *)ptr = regs[r0];
break;
CASE_32_64(st16)
- t0 = tci_read_rval(regs, &tb_ptr);
- t1 = tci_read_rval(regs, &tb_ptr);
- t2 = tci_read_s32(&tb_ptr);
- *(uint16_t *)(t1 + t2) = t0;
+ tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ ptr = (void *)(regs[r1] + ofs);
+ *(uint16_t *)ptr = regs[r0];
break;
case INDEX_op_st_i32:
CASE_64(st32)
- t0 = tci_read_rval(regs, &tb_ptr);
- t1 = tci_read_rval(regs, &tb_ptr);
- t2 = tci_read_s32(&tb_ptr);
- *(uint32_t *)(t1 + t2) = t0;
+ tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ ptr = (void *)(regs[r1] + ofs);
+ *(uint32_t *)ptr = regs[r0];
break;
/* Arithmetic operations (mixed 32/64 bit). */
@@ -673,22 +699,19 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
/* Load/store operations (64 bit). */
case INDEX_op_ld32s_i64:
- t0 = *tb_ptr++;
- t1 = tci_read_rval(regs, &tb_ptr);
- t2 = tci_read_s32(&tb_ptr);
- tci_write_reg(regs, t0, *(int32_t *)(t1 + t2));
+ tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ ptr = (void *)(regs[r1] + ofs);
+ regs[r0] = *(int32_t *)ptr;
break;
case INDEX_op_ld_i64:
- t0 = *tb_ptr++;
- t1 = tci_read_rval(regs, &tb_ptr);
- t2 = tci_read_s32(&tb_ptr);
- tci_write_reg(regs, t0, *(uint64_t *)(t1 + t2));
+ tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ ptr = (void *)(regs[r1] + ofs);
+ regs[r0] = *(uint64_t *)ptr;
break;
case INDEX_op_st_i64:
- t0 = tci_read_rval(regs, &tb_ptr);
- t1 = tci_read_rval(regs, &tb_ptr);
- t2 = tci_read_s32(&tb_ptr);
- *(uint64_t *)(t1 + t2) = t0;
+ tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ ptr = (void *)(regs[r1] + ofs);
+ *(uint64_t *)ptr = regs[r0];
break;
/* Arithmetic operations (64 bit). */