aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-02-23 20:06:57 +0000
committerChris Lattner <sabre@nondot.org>2006-02-23 20:06:57 +0000
commit9f6637db10642fae51fa3628b7833c6999f7fdb3 (patch)
tree13fb672271f9effb6b43f3e2c73fa321d395ffd1
parente3f01570c172570fb2c0bacc6b8860ee6809362d (diff)
downloadexternal_llvm-9f6637db10642fae51fa3628b7833c6999f7fdb3.zip
external_llvm-9f6637db10642fae51fa3628b7833c6999f7fdb3.tar.gz
external_llvm-9f6637db10642fae51fa3628b7833c6999f7fdb3.tar.bz2
Fix an endianness problem on big-endian targets with expanded operands
to inline asms. Mark some methods const. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26334 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp25
1 files changed, 16 insertions, 9 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 4468b56..2028332 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -112,19 +112,19 @@ namespace {
/// this value and returns the result as a ValueVT value. This uses
/// Chain/Flag as the input and updates them for the output Chain/Flag.
SDOperand getCopyFromRegs(SelectionDAG &DAG,
- SDOperand &Chain, SDOperand &Flag);
+ SDOperand &Chain, SDOperand &Flag) const;
/// getCopyToRegs - Emit a series of CopyToReg nodes that copies the
/// specified value into the registers specified by this object. This uses
/// Chain/Flag as the input and updates them for the output Chain/Flag.
void getCopyToRegs(SDOperand Val, SelectionDAG &DAG,
- SDOperand &Chain, SDOperand &Flag);
+ SDOperand &Chain, SDOperand &Flag) const;
/// AddInlineAsmOperands - Add this value to the specified inlineasm node
/// operand list. This adds the code marker and includes the number of
/// values added into it.
void AddInlineAsmOperands(unsigned Code, SelectionDAG &DAG,
- std::vector<SDOperand> &Ops);
+ std::vector<SDOperand> &Ops) const;
};
}
@@ -1181,7 +1181,7 @@ void SelectionDAGLowering::visitCall(CallInst &I) {
}
SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
- SDOperand &Chain, SDOperand &Flag) {
+ SDOperand &Chain, SDOperand &Flag)const{
SDOperand Val = DAG.getCopyFromReg(Chain, Regs[0], RegVT, Flag);
Chain = Val.getValue(1);
Flag = Val.getValue(2);
@@ -1193,7 +1193,10 @@ SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
SDOperand Hi = DAG.getCopyFromReg(Chain, Regs[1], RegVT, Flag);
Chain = Val.getValue(1);
Flag = Val.getValue(2);
- return DAG.getNode(ISD::BUILD_PAIR, ValueVT, Val, Hi);
+ if (DAG.getTargetLoweringInfo().isLittleEndian())
+ return DAG.getNode(ISD::BUILD_PAIR, ValueVT, Val, Hi);
+ else
+ return DAG.getNode(ISD::BUILD_PAIR, ValueVT, Hi, Val);
}
// Otherwise, if the return value was promoted, truncate it to the
@@ -1211,7 +1214,7 @@ SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
/// specified value into the registers specified by this object. This uses
/// Chain/Flag as the input and updates them for the output Chain/Flag.
void RegsForValue::getCopyToRegs(SDOperand Val, SelectionDAG &DAG,
- SDOperand &Chain, SDOperand &Flag) {
+ SDOperand &Chain, SDOperand &Flag) const {
if (Regs.size() == 1) {
// If there is a single register and the types differ, this must be
// a promotion.
@@ -1224,10 +1227,14 @@ void RegsForValue::getCopyToRegs(SDOperand Val, SelectionDAG &DAG,
Chain = DAG.getCopyToReg(Chain, Regs[0], Val, Flag);
Flag = Chain.getValue(1);
} else {
- for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+ std::vector<unsigned> R(Regs);
+ if (!DAG.getTargetLoweringInfo().isLittleEndian())
+ std::reverse(R.begin(), R.end());
+
+ for (unsigned i = 0, e = R.size(); i != e; ++i) {
SDOperand Part = DAG.getNode(ISD::EXTRACT_ELEMENT, RegVT, Val,
DAG.getConstant(i, MVT::i32));
- Chain = DAG.getCopyToReg(Chain, Regs[i], Part, Flag);
+ Chain = DAG.getCopyToReg(Chain, R[i], Part, Flag);
Flag = Chain.getValue(1);
}
}
@@ -1237,7 +1244,7 @@ void RegsForValue::getCopyToRegs(SDOperand Val, SelectionDAG &DAG,
/// operand list. This adds the code marker and includes the number of
/// values added into it.
void RegsForValue::AddInlineAsmOperands(unsigned Code, SelectionDAG &DAG,
- std::vector<SDOperand> &Ops) {
+ std::vector<SDOperand> &Ops) const {
Ops.push_back(DAG.getConstant(Code | (Regs.size() << 3), MVT::i32));
for (unsigned i = 0, e = Regs.size(); i != e; ++i)
Ops.push_back(DAG.getRegister(Regs[i], RegVT));