diff options
| author | Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> | 2020-09-15 10:44:46 -0400 |
|---|---|---|
| committer | Alan Wu <XrXr@users.noreply.github.com> | 2021-10-20 18:19:23 -0400 |
| commit | 2e319492254e529a2f5673038ec6c3ea44087199 (patch) | |
| tree | 4c7eb0334a17f1fbf343ed08a75ec73805125c62 | |
| parent | 090255456aa137f28cc254c609ff95fb7fd3d71b (diff) | |
Ported xor and cmovcc instructions
| -rw-r--r-- | ujit_asm.c | 107 | ||||
| -rw-r--r-- | ujit_asm.h | 31 | ||||
| -rw-r--r-- | ujit_asm_tests.c | 34 |
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"); } |
