diff options
| -rw-r--r-- | compiler/utils/x86/assembler_x86.cc | 14 | ||||
| -rw-r--r-- | compiler/utils/x86/assembler_x86.h | 2 | ||||
| -rw-r--r-- | compiler/utils/x86/assembler_x86_test.cc | 13 | ||||
| -rw-r--r-- | compiler/utils/x86_64/assembler_x86_64.cc | 31 | ||||
| -rw-r--r-- | compiler/utils/x86_64/assembler_x86_64.h | 5 | ||||
| -rw-r--r-- | compiler/utils/x86_64/assembler_x86_64_test.cc | 38 | ||||
| -rw-r--r-- | disassembler/disassembler_x86.cc | 5 |
7 files changed, 108 insertions, 0 deletions
diff --git a/compiler/utils/x86/assembler_x86.cc b/compiler/utils/x86/assembler_x86.cc index 914bd56683..9b3d792903 100644 --- a/compiler/utils/x86/assembler_x86.cc +++ b/compiler/utils/x86/assembler_x86.cc @@ -158,6 +158,20 @@ void X86Assembler::bswapl(Register dst) { EmitUint8(0xC8 + dst); } +void X86Assembler::bsrl(Register dst, Register src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x0F); + EmitUint8(0xBD); + EmitRegisterOperand(dst, src); +} + +void X86Assembler::bsrl(Register dst, const Address& src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x0F); + EmitUint8(0xBD); + EmitOperand(dst, src); +} + void X86Assembler::movzxb(Register dst, ByteRegister src) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitUint8(0x0F); diff --git a/compiler/utils/x86/assembler_x86.h b/compiler/utils/x86/assembler_x86.h index 850e1dab32..a9227f38b0 100644 --- a/compiler/utils/x86/assembler_x86.h +++ b/compiler/utils/x86/assembler_x86.h @@ -234,6 +234,8 @@ class X86Assembler FINAL : public Assembler { void movntl(const Address& dst, Register src); void bswapl(Register dst); + void bsrl(Register dst, Register src); + void bsrl(Register dst, const Address& src); void movzxb(Register dst, ByteRegister src); void movzxb(Register dst, const Address& src); diff --git a/compiler/utils/x86/assembler_x86_test.cc b/compiler/utils/x86/assembler_x86_test.cc index c257b789be..731b5f4ac5 100644 --- a/compiler/utils/x86/assembler_x86_test.cc +++ b/compiler/utils/x86/assembler_x86_test.cc @@ -230,4 +230,17 @@ TEST_F(AssemblerX86Test, RepMovsw) { DriverStr(expected, "rep_movsw"); } +TEST_F(AssemblerX86Test, Bsrl) { + DriverStr(RepeatRR(&x86::X86Assembler::bsrl, "bsrl %{reg2}, %{reg1}"), "bsrl"); +} + +TEST_F(AssemblerX86Test, BsrlAddress) { + GetAssembler()->bsrl(x86::Register(x86::EDI), x86::Address( + x86::Register(x86::EDI), x86::Register(x86::EBX), x86::TIMES_4, 12)); + const char* expected = + "bsrl 0xc(%EDI,%EBX,4), %EDI\n"; + + DriverStr(expected, "bsrl_address"); +} + } // namespace art diff --git a/compiler/utils/x86_64/assembler_x86_64.cc b/compiler/utils/x86_64/assembler_x86_64.cc index 38a9e72dae..dc61c992e0 100644 --- a/compiler/utils/x86_64/assembler_x86_64.cc +++ b/compiler/utils/x86_64/assembler_x86_64.cc @@ -2092,6 +2092,37 @@ void X86_64Assembler::bswapq(CpuRegister dst) { EmitUint8(0xC8 + dst.LowBits()); } +void X86_64Assembler::bsrl(CpuRegister dst, CpuRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitOptionalRex32(dst, src); + EmitUint8(0x0F); + EmitUint8(0xBD); + EmitRegisterOperand(dst.LowBits(), src.LowBits()); +} + +void X86_64Assembler::bsrl(CpuRegister dst, const Address& src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitOptionalRex32(dst, src); + EmitUint8(0x0F); + EmitUint8(0xBD); + EmitOperand(dst.LowBits(), src); +} + +void X86_64Assembler::bsrq(CpuRegister dst, CpuRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitRex64(dst, src); + EmitUint8(0x0F); + EmitUint8(0xBD); + EmitRegisterOperand(dst.LowBits(), src.LowBits()); +} + +void X86_64Assembler::bsrq(CpuRegister dst, const Address& src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitRex64(dst, src); + EmitUint8(0x0F); + EmitUint8(0xBD); + EmitOperand(dst.LowBits(), src); +} void X86_64Assembler::repne_scasw() { AssemblerBuffer::EnsureCapacity ensured(&buffer_); diff --git a/compiler/utils/x86_64/assembler_x86_64.h b/compiler/utils/x86_64/assembler_x86_64.h index 67807850c6..da42213048 100644 --- a/compiler/utils/x86_64/assembler_x86_64.h +++ b/compiler/utils/x86_64/assembler_x86_64.h @@ -606,6 +606,11 @@ class X86_64Assembler FINAL : public Assembler { void bswapl(CpuRegister dst); void bswapq(CpuRegister dst); + void bsrl(CpuRegister dst, CpuRegister src); + void bsrl(CpuRegister dst, const Address& src); + void bsrq(CpuRegister dst, CpuRegister src); + void bsrq(CpuRegister dst, const Address& src); + void repne_scasw(); void repe_cmpsw(); void repe_cmpsl(); diff --git a/compiler/utils/x86_64/assembler_x86_64_test.cc b/compiler/utils/x86_64/assembler_x86_64_test.cc index 7e879e9ce1..8673f039ed 100644 --- a/compiler/utils/x86_64/assembler_x86_64_test.cc +++ b/compiler/utils/x86_64/assembler_x86_64_test.cc @@ -1141,6 +1141,44 @@ TEST_F(AssemblerX86_64Test, Bswapq) { DriverStr(RepeatR(&x86_64::X86_64Assembler::bswapq, "bswap %{reg}"), "bswapq"); } +TEST_F(AssemblerX86_64Test, Bsrl) { + DriverStr(Repeatrr(&x86_64::X86_64Assembler::bsrl, "bsrl %{reg2}, %{reg1}"), "bsrl"); +} + +TEST_F(AssemblerX86_64Test, BsrlAddress) { + GetAssembler()->bsrl(x86_64::CpuRegister(x86_64::R10), x86_64::Address( + x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12)); + GetAssembler()->bsrl(x86_64::CpuRegister(x86_64::RDI), x86_64::Address( + x86_64::CpuRegister(x86_64::R10), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12)); + GetAssembler()->bsrl(x86_64::CpuRegister(x86_64::RDI), x86_64::Address( + x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12)); + const char* expected = + "bsrl 0xc(%RDI,%RBX,4), %R10d\n" + "bsrl 0xc(%R10,%RBX,4), %edi\n" + "bsrl 0xc(%RDI,%R9,4), %edi\n"; + + DriverStr(expected, "bsrl_address"); +} + +TEST_F(AssemblerX86_64Test, Bsrq) { + DriverStr(RepeatRR(&x86_64::X86_64Assembler::bsrq, "bsrq %{reg2}, %{reg1}"), "bsrq"); +} + +TEST_F(AssemblerX86_64Test, BsrqAddress) { + GetAssembler()->bsrq(x86_64::CpuRegister(x86_64::R10), x86_64::Address( + x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12)); + GetAssembler()->bsrq(x86_64::CpuRegister(x86_64::RDI), x86_64::Address( + x86_64::CpuRegister(x86_64::R10), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12)); + GetAssembler()->bsrq(x86_64::CpuRegister(x86_64::RDI), x86_64::Address( + x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12)); + const char* expected = + "bsrq 0xc(%RDI,%RBX,4), %R10\n" + "bsrq 0xc(%R10,%RBX,4), %RDI\n" + "bsrq 0xc(%RDI,%R9,4), %RDI\n"; + + DriverStr(expected, "bsrq_address"); +} + std::string setcc_test_fn(AssemblerX86_64Test::Base* assembler_test, x86_64::X86_64Assembler* assembler) { // From Condition diff --git a/disassembler/disassembler_x86.cc b/disassembler/disassembler_x86.cc index 9bee1040ba..d4574f4f0a 100644 --- a/disassembler/disassembler_x86.cc +++ b/disassembler/disassembler_x86.cc @@ -928,6 +928,11 @@ DISASSEMBLER_ENTRY(cmp, has_modrm = true; load = true; break; + case 0xBD: + opcode1 = "bsr"; + has_modrm = true; + load = true; + break; case 0xBE: opcode1 = "movsxb"; has_modrm = true; |