summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>2020-09-15 10:44:46 -0400
committerAlan Wu <XrXr@users.noreply.github.com>2021-10-20 18:19:23 -0400
commit2e319492254e529a2f5673038ec6c3ea44087199 (patch)
tree4c7eb0334a17f1fbf343ed08a75ec73805125c62
parent090255456aa137f28cc254c609ff95fb7fd3d71b (diff)
Ported xor and cmovcc instructions
-rw-r--r--ujit_asm.c107
-rw-r--r--ujit_asm.h31
-rw-r--r--ujit_asm_tests.c34
3 files changed, 91 insertions, 81 deletions
diff --git a/ujit_asm.c b/ujit_asm.c
index ce0e9fb2fe..75c2dc8dc8 100644
--- a/ujit_asm.c
+++ b/ujit_asm.c
@@ -747,20 +747,19 @@ void cb_write_jcc(codeblock_t* cb, const char* mnem, uint8_t op0, uint8_t op1, s
}
// Encode a conditional move instruction
-/*
-void writeCmov(CodeBlock cb, const char mnem, ubyte opcode1, X86Reg dst, X86Opnd src)
+void cb_write_cmov(codeblock_t* cb, const char* mnem, uint8_t opcode1, x86opnd_t dst, x86opnd_t src)
{
//cb.writeASM(mnem, dst, src);
- assert (src.isReg || src.isMem);
- assert (dst.size >= 16, "invalid dst reg size in cmov");
+ assert (dst.type == OPND_REG);
+ assert (src.type == OPND_REG || src.type == OPND_MEM);
+ assert (dst.num_bits >= 16 && "invalid dst reg size in cmov");
- auto szPref = dst.size is 16;
- auto rexW = dst.size is 64;
+ bool szPref = dst.num_bits == 16;
+ bool rexW = dst.num_bits == 64;
- cb.writeRMInstr!('r', 0xFF, 0x0F, opcode1)(szPref, rexW, X86Opnd(dst), src);
+ cb_write_rm(cb, szPref, rexW, dst, src, 0xFF, 2, 0x0F, opcode1);
}
-*/
// add - Integer addition
void add(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
@@ -822,39 +821,37 @@ void call(codeblock_t* cb, x86opnd_t opnd)
cb_write_rm(cb, false, false, NO_OPND, opnd, 2, 1, 0xFF);
}
-/*
/// cmovcc - Conditional move
-alias cmova = writeCmov!("cmova", 0x47);
-alias cmovae = writeCmov!("cmovae", 0x43);
-alias cmovb = writeCmov!("cmovb", 0x42);
-alias cmovbe = writeCmov!("cmovbe", 0x46);
-alias cmovc = writeCmov!("cmovc", 0x42);
-alias cmove = writeCmov!("cmove", 0x44);
-alias cmovg = writeCmov!("cmovg", 0x4F);
-alias cmovge = writeCmov!("cmovge", 0x4D);
-alias cmovl = writeCmov!("cmovl", 0x4C);
-alias cmovle = writeCmov!("cmovle", 0x4E);
-alias cmovna = writeCmov!("cmovna", 0x46);
-alias cmovnae = writeCmov!("cmovnae", 0x42);
-alias cmovnb = writeCmov!("cmovnb", 0x43);
-alias cmovnbe = writeCmov!("cmovnbe", 0x47);
-alias cmovnc = writeCmov!("cmovnc", 0x43);
-alias cmovne = writeCmov!("cmovne", 0x45);
-alias cmovnge = writeCmov!("cmovng", 0x4E);
-alias cmovnge = writeCmov!("cmovnge", 0x4C);
-alias cmovnl = writeCmov!("cmovnl", 0x4D);
-alias cmovnle = writeCmov!("cmovnle", 0x4F);
-alias cmovno = writeCmov!("cmovno", 0x41);
-alias cmovnp = writeCmov!("cmovnp", 0x4B);
-alias cmovns = writeCmov!("cmovns", 0x49);
-alias cmovnz = writeCmov!("cmovnz", 0x45);
-alias cmovo = writeCmov!("cmovno", 0x40);
-alias cmovp = writeCmov!("cmovp", 0x4A);
-alias cmovpe = writeCmov!("cmovpe", 0x4A);
-alias cmovpo = writeCmov!("cmovpo", 0x4B);
-alias cmovs = writeCmov!("cmovs", 0x48);
-alias cmovz = writeCmov!("cmovz", 0x44);
-*/
+void cmova(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmova", 0x47, dst, src); }
+void cmovae(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovae", 0x43, dst, src); }
+void cmovb(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovb", 0x42, dst, src); }
+void cmovbe(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovbe", 0x46, dst, src); }
+void cmovc(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovc", 0x42, dst, src); }
+void cmove(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmove", 0x44, dst, src); }
+void cmovg(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovg", 0x4F, dst, src); }
+void cmovge(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovge", 0x4D, dst, src); }
+void cmovl(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovl", 0x4C, dst, src); }
+void cmovle(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovle", 0x4E, dst, src); }
+void cmovna(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovna", 0x46, dst, src); }
+void cmovnae(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovnae", 0x42, dst, src); }
+void cmovnb(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovnb", 0x43, dst, src); }
+void cmovnbe(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovnbe", 0x47, dst, src); }
+void cmovnc(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovnc", 0x43, dst, src); }
+void cmovne(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovne", 0x45, dst, src); }
+void cmovng(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovng", 0x4E, dst, src); }
+void cmovnge(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovnge", 0x4C, dst, src); }
+void cmovnl(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovnl" , 0x4D, dst, src); }
+void cmovnle(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovnle", 0x4F, dst, src); }
+void cmovno(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovno", 0x41, dst, src); }
+void cmovnp(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovnp", 0x4B, dst, src); }
+void cmovns(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovns", 0x49, dst, src); }
+void cmovnz(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovnz", 0x45, dst, src); }
+void cmovo(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovo", 0x40, dst, src); }
+void cmovp(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovp", 0x4A, dst, src); }
+void cmovpe(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovpe", 0x4A, dst, src); }
+void cmovpo(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovpo", 0x4B, dst, src); }
+void cmovs(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovs", 0x48, dst, src); }
+void cmovz(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) { cb_write_cmov(cb, "cmovz", 0x44, dst, src); }
/// cmp - Compare and set flags
void cmp(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
@@ -1386,17 +1383,21 @@ void sub(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
);
}
-/*
/// xor - Exclusive bitwise OR
-alias xor = writeRMMulti!(
- "xor",
- 0x30, // opMemReg8
- 0x31, // opMemRegPref
- 0x32, // opRegMem8
- 0x33, // opRegMemPref
- 0x80, // opMemImm8
- 0x83, // opMemImmSml
- 0x81, // opMemImmLrg
- 0x06 // opExtImm
-);
-*/
+void xor(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
+{
+ cb_write_rm_multi(
+ cb,
+ "xor",
+ 0x30, // opMemReg8
+ 0x31, // opMemRegPref
+ 0x32, // opRegMem8
+ 0x33, // opRegMemPref
+ 0x80, // opMemImm8
+ 0x83, // opMemImmSml
+ 0x81, // opMemImmLrg
+ 0x06, // opExtImm
+ opnd0,
+ opnd1
+ );
+}
diff --git a/ujit_asm.h b/ujit_asm.h
index 569c310381..502b7c665f 100644
--- a/ujit_asm.h
+++ b/ujit_asm.h
@@ -196,6 +196,36 @@ void add(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
void and(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
void call_label(codeblock_t* cb, size_t label_idx);
void call(codeblock_t* cb, x86opnd_t opnd);
+void cmova(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovae(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovb(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovbe(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovc(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmove(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovg(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovge(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovl(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovle(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovna(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovnae(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovnb(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovnbe(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovnc(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovne(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovng(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovnge(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovnl(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovnle(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovno(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovnp(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovns(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovnz(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovo(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovp(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovpe(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovpo(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovs(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void cmovz(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
void cmp(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
void cdq(codeblock_t* cb);
void cqo(codeblock_t* cb);
@@ -247,5 +277,6 @@ void sar(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
void shl(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
void shr(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
void sub(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
+void xor(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
#endif
diff --git a/ujit_asm_tests.c b/ujit_asm_tests.c
index e163404d05..a0e3e07e15 100644
--- a/ujit_asm_tests.c
+++ b/ujit_asm_tests.c
@@ -94,29 +94,12 @@ void run_tests()
cb_set_pos(cb, 0); call(cb, RAX); check_bytes(cb, "FFD0");
cb_set_pos(cb, 0); call(cb, mem_opnd(64, RSP, 8)); check_bytes(cb, "FF542408");
- /*
// cmovcc
- test(
- delegate void (CodeBlock cb) { cb.cmovg(ESI, X86Opnd(EDI)); },
- "0F4FF7"
- );
- test(
- delegate void (CodeBlock cb) { cb.cmovg(ESI, X86Opnd(32, RBP, 12)); },
- "0F4F750C"
- );
- test(
- delegate void (CodeBlock cb) { cb.cmovl(EAX, X86Opnd(ECX)); },
- "0F4CC1"
- );
- test(
- delegate void (CodeBlock cb) { cb.cmovl(RBX, X86Opnd(RBP)); },
- "480F4CDD"
- );
- test(
- delegate void (CodeBlock cb) { cb.cmovle(ESI, X86Opnd(32, RSP, 4)); },
- "0F4E742404"
- );
- */
+ cb_set_pos(cb, 0); cmovg(cb, ESI, EDI); check_bytes(cb, "0F4FF7");
+ cb_set_pos(cb, 0); cmovg(cb, ESI, mem_opnd(32, RBP, 12)); check_bytes(cb, "0F4F750C");
+ cb_set_pos(cb, 0); cmovl(cb, EAX, ECX); check_bytes(cb, "0F4CC1");
+ cb_set_pos(cb, 0); cmovl(cb, RBX, RBP); check_bytes(cb, "480F4CDD");
+ cb_set_pos(cb, 0); cmovle(cb, ESI, mem_opnd(32, RSP, 4)); check_bytes(cb, "0F4E742404");
// cmp
/*
@@ -346,13 +329,8 @@ void run_tests()
cb_set_pos(cb, 0); sub(cb, EAX, imm_opnd(1)); check_bytes(cb, "83E801");
cb_set_pos(cb, 0); sub(cb, RAX, imm_opnd(2)); check_bytes(cb, "4883E802");
- /*
// xor
- test(
- delegate void (CodeBlock cb) { cb.xor(X86Opnd(EAX), X86Opnd(EAX)); },
- "31C0"
- );
- */
+ cb_set_pos(cb, 0); xor(cb, EAX, EAX); check_bytes(cb, "31C0");
printf("Assembler tests done\n");
}