SystemZISelLowering.cpp revision c9403659a98bf6487ab6fbf40b81628b5695c02e
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/TargetLoweringObjectFileImpl.h" 34#include "llvm/CodeGen/ValueTypes.h" 35#include "llvm/Target/TargetOptions.h" 36#include "llvm/Support/Debug.h" 37#include "llvm/Support/ErrorHandling.h" 38#include "llvm/Support/raw_ostream.h" 39#include "llvm/ADT/VectorExtras.h" 40using namespace llvm; 41 42SystemZTargetLowering::SystemZTargetLowering(SystemZTargetMachine &tm) : 43 TargetLowering(tm, new TargetLoweringObjectFileELF()), 44 Subtarget(*tm.getSubtargetImpl()), TM(tm) { 45 46 RegInfo = TM.getRegisterInfo(); 47 48 // Set up the register classes. 49 addRegisterClass(MVT::i32, SystemZ::GR32RegisterClass); 50 addRegisterClass(MVT::i64, SystemZ::GR64RegisterClass); 51 addRegisterClass(MVT::v2i32,SystemZ::GR64PRegisterClass); 52 addRegisterClass(MVT::v2i64,SystemZ::GR128RegisterClass); 53 54 if (!UseSoftFloat) { 55 addRegisterClass(MVT::f32, SystemZ::FP32RegisterClass); 56 addRegisterClass(MVT::f64, SystemZ::FP64RegisterClass); 57 } 58 59 // Compute derived properties from the register classes 60 computeRegisterProperties(); 61 62 // Set shifts properties 63 setShiftAmountType(MVT::i64); 64 65 // Provide all sorts of operation actions 66 setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); 67 setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); 68 setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); 69 70 setLoadExtAction(ISD::SEXTLOAD, MVT::f32, Expand); 71 setLoadExtAction(ISD::ZEXTLOAD, MVT::f32, Expand); 72 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand); 73 74 setLoadExtAction(ISD::SEXTLOAD, MVT::f64, Expand); 75 setLoadExtAction(ISD::ZEXTLOAD, MVT::f64, Expand); 76 setLoadExtAction(ISD::EXTLOAD, MVT::f64, Expand); 77 78 setStackPointerRegisterToSaveRestore(SystemZ::R15D); 79 80 // TODO: It may be better to default to latency-oriented scheduling, however 81 // LLVM's current latency-oriented scheduler can't handle physreg definitions 82 // such as SystemZ has with PSW, so set this to the register-pressure 83 // scheduler, because it can. 84 setSchedulingPreference(Sched::RegPressure); 85 86 setBooleanContents(ZeroOrOneBooleanContent); 87 88 setOperationAction(ISD::BR_JT, MVT::Other, Expand); 89 setOperationAction(ISD::BRCOND, MVT::Other, Expand); 90 setOperationAction(ISD::BR_CC, MVT::i32, Custom); 91 setOperationAction(ISD::BR_CC, MVT::i64, Custom); 92 setOperationAction(ISD::BR_CC, MVT::f32, Custom); 93 setOperationAction(ISD::BR_CC, MVT::f64, Custom); 94 setOperationAction(ISD::ConstantPool, MVT::i32, Custom); 95 setOperationAction(ISD::ConstantPool, MVT::i64, Custom); 96 setOperationAction(ISD::GlobalAddress, MVT::i64, Custom); 97 setOperationAction(ISD::JumpTable, MVT::i64, Custom); 98 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand); 99 100 setOperationAction(ISD::SDIV, MVT::i32, Expand); 101 setOperationAction(ISD::UDIV, MVT::i32, Expand); 102 setOperationAction(ISD::SDIV, MVT::i64, Expand); 103 setOperationAction(ISD::UDIV, MVT::i64, Expand); 104 setOperationAction(ISD::SREM, MVT::i32, Expand); 105 setOperationAction(ISD::UREM, MVT::i32, Expand); 106 setOperationAction(ISD::SREM, MVT::i64, Expand); 107 setOperationAction(ISD::UREM, MVT::i64, Expand); 108 109 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); 110 111 setOperationAction(ISD::CTPOP, MVT::i32, Expand); 112 setOperationAction(ISD::CTPOP, MVT::i64, Expand); 113 setOperationAction(ISD::CTTZ, MVT::i32, Expand); 114 setOperationAction(ISD::CTTZ, MVT::i64, Expand); 115 setOperationAction(ISD::CTLZ, MVT::i32, Promote); 116 setOperationAction(ISD::CTLZ, MVT::i64, Legal); 117 118 // FIXME: Can we lower these 2 efficiently? 119 setOperationAction(ISD::SETCC, MVT::i32, Expand); 120 setOperationAction(ISD::SETCC, MVT::i64, Expand); 121 setOperationAction(ISD::SETCC, MVT::f32, Expand); 122 setOperationAction(ISD::SETCC, MVT::f64, Expand); 123 setOperationAction(ISD::SELECT, MVT::i32, Expand); 124 setOperationAction(ISD::SELECT, MVT::i64, Expand); 125 setOperationAction(ISD::SELECT, MVT::f32, Expand); 126 setOperationAction(ISD::SELECT, MVT::f64, Expand); 127 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); 128 setOperationAction(ISD::SELECT_CC, MVT::i64, Custom); 129 setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); 130 setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); 131 132 setOperationAction(ISD::MULHS, MVT::i64, Expand); 133 setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand); 134 135 // FIXME: Can we support these natively? 136 setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand); 137 setOperationAction(ISD::SRL_PARTS, MVT::i64, Expand); 138 setOperationAction(ISD::SHL_PARTS, MVT::i64, Expand); 139 setOperationAction(ISD::SRA_PARTS, MVT::i64, Expand); 140 141 // Lower some FP stuff 142 setOperationAction(ISD::FSIN, MVT::f32, Expand); 143 setOperationAction(ISD::FSIN, MVT::f64, Expand); 144 setOperationAction(ISD::FCOS, MVT::f32, Expand); 145 setOperationAction(ISD::FCOS, MVT::f64, Expand); 146 setOperationAction(ISD::FREM, MVT::f32, Expand); 147 setOperationAction(ISD::FREM, MVT::f64, Expand); 148 149 // We have only 64-bit bitconverts 150 setOperationAction(ISD::BIT_CONVERT, MVT::f32, Expand); 151 setOperationAction(ISD::BIT_CONVERT, MVT::i32, Expand); 152 153 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand); 154 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand); 155 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand); 156 setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand); 157 158 setTruncStoreAction(MVT::f64, MVT::f32, Expand); 159} 160 161SDValue SystemZTargetLowering::LowerOperation(SDValue Op, 162 SelectionDAG &DAG) const { 163 switch (Op.getOpcode()) { 164 case ISD::BR_CC: return LowerBR_CC(Op, DAG); 165 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); 166 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); 167 case ISD::JumpTable: return LowerJumpTable(Op, DAG); 168 case ISD::ConstantPool: return LowerConstantPool(Op, DAG); 169 default: 170 llvm_unreachable("Should not custom lower this!"); 171 return SDValue(); 172 } 173} 174 175bool SystemZTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const { 176 if (UseSoftFloat || (VT != MVT::f32 && VT != MVT::f64)) 177 return false; 178 179 // +0.0 lzer 180 // +0.0f lzdr 181 // -0.0 lzer + lner 182 // -0.0f lzdr + lndr 183 return Imm.isZero() || Imm.isNegZero(); 184} 185 186//===----------------------------------------------------------------------===// 187// SystemZ Inline Assembly Support 188//===----------------------------------------------------------------------===// 189 190/// getConstraintType - Given a constraint letter, return the type of 191/// constraint it is for this target. 192TargetLowering::ConstraintType 193SystemZTargetLowering::getConstraintType(const std::string &Constraint) const { 194 if (Constraint.size() == 1) { 195 switch (Constraint[0]) { 196 case 'r': 197 return C_RegisterClass; 198 default: 199 break; 200 } 201 } 202 return TargetLowering::getConstraintType(Constraint); 203} 204 205std::pair<unsigned, const TargetRegisterClass*> 206SystemZTargetLowering:: 207getRegForInlineAsmConstraint(const std::string &Constraint, 208 EVT VT) const { 209 if (Constraint.size() == 1) { 210 // GCC Constraint Letters 211 switch (Constraint[0]) { 212 default: break; 213 case 'r': // GENERAL_REGS 214 if (VT == MVT::i32) 215 return std::make_pair(0U, SystemZ::GR32RegisterClass); 216 else if (VT == MVT::i128) 217 return std::make_pair(0U, SystemZ::GR128RegisterClass); 218 219 return std::make_pair(0U, SystemZ::GR64RegisterClass); 220 } 221 } 222 223 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); 224} 225 226//===----------------------------------------------------------------------===// 227// Calling Convention Implementation 228//===----------------------------------------------------------------------===// 229 230#include "SystemZGenCallingConv.inc" 231 232SDValue 233SystemZTargetLowering::LowerFormalArguments(SDValue Chain, 234 CallingConv::ID CallConv, 235 bool isVarArg, 236 const SmallVectorImpl<ISD::InputArg> 237 &Ins, 238 DebugLoc dl, 239 SelectionDAG &DAG, 240 SmallVectorImpl<SDValue> &InVals) 241 const { 242 243 switch (CallConv) { 244 default: 245 llvm_unreachable("Unsupported calling convention"); 246 case CallingConv::C: 247 case CallingConv::Fast: 248 return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals); 249 } 250} 251 252SDValue 253SystemZTargetLowering::LowerCall(SDValue Chain, SDValue Callee, 254 CallingConv::ID CallConv, bool isVarArg, 255 bool &isTailCall, 256 const SmallVectorImpl<ISD::OutputArg> &Outs, 257 const SmallVectorImpl<SDValue> &OutVals, 258 const SmallVectorImpl<ISD::InputArg> &Ins, 259 DebugLoc dl, SelectionDAG &DAG, 260 SmallVectorImpl<SDValue> &InVals) const { 261 // SystemZ target does not yet support tail call optimization. 262 isTailCall = false; 263 264 switch (CallConv) { 265 default: 266 llvm_unreachable("Unsupported calling convention"); 267 case CallingConv::Fast: 268 case CallingConv::C: 269 return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall, 270 Outs, OutVals, Ins, dl, DAG, InVals); 271 } 272} 273 274/// LowerCCCArguments - transform physical registers into virtual registers and 275/// generate load operations for arguments places on the stack. 276// FIXME: struct return stuff 277// FIXME: varargs 278SDValue 279SystemZTargetLowering::LowerCCCArguments(SDValue Chain, 280 CallingConv::ID CallConv, 281 bool isVarArg, 282 const SmallVectorImpl<ISD::InputArg> 283 &Ins, 284 DebugLoc dl, 285 SelectionDAG &DAG, 286 SmallVectorImpl<SDValue> &InVals) 287 const { 288 289 MachineFunction &MF = DAG.getMachineFunction(); 290 MachineFrameInfo *MFI = MF.getFrameInfo(); 291 MachineRegisterInfo &RegInfo = MF.getRegInfo(); 292 293 // Assign locations to all of the incoming arguments. 294 SmallVector<CCValAssign, 16> ArgLocs; 295 CCState CCInfo(CallConv, isVarArg, getTargetMachine(), 296 ArgLocs, *DAG.getContext()); 297 CCInfo.AnalyzeFormalArguments(Ins, CC_SystemZ); 298 299 if (isVarArg) 300 report_fatal_error("Varargs not supported yet"); 301 302 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 303 SDValue ArgValue; 304 CCValAssign &VA = ArgLocs[i]; 305 EVT LocVT = VA.getLocVT(); 306 if (VA.isRegLoc()) { 307 // Arguments passed in registers 308 TargetRegisterClass *RC; 309 switch (LocVT.getSimpleVT().SimpleTy) { 310 default: 311#ifndef NDEBUG 312 errs() << "LowerFormalArguments Unhandled argument type: " 313 << LocVT.getSimpleVT().SimpleTy 314 << "\n"; 315#endif 316 llvm_unreachable(0); 317 case MVT::i64: 318 RC = SystemZ::GR64RegisterClass; 319 break; 320 case MVT::f32: 321 RC = SystemZ::FP32RegisterClass; 322 break; 323 case MVT::f64: 324 RC = SystemZ::FP64RegisterClass; 325 break; 326 } 327 328 unsigned VReg = RegInfo.createVirtualRegister(RC); 329 RegInfo.addLiveIn(VA.getLocReg(), VReg); 330 ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, LocVT); 331 } else { 332 // Sanity check 333 assert(VA.isMemLoc()); 334 335 // Create the nodes corresponding to a load from this parameter slot. 336 // Create the frame index object for this incoming parameter... 337 int FI = MFI->CreateFixedObject(LocVT.getSizeInBits()/8, 338 VA.getLocMemOffset(), true); 339 340 // Create the SelectionDAG nodes corresponding to a load 341 // from this parameter 342 SDValue FIN = DAG.getFrameIndex(FI, getPointerTy()); 343 ArgValue = DAG.getLoad(LocVT, dl, Chain, FIN, 344 PseudoSourceValue::getFixedStack(FI), 0, 345 false, false, 0); 346 } 347 348 // If this is an 8/16/32-bit value, it is really passed promoted to 64 349 // bits. Insert an assert[sz]ext to capture this, then truncate to the 350 // right size. 351 if (VA.getLocInfo() == CCValAssign::SExt) 352 ArgValue = DAG.getNode(ISD::AssertSext, dl, LocVT, ArgValue, 353 DAG.getValueType(VA.getValVT())); 354 else if (VA.getLocInfo() == CCValAssign::ZExt) 355 ArgValue = DAG.getNode(ISD::AssertZext, dl, LocVT, ArgValue, 356 DAG.getValueType(VA.getValVT())); 357 358 if (VA.getLocInfo() != CCValAssign::Full) 359 ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); 360 361 InVals.push_back(ArgValue); 362 } 363 364 return Chain; 365} 366 367/// LowerCCCCallTo - functions arguments are copied from virtual regs to 368/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. 369/// TODO: sret. 370SDValue 371SystemZTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, 372 CallingConv::ID CallConv, bool isVarArg, 373 bool isTailCall, 374 const SmallVectorImpl<ISD::OutputArg> 375 &Outs, 376 const SmallVectorImpl<SDValue> &OutVals, 377 const SmallVectorImpl<ISD::InputArg> &Ins, 378 DebugLoc dl, SelectionDAG &DAG, 379 SmallVectorImpl<SDValue> &InVals) const { 380 381 MachineFunction &MF = DAG.getMachineFunction(); 382 383 // Offset to first argument stack slot. 384 const unsigned FirstArgOffset = 160; 385 386 // Analyze operands of the call, assigning locations to each operand. 387 SmallVector<CCValAssign, 16> ArgLocs; 388 CCState CCInfo(CallConv, isVarArg, getTargetMachine(), 389 ArgLocs, *DAG.getContext()); 390 391 CCInfo.AnalyzeCallOperands(Outs, CC_SystemZ); 392 393 // Get a count of how many bytes are to be pushed on the stack. 394 unsigned NumBytes = CCInfo.getNextStackOffset(); 395 396 Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes, 397 getPointerTy(), true)); 398 399 SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; 400 SmallVector<SDValue, 12> MemOpChains; 401 SDValue StackPtr; 402 403 // Walk the register/memloc assignments, inserting copies/loads. 404 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 405 CCValAssign &VA = ArgLocs[i]; 406 407 SDValue Arg = OutVals[i]; 408 409 // Promote the value if needed. 410 switch (VA.getLocInfo()) { 411 default: assert(0 && "Unknown loc info!"); 412 case CCValAssign::Full: break; 413 case CCValAssign::SExt: 414 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 415 break; 416 case CCValAssign::ZExt: 417 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 418 break; 419 case CCValAssign::AExt: 420 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 421 break; 422 } 423 424 // Arguments that can be passed on register must be kept at RegsToPass 425 // vector 426 if (VA.isRegLoc()) { 427 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 428 } else { 429 assert(VA.isMemLoc()); 430 431 if (StackPtr.getNode() == 0) 432 StackPtr = 433 DAG.getCopyFromReg(Chain, dl, 434 (RegInfo->hasFP(MF) ? 435 SystemZ::R11D : SystemZ::R15D), 436 getPointerTy()); 437 438 unsigned Offset = FirstArgOffset + VA.getLocMemOffset(); 439 SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), 440 StackPtr, 441 DAG.getIntPtrConstant(Offset)); 442 443 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, 444 PseudoSourceValue::getStack(), Offset, 445 false, false, 0)); 446 } 447 } 448 449 // Transform all store nodes into one single node because all store nodes are 450 // independent of each other. 451 if (!MemOpChains.empty()) 452 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 453 &MemOpChains[0], MemOpChains.size()); 454 455 // Build a sequence of copy-to-reg nodes chained together with token chain and 456 // flag operands which copy the outgoing args into registers. The InFlag in 457 // necessary since all emited instructions must be stuck together. 458 SDValue InFlag; 459 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 460 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 461 RegsToPass[i].second, InFlag); 462 InFlag = Chain.getValue(1); 463 } 464 465 // If the callee is a GlobalAddress node (quite common, every direct call is) 466 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 467 // Likewise ExternalSymbol -> TargetExternalSymbol. 468 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 469 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, getPointerTy()); 470 else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 471 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), getPointerTy()); 472 473 // Returns a chain & a flag for retval copy to use. 474 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); 475 SmallVector<SDValue, 8> Ops; 476 Ops.push_back(Chain); 477 Ops.push_back(Callee); 478 479 // Add argument registers to the end of the list so that they are 480 // known live into the call. 481 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 482 Ops.push_back(DAG.getRegister(RegsToPass[i].first, 483 RegsToPass[i].second.getValueType())); 484 485 if (InFlag.getNode()) 486 Ops.push_back(InFlag); 487 488 Chain = DAG.getNode(SystemZISD::CALL, dl, NodeTys, &Ops[0], Ops.size()); 489 InFlag = Chain.getValue(1); 490 491 // Create the CALLSEQ_END node. 492 Chain = DAG.getCALLSEQ_END(Chain, 493 DAG.getConstant(NumBytes, getPointerTy(), true), 494 DAG.getConstant(0, getPointerTy(), true), 495 InFlag); 496 InFlag = Chain.getValue(1); 497 498 // Handle result values, copying them out of physregs into vregs that we 499 // return. 500 return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl, 501 DAG, InVals); 502} 503 504/// LowerCallResult - Lower the result values of a call into the 505/// appropriate copies out of appropriate physical registers. 506/// 507SDValue 508SystemZTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, 509 CallingConv::ID CallConv, bool isVarArg, 510 const SmallVectorImpl<ISD::InputArg> 511 &Ins, 512 DebugLoc dl, SelectionDAG &DAG, 513 SmallVectorImpl<SDValue> &InVals) const { 514 515 // Assign locations to each value returned by this call. 516 SmallVector<CCValAssign, 16> RVLocs; 517 CCState CCInfo(CallConv, isVarArg, getTargetMachine(), RVLocs, 518 *DAG.getContext()); 519 520 CCInfo.AnalyzeCallResult(Ins, RetCC_SystemZ); 521 522 // Copy all of the result registers out of their specified physreg. 523 for (unsigned i = 0; i != RVLocs.size(); ++i) { 524 CCValAssign &VA = RVLocs[i]; 525 526 Chain = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), 527 VA.getLocVT(), InFlag).getValue(1); 528 SDValue RetValue = Chain.getValue(0); 529 InFlag = Chain.getValue(2); 530 531 // If this is an 8/16/32-bit value, it is really passed promoted to 64 532 // bits. Insert an assert[sz]ext to capture this, then truncate to the 533 // right size. 534 if (VA.getLocInfo() == CCValAssign::SExt) 535 RetValue = DAG.getNode(ISD::AssertSext, dl, VA.getLocVT(), RetValue, 536 DAG.getValueType(VA.getValVT())); 537 else if (VA.getLocInfo() == CCValAssign::ZExt) 538 RetValue = DAG.getNode(ISD::AssertZext, dl, VA.getLocVT(), RetValue, 539 DAG.getValueType(VA.getValVT())); 540 541 if (VA.getLocInfo() != CCValAssign::Full) 542 RetValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), RetValue); 543 544 InVals.push_back(RetValue); 545 } 546 547 return Chain; 548} 549 550 551SDValue 552SystemZTargetLowering::LowerReturn(SDValue Chain, 553 CallingConv::ID CallConv, bool isVarArg, 554 const SmallVectorImpl<ISD::OutputArg> &Outs, 555 const SmallVectorImpl<SDValue> &OutVals, 556 DebugLoc dl, SelectionDAG &DAG) const { 557 558 // CCValAssign - represent the assignment of the return value to a location 559 SmallVector<CCValAssign, 16> RVLocs; 560 561 // CCState - Info about the registers and stack slot. 562 CCState CCInfo(CallConv, isVarArg, getTargetMachine(), 563 RVLocs, *DAG.getContext()); 564 565 // Analize return values. 566 CCInfo.AnalyzeReturn(Outs, RetCC_SystemZ); 567 568 // If this is the first return lowered for this function, add the regs to the 569 // liveout set for the function. 570 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { 571 for (unsigned i = 0; i != RVLocs.size(); ++i) 572 if (RVLocs[i].isRegLoc()) 573 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); 574 } 575 576 SDValue Flag; 577 578 // Copy the result values into the output registers. 579 for (unsigned i = 0; i != RVLocs.size(); ++i) { 580 CCValAssign &VA = RVLocs[i]; 581 SDValue ResValue = OutVals[i]; 582 assert(VA.isRegLoc() && "Can only return in registers!"); 583 584 // If this is an 8/16/32-bit value, it is really should be passed promoted 585 // to 64 bits. 586 if (VA.getLocInfo() == CCValAssign::SExt) 587 ResValue = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), ResValue); 588 else if (VA.getLocInfo() == CCValAssign::ZExt) 589 ResValue = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), ResValue); 590 else if (VA.getLocInfo() == CCValAssign::AExt) 591 ResValue = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), ResValue); 592 593 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), ResValue, Flag); 594 595 // Guarantee that all emitted copies are stuck together, 596 // avoiding something bad. 597 Flag = Chain.getValue(1); 598 } 599 600 if (Flag.getNode()) 601 return DAG.getNode(SystemZISD::RET_FLAG, dl, MVT::Other, Chain, Flag); 602 603 // Return Void 604 return DAG.getNode(SystemZISD::RET_FLAG, dl, MVT::Other, Chain); 605} 606 607SDValue SystemZTargetLowering::EmitCmp(SDValue LHS, SDValue RHS, 608 ISD::CondCode CC, SDValue &SystemZCC, 609 SelectionDAG &DAG) const { 610 // FIXME: Emit a test if RHS is zero 611 612 bool isUnsigned = false; 613 SystemZCC::CondCodes TCC; 614 switch (CC) { 615 default: 616 llvm_unreachable("Invalid integer condition!"); 617 case ISD::SETEQ: 618 case ISD::SETOEQ: 619 TCC = SystemZCC::E; 620 break; 621 case ISD::SETUEQ: 622 TCC = SystemZCC::NLH; 623 break; 624 case ISD::SETNE: 625 case ISD::SETONE: 626 TCC = SystemZCC::NE; 627 break; 628 case ISD::SETUNE: 629 TCC = SystemZCC::LH; 630 break; 631 case ISD::SETO: 632 TCC = SystemZCC::O; 633 break; 634 case ISD::SETUO: 635 TCC = SystemZCC::NO; 636 break; 637 case ISD::SETULE: 638 if (LHS.getValueType().isFloatingPoint()) { 639 TCC = SystemZCC::NH; 640 break; 641 } 642 isUnsigned = true; // FALLTHROUGH 643 case ISD::SETLE: 644 case ISD::SETOLE: 645 TCC = SystemZCC::LE; 646 break; 647 case ISD::SETUGE: 648 if (LHS.getValueType().isFloatingPoint()) { 649 TCC = SystemZCC::NL; 650 break; 651 } 652 isUnsigned = true; // FALLTHROUGH 653 case ISD::SETGE: 654 case ISD::SETOGE: 655 TCC = SystemZCC::HE; 656 break; 657 case ISD::SETUGT: 658 if (LHS.getValueType().isFloatingPoint()) { 659 TCC = SystemZCC::NLE; 660 break; 661 } 662 isUnsigned = true; // FALLTHROUGH 663 case ISD::SETGT: 664 case ISD::SETOGT: 665 TCC = SystemZCC::H; 666 break; 667 case ISD::SETULT: 668 if (LHS.getValueType().isFloatingPoint()) { 669 TCC = SystemZCC::NHE; 670 break; 671 } 672 isUnsigned = true; // FALLTHROUGH 673 case ISD::SETLT: 674 case ISD::SETOLT: 675 TCC = SystemZCC::L; 676 break; 677 } 678 679 SystemZCC = DAG.getConstant(TCC, MVT::i32); 680 681 DebugLoc dl = LHS.getDebugLoc(); 682 return DAG.getNode((isUnsigned ? SystemZISD::UCMP : SystemZISD::CMP), 683 dl, MVT::i64, LHS, RHS); 684} 685 686 687SDValue SystemZTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const { 688 SDValue Chain = Op.getOperand(0); 689 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); 690 SDValue LHS = Op.getOperand(2); 691 SDValue RHS = Op.getOperand(3); 692 SDValue Dest = Op.getOperand(4); 693 DebugLoc dl = Op.getDebugLoc(); 694 695 SDValue SystemZCC; 696 SDValue Flag = EmitCmp(LHS, RHS, CC, SystemZCC, DAG); 697 return DAG.getNode(SystemZISD::BRCOND, dl, Op.getValueType(), 698 Chain, Dest, SystemZCC, Flag); 699} 700 701SDValue SystemZTargetLowering::LowerSELECT_CC(SDValue Op, 702 SelectionDAG &DAG) const { 703 SDValue LHS = Op.getOperand(0); 704 SDValue RHS = Op.getOperand(1); 705 SDValue TrueV = Op.getOperand(2); 706 SDValue FalseV = Op.getOperand(3); 707 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 708 DebugLoc dl = Op.getDebugLoc(); 709 710 SDValue SystemZCC; 711 SDValue Flag = EmitCmp(LHS, RHS, CC, SystemZCC, DAG); 712 713 SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag); 714 SmallVector<SDValue, 4> Ops; 715 Ops.push_back(TrueV); 716 Ops.push_back(FalseV); 717 Ops.push_back(SystemZCC); 718 Ops.push_back(Flag); 719 720 return DAG.getNode(SystemZISD::SELECT, dl, VTs, &Ops[0], Ops.size()); 721} 722 723SDValue SystemZTargetLowering::LowerGlobalAddress(SDValue Op, 724 SelectionDAG &DAG) const { 725 DebugLoc dl = Op.getDebugLoc(); 726 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 727 int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset(); 728 729 bool IsPic = getTargetMachine().getRelocationModel() == Reloc::PIC_; 730 bool ExtraLoadRequired = 731 Subtarget.GVRequiresExtraLoad(GV, getTargetMachine(), false); 732 733 SDValue Result; 734 if (!IsPic && !ExtraLoadRequired) { 735 Result = DAG.getTargetGlobalAddress(GV, dl, getPointerTy(), Offset); 736 Offset = 0; 737 } else { 738 unsigned char OpFlags = 0; 739 if (ExtraLoadRequired) 740 OpFlags = SystemZII::MO_GOTENT; 741 742 Result = DAG.getTargetGlobalAddress(GV, dl, getPointerTy(), 0, OpFlags); 743 } 744 745 Result = DAG.getNode(SystemZISD::PCRelativeWrapper, dl, 746 getPointerTy(), Result); 747 748 if (ExtraLoadRequired) 749 Result = DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), Result, 750 PseudoSourceValue::getGOT(), 0, false, false, 0); 751 752 // If there was a non-zero offset that we didn't fold, create an explicit 753 // addition for it. 754 if (Offset != 0) 755 Result = DAG.getNode(ISD::ADD, dl, getPointerTy(), Result, 756 DAG.getConstant(Offset, getPointerTy())); 757 758 return Result; 759} 760 761// FIXME: PIC here 762SDValue SystemZTargetLowering::LowerJumpTable(SDValue Op, 763 SelectionDAG &DAG) const { 764 DebugLoc dl = Op.getDebugLoc(); 765 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op); 766 SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), getPointerTy()); 767 768 return DAG.getNode(SystemZISD::PCRelativeWrapper, dl, getPointerTy(), Result); 769} 770 771 772// FIXME: PIC here 773// FIXME: This is just dirty hack. We need to lower cpool properly 774SDValue SystemZTargetLowering::LowerConstantPool(SDValue Op, 775 SelectionDAG &DAG) const { 776 DebugLoc dl = Op.getDebugLoc(); 777 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op); 778 779 SDValue Result = DAG.getTargetConstantPool(CP->getConstVal(), getPointerTy(), 780 CP->getAlignment(), 781 CP->getOffset()); 782 783 return DAG.getNode(SystemZISD::PCRelativeWrapper, dl, getPointerTy(), Result); 784} 785 786const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const { 787 switch (Opcode) { 788 case SystemZISD::RET_FLAG: return "SystemZISD::RET_FLAG"; 789 case SystemZISD::CALL: return "SystemZISD::CALL"; 790 case SystemZISD::BRCOND: return "SystemZISD::BRCOND"; 791 case SystemZISD::CMP: return "SystemZISD::CMP"; 792 case SystemZISD::UCMP: return "SystemZISD::UCMP"; 793 case SystemZISD::SELECT: return "SystemZISD::SELECT"; 794 case SystemZISD::PCRelativeWrapper: return "SystemZISD::PCRelativeWrapper"; 795 default: return NULL; 796 } 797} 798 799//===----------------------------------------------------------------------===// 800// Other Lowering Code 801//===----------------------------------------------------------------------===// 802 803MachineBasicBlock* 804SystemZTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 805 MachineBasicBlock *BB) const { 806 const SystemZInstrInfo &TII = *TM.getInstrInfo(); 807 DebugLoc dl = MI->getDebugLoc(); 808 assert((MI->getOpcode() == SystemZ::Select32 || 809 MI->getOpcode() == SystemZ::SelectF32 || 810 MI->getOpcode() == SystemZ::Select64 || 811 MI->getOpcode() == SystemZ::SelectF64) && 812 "Unexpected instr type to insert"); 813 814 // To "insert" a SELECT instruction, we actually have to insert the diamond 815 // control-flow pattern. The incoming instruction knows the destination vreg 816 // to set, the condition code register to branch on, the true/false values to 817 // select between, and a branch opcode to use. 818 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 819 MachineFunction::iterator I = BB; 820 ++I; 821 822 // thisMBB: 823 // ... 824 // TrueVal = ... 825 // cmpTY ccX, r1, r2 826 // jCC copy1MBB 827 // fallthrough --> copy0MBB 828 MachineBasicBlock *thisMBB = BB; 829 MachineFunction *F = BB->getParent(); 830 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); 831 MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB); 832 SystemZCC::CondCodes CC = (SystemZCC::CondCodes)MI->getOperand(3).getImm(); 833 F->insert(I, copy0MBB); 834 F->insert(I, copy1MBB); 835 // Update machine-CFG edges by transferring all successors of the current 836 // block to the new block which will contain the Phi node for the select. 837 copy1MBB->splice(copy1MBB->begin(), BB, 838 llvm::next(MachineBasicBlock::iterator(MI)), 839 BB->end()); 840 copy1MBB->transferSuccessorsAndUpdatePHIs(BB); 841 // Next, add the true and fallthrough blocks as its successors. 842 BB->addSuccessor(copy0MBB); 843 BB->addSuccessor(copy1MBB); 844 845 BuildMI(BB, dl, TII.getBrCond(CC)).addMBB(copy1MBB); 846 847 // copy0MBB: 848 // %FalseValue = ... 849 // # fallthrough to copy1MBB 850 BB = copy0MBB; 851 852 // Update machine-CFG edges 853 BB->addSuccessor(copy1MBB); 854 855 // copy1MBB: 856 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 857 // ... 858 BB = copy1MBB; 859 BuildMI(*BB, BB->begin(), dl, TII.get(SystemZ::PHI), 860 MI->getOperand(0).getReg()) 861 .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) 862 .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); 863 864 MI->eraseFromParent(); // The pseudo instruction is gone now. 865 return BB; 866} 867