Skip to content

Commit

Permalink
Implement atomic bt[csr]
Browse files Browse the repository at this point in the history
  • Loading branch information
tbodt committed Mar 11, 2019
1 parent 9327969 commit 8308c5c
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 1 deletion.
20 changes: 19 additions & 1 deletion emu/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ __no_instrument DECODER_RET glue(DECODER_NAME, OP_SIZE)(DECODER_ARGS) {
READMODRM; MOVZX(modrm_val, modrm_reg,16,oz); break;

#define GRP8(bit, val,z) \
switch(modrm.opcode) { \
switch (modrm.opcode) { \
case 4: TRACEI("bt"); BT(bit, val,z); break; \
case 5: TRACEI("bts"); BTS(bit, val,z); break; \
case 6: TRACEI("btr"); BTR(bit, val,z); break; \
Expand Down Expand Up @@ -732,6 +732,24 @@ __no_instrument DECODER_RET glue(DECODER_NAME, OP_SIZE)(DECODER_ARGS) {
case 0x0f:
READINSN;
switch (insn) {
case 0xab: TRACEI("lock bts reg, modrm");
READMODRM; ATOMIC_BTS(modrm_reg, modrm_val,oz); break;
case 0xb3: TRACEI("lock btr reg, modrm");
READMODRM; ATOMIC_BTR(modrm_reg, modrm_val,oz); break;
case 0xbb: TRACEI("lock btc reg, modrm");
READMODRM; ATOMIC_BTC(modrm_reg, modrm_val,oz); break;

#define GRP8_ATOMIC(bit, val,z) \
switch (modrm.opcode) { \
case 5: TRACEI("bts"); ATOMIC_BTS(bit, val,z); break; \
case 6: TRACEI("btr"); ATOMIC_BTR(bit, val,z); break; \
case 7: TRACEI("btc"); ATOMIC_BTC(bit, val,z); break; \
default: UNDEFINED; \
}
case 0xba: TRACEI("lock grp8 imm8, modrm");
READMODRM; READIMM8; GRP8_ATOMIC(imm, modrm_val,oz); break;
#undef GRP8_ATOMIC

case 0xb1: TRACEI("lock cmpxchg reg, modrm");
READMODRM_MEM; ATOMIC_CMPXCHG(modrm_reg, modrm_val,oz); break;

Expand Down
3 changes: 3 additions & 0 deletions emu/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,9 @@ static bool modrm_compute(struct cpu_state *cpu, struct tlb *tlb, addr_t *addr_o
#define ATOMIC_DEC DEC
#define ATOMIC_CMPXCHG CMPXCHG
#define ATOMIC_XADD XADD
#define ATOMIC_BTS BTS
#define ATOMIC_BTR BTR
#define ATOMIC_BTC BTC
#include "emu/interp/sse.h"
#include "emu/interp/fpu.h"

Expand Down
38 changes: 38 additions & 0 deletions jit/gadgets-aarch64/bits.S
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@
ldr w8, [_xaddr]
do_bt_op \op, w8, \size, \s
.ifin(\op, btc,bts,btr)
str w8, [_xaddr]
write_done \size, \op\size\()_mem
.endifin
gret 1
Expand Down Expand Up @@ -254,6 +255,43 @@
.gadget_array \op
.endr

# atomic versions of the above

.macro do_bt_atomic op, size, s
.gadget atomic_\op\size\()_mem
bic w8, _tmp, 0x1f
add _addr, _addr, w8, lsr 3
write_prep \size, atomic_\op\size\()_mem
# this is simple enough that I'm comfortable doing it with ldaxr/stlxr
1:
ldaxr w8, [_xaddr]
mov w9, 1
and _tmp, _tmp, \size-1
lsl w9, w9, _tmp
tst w8, w9
.ifc \op,btc
eor w8, w8, w9
.else N .ifc \op,bts
orr w8, w8, w9
.else N .ifc \op,btr
bic w8, w8, w9
.endif N .endif N .endif
cset w9, ne
stlxr w10, w8, [_xaddr]
cbnz w10, 1b
strb w9, [_cpu, CPU_cf]
write_done \size, atomic_\op\size\()_mem
gret 1
write_bullshit \size, atomic_\op\size\()_mem
.endm

.irp op, btc,bts,btr
.irp size, 16,32
ss \size, do_bt_atomic, \op
.endr
.gadget_array atomic_\op
.endr

.macro x name reg
.gadget bswap_\name
rev \reg, \reg
Expand Down
22 changes: 22 additions & 0 deletions jit/gadgets-x86_64/bits.S
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,28 @@
.gadget_array \op
.endr

# atomic versions of the above

.macro do_bt_atomic op, size, s, ss
.gadget atomic_\op\size\()_mem
mov\ss %tmp\s, %r14\s
andl $~(\size-1), %r14d
shrl $3, %r14d
addl %r14d, %_addr
read_prep \size, atomic_\op\size\()_mem
and\ss $(\size-1), %tmp\s
lock \op\ss %tmp\s, (%_addrq)
setf_c
gret 1
.endm

.irp op, btc,bts,btr
.irp size, 16,32
ss \size, do_bt_atomic, \op
.endr
.gadget_array atomic_\op
.endr

.macro x name reg
.gadget bswap_\name
bswap %\reg
Expand Down
3 changes: 3 additions & 0 deletions jit/gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,9 @@ void helper_rdtsc(struct cpu_state *cpu);
#define ATOMIC_DEC(val,z) op(atomic_dec, val, z)
#define ATOMIC_CMPXCHG(src, dst,z) atomic_op(cmpxchg, src, dst, z)
#define ATOMIC_XADD(src, dst,z) load(src, z); op(atomic_xadd, dst, z); store(src, z)
#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)

// sse
#define XORP(src, dst) UNDEFINED
Expand Down

0 comments on commit 8308c5c

Please sign in to comment.