LLVM API Documentation
00001 //===-- XCoreISelDAGToDAG.cpp - A dag to dag inst selector for XCore ------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines an instruction selector for the XCore target. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "XCore.h" 00015 #include "XCoreISelLowering.h" 00016 #include "XCoreTargetMachine.h" 00017 #include "llvm/DerivedTypes.h" 00018 #include "llvm/Function.h" 00019 #include "llvm/Intrinsics.h" 00020 #include "llvm/CallingConv.h" 00021 #include "llvm/Constants.h" 00022 #include "llvm/CodeGen/MachineFrameInfo.h" 00023 #include "llvm/CodeGen/MachineFunction.h" 00024 #include "llvm/CodeGen/MachineInstrBuilder.h" 00025 #include "llvm/CodeGen/MachineRegisterInfo.h" 00026 #include "llvm/CodeGen/SelectionDAG.h" 00027 #include "llvm/CodeGen/SelectionDAGISel.h" 00028 #include "llvm/Target/TargetLowering.h" 00029 #include "llvm/Support/Compiler.h" 00030 #include "llvm/Support/Debug.h" 00031 #include <queue> 00032 #include <set> 00033 using namespace llvm; 00034 00035 /// XCoreDAGToDAGISel - XCore specific code to select XCore machine 00036 /// instructions for SelectionDAG operations. 00037 /// 00038 namespace { 00039 class XCoreDAGToDAGISel : public SelectionDAGISel { 00040 XCoreTargetLowering &Lowering; 00041 const XCoreSubtarget &Subtarget; 00042 00043 public: 00044 XCoreDAGToDAGISel(XCoreTargetMachine &TM) 00045 : SelectionDAGISel(TM), 00046 Lowering(*TM.getTargetLowering()), 00047 Subtarget(*TM.getSubtargetImpl()) { } 00048 00049 SDNode *Select(SDValue Op); 00050 00051 /// getI32Imm - Return a target constant with the specified value, of type 00052 /// i32. 00053 inline SDValue getI32Imm(unsigned Imm) { 00054 return CurDAG->getTargetConstant(Imm, MVT::i32); 00055 } 00056 00057 // Complex Pattern Selectors. 00058 bool SelectADDRspii(SDValue Op, SDValue Addr, SDValue &Base, 00059 SDValue &Offset); 00060 bool SelectADDRdpii(SDValue Op, SDValue Addr, SDValue &Base, 00061 SDValue &Offset); 00062 bool SelectADDRcpii(SDValue Op, SDValue Addr, SDValue &Base, 00063 SDValue &Offset); 00064 00065 virtual void InstructionSelect(); 00066 00067 virtual const char *getPassName() const { 00068 return "XCore DAG->DAG Pattern Instruction Selection"; 00069 } 00070 00071 // Include the pieces autogenerated from the target description. 00072 #include "XCoreGenDAGISel.inc" 00073 }; 00074 } // end anonymous namespace 00075 00076 /// createXCoreISelDag - This pass converts a legalized DAG into a 00077 /// XCore-specific DAG, ready for instruction scheduling. 00078 /// 00079 FunctionPass *llvm::createXCoreISelDag(XCoreTargetMachine &TM) { 00080 return new XCoreDAGToDAGISel(TM); 00081 } 00082 00083 bool XCoreDAGToDAGISel::SelectADDRspii(SDValue Op, SDValue Addr, 00084 SDValue &Base, SDValue &Offset) { 00085 FrameIndexSDNode *FIN = 0; 00086 if ((FIN = dyn_cast<FrameIndexSDNode>(Addr))) { 00087 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 00088 Offset = CurDAG->getTargetConstant(0, MVT::i32); 00089 return true; 00090 } 00091 if (Addr.getOpcode() == ISD::ADD) { 00092 ConstantSDNode *CN = 0; 00093 if ((FIN = dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) 00094 && (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) 00095 && (CN->getSExtValue() % 4 == 0 && CN->getSExtValue() >= 0)) { 00096 // Constant positive word offset from frame index 00097 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 00098 Offset = CurDAG->getTargetConstant(CN->getSExtValue(), MVT::i32); 00099 return true; 00100 } 00101 } 00102 return false; 00103 } 00104 00105 bool XCoreDAGToDAGISel::SelectADDRdpii(SDValue Op, SDValue Addr, 00106 SDValue &Base, SDValue &Offset) { 00107 if (Addr.getOpcode() == XCoreISD::DPRelativeWrapper) { 00108 Base = Addr.getOperand(0); 00109 Offset = CurDAG->getTargetConstant(0, MVT::i32); 00110 return true; 00111 } 00112 if (Addr.getOpcode() == ISD::ADD) { 00113 ConstantSDNode *CN = 0; 00114 if ((Addr.getOperand(0).getOpcode() == XCoreISD::DPRelativeWrapper) 00115 && (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) 00116 && (CN->getSExtValue() % 4 == 0)) { 00117 // Constant word offset from a object in the data region 00118 Base = Addr.getOperand(0).getOperand(0); 00119 Offset = CurDAG->getTargetConstant(CN->getSExtValue(), MVT::i32); 00120 return true; 00121 } 00122 } 00123 return false; 00124 } 00125 00126 bool XCoreDAGToDAGISel::SelectADDRcpii(SDValue Op, SDValue Addr, 00127 SDValue &Base, SDValue &Offset) { 00128 if (Addr.getOpcode() == XCoreISD::CPRelativeWrapper) { 00129 Base = Addr.getOperand(0); 00130 Offset = CurDAG->getTargetConstant(0, MVT::i32); 00131 return true; 00132 } 00133 if (Addr.getOpcode() == ISD::ADD) { 00134 ConstantSDNode *CN = 0; 00135 if ((Addr.getOperand(0).getOpcode() == XCoreISD::CPRelativeWrapper) 00136 && (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) 00137 && (CN->getSExtValue() % 4 == 0)) { 00138 // Constant word offset from a object in the data region 00139 Base = Addr.getOperand(0).getOperand(0); 00140 Offset = CurDAG->getTargetConstant(CN->getSExtValue(), MVT::i32); 00141 return true; 00142 } 00143 } 00144 return false; 00145 } 00146 00147 /// InstructionSelect - This callback is invoked by 00148 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 00149 void XCoreDAGToDAGISel:: 00150 InstructionSelect() { 00151 DEBUG(BB->dump()); 00152 00153 // Select target instructions for the DAG. 00154 SelectRoot(*CurDAG); 00155 00156 CurDAG->RemoveDeadNodes(); 00157 } 00158 00159 SDNode *XCoreDAGToDAGISel::Select(SDValue Op) { 00160 SDNode *N = Op.getNode(); 00161 MVT NVT = N->getValueType(0); 00162 if (NVT == MVT::i32) { 00163 switch (N->getOpcode()) { 00164 default: break; 00165 case ISD::Constant: { 00166 if (Predicate_immMskBitp(N)) { 00167 SDValue MskSize = Transform_msksize_xform(N); 00168 return CurDAG->getTargetNode(XCore::MKMSK_rus, MVT::i32, MskSize); 00169 } 00170 else if (! Predicate_immU16(N)) { 00171 unsigned Val = cast<ConstantSDNode>(N)->getZExtValue(); 00172 SDValue CPIdx = 00173 CurDAG->getTargetConstantPool(ConstantInt::get(Type::Int32Ty, Val), 00174 TLI.getPointerTy()); 00175 return CurDAG->getTargetNode(XCore::LDWCP_lru6, MVT::i32, MVT::Other, 00176 CPIdx, CurDAG->getEntryNode()); 00177 } 00178 break; 00179 } 00180 case ISD::SMUL_LOHI: { 00181 // FIXME fold addition into the macc instruction 00182 if (!Subtarget.isXS1A()) { 00183 SDValue Zero(CurDAG->getTargetNode(XCore::LDC_ru6, MVT::i32, 00184 CurDAG->getTargetConstant(0, MVT::i32)), 0); 00185 SDValue Ops[] = { Zero, Zero, Op.getOperand(0), Op.getOperand(1) }; 00186 SDNode *ResNode = CurDAG->getTargetNode(XCore::MACCS_l4r, MVT::i32, 00187 MVT::i32, Ops, 4); 00188 ReplaceUses(SDValue(N, 0), SDValue(ResNode, 1)); 00189 ReplaceUses(SDValue(N, 1), SDValue(ResNode, 0)); 00190 return NULL; 00191 } 00192 break; 00193 } 00194 case ISD::UMUL_LOHI: { 00195 // FIXME fold addition into the macc / lmul instruction 00196 SDValue Zero(CurDAG->getTargetNode(XCore::LDC_ru6, MVT::i32, 00197 CurDAG->getTargetConstant(0, MVT::i32)), 0); 00198 SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), 00199 Zero, Zero }; 00200 SDNode *ResNode = CurDAG->getTargetNode(XCore::LMUL_l6r, MVT::i32, 00201 MVT::i32, Ops, 4); 00202 ReplaceUses(SDValue(N, 0), SDValue(ResNode, 1)); 00203 ReplaceUses(SDValue(N, 1), SDValue(ResNode, 0)); 00204 return NULL; 00205 } 00206 case XCoreISD::LADD: { 00207 if (!Subtarget.isXS1A()) { 00208 SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), 00209 Op.getOperand(2) }; 00210 return CurDAG->getTargetNode(XCore::LADD_l5r, MVT::i32, MVT::i32, 00211 Ops, 3); 00212 } 00213 break; 00214 } 00215 case XCoreISD::LSUB: { 00216 if (!Subtarget.isXS1A()) { 00217 SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), 00218 Op.getOperand(2) }; 00219 return CurDAG->getTargetNode(XCore::LSUB_l5r, MVT::i32, MVT::i32, 00220 Ops, 3); 00221 } 00222 break; 00223 } 00224 // Other cases are autogenerated. 00225 } 00226 } 00227 return SelectCode(Op); 00228 }