diff options
author | Chris Lattner <sabre@nondot.org> | 2005-01-08 05:45:24 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-01-08 05:45:24 +0000 |
commit | 7ab65934a0b126d198ff17dd4bc734ddd0d46dd4 (patch) | |
tree | 7ec4616a0ce0048b727543694546cc0f0fec5add | |
parent | fb0c3bd5314a26fd95d1c25d81960548200dbbbe (diff) | |
download | external_llvm-7ab65934a0b126d198ff17dd4bc734ddd0d46dd4.zip external_llvm-7ab65934a0b126d198ff17dd4bc734ddd0d46dd4.tar.gz external_llvm-7ab65934a0b126d198ff17dd4bc734ddd0d46dd4.tar.bz2 |
The X86 instruction selector already handles codegen of:
store float 123.45, float* %P
as an integer store. This adds handling of float immediate stores as integers
for arguments passed function calls.
This is now tested by CodeGen/X86/store-fp-constant.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19364 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/X86/X86ISelSimple.cpp | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp index 4aeab3e..9de2ef2 100644 --- a/lib/Target/X86/X86ISelSimple.cpp +++ b/lib/Target/X86/X86ISelSimple.cpp @@ -1631,15 +1631,40 @@ void X86ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI, break; case cFP: - ArgReg = Args[i].Val ? getReg(Args[i].Val) : Args[i].Reg; - if (Args[i].Ty == Type::FloatTy) { - addRegOffset(BuildMI(BB, X86::FST32m, 5), - X86::ESP, ArgOffset).addReg(ArgReg); + if (ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(Args[i].Val)) { + // Store constant FP values with integer instructions to avoid having to + // load the constants from the constant pool then do a store. + if (CFP->getType() == Type::FloatTy) { + union { + unsigned I; + float F; + } V; + V.F = CFP->getValue(); + addRegOffset(BuildMI(BB, X86::MOV32mi, 5), + X86::ESP, ArgOffset).addImm(V.I); + } else { + union { + uint64_t I; + double F; + } V; + V.F = CFP->getValue(); + addRegOffset(BuildMI(BB, X86::MOV32mi, 5), + X86::ESP, ArgOffset).addImm((unsigned)V.I); + addRegOffset(BuildMI(BB, X86::MOV32mi, 5), + X86::ESP, ArgOffset+4).addImm(unsigned(V.I >> 32)); + ArgOffset += 4; // 8 byte entry, not 4. + } } else { - assert(Args[i].Ty == Type::DoubleTy && "Unknown FP type!"); - addRegOffset(BuildMI(BB, X86::FST64m, 5), - X86::ESP, ArgOffset).addReg(ArgReg); - ArgOffset += 4; // 8 byte entry, not 4. + ArgReg = Args[i].Val ? getReg(Args[i].Val) : Args[i].Reg; + if (Args[i].Ty == Type::FloatTy) { + addRegOffset(BuildMI(BB, X86::FST32m, 5), + X86::ESP, ArgOffset).addReg(ArgReg); + } else { + assert(Args[i].Ty == Type::DoubleTy && "Unknown FP type!"); + addRegOffset(BuildMI(BB, X86::FST64m, 5), + X86::ESP, ArgOffset).addReg(ArgReg); + ArgOffset += 4; // 8 byte entry, not 4. + } } break; |