SparcISelDAGToDAG.cpp revision 4b4863188fe226c00d961ec611f2eb1ee8aac4c0
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 computeRegisterProperties(); 65} 66 67std::vector<SDOperand> 68SparcV8TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { 69 MachineFunction &MF = DAG.getMachineFunction(); 70 SSARegMap *RegMap = MF.getSSARegMap(); 71 std::vector<SDOperand> ArgValues; 72 73 static const unsigned GPR[] = { 74 V8::I0, V8::I1, V8::I2, V8::I3, V8::I4, V8::I5 75 }; 76 unsigned ArgNo = 0; 77 for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { 78 MVT::ValueType ObjectVT = getValueType(I->getType()); 79 assert(ArgNo < 6 && "Only args in regs for now"); 80 81 switch (ObjectVT) { 82 default: assert(0 && "Unhandled argument type!"); 83 // TODO: MVT::i64 & FP 84 case MVT::i1: 85 case MVT::i8: 86 case MVT::i16: 87 case MVT::i32: { 88 unsigned VReg = RegMap->createVirtualRegister(&V8::IntRegsRegClass); 89 MF.addLiveIn(GPR[ArgNo++], VReg); 90 SDOperand Arg = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32); 91 DAG.setRoot(Arg.getValue(1)); 92 if (ObjectVT != MVT::i32) { 93 unsigned AssertOp = I->getType()->isSigned() ? ISD::AssertSext 94 : ISD::AssertZext; 95 Arg = DAG.getNode(AssertOp, MVT::i32, Arg, 96 DAG.getValueType(ObjectVT)); 97 Arg = DAG.getNode(ISD::TRUNCATE, ObjectVT, Arg); 98 } 99 ArgValues.push_back(Arg); 100 } 101 } 102 } 103 104 assert(!F.isVarArg() && "Unimp"); 105 106 // Finally, inform the code generator which regs we return values in. 107 switch (getValueType(F.getReturnType())) { 108 default: assert(0 && "Unknown type!"); 109 case MVT::isVoid: break; 110 case MVT::i1: 111 case MVT::i8: 112 case MVT::i16: 113 case MVT::i32: 114 MF.addLiveOut(V8::I0); 115 break; 116 case MVT::i64: 117 MF.addLiveOut(V8::I0); 118 MF.addLiveOut(V8::I1); 119 break; 120 case MVT::f32: 121 MF.addLiveOut(V8::F0); 122 break; 123 case MVT::f64: 124 MF.addLiveOut(V8::D0); 125 break; 126 } 127 128 return ArgValues; 129} 130 131std::pair<SDOperand, SDOperand> 132SparcV8TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, 133 bool isVarArg, unsigned CC, 134 bool isTailCall, SDOperand Callee, 135 ArgListTy &Args, SelectionDAG &DAG) { 136 assert(0 && "Unimp"); 137 abort(); 138} 139 140SDOperand SparcV8TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op, 141 SelectionDAG &DAG) { 142 if (Op.getValueType() == MVT::i64) { 143 SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, 144 DAG.getConstant(1, MVT::i32)); 145 SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, 146 DAG.getConstant(0, MVT::i32)); 147 return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Hi); 148 } else { 149 return DAG.getNode(ISD::RET, MVT::Other, Chain, Op); 150 } 151} 152 153SDOperand SparcV8TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, 154 Value *VAListV, SelectionDAG &DAG) { 155 assert(0 && "Unimp"); 156 abort(); 157} 158 159std::pair<SDOperand,SDOperand> 160SparcV8TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, 161 const Type *ArgTy, SelectionDAG &DAG) { 162 assert(0 && "Unimp"); 163 abort(); 164} 165 166std::pair<SDOperand, SDOperand> 167SparcV8TargetLowering::LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, 168 SelectionDAG &DAG) { 169 assert(0 && "Unimp"); 170 abort(); 171} 172 173//===----------------------------------------------------------------------===// 174// Instruction Selector Implementation 175//===----------------------------------------------------------------------===// 176 177//===--------------------------------------------------------------------===// 178/// SparcV8DAGToDAGISel - PPC specific code to select Sparc V8 machine 179/// instructions for SelectionDAG operations. 180/// 181namespace { 182class SparcV8DAGToDAGISel : public SelectionDAGISel { 183 SparcV8TargetLowering V8Lowering; 184public: 185 SparcV8DAGToDAGISel(TargetMachine &TM) 186 : SelectionDAGISel(V8Lowering), V8Lowering(TM) {} 187 188 SDOperand Select(SDOperand Op); 189 190 /// InstructionSelectBasicBlock - This callback is invoked by 191 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 192 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); 193 194 virtual const char *getPassName() const { 195 return "PowerPC DAG->DAG Pattern Instruction Selection"; 196 } 197 198 // Include the pieces autogenerated from the target description. 199#include "SparcV8GenDAGISel.inc" 200}; 201} // end anonymous namespace 202 203/// InstructionSelectBasicBlock - This callback is invoked by 204/// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 205void SparcV8DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { 206 DEBUG(BB->dump()); 207 208 // Select target instructions for the DAG. 209 DAG.setRoot(Select(DAG.getRoot())); 210 CodeGenMap.clear(); 211 DAG.RemoveDeadNodes(); 212 213 // Emit machine code to BB. 214 ScheduleAndEmitDAG(DAG); 215} 216 217 218SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) { 219 SDNode *N = Op.Val; 220 if (N->getOpcode() >= ISD::BUILTIN_OP_END/* && 221 N->getOpcode() < V8ISD::FIRST_NUMBER*/) 222 return Op; // Already selected. 223 // If this has already been converted, use it. 224 std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op); 225 if (CGMI != CodeGenMap.end()) return CGMI->second; 226 227 switch (N->getOpcode()) { 228 default: break; 229 case ISD::RET: { 230 if (N->getNumOperands() == 2) { 231 SDOperand Chain = Select(N->getOperand(0)); // Token chain. 232 SDOperand Val = Select(N->getOperand(1)); 233 if (N->getOperand(1).getValueType() == MVT::i32) { 234 Chain = CurDAG->getCopyToReg(Chain, V8::I0, Val); 235 } else if (N->getOperand(1).getValueType() == MVT::f32) { 236 Chain = CurDAG->getCopyToReg(Chain, V8::F0, Val); 237 } else { 238 assert(N->getOperand(1).getValueType() == MVT::f64); 239 Chain = CurDAG->getCopyToReg(Chain, V8::D0, Val); 240 } 241 return CurDAG->SelectNodeTo(N, V8::RETL, MVT::Other, Chain); 242 } else if (N->getNumOperands() > 1) { 243 SDOperand Chain = Select(N->getOperand(0)); // Token chain. 244 assert(N->getOperand(1).getValueType() == MVT::i32 && 245 N->getOperand(2).getValueType() == MVT::i32 && 246 N->getNumOperands() == 3 && "Unknown two-register ret value!"); 247 Chain = CurDAG->getCopyToReg(Chain, V8::I0, Select(N->getOperand(1))); 248 Chain = CurDAG->getCopyToReg(Chain, V8::I1, Select(N->getOperand(2))); 249 return CurDAG->SelectNodeTo(N, V8::RETL, MVT::Other, Chain); 250 } 251 break; // Generated code handles the void case. 252 } 253 } 254 255 return SelectCode(Op); 256} 257 258 259/// createPPCISelDag - This pass converts a legalized DAG into a 260/// PowerPC-specific DAG, ready for instruction scheduling. 261/// 262FunctionPass *llvm::createSparcV8ISelDag(TargetMachine &TM) { 263 return new SparcV8DAGToDAGISel(TM); 264} 265