target/i386/emulate: stop overloading decode->op[N].ptr

decode->op[N].ptr can contain either a host pointer (!) in CPUState
or a guest virtual address.  Pass the whole struct to read_val_ext
and write_val_ext, so that it can decide the contents based on the
operand type.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2025-05-02 22:21:42 +02:00
parent ad441b8b79
commit 77a2dba45c
4 changed files with 109 additions and 101 deletions

View file

@ -109,8 +109,8 @@ static void decode_modrm_reg(CPUX86State *env, struct x86_decode *decode,
{
op->type = X86_VAR_REG;
op->reg = decode->modrm.reg;
op->ptr = get_reg_ref(env, op->reg, decode->rex.rex, decode->rex.r,
decode->operand_size);
op->regptr = get_reg_ref(env, op->reg, decode->rex.rex, decode->rex.r,
decode->operand_size);
}
static void decode_rax(CPUX86State *env, struct x86_decode *decode,
@ -119,8 +119,8 @@ static void decode_rax(CPUX86State *env, struct x86_decode *decode,
op->type = X86_VAR_REG;
op->reg = R_EAX;
/* Since reg is always AX, REX prefix has no impact. */
op->ptr = get_reg_ref(env, op->reg, false, 0,
decode->operand_size);
op->regptr = get_reg_ref(env, op->reg, false, 0,
decode->operand_size);
}
static inline void decode_immediate(CPUX86State *env, struct x86_decode *decode,
@ -262,16 +262,16 @@ static void decode_incgroup(CPUX86State *env, struct x86_decode *decode)
{
decode->op[0].type = X86_VAR_REG;
decode->op[0].reg = decode->opcode[0] - 0x40;
decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
decode->rex.b, decode->operand_size);
decode->op[0].regptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
decode->rex.b, decode->operand_size);
}
static void decode_decgroup(CPUX86State *env, struct x86_decode *decode)
{
decode->op[0].type = X86_VAR_REG;
decode->op[0].reg = decode->opcode[0] - 0x48;
decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
decode->rex.b, decode->operand_size);
decode->op[0].regptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
decode->rex.b, decode->operand_size);
}
static void decode_incgroup2(CPUX86State *env, struct x86_decode *decode)
@ -287,16 +287,16 @@ static void decode_pushgroup(CPUX86State *env, struct x86_decode *decode)
{
decode->op[0].type = X86_VAR_REG;
decode->op[0].reg = decode->opcode[0] - 0x50;
decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
decode->rex.b, decode->operand_size);
decode->op[0].regptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
decode->rex.b, decode->operand_size);
}
static void decode_popgroup(CPUX86State *env, struct x86_decode *decode)
{
decode->op[0].type = X86_VAR_REG;
decode->op[0].reg = decode->opcode[0] - 0x58;
decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
decode->rex.b, decode->operand_size);
decode->op[0].regptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
decode->rex.b, decode->operand_size);
}
static void decode_jxx(CPUX86State *env, struct x86_decode *decode)
@ -377,16 +377,16 @@ static void decode_xchgroup(CPUX86State *env, struct x86_decode *decode)
{
decode->op[0].type = X86_VAR_REG;
decode->op[0].reg = decode->opcode[0] - 0x90;
decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
decode->rex.b, decode->operand_size);
decode->op[0].regptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
decode->rex.b, decode->operand_size);
}
static void decode_movgroup(CPUX86State *env, struct x86_decode *decode)
{
decode->op[0].type = X86_VAR_REG;
decode->op[0].reg = decode->opcode[0] - 0xb8;
decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
decode->rex.b, decode->operand_size);
decode->op[0].regptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
decode->rex.b, decode->operand_size);
decode_immediate(env, decode, &decode->op[1], decode->operand_size);
}
@ -394,15 +394,15 @@ static void fetch_moffs(CPUX86State *env, struct x86_decode *decode,
struct x86_decode_op *op)
{
op->type = X86_VAR_OFFSET;
op->ptr = decode_bytes(env, decode, decode->addressing_size);
op->addr = decode_bytes(env, decode, decode->addressing_size);
}
static void decode_movgroup8(CPUX86State *env, struct x86_decode *decode)
{
decode->op[0].type = X86_VAR_REG;
decode->op[0].reg = decode->opcode[0] - 0xb0;
decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
decode->rex.b, decode->operand_size);
decode->op[0].regptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
decode->rex.b, decode->operand_size);
decode_immediate(env, decode, &decode->op[1], decode->operand_size);
}
@ -411,8 +411,8 @@ static void decode_rcx(CPUX86State *env, struct x86_decode *decode,
{
op->type = X86_VAR_REG;
op->reg = R_ECX;
op->ptr = get_reg_ref(env, op->reg, decode->rex.rex, decode->rex.b,
decode->operand_size);
op->regptr = get_reg_ref(env, op->reg, decode->rex.rex, decode->rex.b,
decode->operand_size);
}
struct decode_tbl {
@ -631,8 +631,8 @@ static void decode_bswap(CPUX86State *env, struct x86_decode *decode)
{
decode->op[0].type = X86_VAR_REG;
decode->op[0].reg = decode->opcode[1] - 0xc8;
decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
decode->rex.b, decode->operand_size);
decode->op[0].regptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex,
decode->rex.b, decode->operand_size);
}
static void decode_d9_4(CPUX86State *env, struct x86_decode *decode)
@ -1656,16 +1656,16 @@ void calc_modrm_operand16(CPUX86State *env, struct x86_decode *decode,
}
calc_addr:
if (X86_DECODE_CMD_LEA == decode->cmd) {
op->ptr = (uint16_t)ptr;
op->addr = (uint16_t)ptr;
} else {
op->ptr = decode_linear_addr(env, decode, (uint16_t)ptr, seg);
op->addr = decode_linear_addr(env, decode, (uint16_t)ptr, seg);
}
}
target_ulong get_reg_ref(CPUX86State *env, int reg, int rex_present,
void *get_reg_ref(CPUX86State *env, int reg, int rex_present,
int is_extended, int size)
{
target_ulong ptr = 0;
void *ptr = NULL;
if (is_extended) {
reg |= R_R8;
@ -1674,13 +1674,13 @@ target_ulong get_reg_ref(CPUX86State *env, int reg, int rex_present,
switch (size) {
case 1:
if (is_extended || reg < 4 || rex_present) {
ptr = (target_ulong)&RL(env, reg);
ptr = &RL(env, reg);
} else {
ptr = (target_ulong)&RH(env, reg - 4);
ptr = &RH(env, reg - 4);
}
break;
default:
ptr = (target_ulong)&RRX(env, reg);
ptr = &RRX(env, reg);
break;
}
return ptr;
@ -1691,7 +1691,7 @@ target_ulong get_reg_val(CPUX86State *env, int reg, int rex_present,
{
target_ulong val = 0;
memcpy(&val,
(void *)get_reg_ref(env, reg, rex_present, is_extended, size),
get_reg_ref(env, reg, rex_present, is_extended, size),
size);
return val;
}
@ -1758,9 +1758,9 @@ void calc_modrm_operand32(CPUX86State *env, struct x86_decode *decode,
}
if (X86_DECODE_CMD_LEA == decode->cmd) {
op->ptr = (uint32_t)ptr;
op->addr = (uint32_t)ptr;
} else {
op->ptr = decode_linear_addr(env, decode, (uint32_t)ptr, seg);
op->addr = decode_linear_addr(env, decode, (uint32_t)ptr, seg);
}
}
@ -1788,9 +1788,9 @@ void calc_modrm_operand64(CPUX86State *env, struct x86_decode *decode,
}
if (X86_DECODE_CMD_LEA == decode->cmd) {
op->ptr = ptr;
op->addr = ptr;
} else {
op->ptr = decode_linear_addr(env, decode, ptr, seg);
op->addr = decode_linear_addr(env, decode, ptr, seg);
}
}
@ -1801,8 +1801,8 @@ void calc_modrm_operand(CPUX86State *env, struct x86_decode *decode,
if (3 == decode->modrm.mod) {
op->reg = decode->modrm.reg;
op->type = X86_VAR_REG;
op->ptr = get_reg_ref(env, decode->modrm.rm, decode->rex.rex,
decode->rex.b, decode->operand_size);
op->regptr = get_reg_ref(env, decode->modrm.rm, decode->rex.rex,
decode->rex.b, decode->operand_size);
return;
}

View file

@ -266,7 +266,10 @@ typedef struct x86_decode_op {
int reg;
target_ulong val;
target_ulong ptr;
union {
target_ulong addr;
void *regptr;
};
} x86_decode_op;
typedef struct x86_decode {
@ -301,8 +304,8 @@ uint64_t sign(uint64_t val, int size);
uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode);
target_ulong get_reg_ref(CPUX86State *env, int reg, int rex_present,
int is_extended, int size);
void *get_reg_ref(CPUX86State *env, int reg, int rex_present,
int is_extended, int size);
target_ulong get_reg_val(CPUX86State *env, int reg, int rex_present,
int is_extended, int size);
void calc_modrm_operand(CPUX86State *env, struct x86_decode *decode,

View file

@ -52,7 +52,7 @@
uint8_t v2 = (uint8_t)decode->op[1].val; \
uint8_t diff = v1 cmd v2; \
if (save_res) { \
write_val_ext(env, decode->op[0].ptr, diff, 1); \
write_val_ext(env, &decode->op[0], diff, 1); \
} \
FLAGS_FUNC##8(env, v1, v2, diff); \
break; \
@ -63,7 +63,7 @@
uint16_t v2 = (uint16_t)decode->op[1].val; \
uint16_t diff = v1 cmd v2; \
if (save_res) { \
write_val_ext(env, decode->op[0].ptr, diff, 2); \
write_val_ext(env, &decode->op[0], diff, 2); \
} \
FLAGS_FUNC##16(env, v1, v2, diff); \
break; \
@ -74,7 +74,7 @@
uint32_t v2 = (uint32_t)decode->op[1].val; \
uint32_t diff = v1 cmd v2; \
if (save_res) { \
write_val_ext(env, decode->op[0].ptr, diff, 4); \
write_val_ext(env, &decode->op[0], diff, 4); \
} \
FLAGS_FUNC##32(env, v1, v2, diff); \
break; \
@ -121,7 +121,7 @@ void write_reg(CPUX86State *env, int reg, target_ulong val, int size)
}
}
target_ulong read_val_from_reg(target_ulong reg_ptr, int size)
target_ulong read_val_from_reg(void *reg_ptr, int size)
{
target_ulong val;
@ -144,7 +144,7 @@ target_ulong read_val_from_reg(target_ulong reg_ptr, int size)
return val;
}
void write_val_to_reg(target_ulong reg_ptr, target_ulong val, int size)
void write_val_to_reg(void *reg_ptr, target_ulong val, int size)
{
switch (size) {
case 1:
@ -164,18 +164,18 @@ void write_val_to_reg(target_ulong reg_ptr, target_ulong val, int size)
}
}
static bool is_host_reg(CPUX86State *env, target_ulong ptr)
static void write_val_to_mem(CPUX86State *env, target_ulong ptr, target_ulong val, int size)
{
return (ptr - (target_ulong)&env->regs[0]) < sizeof(env->regs);
emul_ops->write_mem(env_cpu(env), &val, ptr, size);
}
void write_val_ext(CPUX86State *env, target_ulong ptr, target_ulong val, int size)
void write_val_ext(CPUX86State *env, struct x86_decode_op *decode, target_ulong val, int size)
{
if (is_host_reg(env, ptr)) {
write_val_to_reg(ptr, val, size);
return;
if (decode->type == X86_VAR_REG) {
write_val_to_reg(decode->regptr, val, size);
} else {
write_val_to_mem(env, decode->addr, val, size);
}
emul_ops->write_mem(env_cpu(env), &val, ptr, size);
}
uint8_t *read_mmio(CPUX86State *env, target_ulong ptr, int bytes)
@ -185,15 +185,11 @@ uint8_t *read_mmio(CPUX86State *env, target_ulong ptr, int bytes)
}
target_ulong read_val_ext(CPUX86State *env, target_ulong ptr, int size)
static target_ulong read_val_from_mem(CPUX86State *env, target_long ptr, int size)
{
target_ulong val;
uint8_t *mmio_ptr;
if (is_host_reg(env, ptr)) {
return read_val_from_reg(ptr, size);
}
mmio_ptr = read_mmio(env, ptr, size);
switch (size) {
case 1:
@ -215,6 +211,15 @@ target_ulong read_val_ext(CPUX86State *env, target_ulong ptr, int size)
return val;
}
target_ulong read_val_ext(CPUX86State *env, struct x86_decode_op *decode, int size)
{
if (decode->type == X86_VAR_REG) {
return read_val_from_reg(decode->regptr, size);
} else {
return read_val_from_mem(env, decode->addr, size);
}
}
static void fetch_operands(CPUX86State *env, struct x86_decode *decode,
int n, bool val_op0, bool val_op1, bool val_op2)
{
@ -226,25 +231,25 @@ static void fetch_operands(CPUX86State *env, struct x86_decode *decode,
case X86_VAR_IMMEDIATE:
break;
case X86_VAR_REG:
VM_PANIC_ON(!decode->op[i].ptr);
VM_PANIC_ON(!decode->op[i].regptr);
if (calc_val[i]) {
decode->op[i].val = read_val_from_reg(decode->op[i].ptr,
decode->op[i].val = read_val_from_reg(decode->op[i].regptr,
decode->operand_size);
}
break;
case X86_VAR_RM:
calc_modrm_operand(env, decode, &decode->op[i]);
if (calc_val[i]) {
decode->op[i].val = read_val_ext(env, decode->op[i].ptr,
decode->op[i].val = read_val_ext(env, &decode->op[i],
decode->operand_size);
}
break;
case X86_VAR_OFFSET:
decode->op[i].ptr = decode_linear_addr(env, decode,
decode->op[i].ptr,
R_DS);
decode->op[i].addr = decode_linear_addr(env, decode,
decode->op[i].addr,
R_DS);
if (calc_val[i]) {
decode->op[i].val = read_val_ext(env, decode->op[i].ptr,
decode->op[i].val = read_val_ext(env, &decode->op[i],
decode->operand_size);
}
break;
@ -257,7 +262,7 @@ static void fetch_operands(CPUX86State *env, struct x86_decode *decode,
static void exec_mov(CPUX86State *env, struct x86_decode *decode)
{
fetch_operands(env, decode, 2, false, true, false);
write_val_ext(env, decode->op[0].ptr, decode->op[1].val,
write_val_ext(env, &decode->op[0], decode->op[1].val,
decode->operand_size);
env->eip += decode->len;
@ -312,7 +317,7 @@ static void exec_neg(CPUX86State *env, struct x86_decode *decode)
fetch_operands(env, decode, 2, true, true, false);
val = 0 - sign(decode->op[1].val, decode->operand_size);
write_val_ext(env, decode->op[1].ptr, val, decode->operand_size);
write_val_ext(env, &decode->op[1], val, decode->operand_size);
if (4 == decode->operand_size) {
SET_FLAGS_OSZAPC_SUB32(env, 0, 0 - val, val);
@ -363,7 +368,7 @@ static void exec_not(CPUX86State *env, struct x86_decode *decode)
{
fetch_operands(env, decode, 1, true, false, false);
write_val_ext(env, decode->op[0].ptr, ~decode->op[0].val,
write_val_ext(env, &decode->op[0], ~decode->op[0].val,
decode->operand_size);
env->eip += decode->len;
}
@ -382,8 +387,8 @@ void exec_movzx(CPUX86State *env, struct x86_decode *decode)
}
decode->operand_size = src_op_size;
calc_modrm_operand(env, decode, &decode->op[1]);
decode->op[1].val = read_val_ext(env, decode->op[1].ptr, src_op_size);
write_val_ext(env, decode->op[0].ptr, decode->op[1].val, op_size);
decode->op[1].val = read_val_ext(env, &decode->op[1], src_op_size);
write_val_ext(env, &decode->op[0], decode->op[1].val, op_size);
env->eip += decode->len;
}
@ -535,8 +540,8 @@ static void exec_movs_single(CPUX86State *env, struct x86_decode *decode)
dst_addr = linear_addr_size(env_cpu(env), RDI(env),
decode->addressing_size, R_ES);
val = read_val_ext(env, src_addr, decode->operand_size);
write_val_ext(env, dst_addr, val, decode->operand_size);
val = read_val_from_mem(env, src_addr, decode->operand_size);
write_val_to_mem(env, dst_addr, val, decode->operand_size);
string_increment_reg(env, R_ESI, decode);
string_increment_reg(env, R_EDI, decode);
@ -563,9 +568,9 @@ static void exec_cmps_single(CPUX86State *env, struct x86_decode *decode)
decode->addressing_size, R_ES);
decode->op[0].type = X86_VAR_IMMEDIATE;
decode->op[0].val = read_val_ext(env, src_addr, decode->operand_size);
decode->op[0].val = read_val_from_mem(env, src_addr, decode->operand_size);
decode->op[1].type = X86_VAR_IMMEDIATE;
decode->op[1].val = read_val_ext(env, dst_addr, decode->operand_size);
decode->op[1].val = read_val_from_mem(env, dst_addr, decode->operand_size);
EXEC_2OP_FLAGS_CMD(env, decode, -, SET_FLAGS_OSZAPC_SUB, false);
@ -697,15 +702,15 @@ static void do_bt(CPUX86State *env, struct x86_decode *decode, int flag)
if (decode->op[0].type != X86_VAR_REG) {
if (4 == decode->operand_size) {
displacement = ((int32_t) (decode->op[1].val & 0xffffffe0)) / 32;
decode->op[0].ptr += 4 * displacement;
decode->op[0].addr += 4 * displacement;
} else if (2 == decode->operand_size) {
displacement = ((int16_t) (decode->op[1].val & 0xfff0)) / 16;
decode->op[0].ptr += 2 * displacement;
decode->op[0].addr += 2 * displacement;
} else {
VM_PANIC("bt 64bit\n");
}
}
decode->op[0].val = read_val_ext(env, decode->op[0].ptr,
decode->op[0].val = read_val_ext(env, &decode->op[0],
decode->operand_size);
cf = (decode->op[0].val >> index) & 0x01;
@ -723,7 +728,7 @@ static void do_bt(CPUX86State *env, struct x86_decode *decode, int flag)
decode->op[0].val &= ~(1u << index);
break;
}
write_val_ext(env, decode->op[0].ptr, decode->op[0].val,
write_val_ext(env, &decode->op[0], decode->op[0].val,
decode->operand_size);
set_CF(env, cf);
}
@ -775,7 +780,7 @@ void exec_shl(CPUX86State *env, struct x86_decode *decode)
of = cf ^ (res >> 7);
}
write_val_ext(env, decode->op[0].ptr, res, 1);
write_val_ext(env, &decode->op[0], res, 1);
SET_FLAGS_OSZAPC_LOGIC8(env, 0, 0, res);
SET_FLAGS_OxxxxC(env, of, cf);
break;
@ -791,7 +796,7 @@ void exec_shl(CPUX86State *env, struct x86_decode *decode)
of = cf ^ (res >> 15); /* of = cf ^ result15 */
}
write_val_ext(env, decode->op[0].ptr, res, 2);
write_val_ext(env, &decode->op[0], res, 2);
SET_FLAGS_OSZAPC_LOGIC16(env, 0, 0, res);
SET_FLAGS_OxxxxC(env, of, cf);
break;
@ -800,7 +805,7 @@ void exec_shl(CPUX86State *env, struct x86_decode *decode)
{
uint32_t res = decode->op[0].val << count;
write_val_ext(env, decode->op[0].ptr, res, 4);
write_val_ext(env, &decode->op[0], res, 4);
SET_FLAGS_OSZAPC_LOGIC32(env, 0, 0, res);
cf = (decode->op[0].val >> (32 - count)) & 0x1;
of = cf ^ (res >> 31); /* of = cf ^ result31 */
@ -831,10 +836,10 @@ void exec_movsx(CPUX86State *env, struct x86_decode *decode)
decode->operand_size = src_op_size;
calc_modrm_operand(env, decode, &decode->op[1]);
decode->op[1].val = sign(read_val_ext(env, decode->op[1].ptr, src_op_size),
decode->op[1].val = sign(read_val_ext(env, &decode->op[1], src_op_size),
src_op_size);
write_val_ext(env, decode->op[0].ptr, decode->op[1].val, op_size);
write_val_ext(env, &decode->op[0], decode->op[1].val, op_size);
env->eip += decode->len;
}
@ -862,7 +867,7 @@ void exec_ror(CPUX86State *env, struct x86_decode *decode)
count &= 0x7; /* use only bottom 3 bits */
res = ((uint8_t)decode->op[0].val >> count) |
((uint8_t)decode->op[0].val << (8 - count));
write_val_ext(env, decode->op[0].ptr, res, 1);
write_val_ext(env, &decode->op[0], res, 1);
bit6 = (res >> 6) & 1;
bit7 = (res >> 7) & 1;
/* set eflags: ROR count affects the following flags: C, O */
@ -886,7 +891,7 @@ void exec_ror(CPUX86State *env, struct x86_decode *decode)
count &= 0x0f; /* use only 4 LSB's */
res = ((uint16_t)decode->op[0].val >> count) |
((uint16_t)decode->op[0].val << (16 - count));
write_val_ext(env, decode->op[0].ptr, res, 2);
write_val_ext(env, &decode->op[0], res, 2);
bit14 = (res >> 14) & 1;
bit15 = (res >> 15) & 1;
@ -904,7 +909,7 @@ void exec_ror(CPUX86State *env, struct x86_decode *decode)
if (count) {
res = ((uint32_t)decode->op[0].val >> count) |
((uint32_t)decode->op[0].val << (32 - count));
write_val_ext(env, decode->op[0].ptr, res, 4);
write_val_ext(env, &decode->op[0], res, 4);
bit31 = (res >> 31) & 1;
bit30 = (res >> 30) & 1;
@ -941,7 +946,7 @@ void exec_rol(CPUX86State *env, struct x86_decode *decode)
res = ((uint8_t)decode->op[0].val << count) |
((uint8_t)decode->op[0].val >> (8 - count));
write_val_ext(env, decode->op[0].ptr, res, 1);
write_val_ext(env, &decode->op[0], res, 1);
/* set eflags:
* ROL count affects the following flags: C, O
*/
@ -968,7 +973,7 @@ void exec_rol(CPUX86State *env, struct x86_decode *decode)
res = ((uint16_t)decode->op[0].val << count) |
((uint16_t)decode->op[0].val >> (16 - count));
write_val_ext(env, decode->op[0].ptr, res, 2);
write_val_ext(env, &decode->op[0], res, 2);
bit0 = (res & 0x1);
bit15 = (res >> 15);
/* of = cf ^ result15 */
@ -986,7 +991,7 @@ void exec_rol(CPUX86State *env, struct x86_decode *decode)
res = ((uint32_t)decode->op[0].val << count) |
((uint32_t)decode->op[0].val >> (32 - count));
write_val_ext(env, decode->op[0].ptr, res, 4);
write_val_ext(env, &decode->op[0], res, 4);
bit0 = (res & 0x1);
bit31 = (res >> 31);
/* of = cf ^ result31 */
@ -1024,7 +1029,7 @@ void exec_rcl(CPUX86State *env, struct x86_decode *decode)
(op1_8 >> (9 - count));
}
write_val_ext(env, decode->op[0].ptr, res, 1);
write_val_ext(env, &decode->op[0], res, 1);
cf = (op1_8 >> (8 - count)) & 0x01;
of = cf ^ (res >> 7); /* of = cf ^ result7 */
@ -1050,7 +1055,7 @@ void exec_rcl(CPUX86State *env, struct x86_decode *decode)
(op1_16 >> (17 - count));
}
write_val_ext(env, decode->op[0].ptr, res, 2);
write_val_ext(env, &decode->op[0], res, 2);
cf = (op1_16 >> (16 - count)) & 0x1;
of = cf ^ (res >> 15); /* of = cf ^ result15 */
@ -1073,7 +1078,7 @@ void exec_rcl(CPUX86State *env, struct x86_decode *decode)
(op1_32 >> (33 - count));
}
write_val_ext(env, decode->op[0].ptr, res, 4);
write_val_ext(env, &decode->op[0], res, 4);
cf = (op1_32 >> (32 - count)) & 0x1;
of = cf ^ (res >> 31); /* of = cf ^ result31 */
@ -1105,7 +1110,7 @@ void exec_rcr(CPUX86State *env, struct x86_decode *decode)
res = (op1_8 >> count) | (get_CF(env) << (8 - count)) |
(op1_8 << (9 - count));
write_val_ext(env, decode->op[0].ptr, res, 1);
write_val_ext(env, &decode->op[0], res, 1);
cf = (op1_8 >> (count - 1)) & 0x1;
of = (((res << 1) ^ res) >> 7) & 0x1; /* of = result6 ^ result7 */
@ -1124,7 +1129,7 @@ void exec_rcr(CPUX86State *env, struct x86_decode *decode)
res = (op1_16 >> count) | (get_CF(env) << (16 - count)) |
(op1_16 << (17 - count));
write_val_ext(env, decode->op[0].ptr, res, 2);
write_val_ext(env, &decode->op[0], res, 2);
cf = (op1_16 >> (count - 1)) & 0x1;
of = ((uint16_t)((res << 1) ^ res) >> 15) & 0x1; /* of = result15 ^
@ -1148,7 +1153,7 @@ void exec_rcr(CPUX86State *env, struct x86_decode *decode)
(op1_32 << (33 - count));
}
write_val_ext(env, decode->op[0].ptr, res, 4);
write_val_ext(env, &decode->op[0], res, 4);
cf = (op1_32 >> (count - 1)) & 0x1;
of = ((res << 1) ^ res) >> 31; /* of = result30 ^ result31 */
@ -1163,9 +1168,9 @@ static void exec_xchg(CPUX86State *env, struct x86_decode *decode)
{
fetch_operands(env, decode, 2, true, true, false);
write_val_ext(env, decode->op[0].ptr, decode->op[1].val,
write_val_ext(env, &decode->op[0], decode->op[1].val,
decode->operand_size);
write_val_ext(env, decode->op[1].ptr, decode->op[0].val,
write_val_ext(env, &decode->op[1], decode->op[0].val,
decode->operand_size);
env->eip += decode->len;
@ -1174,7 +1179,7 @@ static void exec_xchg(CPUX86State *env, struct x86_decode *decode)
static void exec_xadd(CPUX86State *env, struct x86_decode *decode)
{
EXEC_2OP_FLAGS_CMD(env, decode, +, SET_FLAGS_OSZAPC_ADD, true);
write_val_ext(env, decode->op[1].ptr, decode->op[0].val,
write_val_ext(env, &decode->op[1], decode->op[0].val,
decode->operand_size);
env->eip += decode->len;

View file

@ -42,11 +42,11 @@ void x86_emul_raise_exception(CPUX86State *env, int exception_index, int error_c
target_ulong read_reg(CPUX86State *env, int reg, int size);
void write_reg(CPUX86State *env, int reg, target_ulong val, int size);
target_ulong read_val_from_reg(target_ulong reg_ptr, int size);
void write_val_to_reg(target_ulong reg_ptr, target_ulong val, int size);
void write_val_ext(CPUX86State *env, target_ulong ptr, target_ulong val, int size);
target_ulong read_val_from_reg(void *reg_ptr, int size);
void write_val_to_reg(void *reg_ptr, target_ulong val, int size);
void write_val_ext(CPUX86State *env, struct x86_decode_op *decode, target_ulong val, int size);
uint8_t *read_mmio(CPUX86State *env, target_ulong ptr, int bytes);
target_ulong read_val_ext(CPUX86State *env, target_ulong ptr, int size);
target_ulong read_val_ext(CPUX86State *env, struct x86_decode_op *decode, int size);
void exec_movzx(CPUX86State *env, struct x86_decode *decode);
void exec_shl(CPUX86State *env, struct x86_decode *decode);