Skip to content

Commit

Permalink
Implement cmpxchg8b
Browse files Browse the repository at this point in the history
  • Loading branch information
tbodt committed Dec 10, 2019
1 parent f2833e4 commit f1b738a
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 3 deletions.
7 changes: 7 additions & 0 deletions emu/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,13 @@ __no_instrument DECODER_RET glue(DECODER_NAME, OP_SIZE)(DECODER_ARGS) {
READMODRM_MEM; ATOMIC_XADD(modrm_reg, modrm_val,8); break;
case 0xc1: TRACEI("lock xadd reg, modrm");
READMODRM_MEM; ATOMIC_XADD(modrm_reg, modrm_val,oz); break;

case 0xc7: READMODRM_MEM; switch (modrm.opcode) {
case 1: TRACEI("lock cmpxchg8b modrm");
ATOMIC_CMPXCHG8B(modrm_val,64); break;
default: UNDEFINED;
};
break;
default: TRACE("undefined"); UNDEFINED;
}
break;
Expand Down
1 change: 1 addition & 0 deletions jit/gadgets-aarch64/gadgets.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ eax .req w20
xax .req x20
ebx .req w21
ecx .req w22
xcx .req x22
edx .req w23
xdx .req x23
esi .req w24
Expand Down
28 changes: 28 additions & 0 deletions jit/gadgets-aarch64/misc.S
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,34 @@
.gadget_array cmpxchg
.gadget_array atomic_cmpxchg

.gadget atomic_cmpxchg8b
write_prep 64, atomic_cmpxchg8b
mov w9, eax
bfi x9, xdx, 32, 32
mov w10, ebx
bfi x10, xcx, 32, 32

1:
ldaxr x8, [_xaddr]
cmp x9, x8
csel x9, x8, x9, ne
csel x8, x10, x8, eq
cset w11, eq
stlxr w12, x8, [_xaddr]
cbnz w12, 1b
write_done 64, atomic_cmpxchg8b
ubfx xax, x9, 0, 32
ubfx xdx, x9, 32, 32

ldr w8, [_cpu, CPU_flags_res]
ldr w9, [_cpu, CPU_eflags]
and w8, w8, ~ZF_RES
bfi w9, w11, 6, 1
str w8, [_cpu, CPU_flags_res]
str w9, [_cpu, CPU_eflags]
gret 1
write_bullshit 64, atomic_cmpxchg8b

.macro do_helper type, size=
.gadget helper_\type\size
.ifin(\type, read,write)
Expand Down
11 changes: 11 additions & 0 deletions jit/gadgets-x86_64/misc.S
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@
.gadget_array cmpxchg
.gadget_array atomic_cmpxchg

.gadget atomic_cmpxchg8b
write_prep 64, atomic_cmpxchg8b
lock cmpxchg8b (%_addrq)
setz %r15b
write_done 64, atomic_cmpxchg8b
andl $~ZF_RES, CPU_flags_res(%_cpu)
andl $~ZF_FLAG, CPU_eflags(%_cpu)
shlb $6, %r15b
orb %r15b, CPU_eflags(%_cpu)
gret 1

.macro do_helper type, size=
.gadget helper_\type\size
.ifin(\type, read,write)
Expand Down
1 change: 1 addition & 0 deletions jit/gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ void helper_rdtsc(struct cpu_state *cpu);
#define ATOMIC_BTC(bit, val,z) lo(atomic_btc, val, bit, z)
#define ATOMIC_BTS(bit, val,z) lo(atomic_bts, val, bit, z)
#define ATOMIC_BTR(bit, val,z) lo(atomic_btr, val, bit, z)
#define ATOMIC_CMPXCHG8B(dst,z) g_addr(); gg(atomic_cmpxchg8b, saved_ip)

// fpu
#define st_0 0
Expand Down
4 changes: 1 addition & 3 deletions tests/manual/qemu-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1191,7 +1191,6 @@ void test_xchg(void)
TEST_CMPXCHG(cmpxchgw, "w", "+m", 0xfffefdfc);
TEST_CMPXCHG(cmpxchgb, "b", "+m", 0xfffefdfc);

#if 0
{
uint64_t op0, op1, op2;
long eax, edx;
Expand All @@ -1206,7 +1205,7 @@ void test_xchg(void)
else
op1 = op0;
op2 = 0x6532432432434LL;
asm("cmpxchg8b %2\n"
asm("lock cmpxchg8b %2\n"
"pushf\n"
"pop %3\n"
: "=a" (eax), "=d" (edx), "=m" (op1), "=g" (eflags)
Expand All @@ -1215,7 +1214,6 @@ void test_xchg(void)
eax, edx, op1, eflags & CC_Z);
}
}
#endif
}

#ifdef TEST_SEGS
Expand Down

0 comments on commit f1b738a

Please sign in to comment.