aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/Sparc
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-12-17 22:55:57 +0000
committerChris Lattner <sabre@nondot.org>2005-12-17 22:55:57 +0000
commitd19fc65345c773af2e82a6e5227e4b020aab7d4c (patch)
tree1892e63610eeb99df4ace20dfda0bf98375f7e74 /lib/Target/Sparc
parent7087e57872f68978945be227aafd17d6d43ae03e (diff)
Implement 64-bit add/sub, make sure to receive and return 64-bit args with
the right halves in the right regs git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24799 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Sparc')
-rw-r--r--lib/Target/Sparc/SparcISelDAGToDAG.cpp36
1 files changed, 32 insertions, 4 deletions
diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp
index 4779c3c536..770ea8ddc4 100644
--- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp
+++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp
@@ -109,10 +109,10 @@ SparcV8TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
break;
}
case MVT::i64: {
- unsigned VRegLo = RegMap->createVirtualRegister(&V8::IntRegsRegClass);
- MF.addLiveIn(GPR[ArgNo++], VRegLo);
unsigned VRegHi = RegMap->createVirtualRegister(&V8::IntRegsRegClass);
MF.addLiveIn(GPR[ArgNo++], VRegHi);
+ unsigned VRegLo = RegMap->createVirtualRegister(&V8::IntRegsRegClass);
+ MF.addLiveIn(GPR[ArgNo++], VRegLo);
SDOperand ArgLo = DAG.getCopyFromReg(DAG.getRoot(), VRegLo, MVT::i32);
SDOperand ArgHi = DAG.getCopyFromReg(ArgLo.getValue(1), VRegHi, MVT::i32);
DAG.setRoot(ArgHi.getValue(1));
@@ -282,6 +282,34 @@ SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
switch (N->getOpcode()) {
default: break;
+ case ISD::ADD_PARTS: {
+ SDOperand LHSL = Select(N->getOperand(0));
+ SDOperand LHSH = Select(N->getOperand(1));
+ SDOperand RHSL = Select(N->getOperand(2));
+ SDOperand RHSH = Select(N->getOperand(3));
+ // FIXME, handle immediate RHS.
+ SDOperand Low = CurDAG->getTargetNode(V8::ADDCCrr, MVT::i32, MVT::Flag,
+ LHSL, RHSL);
+ SDOperand Hi = CurDAG->getTargetNode(V8::ADDXrr, MVT::i32, LHSH, RHSH,
+ Low.getValue(1));
+ CodeGenMap[SDOperand(N, 0)] = Low;
+ CodeGenMap[SDOperand(N, 1)] = Hi;
+ return Op.ResNo ? Hi : Low;
+ }
+ case ISD::SUB_PARTS: {
+ SDOperand LHSL = Select(N->getOperand(0));
+ SDOperand LHSH = Select(N->getOperand(1));
+ SDOperand RHSL = Select(N->getOperand(2));
+ SDOperand RHSH = Select(N->getOperand(3));
+ // FIXME, handle immediate RHS.
+ SDOperand Low = CurDAG->getTargetNode(V8::SUBCCrr, MVT::i32, MVT::Flag,
+ LHSL, RHSL);
+ SDOperand Hi = CurDAG->getTargetNode(V8::SUBXrr, MVT::i32, LHSH, RHSH,
+ Low.getValue(1));
+ CodeGenMap[SDOperand(N, 0)] = Low;
+ CodeGenMap[SDOperand(N, 1)] = Hi;
+ return Op.ResNo ? Hi : Low;
+ }
case ISD::SDIV:
case ISD::UDIV: {
// FIXME: should use a custom expander to expose the SRA to the dag.
@@ -333,8 +361,8 @@ SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
assert(N->getOperand(1).getValueType() == MVT::i32 &&
N->getOperand(2).getValueType() == MVT::i32 &&
N->getNumOperands() == 3 && "Unknown two-register ret value!");
- Chain = CurDAG->getCopyToReg(Chain, V8::I0, Select(N->getOperand(1)));
- Chain = CurDAG->getCopyToReg(Chain, V8::I1, Select(N->getOperand(2)));
+ Chain = CurDAG->getCopyToReg(Chain, V8::I1, Select(N->getOperand(1)));
+ Chain = CurDAG->getCopyToReg(Chain, V8::I0, Select(N->getOperand(2)));
return CurDAG->SelectNodeTo(N, V8::RETL, MVT::Other, Chain);
}
break; // Generated code handles the void case.