SparcISelDAGToDAG.cpp revision 217aabf89ee0316bb4bbcc460bdc24900fe50a02
1//===-- SparcV8ISelDAGToDAG.cpp - A dag to dag inst selector for SparcV8 --===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by Chris Lattner and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines an instruction selector for the V8 target 11// 12//===----------------------------------------------------------------------===// 13 14#include "SparcV8.h" 15#include "SparcV8TargetMachine.h" 16#include "llvm/Function.h" 17#include "llvm/CodeGen/MachineFunction.h" 18#include "llvm/CodeGen/SelectionDAG.h" 19#include "llvm/CodeGen/SelectionDAGISel.h" 20#include "llvm/CodeGen/SSARegMap.h" 21#include "llvm/Target/TargetLowering.h" 22#include "llvm/Support/Debug.h" 23#include <iostream> 24using namespace llvm; 25 26//===----------------------------------------------------------------------===// 27// TargetLowering Implementation 28//===----------------------------------------------------------------------===// 29 30namespace { 31 class SparcV8TargetLowering : public TargetLowering { 32 public: 33 SparcV8TargetLowering(TargetMachine &TM); 34 35 virtual std::vector<SDOperand> 36 LowerArguments(Function &F, SelectionDAG &DAG); 37 virtual std::pair<SDOperand, SDOperand> 38 LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, 39 unsigned CC, 40 bool isTailCall, SDOperand Callee, ArgListTy &Args, 41 SelectionDAG &DAG); 42 43 virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op, 44 SelectionDAG &DAG); 45 virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, 46 Value *VAListV, SelectionDAG &DAG); 47 virtual std::pair<SDOperand,SDOperand> 48 LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, 49 const Type *ArgTy, SelectionDAG &DAG); 50 virtual std::pair<SDOperand, SDOperand> 51 LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, 52 SelectionDAG &DAG); 53 }; 54} 55 56SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM) 57 : TargetLowering(TM) { 58 59 // Set up the register classes. 60 addRegisterClass(MVT::i32, V8::IntRegsRegisterClass); 61 addRegisterClass(MVT::f32, V8::FPRegsRegisterClass); 62 addRegisterClass(MVT::f64, V8::DFPRegsRegisterClass); 63 64 // Sparc doesn't have sext_inreg, replace them with shl/sra 65 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16 , Expand); 66 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand); 67 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand); 68 69 computeRegisterProperties(); 70} 71 72std::vector<SDOperand> 73SparcV8TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { 74 MachineFunction &MF = DAG.getMachineFunction(); 75 SSARegMap *RegMap = MF.getSSARegMap(); 76 std::vector<SDOperand> ArgValues; 77 78 static const unsigned GPR[] = { 79 V8::I0, V8::I1, V8::I2, V8::I3, V8::I4, V8::I5 80 }; 81 unsigned ArgNo = 0; 82 for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { 83 MVT::ValueType ObjectVT = getValueType(I->getType()); 84 assert(ArgNo < 6 && "Only args in regs for now"); 85 86 switch (ObjectVT) { 87 default: assert(0 && "Unhandled argument type!"); 88 // TODO: MVT::i64 & FP 89 case MVT::i1: 90 case MVT::i8: 91 case MVT::i16: 92 case MVT::i32: { 93 unsigned VReg = RegMap->createVirtualRegister(&V8::IntRegsRegClass); 94 MF.addLiveIn(GPR[ArgNo++], VReg); 95 SDOperand Arg = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32); 96 DAG.setRoot(Arg.getValue(1)); 97 if (ObjectVT != MVT::i32) { 98 unsigned AssertOp = I->getType()->isSigned() ? ISD::AssertSext 99 : ISD::AssertZext; 100 Arg = DAG.getNode(AssertOp, MVT::i32, Arg, 101 DAG.getValueType(ObjectVT)); 102 Arg = DAG.getNode(ISD::TRUNCATE, ObjectVT, Arg); 103 } 104 ArgValues.push_back(Arg); 105 break; 106 } 107 case MVT::i64: { 108 unsigned VRegLo = RegMap->createVirtualRegister(&V8::IntRegsRegClass); 109 MF.addLiveIn(GPR[ArgNo++], VRegLo); 110 unsigned VRegHi = RegMap->createVirtualRegister(&V8::IntRegsRegClass); 111 MF.addLiveIn(GPR[ArgNo++], VRegHi); 112 SDOperand ArgLo = DAG.getCopyFromReg(DAG.getRoot(), VRegLo, MVT::i32); 113 SDOperand ArgHi = DAG.getCopyFromReg(ArgLo.getValue(1), VRegHi, MVT::i32); 114 DAG.setRoot(ArgHi.getValue(1)); 115 ArgValues.push_back(DAG.getNode(ISD::BUILD_PAIR, MVT::i64, ArgLo, ArgHi)); 116 break; 117 } 118 } 119 } 120 121 assert(!F.isVarArg() && "Unimp"); 122 123 // Finally, inform the code generator which regs we return values in. 124 switch (getValueType(F.getReturnType())) { 125 default: assert(0 && "Unknown type!"); 126 case MVT::isVoid: break; 127 case MVT::i1: 128 case MVT::i8: 129 case MVT::i16: 130 case MVT::i32: 131 MF.addLiveOut(V8::I0); 132 break; 133 case MVT::i64: 134 MF.addLiveOut(V8::I0); 135 MF.addLiveOut(V8::I1); 136 break; 137 case MVT::f32: 138 MF.addLiveOut(V8::F0); 139 break; 140 case MVT::f64: 141 MF.addLiveOut(V8::D0); 142 break; 143 } 144 145 return ArgValues; 146} 147 148std::pair<SDOperand, SDOperand> 149SparcV8TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, 150 bool isVarArg, unsigned CC, 151 bool isTailCall, SDOperand Callee, 152 ArgListTy &Args, SelectionDAG &DAG) { 153 assert(0 && "Unimp"); 154 abort(); 155} 156 157SDOperand SparcV8TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op, 158 SelectionDAG &DAG) { 159 if (Op.getValueType() == MVT::i64) { 160 SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, 161 DAG.getConstant(1, MVT::i32)); 162 SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, 163 DAG.getConstant(0, MVT::i32)); 164 return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Hi); 165 } else { 166 return DAG.getNode(ISD::RET, MVT::Other, Chain, Op); 167 } 168} 169 170SDOperand SparcV8TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, 171 Value *VAListV, SelectionDAG &DAG) { 172 assert(0 && "Unimp"); 173 abort(); 174} 175 176std::pair<SDOperand,SDOperand> 177SparcV8TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, 178 const Type *ArgTy, SelectionDAG &DAG) { 179 assert(0 && "Unimp"); 180 abort(); 181} 182 183std::pair<SDOperand, SDOperand> 184SparcV8TargetLowering::LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, 185 SelectionDAG &DAG) { 186 assert(0 && "Unimp"); 187 abort(); 188} 189 190//===----------------------------------------------------------------------===// 191// Instruction Selector Implementation 192//===----------------------------------------------------------------------===// 193 194//===--------------------------------------------------------------------===// 195/// SparcV8DAGToDAGISel - PPC specific code to select Sparc V8 machine 196/// instructions for SelectionDAG operations. 197/// 198namespace { 199class SparcV8DAGToDAGISel : public SelectionDAGISel { 200 SparcV8TargetLowering V8Lowering; 201public: 202 SparcV8DAGToDAGISel(TargetMachine &TM) 203 : SelectionDAGISel(V8Lowering), V8Lowering(TM) {} 204 205 SDOperand Select(SDOperand Op); 206 207 // Complex Pattern Selectors. 208 bool SelectADDRrr(SDOperand N, SDOperand &R1, SDOperand &R2); 209 bool SelectADDRri(SDOperand N, SDOperand &Base, SDOperand &Offset); 210 211 /// InstructionSelectBasicBlock - This callback is invoked by 212 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 213 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); 214 215 virtual const char *getPassName() const { 216 return "PowerPC DAG->DAG Pattern Instruction Selection"; 217 } 218 219 // Include the pieces autogenerated from the target description. 220#include "SparcV8GenDAGISel.inc" 221}; 222} // end anonymous namespace 223 224/// InstructionSelectBasicBlock - This callback is invoked by 225/// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 226void SparcV8DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { 227 DEBUG(BB->dump()); 228 229 // Select target instructions for the DAG. 230 DAG.setRoot(Select(DAG.getRoot())); 231 CodeGenMap.clear(); 232 DAG.RemoveDeadNodes(); 233 234 // Emit machine code to BB. 235 ScheduleAndEmitDAG(DAG); 236} 237 238bool SparcV8DAGToDAGISel::SelectADDRrr(SDOperand N, SDOperand &R1, 239 SDOperand &R2) { 240 // FIXME: This should obviously be smarter. 241 R1 = Select(N); 242 R2 = CurDAG->getRegister(V8::G0, MVT::i32); 243 return true; 244} 245 246bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand N, SDOperand &Base, 247 SDOperand &Offset) { 248 // FIXME: This should obviously be smarter. 249 Base = Select(N); 250 Offset = CurDAG->getTargetConstant(0, MVT::i32); 251 return true; 252} 253 254 255SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) { 256 SDNode *N = Op.Val; 257 if (N->getOpcode() >= ISD::BUILTIN_OP_END/* && 258 N->getOpcode() < V8ISD::FIRST_NUMBER*/) 259 return Op; // Already selected. 260 // If this has already been converted, use it. 261 std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op); 262 if (CGMI != CodeGenMap.end()) return CGMI->second; 263 264 switch (N->getOpcode()) { 265 default: break; 266 case ISD::RET: { 267 if (N->getNumOperands() == 2) { 268 SDOperand Chain = Select(N->getOperand(0)); // Token chain. 269 SDOperand Val = Select(N->getOperand(1)); 270 if (N->getOperand(1).getValueType() == MVT::i32) { 271 Chain = CurDAG->getCopyToReg(Chain, V8::I0, Val); 272 } else if (N->getOperand(1).getValueType() == MVT::f32) { 273 Chain = CurDAG->getCopyToReg(Chain, V8::F0, Val); 274 } else { 275 assert(N->getOperand(1).getValueType() == MVT::f64); 276 Chain = CurDAG->getCopyToReg(Chain, V8::D0, Val); 277 } 278 return CurDAG->SelectNodeTo(N, V8::RETL, MVT::Other, Chain); 279 } else if (N->getNumOperands() > 1) { 280 SDOperand Chain = Select(N->getOperand(0)); // Token chain. 281 assert(N->getOperand(1).getValueType() == MVT::i32 && 282 N->getOperand(2).getValueType() == MVT::i32 && 283 N->getNumOperands() == 3 && "Unknown two-register ret value!"); 284 Chain = CurDAG->getCopyToReg(Chain, V8::I0, Select(N->getOperand(1))); 285 Chain = CurDAG->getCopyToReg(Chain, V8::I1, Select(N->getOperand(2))); 286 return CurDAG->SelectNodeTo(N, V8::RETL, MVT::Other, Chain); 287 } 288 break; // Generated code handles the void case. 289 } 290 } 291 292 return SelectCode(Op); 293} 294 295 296/// createPPCISelDag - This pass converts a legalized DAG into a 297/// PowerPC-specific DAG, ready for instruction scheduling. 298/// 299FunctionPass *llvm::createSparcV8ISelDag(TargetMachine &TM) { 300 return new SparcV8DAGToDAGISel(TM); 301} 302