diff options
author | James Y Knight <jyknight@google.com> | 2015-12-15 19:23:12 +0000 |
---|---|---|
committer | James Y Knight <jyknight@google.com> | 2015-12-15 19:23:12 +0000 |
commit | 33beb24318f9e5355f1aa481cddcbb50eaf2a156 (patch) | |
tree | 52765053c7f094b0917a768baa33bf6b2bef4355 /llvm/lib | |
parent | 6c3b8374522c1c7d8a34306f90eb4b1204d40506 (diff) | |
download | bcm5719-llvm-33beb24318f9e5355f1aa481cddcbb50eaf2a156.tar.gz bcm5719-llvm-33beb24318f9e5355f1aa481cddcbb50eaf2a156.zip |
[Sparc] Fix handling of double incoming arguments on sparc little-endian.
On SparcV8, doubles get passed in two 32-bit integer registers. The call
code was already handling endianness correctly, but the incoming
argument code was not -- it got the two halves in opposite order.
Also remove some dead code in LowerFormalArguments_32 to handle
less-than-32bit values, which can't actually happen.
Finally, add some test cases for the 32-bit calling convention, cribbed
from the 64abi.ll test, and run for both big and little-endian.
llvm-svn: 255668
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/Sparc/SparcISelLowering.cpp | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp index 799fe00aebc..47c8c3a07b1 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -400,6 +400,7 @@ LowerFormalArguments_32(SDValue Chain, CCInfo.AnalyzeFormalArguments(Ins, CC_Sparc32); const unsigned StackOffset = 92; + bool IsLittleEndian = DAG.getDataLayout().isLittleEndian(); unsigned InIdx = 0; for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i, ++InIdx) { @@ -442,6 +443,10 @@ LowerFormalArguments_32(SDValue Chain, &SP::IntRegsRegClass); LoVal = DAG.getCopyFromReg(Chain, dl, loReg, MVT::i32); } + + if (IsLittleEndian) + std::swap(LoVal, HiVal); + SDValue WholeValue = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, LoVal, HiVal); WholeValue = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), WholeValue); @@ -498,6 +503,9 @@ LowerFormalArguments_32(SDValue Chain, MachinePointerInfo(), false, false, false, 0); + if (IsLittleEndian) + std::swap(LoVal, HiVal); + SDValue WholeValue = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, LoVal, HiVal); WholeValue = DAG.getNode(ISD::BITCAST, dl, VA.getValVT(), WholeValue); @@ -514,16 +522,12 @@ LowerFormalArguments_32(SDValue Chain, Load = DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr, MachinePointerInfo(), false, false, false, 0); + } else if (VA.getValVT() == MVT::f128) { + report_fatal_error("SPARCv8 does not handle f128 in calls; " + "pass indirectly"); } else { - ISD::LoadExtType LoadOp = ISD::SEXTLOAD; - // Sparc is big endian, so add an offset based on the ObjectVT. - unsigned Offset = 4-std::max(1U, VA.getValVT().getSizeInBits()/8); - FIPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, FIPtr, - DAG.getConstant(Offset, dl, MVT::i32)); - Load = DAG.getExtLoad(LoadOp, dl, MVT::i32, Chain, FIPtr, - MachinePointerInfo(), - VA.getValVT(), false, false, false,0); - Load = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), Load); + // We shouldn't see any other value types here. + assert(false && "Unexpected ValVT encountered in frame lowering."); } InVals.push_back(Load); } |