From c51f45239d7dbac7e8f8243937320843e120a90d Mon Sep 17 00:00:00 2001 From: Clement Courbet Date: Fri, 19 Oct 2018 09:56:54 +0000 Subject: [PATCH] [llvm-exegesis] X87 RFP setup code. Summary: This was lost during refactoring in rL342644. Fix and simplify simplify value size handling: always go through a 80 bit value, because the value can be 1 byte). Add unit tests. Reviewers: gchatelet Subscribers: tschuett, llvm-commits Differential Revision: https://reviews.llvm.org/D53423 llvm-svn: 344779 --- llvm/tools/llvm-exegesis/lib/X86/Target.cpp | 40 ++++++++++------ .../tools/llvm-exegesis/X86/TargetTest.cpp | 54 +++++++++++++++++++--- 2 files changed, 74 insertions(+), 20 deletions(-) diff --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp index 20bb65e..ae5c2e8 100644 --- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp @@ -182,12 +182,10 @@ struct ConstantInliner { return std::move(Instructions); } - std::vector - loadX87AndFinalize(unsigned Reg, unsigned RegBitWidth, unsigned Opcode) { - assert((RegBitWidth & 7) == 0 && - "RegBitWidth must be a multiple of 8 bits"); - initStack(RegBitWidth / 8); - add(llvm::MCInstBuilder(Opcode) + std::vector loadX87STAndFinalize(unsigned Reg) { + initStack(kF80Bytes); + add(llvm::MCInstBuilder(llvm::X86::LD_F80m) + // Address = ESP .addReg(llvm::X86::RSP) // BaseReg .addImm(1) // ScaleAmt .addReg(0) // IndexReg @@ -195,7 +193,21 @@ struct ConstantInliner { .addReg(0)); // Segment if (Reg != llvm::X86::ST0) add(llvm::MCInstBuilder(llvm::X86::ST_Frr).addReg(Reg)); - add(releaseStackSpace(RegBitWidth / 8)); + add(releaseStackSpace(kF80Bytes)); + return std::move(Instructions); + } + + std::vector loadX87FPAndFinalize(unsigned Reg) { + initStack(kF80Bytes); + add(llvm::MCInstBuilder(llvm::X86::LD_Fp80m) + .addReg(Reg) + // Address = ESP + .addReg(llvm::X86::RSP) // BaseReg + .addImm(1) // ScaleAmt + .addReg(0) // IndexReg + .addImm(0) // Disp + .addReg(0)); // Segment + add(releaseStackSpace(kF80Bytes)); return std::move(Instructions); } @@ -206,6 +218,8 @@ struct ConstantInliner { } private: + static constexpr const unsigned kF80Bytes = 10; // 80 bits. + ConstantInliner &add(const llvm::MCInst &Inst) { Instructions.push_back(Inst); return *this; @@ -318,12 +332,12 @@ class ExegesisX86Target : public ExegesisTarget { if (STI.getFeatureBits()[llvm::X86::FeatureAVX512]) return CI.loadAndFinalize(Reg, 512, llvm::X86::VMOVDQU32Zrm); if (llvm::X86::RSTRegClass.contains(Reg)) { - if (Value.getBitWidth() == 32) - return CI.loadX87AndFinalize(Reg, 32, llvm::X86::LD_F32m); - if (Value.getBitWidth() == 64) - return CI.loadX87AndFinalize(Reg, 64, llvm::X86::LD_F64m); - if (Value.getBitWidth() == 80) - return CI.loadX87AndFinalize(Reg, 80, llvm::X86::LD_F80m); + return CI.loadX87STAndFinalize(Reg); + } + if (llvm::X86::RFP32RegClass.contains(Reg) || + llvm::X86::RFP64RegClass.contains(Reg) || + llvm::X86::RFP80RegClass.contains(Reg)) { + return CI.loadX87FPAndFinalize(Reg); } if (Reg == llvm::X86::EFLAGS) return CI.popFlagAndFinalize(); diff --git a/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp index 6e7554c..5ada03b 100644 --- a/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp @@ -296,12 +296,17 @@ TEST_F(Core2Avx512TargetTest, SetRegToVR512Value) { IsStackDeallocate(64)})); } +// Note: We always put 80 bits on the stack independently of the size of the +// value. This uses a bit more space but makes the code simpler. + TEST_F(Core2TargetTest, SetRegToST0_32Bits) { EXPECT_THAT( setRegTo(llvm::X86::ST0, APInt(32, 0x11112222ULL)), - ElementsAre(IsStackAllocate(4), + ElementsAre(IsStackAllocate(10), IsMovValueToStack(llvm::X86::MOV32mi, 0x11112222UL, 0), - OpcodeIs(llvm::X86::LD_F32m), IsStackDeallocate(4))); + IsMovValueToStack(llvm::X86::MOV32mi, 0x00000000UL, 4), + IsMovValueToStack(llvm::X86::MOV16mi, 0x0000UL, 8), + OpcodeIs(llvm::X86::LD_F80m), IsStackDeallocate(10))); } TEST_F(Core2TargetTest, SetRegToST1_32Bits) { @@ -309,19 +314,22 @@ TEST_F(Core2TargetTest, SetRegToST1_32Bits) { llvm::MCInstBuilder(llvm::X86::ST_Frr).addReg(llvm::X86::ST1); EXPECT_THAT( setRegTo(llvm::X86::ST1, APInt(32, 0x11112222ULL)), - ElementsAre(IsStackAllocate(4), + ElementsAre(IsStackAllocate(10), IsMovValueToStack(llvm::X86::MOV32mi, 0x11112222UL, 0), - OpcodeIs(llvm::X86::LD_F32m), CopySt0ToSt1, - IsStackDeallocate(4))); + IsMovValueToStack(llvm::X86::MOV32mi, 0x00000000UL, 4), + IsMovValueToStack(llvm::X86::MOV16mi, 0x0000UL, 8), + OpcodeIs(llvm::X86::LD_F80m), CopySt0ToSt1, + IsStackDeallocate(10))); } TEST_F(Core2TargetTest, SetRegToST0_64Bits) { EXPECT_THAT( setRegTo(llvm::X86::ST0, APInt(64, 0x1111222233334444ULL)), - ElementsAre(IsStackAllocate(8), + ElementsAre(IsStackAllocate(10), IsMovValueToStack(llvm::X86::MOV32mi, 0x33334444UL, 0), IsMovValueToStack(llvm::X86::MOV32mi, 0x11112222UL, 4), - OpcodeIs(llvm::X86::LD_F64m), IsStackDeallocate(8))); + IsMovValueToStack(llvm::X86::MOV16mi, 0x0000UL, 8), + OpcodeIs(llvm::X86::LD_F80m), IsStackDeallocate(10))); } TEST_F(Core2TargetTest, SetRegToST0_80Bits) { @@ -334,5 +342,37 @@ TEST_F(Core2TargetTest, SetRegToST0_80Bits) { OpcodeIs(llvm::X86::LD_F80m), IsStackDeallocate(10))); } +TEST_F(Core2TargetTest, SetRegToFP0_80Bits) { + EXPECT_THAT( + setRegTo(llvm::X86::FP0, APInt(80, "11112222333344445555", 16)), + ElementsAre(IsStackAllocate(10), + IsMovValueToStack(llvm::X86::MOV32mi, 0x44445555UL, 0), + IsMovValueToStack(llvm::X86::MOV32mi, 0x22223333UL, 4), + IsMovValueToStack(llvm::X86::MOV16mi, 0x1111UL, 8), + OpcodeIs(llvm::X86::LD_Fp80m), IsStackDeallocate(10))); +} + +TEST_F(Core2TargetTest, SetRegToFP1_32Bits) { + EXPECT_THAT( + setRegTo(llvm::X86::FP1, APInt(32, 0x11112222ULL)), + ElementsAre(IsStackAllocate(10), + IsMovValueToStack(llvm::X86::MOV32mi, 0x11112222UL, 0), + IsMovValueToStack(llvm::X86::MOV32mi, 0x00000000UL, 4), + IsMovValueToStack(llvm::X86::MOV16mi, 0x0000UL, 8), + OpcodeIs(llvm::X86::LD_Fp80m), + IsStackDeallocate(10))); +} + +TEST_F(Core2TargetTest, SetRegToFP1_4Bits) { + EXPECT_THAT( + setRegTo(llvm::X86::FP1, APInt(4, 0x1ULL)), + ElementsAre(IsStackAllocate(10), + IsMovValueToStack(llvm::X86::MOV32mi, 0x00000001UL, 0), + IsMovValueToStack(llvm::X86::MOV32mi, 0x00000000UL, 4), + IsMovValueToStack(llvm::X86::MOV16mi, 0x0000UL, 8), + OpcodeIs(llvm::X86::LD_Fp80m), + IsStackDeallocate(10))); +} + } // namespace } // namespace exegesis -- 2.7.4