summaryrefslogtreecommitdiff
path: root/yjit_asm.c
diff options
context:
space:
mode:
authorMaxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>2021-05-12 10:18:46 -0400
committerAlan Wu <XrXr@users.noreply.github.com>2021-10-20 18:19:35 -0400
commit6b5d26dc788bfcf1d39db0bfe25645173507299c (patch)
treeaa6e79094f52ed8ab427fc7432dc0d3fd5d96911 /yjit_asm.c
parent5c2f74fc32951fc038dca465985a4859c517ef47 (diff)
Implement basic encodings for xchg
Diffstat (limited to 'yjit_asm.c')
-rw-r--r--yjit_asm.c23
1 files changed, 23 insertions, 0 deletions
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)
{