SystemZISelLowering.cpp revision c7b71bede49dc1eae107c79a74b5c618c39506ac
1//===-- SystemZISelLowering.cpp - SystemZ DAG Lowering Implementation -----==// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the SystemZTargetLowering class. 11// 12//===----------------------------------------------------------------------===// 13 14#define DEBUG_TYPE "systemz-lower" 15 16#include "SystemZISelLowering.h" 17#include "SystemZ.h" 18#include "SystemZTargetMachine.h" 19#include "SystemZSubtarget.h" 20#include "llvm/DerivedTypes.h" 21#include "llvm/Function.h" 22#include "llvm/Intrinsics.h" 23#include "llvm/CallingConv.h" 24#include "llvm/GlobalVariable.h" 25#include "llvm/GlobalAlias.h" 26#include "llvm/CodeGen/CallingConvLower.h" 27#include "llvm/CodeGen/MachineFrameInfo.h" 28#include "llvm/CodeGen/MachineFunction.h" 29#include "llvm/CodeGen/MachineInstrBuilder.h" 30#include "llvm/CodeGen/MachineRegisterInfo.h" 31#include "llvm/CodeGen/PseudoSourceValue.h" 32#include "llvm/CodeGen/SelectionDAGISel.h" 33#include "llvm/CodeGen/ValueTypes.h" 34#include "llvm/Support/Debug.h" 35#include "llvm/ADT/VectorExtras.h" 36using namespace llvm; 37 38SystemZTargetLowering::SystemZTargetLowering(SystemZTargetMachine &tm) : 39 TargetLowering(tm), Subtarget(*tm.getSubtargetImpl()), TM(tm) { 40 41 RegInfo = TM.getRegisterInfo(); 42 43 // Set up the register classes. 44 addRegisterClass(MVT::i32, SystemZ::GR32RegisterClass); 45 addRegisterClass(MVT::i64, SystemZ::GR64RegisterClass); 46 47 // Compute derived properties from the register classes 48 computeRegisterProperties(); 49 50 // Set shifts properties 51 setShiftAmountFlavor(Extend); 52 setShiftAmountType(MVT::i32); 53 54 // Provide all sorts of operation actions 55 56 setStackPointerRegisterToSaveRestore(SystemZ::R15D); 57 setSchedulingPreference(SchedulingForLatency); 58 59 setOperationAction(ISD::RET, MVT::Other, Custom); 60} 61 62SDValue SystemZTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { 63 switch (Op.getOpcode()) { 64 case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); 65 case ISD::RET: return LowerRET(Op, DAG); 66 case ISD::CALL: return LowerCALL(Op, DAG); 67 default: 68 assert(0 && "unimplemented operand"); 69 return SDValue(); 70 } 71} 72 73//===----------------------------------------------------------------------===// 74// Calling Convention Implementation 75//===----------------------------------------------------------------------===// 76 77#include "SystemZGenCallingConv.inc" 78 79SDValue SystemZTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, 80 SelectionDAG &DAG) { 81 unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); 82 switch (CC) { 83 default: 84 assert(0 && "Unsupported calling convention"); 85 case CallingConv::C: 86 case CallingConv::Fast: 87 return LowerCCCArguments(Op, DAG); 88 } 89} 90 91SDValue SystemZTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { 92 CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); 93 unsigned CallingConv = TheCall->getCallingConv(); 94 switch (CallingConv) { 95 default: 96 assert(0 && "Unsupported calling convention"); 97 case CallingConv::Fast: 98 case CallingConv::C: 99 return LowerCCCCallTo(Op, DAG, CallingConv); 100 } 101} 102 103/// LowerCCCArguments - transform physical registers into virtual registers and 104/// generate load operations for arguments places on the stack. 105// FIXME: struct return stuff 106// FIXME: varargs 107SDValue SystemZTargetLowering::LowerCCCArguments(SDValue Op, 108 SelectionDAG &DAG) { 109 MachineFunction &MF = DAG.getMachineFunction(); 110 MachineFrameInfo *MFI = MF.getFrameInfo(); 111 MachineRegisterInfo &RegInfo = MF.getRegInfo(); 112 SDValue Root = Op.getOperand(0); 113 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; 114 unsigned CC = MF.getFunction()->getCallingConv(); 115 DebugLoc dl = Op.getDebugLoc(); 116 117 // Assign locations to all of the incoming arguments. 118 SmallVector<CCValAssign, 16> ArgLocs; 119 CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); 120 CCInfo.AnalyzeFormalArguments(Op.getNode(), CC_SystemZ); 121 122 assert(!isVarArg && "Varargs not supported yet"); 123 124 SmallVector<SDValue, 16> ArgValues; 125 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 126 CCValAssign &VA = ArgLocs[i]; 127 if (VA.isRegLoc()) { 128 // Arguments passed in registers 129 MVT RegVT = VA.getLocVT(); 130 switch (RegVT.getSimpleVT()) { 131 default: 132 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " 133 << RegVT.getSimpleVT() 134 << "\n"; 135 abort(); 136 case MVT::i64: 137 unsigned VReg = 138 RegInfo.createVirtualRegister(SystemZ::GR64RegisterClass); 139 RegInfo.addLiveIn(VA.getLocReg(), VReg); 140 SDValue ArgValue = DAG.getCopyFromReg(Root, dl, VReg, RegVT); 141 142 // If this is an 8/16/32-bit value, it is really passed promoted to 64 143 // bits. Insert an assert[sz]ext to capture this, then truncate to the 144 // right size. 145 if (VA.getLocInfo() == CCValAssign::SExt) 146 ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, 147 DAG.getValueType(VA.getValVT())); 148 else if (VA.getLocInfo() == CCValAssign::ZExt) 149 ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, 150 DAG.getValueType(VA.getValVT())); 151 152 if (VA.getLocInfo() != CCValAssign::Full) 153 ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); 154 155 ArgValues.push_back(ArgValue); 156 } 157 } else { 158 // Sanity check 159 assert(VA.isMemLoc()); 160 // Load the argument to a virtual register 161 unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; 162 if (ObjSize > 8) { 163 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " 164 << VA.getLocVT().getSimpleVT() 165 << "\n"; 166 } 167 // Create the frame index object for this incoming parameter... 168 int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset()); 169 170 // Create the SelectionDAG nodes corresponding to a load 171 //from this parameter 172 SDValue FIN = DAG.getFrameIndex(FI, MVT::i64); 173 ArgValues.push_back(DAG.getLoad(VA.getLocVT(), dl, Root, FIN, 174 PseudoSourceValue::getFixedStack(FI), 0)); 175 } 176 } 177 178 ArgValues.push_back(Root); 179 180 // Return the new list of results. 181 return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), 182 &ArgValues[0], ArgValues.size()).getValue(Op.getResNo()); 183} 184 185/// LowerCCCCallTo - functions arguments are copied from virtual regs to 186/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. 187/// TODO: sret. 188SDValue SystemZTargetLowering::LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, 189 unsigned CC) { 190 CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); 191 SDValue Chain = TheCall->getChain(); 192 SDValue Callee = TheCall->getCallee(); 193 bool isVarArg = TheCall->isVarArg(); 194 DebugLoc dl = Op.getDebugLoc(); 195 MachineFunction &MF = DAG.getMachineFunction(); 196 197 // Offset to first argument stack slot. 198 const unsigned FirstArgOffset = 160; 199 200 // Analyze operands of the call, assigning locations to each operand. 201 SmallVector<CCValAssign, 16> ArgLocs; 202 CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); 203 204 CCInfo.AnalyzeCallOperands(TheCall, CC_SystemZ); 205 206 // Get a count of how many bytes are to be pushed on the stack. 207 unsigned NumBytes = CCInfo.getNextStackOffset(); 208 209 Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes, 210 getPointerTy(), true)); 211 212 SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; 213 SmallVector<SDValue, 12> MemOpChains; 214 SDValue StackPtr; 215 216 // Walk the register/memloc assignments, inserting copies/loads. 217 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 218 CCValAssign &VA = ArgLocs[i]; 219 220 // Arguments start after the 5 first operands of ISD::CALL 221 SDValue Arg = TheCall->getArg(i); 222 223 // Promote the value if needed. 224 switch (VA.getLocInfo()) { 225 default: assert(0 && "Unknown loc info!"); 226 case CCValAssign::Full: break; 227 case CCValAssign::SExt: 228 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 229 break; 230 case CCValAssign::ZExt: 231 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 232 break; 233 case CCValAssign::AExt: 234 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 235 break; 236 } 237 238 // Arguments that can be passed on register must be kept at RegsToPass 239 // vector 240 if (VA.isRegLoc()) { 241 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 242 } else { 243 assert(VA.isMemLoc()); 244 245 if (StackPtr.getNode() == 0) 246 StackPtr = 247 DAG.getCopyFromReg(Chain, dl, 248 (RegInfo->hasFP(MF) ? 249 SystemZ::R11D : SystemZ::R15D), 250 getPointerTy()); 251 252 unsigned Offset = FirstArgOffset + VA.getLocMemOffset(); 253 SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), 254 StackPtr, 255 DAG.getIntPtrConstant(Offset)); 256 257 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, 258 PseudoSourceValue::getStack(), Offset)); 259 } 260 } 261 262 // Transform all store nodes into one single node because all store nodes are 263 // independent of each other. 264 if (!MemOpChains.empty()) 265 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 266 &MemOpChains[0], MemOpChains.size()); 267 268 // Build a sequence of copy-to-reg nodes chained together with token chain and 269 // flag operands which copy the outgoing args into registers. The InFlag in 270 // necessary since all emited instructions must be stuck together. 271 SDValue InFlag; 272 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 273 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 274 RegsToPass[i].second, InFlag); 275 InFlag = Chain.getValue(1); 276 } 277 278 // If the callee is a GlobalAddress node (quite common, every direct call is) 279 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 280 // Likewise ExternalSymbol -> TargetExternalSymbol. 281 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 282 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy()); 283 else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 284 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), getPointerTy()); 285 286 // Returns a chain & a flag for retval copy to use. 287 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); 288 SmallVector<SDValue, 8> Ops; 289 Ops.push_back(Chain); 290 Ops.push_back(Callee); 291 292 // Add argument registers to the end of the list so that they are 293 // known live into the call. 294 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 295 Ops.push_back(DAG.getRegister(RegsToPass[i].first, 296 RegsToPass[i].second.getValueType())); 297 298 if (InFlag.getNode()) 299 Ops.push_back(InFlag); 300 301 Chain = DAG.getNode(SystemZISD::CALL, dl, NodeTys, &Ops[0], Ops.size()); 302 InFlag = Chain.getValue(1); 303 304 // Create the CALLSEQ_END node. 305 Chain = DAG.getCALLSEQ_END(Chain, 306 DAG.getConstant(NumBytes, getPointerTy(), true), 307 DAG.getConstant(0, getPointerTy(), true), 308 InFlag); 309 InFlag = Chain.getValue(1); 310 311 // Handle result values, copying them out of physregs into vregs that we 312 // return. 313 return SDValue(LowerCallResult(Chain, InFlag, TheCall, CC, DAG), 314 Op.getResNo()); 315} 316 317/// LowerCallResult - Lower the result values of an ISD::CALL into the 318/// appropriate copies out of appropriate physical registers. This assumes that 319/// Chain/InFlag are the input chain/flag to use, and that TheCall is the call 320/// being lowered. Returns a SDNode with the same number of values as the 321/// ISD::CALL. 322SDNode* 323SystemZTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, 324 CallSDNode *TheCall, 325 unsigned CallingConv, 326 SelectionDAG &DAG) { 327 bool isVarArg = TheCall->isVarArg(); 328 DebugLoc dl = TheCall->getDebugLoc(); 329 330 // Assign locations to each value returned by this call. 331 SmallVector<CCValAssign, 16> RVLocs; 332 CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), RVLocs); 333 334 CCInfo.AnalyzeCallResult(TheCall, RetCC_SystemZ); 335 SmallVector<SDValue, 8> ResultVals; 336 337 // Copy all of the result registers out of their specified physreg. 338 for (unsigned i = 0; i != RVLocs.size(); ++i) { 339 Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), 340 RVLocs[i].getValVT(), InFlag).getValue(1); 341 InFlag = Chain.getValue(2); 342 ResultVals.push_back(Chain.getValue(0)); 343 } 344 345 ResultVals.push_back(Chain); 346 347 // Merge everything together with a MERGE_VALUES node. 348 return DAG.getNode(ISD::MERGE_VALUES, dl, TheCall->getVTList(), 349 &ResultVals[0], ResultVals.size()).getNode(); 350} 351 352 353SDValue SystemZTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { 354 // CCValAssign - represent the assignment of the return value to a location 355 SmallVector<CCValAssign, 16> RVLocs; 356 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); 357 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); 358 DebugLoc dl = Op.getDebugLoc(); 359 360 // CCState - Info about the registers and stack slot. 361 CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs); 362 363 // Analize return values of ISD::RET 364 CCInfo.AnalyzeReturn(Op.getNode(), RetCC_SystemZ); 365 366 // If this is the first return lowered for this function, add the regs to the 367 // liveout set for the function. 368 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { 369 for (unsigned i = 0; i != RVLocs.size(); ++i) 370 if (RVLocs[i].isRegLoc()) 371 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); 372 } 373 374 // The chain is always operand #0 375 SDValue Chain = Op.getOperand(0); 376 SDValue Flag; 377 378 // Copy the result values into the output registers. 379 for (unsigned i = 0; i != RVLocs.size(); ++i) { 380 CCValAssign &VA = RVLocs[i]; 381 SDValue ResValue = Op.getOperand(i*2+1); 382 assert(VA.isRegLoc() && "Can only return in registers!"); 383 384 // If this is an 8/16/32-bit value, it is really should be passed promoted 385 // to 64 bits. 386 if (VA.getLocInfo() == CCValAssign::SExt) 387 ResValue = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), ResValue); 388 else if (VA.getLocInfo() == CCValAssign::ZExt) 389 ResValue = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), ResValue); 390 else if (VA.getLocInfo() == CCValAssign::AExt) 391 ResValue = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), ResValue); 392 393 // ISD::RET => ret chain, (regnum1,val1), ... 394 // So i*2+1 index only the regnums 395 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), ResValue, Flag); 396 397 // Guarantee that all emitted copies are stuck together, 398 // avoiding something bad. 399 Flag = Chain.getValue(1); 400 } 401 402 if (Flag.getNode()) 403 return DAG.getNode(SystemZISD::RET_FLAG, dl, MVT::Other, Chain, Flag); 404 405 // Return Void 406 return DAG.getNode(SystemZISD::RET_FLAG, dl, MVT::Other, Chain); 407} 408 409const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const { 410 switch (Opcode) { 411 case SystemZISD::RET_FLAG: return "SystemZISD::RET_FLAG"; 412 case SystemZISD::CALL: return "SystemZISD::CALL"; 413 default: return NULL; 414 } 415} 416 417