diff options
| author | Fiora <fioraaeterna@gmail.com> | 2014-08-24 17:39:30 -0700 |
|---|---|---|
| committer | Fiora <fioraaeterna@gmail.com> | 2014-09-03 10:04:01 -0700 |
| commit | 5088a2b4e24527ddf0280ffbc935b4ee8605f326 (patch) | |
| tree | 3deef7693b7d6825d9eef33d717567eed1246a65 /Source/UnitTests/Common/x64EmitterTest.cpp | |
| parent | b583879c2a5b705df1bd7e4ad4450c2d6439be78 (diff) | |
x64Emitter: add BMI1/BMI2 support
TZCNT and LZCNT use a completely different encoding scheme, so they should
probably go in a separate patch.
Also add some tests.
Diffstat (limited to 'Source/UnitTests/Common/x64EmitterTest.cpp')
| -rw-r--r-- | Source/UnitTests/Common/x64EmitterTest.cpp | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/Source/UnitTests/Common/x64EmitterTest.cpp b/Source/UnitTests/Common/x64EmitterTest.cpp index fc47d5a20c..8051e10b07 100644 --- a/Source/UnitTests/Common/x64EmitterTest.cpp +++ b/Source/UnitTests/Common/x64EmitterTest.cpp @@ -833,4 +833,121 @@ TWO_OP_SSE_TEST(PMOVZXDQ, "qword") // TODO: AVX +// for VEX GPR instructions that take the form op reg, r/m, reg +#define VEX_RMR_TEST(Name) \ + TEST_F(x64EmitterTest, Name) \ + { \ + struct { \ + int bits; \ + std::vector<NamedReg> regs; \ + std::string out_name; \ + std::string size; \ + } regsets[] = { \ + { 32, reg32names, "eax", "dword" }, \ + { 64, reg64names, "rax", "qword" }, \ + }; \ + for (const auto& regset : regsets) \ + for (const auto& r : regset.regs) \ + { \ + emitter->Name(regset.bits, r.reg, R(RAX), RAX); \ + emitter->Name(regset.bits, RAX, R(r.reg), RAX); \ + emitter->Name(regset.bits, RAX, MatR(R12), r.reg); \ + ExpectDisassembly(#Name " " + r.name + ", " + regset.out_name + ", " + regset.out_name + " " \ + #Name " " + regset.out_name + ", " + r.name + ", " + regset.out_name + " " \ + #Name " " + regset.out_name + ", " + regset.size + " ptr ds:[r12], " + r.name + " "); \ + } \ + } + +VEX_RMR_TEST(SHRX) +VEX_RMR_TEST(SARX) +VEX_RMR_TEST(SHLX) +VEX_RMR_TEST(BEXTR) +VEX_RMR_TEST(BZHI) + +// for VEX GPR instructions that take the form op reg, reg, r/m +#define VEX_RRM_TEST(Name) \ + TEST_F(x64EmitterTest, Name) \ + { \ + struct { \ + int bits; \ + std::vector<NamedReg> regs; \ + std::string out_name; \ + std::string size; \ + } regsets[] = { \ + { 32, reg32names, "eax", "dword" }, \ + { 64, reg64names, "rax", "qword" }, \ + }; \ + for (const auto& regset : regsets) \ + for (const auto& r : regset.regs) \ + { \ + emitter->Name(regset.bits, r.reg, RAX, R(RAX)); \ + emitter->Name(regset.bits, RAX, RAX, R(r.reg)); \ + emitter->Name(regset.bits, RAX, r.reg, MatR(R12)); \ + ExpectDisassembly(#Name " " + r.name+ ", " + regset.out_name + ", " + regset.out_name + " " \ + #Name " " + regset.out_name + ", " + regset.out_name + ", " + r.name + " " \ + #Name " " + regset.out_name + ", " + r.name + ", " + regset.size + " ptr ds:[r12] "); \ + } \ + } + +VEX_RRM_TEST(PEXT) +VEX_RRM_TEST(PDEP) +VEX_RRM_TEST(MULX) +VEX_RRM_TEST(ANDN) + +// for VEX GPR instructions that take the form op reg, r/m +#define VEX_RM_TEST(Name) \ + TEST_F(x64EmitterTest, Name) \ + { \ + struct { \ + int bits; \ + std::vector<NamedReg> regs; \ + std::string out_name; \ + std::string size; \ + } regsets[] = { \ + { 32, reg32names, "eax", "dword" }, \ + { 64, reg64names, "rax", "qword" }, \ + }; \ + for (const auto& regset : regsets) \ + for (const auto& r : regset.regs) \ + { \ + emitter->Name(regset.bits, r.reg, R(RAX)); \ + emitter->Name(regset.bits, RAX, R(r.reg)); \ + emitter->Name(regset.bits, r.reg, MatR(R12)); \ + ExpectDisassembly(#Name " " + r.name+ ", " + regset.out_name + " " \ + #Name " " + regset.out_name + ", " + r.name + " " \ + #Name " " + r.name + ", " + regset.size + " ptr ds:[r12] "); \ + } \ + } + +VEX_RM_TEST(BLSR) +VEX_RM_TEST(BLSMSK) +VEX_RM_TEST(BLSI) + +// for VEX GPR instructions that take the form op reg, r/m, imm +#define VEX_RMI_TEST(Name) \ + TEST_F(x64EmitterTest, Name) \ + { \ + struct { \ + int bits; \ + std::vector<NamedReg> regs; \ + std::string out_name; \ + std::string size; \ + } regsets[] = { \ + { 32, reg32names, "eax", "dword" }, \ + { 64, reg64names, "rax", "qword" }, \ + }; \ + for (const auto& regset : regsets) \ + for (const auto& r : regset.regs) \ + { \ + emitter->Name(regset.bits, r.reg, R(RAX), 4); \ + emitter->Name(regset.bits, RAX, R(r.reg), 4); \ + emitter->Name(regset.bits, r.reg, MatR(R12), 4); \ + ExpectDisassembly(#Name " " + r.name+ ", " + regset.out_name + ", 0x04 " \ + #Name " " + regset.out_name + ", " + r.name + ", 0x04 " \ + #Name " " + r.name + ", " + regset.size + " ptr ds:[r12], 0x04 "); \ + } \ + } + +VEX_RMI_TEST(RORX) + } // namespace Gen |
