From 4492b1b7a0d3eedf01a4a620260f0266dc391819 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 18 Dec 2005 06:59:57 +0000 Subject: [PATCH] Add frameindex support Add support for copying (e.g. returning) doubles Add support for F<->I instructions llvm-svn: 24818 --- .../Target/SparcV8/SparcV8ISelDAGToDAG.cpp | 114 ++++++++++++++---- llvm/lib/Target/SparcV8/SparcV8InstrInfo.td | 18 ++- 2 files changed, 101 insertions(+), 31 deletions(-) diff --git a/llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp b/llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp index 860c76fdb14b..751a8e2b1aca 100644 --- a/llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp +++ b/llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.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,8 +348,48 @@ void SparcV8DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { ScheduleAndEmitDAG(DAG); } +bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base, + SDOperand &Offset) { + if (Addr.getOpcode() == ISD::FrameIndex) { + int FI = cast(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(Addr.getOperand(1))) { + if (Predicate_simm13(CN)) { + if (Addr.getOperand(0).getOpcode() == ISD::FrameIndex) { + // Constant offset from frame ref. + int FI = cast(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); + return true; + } + if (Addr.getOperand(1).getOpcode() == V8ISD::Lo) { + Base = Select(Addr.getOperand(0)); + Offset = Addr.getOperand(1).getOperand(0); + return true; + } + } + Base = Select(Addr); + Offset = CurDAG->getTargetConstant(0, MVT::i32); + 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(Addr.getOperand(1)) && Predicate_simm13(Addr.getOperand(1).Val)) @@ -330,32 +407,6 @@ bool SparcV8DAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1, return true; } -bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base, - SDOperand &Offset) { - if (Addr.getOpcode() == ISD::ADD) { - if (ConstantSDNode *CN = dyn_cast(Addr.getOperand(1))) - if (Predicate_simm13(CN)) { - 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); - return true; - } - if (Addr.getOperand(1).getOpcode() == V8ISD::Lo) { - Base = Select(Addr.getOperand(0)); - Offset = Addr.getOperand(1).getOperand(0); - return true; - } - } - Base = Select(Addr); - Offset = CurDAG->getTargetConstant(0, MVT::i32); - return true; -} - - SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) { SDNode *N = Op.Val; if (N->getOpcode() >= ISD::BUILTIN_OP_END && @@ -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(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/llvm/lib/Target/SparcV8/SparcV8InstrInfo.td b/llvm/lib/Target/SparcV8/SparcV8InstrInfo.td index 22ed2417df59..fabd23555c74 100644 --- a/llvm/lib/Target/SparcV8/SparcV8InstrInfo.td +++ b/llvm/lib/Target/SparcV8/SparcV8InstrInfo.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,