summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorJames Y Knight <jyknight@google.com>2015-12-15 19:23:12 +0000
committerJames Y Knight <jyknight@google.com>2015-12-15 19:23:12 +0000
commit33beb24318f9e5355f1aa481cddcbb50eaf2a156 (patch)
tree52765053c7f094b0917a768baa33bf6b2bef4355 /llvm/lib
parent6c3b8374522c1c7d8a34306f90eb4b1204d40506 (diff)
downloadbcm5719-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.cpp22
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);
}
OpenPOWER on IntegriCloud