diff options
author | Eric Christopher <echristo@apple.com> | 2010-10-01 00:00:11 +0000 |
---|---|---|
committer | Eric Christopher <echristo@apple.com> | 2010-10-01 00:00:11 +0000 |
commit | 14df88282bf897403db6ac1dc20ad01a0ae79835 (patch) | |
tree | b9b959bca8bd61068b6f670066376b64619a8272 /lib/Target/ARM/ARMFastISel.cpp | |
parent | 0488fb649a56b7fc89a5814df5308813f9e5a85d (diff) |
Implement double return values in calls. Fixes
SingleSource/Regression/C/casts.c.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115246 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/ARMFastISel.cpp')
-rw-r--r-- | lib/Target/ARM/ARMFastISel.cpp | 44 |
1 files changed, 35 insertions, 9 deletions
diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index b4fd1b402c..6d77ce1a8f 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -1162,17 +1162,43 @@ bool ARMFastISel::FinishCall(EVT RetVT, SmallVectorImpl<unsigned> &UsedRegs, CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true)); // Copy all of the result registers out of their specified physreg. - assert(RVLocs.size() == 1 && "Can't handle multi-value calls!"); - EVT CopyVT = RVLocs[0].getValVT(); - TargetRegisterClass* DstRC = TLI.getRegClassFor(CopyVT); + if (RVLocs.size() == 2 && RetVT.getSimpleVT().SimpleTy == MVT::f64) { + // For this move we copy into two registers and then move into the + // double fp reg we want. + // TODO: Are the copies necessary? + TargetRegisterClass *CopyRC = TLI.getRegClassFor(MVT::i32); + unsigned Copy1 = createResultReg(CopyRC); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), + Copy1).addReg(RVLocs[0].getLocReg()); + UsedRegs.push_back(RVLocs[0].getLocReg()); + + unsigned Copy2 = createResultReg(CopyRC); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), + Copy2).addReg(RVLocs[1].getLocReg()); + UsedRegs.push_back(RVLocs[1].getLocReg()); + + EVT DestVT = RVLocs[0].getValVT(); + TargetRegisterClass* DstRC = TLI.getRegClassFor(DestVT); + unsigned ResultReg = createResultReg(DstRC); + AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, + TII.get(ARM::VMOVDRR), ResultReg) + .addReg(Copy1).addReg(Copy2)); + + // Finally update the result. + UpdateValueMap(I, ResultReg); + } else { + assert(RVLocs.size() == 1 && "Can't handle non-double multi-reg retvals!"); + EVT CopyVT = RVLocs[0].getValVT(); + TargetRegisterClass* DstRC = TLI.getRegClassFor(CopyVT); - unsigned ResultReg = createResultReg(DstRC); - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), - ResultReg).addReg(RVLocs[0].getLocReg()); - UsedRegs.push_back(RVLocs[0].getLocReg()); + unsigned ResultReg = createResultReg(DstRC); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), + ResultReg).addReg(RVLocs[0].getLocReg()); + UsedRegs.push_back(RVLocs[0].getLocReg()); - // Finally update the result. - UpdateValueMap(I, ResultReg); + // Finally update the result. + UpdateValueMap(I, ResultReg); + } } return true; |