diff options
author | Chris Lattner <sabre@nondot.org> | 2005-12-18 06:59:57 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-12-18 06:59:57 +0000 |
commit | 8fa54dc70239dc08cc3c93cb7513e0625be50eb4 (patch) | |
tree | 25d59c96342934171a2da33fe9059345657e137e /lib/Target/Sparc | |
parent | abfc2a73637a73ac6a9d2404ba1936c0fb6e64de (diff) |
Add frameindex support
Add support for copying (e.g. returning) doubles
Add support for F<->I instructions
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24818 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Sparc')
-rw-r--r-- | lib/Target/Sparc/SparcISelDAGToDAG.cpp | 104 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcInstrInfo.td | 18 |
2 files changed, 96 insertions, 26 deletions
diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp index 860c76fdb1..751a8e2b1a 100644 --- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -14,6 +14,7 @@ #include "SparcV8.h" #include "SparcV8TargetMachine.h" #include "llvm/Function.h" +#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/SelectionDAGISel.h" @@ -36,6 +37,9 @@ namespace V8ISD { BRFCC, // Branch to dest on fcc condition Hi, Lo, // Hi/Lo operations, typically on a global address. + + FTOI, // FP to Int within a FP register. + ITOF, // Int to FP within a FP register. }; } @@ -85,6 +89,14 @@ SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM) // Sparc has no REM operation. setOperationAction(ISD::UREM, MVT::i32, Expand); setOperationAction(ISD::SREM, MVT::i32, Expand); + + // Custom expand fp<->sint + setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); + setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom); + + // Expand fp<->uint + setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand); + setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand); // Sparc has no select or setcc: expand to SELECT_CC. setOperationAction(ISD::SELECT, MVT::i32, Expand); @@ -259,6 +271,31 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) { SDOperand Lo = DAG.getNode(V8ISD::Lo, MVT::i32, CP); return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi); } + case ISD::FP_TO_SINT: { + // Convert the fp value to integer in an FP register. + Op = DAG.getNode(V8ISD::FTOI, Op.getOperand(0).getValueType(), + Op.getOperand(0)); + int Size = Op.getOperand(0).getValueType() == MVT::f32 ? 4 : 8; + int FrameIdx = + DAG.getMachineFunction().getFrameInfo()->CreateStackObject(Size, Size); + SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32); + SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(), + Op, FI, DAG.getSrcValue(0)); + return DAG.getLoad(MVT::i32, ST, FI, DAG.getSrcValue(0)); + } + case ISD::SINT_TO_FP: { + int Size = Op.getOperand(0).getValueType() == MVT::f32 ? 4 : 8; + int FrameIdx = + DAG.getMachineFunction().getFrameInfo()->CreateStackObject(Size, Size); + SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32); + SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(), + Op.getOperand(0), FI, DAG.getSrcValue(0)); + + Op = DAG.getLoad(Op.getValueType(), ST, FI, DAG.getSrcValue(0)); + + // Convert the int value to FP in an FP register. + return DAG.getNode(V8ISD::ITOF, Op.getValueType(), Op); + } } } @@ -311,34 +348,29 @@ void SparcV8DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { ScheduleAndEmitDAG(DAG); } -bool SparcV8DAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1, - SDOperand &R2) { - if (Addr.getOpcode() == ISD::ADD) { - if (isa<ConstantSDNode>(Addr.getOperand(1)) && - Predicate_simm13(Addr.getOperand(1).Val)) - return false; // Let the reg+imm pattern catch this! - if (Addr.getOperand(0).getOpcode() == V8ISD::Lo || - Addr.getOperand(1).getOpcode() == V8ISD::Lo) - return false; // Let the reg+imm pattern catch this! - R1 = Select(Addr.getOperand(0)); - R2 = Select(Addr.getOperand(1)); - return true; - } - - R1 = Select(Addr); - R2 = CurDAG->getRegister(V8::G0, MVT::i32); - return true; -} - bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base, SDOperand &Offset) { + if (Addr.getOpcode() == ISD::FrameIndex) { + int FI = cast<FrameIndexSDNode>(Addr)->getIndex(); + Base = CurDAG->getTargetFrameIndex(FI, MVT::i32); + Offset = CurDAG->getTargetConstant(0, MVT::i32); + return true; + } + if (Addr.getOpcode() == ISD::ADD) { - if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) + if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) { if (Predicate_simm13(CN)) { - Base = Select(Addr.getOperand(0)); + if (Addr.getOperand(0).getOpcode() == ISD::FrameIndex) { + // Constant offset from frame ref. + int FI = cast<FrameIndexSDNode>(Addr)->getIndex(); + Base = CurDAG->getTargetFrameIndex(FI, MVT::i32); + } else { + Base = Select(Addr.getOperand(0)); + } Offset = CurDAG->getTargetConstant(CN->getValue(), MVT::i32); return true; } + } if (Addr.getOperand(0).getOpcode() == V8ISD::Lo) { Base = Select(Addr.getOperand(1)); Offset = Addr.getOperand(0).getOperand(0); @@ -355,6 +387,25 @@ bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base, return true; } +bool SparcV8DAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1, + SDOperand &R2) { + if (Addr.getOpcode() == ISD::FrameIndex) return false; + if (Addr.getOpcode() == ISD::ADD) { + if (isa<ConstantSDNode>(Addr.getOperand(1)) && + Predicate_simm13(Addr.getOperand(1).Val)) + return false; // Let the reg+imm pattern catch this! + if (Addr.getOperand(0).getOpcode() == V8ISD::Lo || + Addr.getOperand(1).getOpcode() == V8ISD::Lo) + return false; // Let the reg+imm pattern catch this! + R1 = Select(Addr.getOperand(0)); + R2 = Select(Addr.getOperand(1)); + return true; + } + + R1 = Select(Addr); + R2 = CurDAG->getRegister(V8::G0, MVT::i32); + return true; +} SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) { SDNode *N = Op.Val; @@ -368,6 +419,17 @@ SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) { switch (N->getOpcode()) { default: break; case ISD::BasicBlock: return CodeGenMap[Op] = Op; + case ISD::FrameIndex: { + int FI = cast<FrameIndexSDNode>(N)->getIndex(); + if (N->hasOneUse()) + return CurDAG->SelectNodeTo(N, V8::ADDri, MVT::i32, + CurDAG->getTargetFrameIndex(FI, MVT::i32), + CurDAG->getTargetConstant(0, MVT::i32)); + return CodeGenMap[Op] = + CurDAG->getTargetNode(V8::ADDri, MVT::i32, + CurDAG->getTargetFrameIndex(FI, MVT::i32), + CurDAG->getTargetConstant(0, MVT::i32)); + } case V8ISD::CMPICC: { // FIXME: Handle compare with immediate. SDOperand LHS = Select(N->getOperand(0)); diff --git a/lib/Target/Sparc/SparcInstrInfo.td b/lib/Target/Sparc/SparcInstrInfo.td index 22ed2417df..fabd23555c 100644 --- a/lib/Target/Sparc/SparcInstrInfo.td +++ b/lib/Target/Sparc/SparcInstrInfo.td @@ -87,6 +87,9 @@ def V8brfcc : SDNode<"V8ISD::BRFCC", SDTV8brcc, [SDNPHasChain]>; def V8hi : SDNode<"V8ISD::Hi", SDTIntUnaryOp>; def V8lo : SDNode<"V8ISD::Lo", SDTIntUnaryOp>; +def V8ftoi : SDNode<"V8ISD::FTOI", SDTFPUnaryOp>; +def V8itof : SDNode<"V8ISD::ITOF", SDTFPUnaryOp>; + //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -104,7 +107,8 @@ def ADJCALLSTACKUP : PseudoInstV8<"!ADJCALLSTACKUP $amt", //def IMPLICIT_USE : PseudoInstV8<"!IMPLICIT_USE",(ops variable_ops)>; def IMPLICIT_DEF : PseudoInstV8<"!IMPLICIT_DEF $dst", (ops IntRegs:$dst)>; -def FpMOVD : PseudoInstV8<"!FpMOVD", (ops)>; // pseudo 64-bit double move +def FpMOVD : PseudoInstV8<"!FpMOVD", // pseudo 64-bit double move + (ops DFPRegs:$dst, DFPRegs:$src)>; // Section A.3 - Synthetic Instructions, p. 85 // special cases of JMPL: @@ -544,18 +548,22 @@ def WRYri : F3_2<2, 0b110000, // Convert Integer to Floating-point Instructions, p. 141 def FITOS : F3_3<2, 0b110100, 0b011000100, (ops FPRegs:$dst, FPRegs:$src), - "fitos $src, $dst", []>; + "fitos $src, $dst", + [(set FPRegs:$dst, (V8itof FPRegs:$src))]>; def FITOD : F3_3<2, 0b110100, 0b011001000, (ops DFPRegs:$dst, DFPRegs:$src), - "fitod $src, $dst", []>; + "fitod $src, $dst", + [(set DFPRegs:$dst, (V8itof DFPRegs:$src))]>; // Convert Floating-point to Integer Instructions, p. 142 def FSTOI : F3_3<2, 0b110100, 0b011010001, (ops FPRegs:$dst, FPRegs:$src), - "fstoi $src, $dst", []>; + "fstoi $src, $dst", + [(set FPRegs:$dst, (V8ftoi FPRegs:$src))]>; def FDTOI : F3_3<2, 0b110100, 0b011010010, (ops DFPRegs:$dst, DFPRegs:$src), - "fdtoi $src, $dst", []>; + "fdtoi $src, $dst", + [(set DFPRegs:$dst, (V8ftoi DFPRegs:$src))]>; // Convert between Floating-point Formats Instructions, p. 143 def FSTOD : F3_3<2, 0b110100, 0b011001001, |