From 0a18601f141d864a26d4b74ff5613e69ae411483 Mon Sep 17 00:00:00 2001 From: Roland Levillain Date: Mon, 13 Apr 2015 17:00:20 +0100 Subject: [PATCH] Exercise the x86 and x86-64 FILD and FISTP instructions. - Ensure the double- and quadword x87 (FPU) instructions for integer loading (resp. fildl and fildll) are properly generated by the x86 and x86-64 generators (resp. X86Assembler::filds/X86_64Assembler::filds and X86Assembler::fildl/X86_64Assembler::fildl). - Ensure the double- and quadword x87 (FPU) instructions for integer storing & popping (resp. filstpl and fistpll) are properly generated by the x86 and x86-64 generators (resp. X86Assembler::fistps/X86_64Assembler::fistps and X86Assembler::fistpl/X86_64Assembler::fistpl). These instructions can be used in the implementation of the long-to-float and long-to-double Dex type conversions. Change-Id: Iade52a9aee326d189d77d3dbd352a2b5dab52e46 --- compiler/utils/x86/assembler_x86.cc | 7 +++++++ compiler/utils/x86/assembler_x86.h | 1 + compiler/utils/x86/assembler_x86_test.cc | 18 ++++++++++++++++++ compiler/utils/x86_64/assembler_x86_64.cc | 7 +++++++ compiler/utils/x86_64/assembler_x86_64.h | 1 + compiler/utils/x86_64/assembler_x86_64_test.cc | 18 ++++++++++++++++++ 6 files changed, 52 insertions(+) diff --git a/compiler/utils/x86/assembler_x86.cc b/compiler/utils/x86/assembler_x86.cc index 51cc7acbd..329698ce1 100644 --- a/compiler/utils/x86/assembler_x86.cc +++ b/compiler/utils/x86/assembler_x86.cc @@ -883,6 +883,13 @@ void X86Assembler::fildl(const Address& src) { } +void X86Assembler::filds(const Address& src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0xDB); + EmitOperand(0, src); +} + + void X86Assembler::fincstp() { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitUint8(0xD9); diff --git a/compiler/utils/x86/assembler_x86.h b/compiler/utils/x86/assembler_x86.h index f3675aece..a933474a3 100644 --- a/compiler/utils/x86/assembler_x86.h +++ b/compiler/utils/x86/assembler_x86.h @@ -349,6 +349,7 @@ class X86Assembler FINAL : public Assembler { void fistpl(const Address& dst); void fistps(const Address& dst); void fildl(const Address& src); + void filds(const Address& src); void fincstp(); void ffree(const Immediate& index); diff --git a/compiler/utils/x86/assembler_x86_test.cc b/compiler/utils/x86/assembler_x86_test.cc index dba3b6ba6..f326e496d 100644 --- a/compiler/utils/x86/assembler_x86_test.cc +++ b/compiler/utils/x86/assembler_x86_test.cc @@ -172,4 +172,22 @@ TEST_F(AssemblerX86Test, LockCmpxchg8b) { DriverStr(expected, "lock_cmpxchg8b"); } +TEST_F(AssemblerX86Test, FPUIntegerLoad) { + GetAssembler()->filds(x86::Address(x86::Register(x86::ESP), 4)); + GetAssembler()->fildl(x86::Address(x86::Register(x86::ESP), 12)); + const char* expected = + "fildl 0x4(%ESP)\n" + "fildll 0xc(%ESP)\n"; + DriverStr(expected, "FPUIntegerLoad"); +} + +TEST_F(AssemblerX86Test, FPUIntegerStore) { + GetAssembler()->fistps(x86::Address(x86::Register(x86::ESP), 16)); + GetAssembler()->fistpl(x86::Address(x86::Register(x86::ESP), 24)); + const char* expected = + "fistpl 0x10(%ESP)\n" + "fistpll 0x18(%ESP)\n"; + DriverStr(expected, "FPUIntegerStore"); +} + } // namespace art diff --git a/compiler/utils/x86_64/assembler_x86_64.cc b/compiler/utils/x86_64/assembler_x86_64.cc index 638659d63..32204a997 100644 --- a/compiler/utils/x86_64/assembler_x86_64.cc +++ b/compiler/utils/x86_64/assembler_x86_64.cc @@ -988,6 +988,13 @@ void X86_64Assembler::fildl(const Address& src) { } +void X86_64Assembler::filds(const Address& src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0xDB); + EmitOperand(0, src); +} + + void X86_64Assembler::fincstp() { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitUint8(0xD9); diff --git a/compiler/utils/x86_64/assembler_x86_64.h b/compiler/utils/x86_64/assembler_x86_64.h index 15b8b15c7..16ef70b85 100644 --- a/compiler/utils/x86_64/assembler_x86_64.h +++ b/compiler/utils/x86_64/assembler_x86_64.h @@ -448,6 +448,7 @@ class X86_64Assembler FINAL : public Assembler { void fistpl(const Address& dst); void fistps(const Address& dst); void fildl(const Address& src); + void filds(const Address& src); void fincstp(); void ffree(const Immediate& index); diff --git a/compiler/utils/x86_64/assembler_x86_64_test.cc b/compiler/utils/x86_64/assembler_x86_64_test.cc index 116190a83..5ca0373a6 100644 --- a/compiler/utils/x86_64/assembler_x86_64_test.cc +++ b/compiler/utils/x86_64/assembler_x86_64_test.cc @@ -849,6 +849,24 @@ TEST_F(AssemblerX86_64Test, X87) { DriverFn(&x87_fn, "x87"); } +TEST_F(AssemblerX86_64Test, FPUIntegerLoad) { + GetAssembler()->filds(x86_64::Address(x86_64::CpuRegister(x86_64::RSP), 4)); + GetAssembler()->fildl(x86_64::Address(x86_64::CpuRegister(x86_64::RSP), 12)); + const char* expected = + "fildl 0x4(%RSP)\n" + "fildll 0xc(%RSP)\n"; + DriverStr(expected, "FPUIntegerLoad"); +} + +TEST_F(AssemblerX86_64Test, FPUIntegerStore) { + GetAssembler()->fistps(x86_64::Address(x86_64::CpuRegister(x86_64::RSP), 16)); + GetAssembler()->fistpl(x86_64::Address(x86_64::CpuRegister(x86_64::RSP), 24)); + const char* expected = + "fistpl 0x10(%RSP)\n" + "fistpll 0x18(%RSP)\n"; + DriverStr(expected, "FPUIntegerStore"); +} + //////////////// // CALL / JMP // //////////////// -- 2.11.0