From 6b5d26dc788bfcf1d39db0bfe25645173507299c Mon Sep 17 00:00:00 2001 From: Maxime Chevalier-Boisvert Date: Wed, 12 May 2021 10:18:46 -0400 Subject: Implement basic encodings for xchg --- yjit_asm.c | 23 +++++++++++++++++++++++ yjit_asm.h | 2 +- yjit_asm_tests.c | 6 ++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/yjit_asm.c b/yjit_asm.c index 76fc3bf8db..da640e6d7d 100644 --- a/yjit_asm.c +++ b/yjit_asm.c @@ -1682,6 +1682,29 @@ void ud2(codeblock_t* cb) cb_write_bytes(cb, 2, 0x0F, 0x0B); } +/// xchg - Exchange Register/Memory with Register +void xchg(codeblock_t* cb, x86opnd_t rm_opnd, x86opnd_t r_opnd) +{ + assert (rm_opnd.num_bits == 64); + assert (r_opnd.num_bits == 64); + assert (rm_opnd.type == OPND_REG); + assert (r_opnd.type == OPND_REG); + + // If we're exchanging with RAX + if (rm_opnd.type == OPND_REG && rm_opnd.as.reg.reg_no == RAX.as.reg.reg_no) + { + // Write the REX byte + cb_write_rex(cb, rm_opnd.num_bits == 64, 0, 0, r_opnd.as.reg.reg_no); + + // Write the opcode and register number + cb_write_byte(cb, 0x90 + (r_opnd.as.reg.reg_no & 7)); + } + else + { + cb_write_rm(cb, rm_opnd.num_bits == 16, rm_opnd.num_bits == 64, r_opnd, rm_opnd, 0xFF, 1, 0x87); + } +} + /// xor - Exclusive bitwise OR void xor(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1) { diff --git a/yjit_asm.h b/yjit_asm.h index 617a32aafc..15c670fec7 100644 --- a/yjit_asm.h +++ b/yjit_asm.h @@ -377,8 +377,8 @@ void shr(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1); void sub(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1); void test(codeblock_t* cb, x86opnd_t rm_opnd, x86opnd_t test_opnd); void ud2(codeblock_t* cb); +void xchg(codeblock_t* cb, x86opnd_t rm_opnd, x86opnd_t r_opnd); void xor(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1); - void cb_write_lock_prefix(codeblock_t* cb); #endif diff --git a/yjit_asm_tests.c b/yjit_asm_tests.c index 7fc40d497b..3d948d38f4 100644 --- a/yjit_asm_tests.c +++ b/yjit_asm_tests.c @@ -341,6 +341,12 @@ void run_tests() cb_set_pos(cb, 0); test(cb, RAX, RSI); check_bytes(cb, "4885F0"); cb_set_pos(cb, 0); test(cb, mem_opnd(64, RSI, 64), imm_opnd(~0x08)); check_bytes(cb, "48F74640F7FFFFFF"); + // xchg + cb_set_pos(cb, 0); xchg(cb, RAX, RCX); check_bytes(cb, "4891"); + cb_set_pos(cb, 0); xchg(cb, RAX, R13); check_bytes(cb, "4995"); + cb_set_pos(cb, 0); xchg(cb, RCX, RBX); check_bytes(cb, "4887D9"); + cb_set_pos(cb, 0); xchg(cb, R9, R15); check_bytes(cb, "4D87F9"); + // xor cb_set_pos(cb, 0); xor(cb, EAX, EAX); check_bytes(cb, "31C0"); -- cgit v1.2.3