1 //===-- AlphaISelLowering.cpp - Alpha 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 AlphaISelLowering class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "AlphaISelLowering.h" 15 #include "AlphaTargetMachine.h" 16 #include "AlphaMachineFunctionInfo.h" 17 #include "llvm/CodeGen/CallingConvLower.h" 18 #include "llvm/CodeGen/MachineFrameInfo.h" 19 #include "llvm/CodeGen/MachineFunction.h" 20 #include "llvm/CodeGen/MachineInstrBuilder.h" 21 #include "llvm/CodeGen/MachineRegisterInfo.h" 22 #include "llvm/CodeGen/SelectionDAG.h" 23 #include "llvm/CodeGen/MachineRegisterInfo.h" 24 #include "llvm/CodeGen/PseudoSourceValue.h" 25 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 26 #include "llvm/Constants.h" 27 #include "llvm/Function.h" 28 #include "llvm/Module.h" 29 #include "llvm/Intrinsics.h" 30 #include "llvm/Type.h" 31 #include "llvm/Support/CommandLine.h" 32 #include "llvm/Support/ErrorHandling.h" 33 #include "llvm/Support/raw_ostream.h" 34 using namespace llvm; 35 36 /// AddLiveIn - This helper function adds the specified physical register to the 37 /// MachineFunction as a live in value. It also creates a corresponding virtual 38 /// register for it. 39 static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg, 40 TargetRegisterClass *RC) { 41 assert(RC->contains(PReg) && "Not the correct regclass!"); 42 unsigned VReg = MF.getRegInfo().createVirtualRegister(RC); 43 MF.getRegInfo().addLiveIn(PReg, VReg); 44 return VReg; 45 } 46 47 AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) 48 : TargetLowering(TM, new TargetLoweringObjectFileELF()) { 49 // Set up the TargetLowering object. 50 //I am having problems with shr n i8 1 51 setBooleanContents(ZeroOrOneBooleanContent); 52 setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct? 53 54 addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass); 55 addRegisterClass(MVT::f64, Alpha::F8RCRegisterClass); 56 addRegisterClass(MVT::f32, Alpha::F4RCRegisterClass); 57 58 // We want to custom lower some of our intrinsics. 59 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); 60 61 setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); 62 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand); 63 64 setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); 65 setLoadExtAction(ISD::ZEXTLOAD, MVT::i32, Expand); 66 67 setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); 68 setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand); 69 setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand); 70 71 setTruncStoreAction(MVT::f64, MVT::f32, Expand); 72 73 // setOperationAction(ISD::BRIND, MVT::Other, Expand); 74 setOperationAction(ISD::BR_JT, MVT::Other, Expand); 75 setOperationAction(ISD::BR_CC, MVT::Other, Expand); 76 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand); 77 78 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); 79 80 setOperationAction(ISD::FREM, MVT::f32, Expand); 81 setOperationAction(ISD::FREM, MVT::f64, Expand); 82 83 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand); 84 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom); 85 setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand); 86 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); 87 88 if (!TM.getSubtarget<AlphaSubtarget>().hasCT()) { 89 setOperationAction(ISD::CTPOP , MVT::i64 , Expand); 90 setOperationAction(ISD::CTTZ , MVT::i64 , Expand); 91 setOperationAction(ISD::CTLZ , MVT::i64 , Expand); 92 } 93 setOperationAction(ISD::BSWAP , MVT::i64, Expand); 94 setOperationAction(ISD::ROTL , MVT::i64, Expand); 95 setOperationAction(ISD::ROTR , MVT::i64, Expand); 96 97 setOperationAction(ISD::SREM , MVT::i64, Custom); 98 setOperationAction(ISD::UREM , MVT::i64, Custom); 99 setOperationAction(ISD::SDIV , MVT::i64, Custom); 100 setOperationAction(ISD::UDIV , MVT::i64, Custom); 101 102 setOperationAction(ISD::ADDC , MVT::i64, Expand); 103 setOperationAction(ISD::ADDE , MVT::i64, Expand); 104 setOperationAction(ISD::SUBC , MVT::i64, Expand); 105 setOperationAction(ISD::SUBE , MVT::i64, Expand); 106 107 setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand); 108 setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand); 109 110 setOperationAction(ISD::SRL_PARTS, MVT::i64, Custom); 111 setOperationAction(ISD::SRA_PARTS, MVT::i64, Expand); 112 setOperationAction(ISD::SHL_PARTS, MVT::i64, Expand); 113 114 // We don't support sin/cos/sqrt/pow 115 setOperationAction(ISD::FSIN , MVT::f64, Expand); 116 setOperationAction(ISD::FCOS , MVT::f64, Expand); 117 setOperationAction(ISD::FSIN , MVT::f32, Expand); 118 setOperationAction(ISD::FCOS , MVT::f32, Expand); 119 120 setOperationAction(ISD::FSQRT, MVT::f64, Expand); 121 setOperationAction(ISD::FSQRT, MVT::f32, Expand); 122 123 setOperationAction(ISD::FPOW , MVT::f32, Expand); 124 setOperationAction(ISD::FPOW , MVT::f64, Expand); 125 126 setOperationAction(ISD::FMA, MVT::f64, Expand); 127 setOperationAction(ISD::FMA, MVT::f32, Expand); 128 129 setOperationAction(ISD::SETCC, MVT::f32, Promote); 130 131 setOperationAction(ISD::BITCAST, MVT::f32, Promote); 132 133 setOperationAction(ISD::EH_LABEL, MVT::Other, Expand); 134 135 // Not implemented yet. 136 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); 137 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); 138 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand); 139 140 // We want to legalize GlobalAddress and ConstantPool and 141 // ExternalSymbols nodes into the appropriate instructions to 142 // materialize the address. 143 setOperationAction(ISD::GlobalAddress, MVT::i64, Custom); 144 setOperationAction(ISD::ConstantPool, MVT::i64, Custom); 145 setOperationAction(ISD::ExternalSymbol, MVT::i64, Custom); 146 setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom); 147 148 setOperationAction(ISD::VASTART, MVT::Other, Custom); 149 setOperationAction(ISD::VAEND, MVT::Other, Expand); 150 setOperationAction(ISD::VACOPY, MVT::Other, Custom); 151 setOperationAction(ISD::VAARG, MVT::Other, Custom); 152 setOperationAction(ISD::VAARG, MVT::i32, Custom); 153 154 setOperationAction(ISD::JumpTable, MVT::i64, Custom); 155 setOperationAction(ISD::JumpTable, MVT::i32, Custom); 156 157 setOperationAction(ISD::ATOMIC_LOAD, MVT::i32, Expand); 158 setOperationAction(ISD::ATOMIC_STORE, MVT::i32, Expand); 159 160 setStackPointerRegisterToSaveRestore(Alpha::R30); 161 162 setJumpBufSize(272); 163 setJumpBufAlignment(16); 164 165 setMinFunctionAlignment(4); 166 167 setInsertFencesForAtomic(true); 168 169 computeRegisterProperties(); 170 } 171 172 EVT AlphaTargetLowering::getSetCCResultType(EVT VT) const { 173 return MVT::i64; 174 } 175 176 const char *AlphaTargetLowering::getTargetNodeName(unsigned Opcode) const { 177 switch (Opcode) { 178 default: return 0; 179 case AlphaISD::CVTQT_: return "Alpha::CVTQT_"; 180 case AlphaISD::CVTQS_: return "Alpha::CVTQS_"; 181 case AlphaISD::CVTTQ_: return "Alpha::CVTTQ_"; 182 case AlphaISD::GPRelHi: return "Alpha::GPRelHi"; 183 case AlphaISD::GPRelLo: return "Alpha::GPRelLo"; 184 case AlphaISD::RelLit: return "Alpha::RelLit"; 185 case AlphaISD::GlobalRetAddr: return "Alpha::GlobalRetAddr"; 186 case AlphaISD::CALL: return "Alpha::CALL"; 187 case AlphaISD::DivCall: return "Alpha::DivCall"; 188 case AlphaISD::RET_FLAG: return "Alpha::RET_FLAG"; 189 case AlphaISD::COND_BRANCH_I: return "Alpha::COND_BRANCH_I"; 190 case AlphaISD::COND_BRANCH_F: return "Alpha::COND_BRANCH_F"; 191 } 192 } 193 194 static SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) { 195 EVT PtrVT = Op.getValueType(); 196 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op); 197 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT); 198 // FIXME there isn't really any debug info here 199 DebugLoc dl = Op.getDebugLoc(); 200 201 SDValue Hi = DAG.getNode(AlphaISD::GPRelHi, dl, MVT::i64, JTI, 202 DAG.getGLOBAL_OFFSET_TABLE(MVT::i64)); 203 SDValue Lo = DAG.getNode(AlphaISD::GPRelLo, dl, MVT::i64, JTI, Hi); 204 return Lo; 205 } 206 207 //http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/ 208 //AA-PY8AC-TET1_html/callCH3.html#BLOCK21 209 210 //For now, just use variable size stack frame format 211 212 //In a standard call, the first six items are passed in registers $16 213 //- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details 214 //of argument-to-register correspondence.) The remaining items are 215 //collected in a memory argument list that is a naturally aligned 216 //array of quadwords. In a standard call, this list, if present, must 217 //be passed at 0(SP). 218 //7 ... n 0(SP) ... (n-7)*8(SP) 219 220 // //#define FP $15 221 // //#define RA $26 222 // //#define PV $27 223 // //#define GP $29 224 // //#define SP $30 225 226 #include "AlphaGenCallingConv.inc" 227 228 SDValue 229 AlphaTargetLowering::LowerCall(SDValue Chain, SDValue Callee, 230 CallingConv::ID CallConv, bool isVarArg, 231 bool &isTailCall, 232 const SmallVectorImpl<ISD::OutputArg> &Outs, 233 const SmallVectorImpl<SDValue> &OutVals, 234 const SmallVectorImpl<ISD::InputArg> &Ins, 235 DebugLoc dl, SelectionDAG &DAG, 236 SmallVectorImpl<SDValue> &InVals) const { 237 // Alpha target does not yet support tail call optimization. 238 isTailCall = false; 239 240 // Analyze operands of the call, assigning locations to each operand. 241 SmallVector<CCValAssign, 16> ArgLocs; 242 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 243 getTargetMachine(), ArgLocs, *DAG.getContext()); 244 245 CCInfo.AnalyzeCallOperands(Outs, CC_Alpha); 246 247 // Get a count of how many bytes are to be pushed on the stack. 248 unsigned NumBytes = CCInfo.getNextStackOffset(); 249 250 Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(NumBytes, 251 getPointerTy(), true)); 252 253 SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; 254 SmallVector<SDValue, 12> MemOpChains; 255 SDValue StackPtr; 256 257 // Walk the register/memloc assignments, inserting copies/loads. 258 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 259 CCValAssign &VA = ArgLocs[i]; 260 261 SDValue Arg = OutVals[i]; 262 263 // Promote the value if needed. 264 switch (VA.getLocInfo()) { 265 default: assert(0 && "Unknown loc info!"); 266 case CCValAssign::Full: break; 267 case CCValAssign::SExt: 268 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 269 break; 270 case CCValAssign::ZExt: 271 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 272 break; 273 case CCValAssign::AExt: 274 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 275 break; 276 } 277 278 // Arguments that can be passed on register must be kept at RegsToPass 279 // vector 280 if (VA.isRegLoc()) { 281 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 282 } else { 283 assert(VA.isMemLoc()); 284 285 if (StackPtr.getNode() == 0) 286 StackPtr = DAG.getCopyFromReg(Chain, dl, Alpha::R30, MVT::i64); 287 288 SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), 289 StackPtr, 290 DAG.getIntPtrConstant(VA.getLocMemOffset())); 291 292 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, 293 MachinePointerInfo(),false, false, 0)); 294 } 295 } 296 297 // Transform all store nodes into one single node because all store nodes are 298 // independent of each other. 299 if (!MemOpChains.empty()) 300 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 301 &MemOpChains[0], MemOpChains.size()); 302 303 // Build a sequence of copy-to-reg nodes chained together with token chain and 304 // flag operands which copy the outgoing args into registers. The InFlag in 305 // necessary since all emitted instructions must be stuck together. 306 SDValue InFlag; 307 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 308 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 309 RegsToPass[i].second, InFlag); 310 InFlag = Chain.getValue(1); 311 } 312 313 // Returns a chain & a flag for retval copy to use. 314 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 315 SmallVector<SDValue, 8> Ops; 316 Ops.push_back(Chain); 317 Ops.push_back(Callee); 318 319 // Add argument registers to the end of the list so that they are 320 // known live into the call. 321 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 322 Ops.push_back(DAG.getRegister(RegsToPass[i].first, 323 RegsToPass[i].second.getValueType())); 324 325 if (InFlag.getNode()) 326 Ops.push_back(InFlag); 327 328 Chain = DAG.getNode(AlphaISD::CALL, dl, NodeTys, &Ops[0], Ops.size()); 329 InFlag = Chain.getValue(1); 330 331 // Create the CALLSEQ_END node. 332 Chain = DAG.getCALLSEQ_END(Chain, 333 DAG.getConstant(NumBytes, getPointerTy(), true), 334 DAG.getConstant(0, getPointerTy(), true), 335 InFlag); 336 InFlag = Chain.getValue(1); 337 338 // Handle result values, copying them out of physregs into vregs that we 339 // return. 340 return LowerCallResult(Chain, InFlag, CallConv, isVarArg, 341 Ins, dl, DAG, InVals); 342 } 343 344 /// LowerCallResult - Lower the result values of a call into the 345 /// appropriate copies out of appropriate physical registers. 346 /// 347 SDValue 348 AlphaTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, 349 CallingConv::ID CallConv, bool isVarArg, 350 const SmallVectorImpl<ISD::InputArg> &Ins, 351 DebugLoc dl, SelectionDAG &DAG, 352 SmallVectorImpl<SDValue> &InVals) const { 353 354 // Assign locations to each value returned by this call. 355 SmallVector<CCValAssign, 16> RVLocs; 356 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 357 getTargetMachine(), RVLocs, *DAG.getContext()); 358 359 CCInfo.AnalyzeCallResult(Ins, RetCC_Alpha); 360 361 // Copy all of the result registers out of their specified physreg. 362 for (unsigned i = 0; i != RVLocs.size(); ++i) { 363 CCValAssign &VA = RVLocs[i]; 364 365 Chain = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), 366 VA.getLocVT(), InFlag).getValue(1); 367 SDValue RetValue = Chain.getValue(0); 368 InFlag = Chain.getValue(2); 369 370 // If this is an 8/16/32-bit value, it is really passed promoted to 64 371 // bits. Insert an assert[sz]ext to capture this, then truncate to the 372 // right size. 373 if (VA.getLocInfo() == CCValAssign::SExt) 374 RetValue = DAG.getNode(ISD::AssertSext, dl, VA.getLocVT(), RetValue, 375 DAG.getValueType(VA.getValVT())); 376 else if (VA.getLocInfo() == CCValAssign::ZExt) 377 RetValue = DAG.getNode(ISD::AssertZext, dl, VA.getLocVT(), RetValue, 378 DAG.getValueType(VA.getValVT())); 379 380 if (VA.getLocInfo() != CCValAssign::Full) 381 RetValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), RetValue); 382 383 InVals.push_back(RetValue); 384 } 385 386 return Chain; 387 } 388 389 SDValue 390 AlphaTargetLowering::LowerFormalArguments(SDValue Chain, 391 CallingConv::ID CallConv, bool isVarArg, 392 const SmallVectorImpl<ISD::InputArg> 393 &Ins, 394 DebugLoc dl, SelectionDAG &DAG, 395 SmallVectorImpl<SDValue> &InVals) 396 const { 397 398 MachineFunction &MF = DAG.getMachineFunction(); 399 MachineFrameInfo *MFI = MF.getFrameInfo(); 400 AlphaMachineFunctionInfo *FuncInfo = MF.getInfo<AlphaMachineFunctionInfo>(); 401 402 unsigned args_int[] = { 403 Alpha::R16, Alpha::R17, Alpha::R18, Alpha::R19, Alpha::R20, Alpha::R21}; 404 unsigned args_float[] = { 405 Alpha::F16, Alpha::F17, Alpha::F18, Alpha::F19, Alpha::F20, Alpha::F21}; 406 407 for (unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) { 408 SDValue argt; 409 EVT ObjectVT = Ins[ArgNo].VT; 410 SDValue ArgVal; 411 412 if (ArgNo < 6) { 413 switch (ObjectVT.getSimpleVT().SimpleTy) { 414 default: 415 assert(false && "Invalid value type!"); 416 case MVT::f64: 417 args_float[ArgNo] = AddLiveIn(MF, args_float[ArgNo], 418 &Alpha::F8RCRegClass); 419 ArgVal = DAG.getCopyFromReg(Chain, dl, args_float[ArgNo], ObjectVT); 420 break; 421 case MVT::f32: 422 args_float[ArgNo] = AddLiveIn(MF, args_float[ArgNo], 423 &Alpha::F4RCRegClass); 424 ArgVal = DAG.getCopyFromReg(Chain, dl, args_float[ArgNo], ObjectVT); 425 break; 426 case MVT::i64: 427 args_int[ArgNo] = AddLiveIn(MF, args_int[ArgNo], 428 &Alpha::GPRCRegClass); 429 ArgVal = DAG.getCopyFromReg(Chain, dl, args_int[ArgNo], MVT::i64); 430 break; 431 } 432 } else { //more args 433 // Create the frame index object for this incoming parameter... 434 int FI = MFI->CreateFixedObject(8, 8 * (ArgNo - 6), true); 435 436 // Create the SelectionDAG nodes corresponding to a load 437 //from this parameter 438 SDValue FIN = DAG.getFrameIndex(FI, MVT::i64); 439 ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo(), 440 false, false, 0); 441 } 442 InVals.push_back(ArgVal); 443 } 444 445 // If the functions takes variable number of arguments, copy all regs to stack 446 if (isVarArg) { 447 FuncInfo->setVarArgsOffset(Ins.size() * 8); 448 std::vector<SDValue> LS; 449 for (int i = 0; i < 6; ++i) { 450 if (TargetRegisterInfo::isPhysicalRegister(args_int[i])) 451 args_int[i] = AddLiveIn(MF, args_int[i], &Alpha::GPRCRegClass); 452 SDValue argt = DAG.getCopyFromReg(Chain, dl, args_int[i], MVT::i64); 453 int FI = MFI->CreateFixedObject(8, -8 * (6 - i), true); 454 if (i == 0) FuncInfo->setVarArgsBase(FI); 455 SDValue SDFI = DAG.getFrameIndex(FI, MVT::i64); 456 LS.push_back(DAG.getStore(Chain, dl, argt, SDFI, MachinePointerInfo(), 457 false, false, 0)); 458 459 if (TargetRegisterInfo::isPhysicalRegister(args_float[i])) 460 args_float[i] = AddLiveIn(MF, args_float[i], &Alpha::F8RCRegClass); 461 argt = DAG.getCopyFromReg(Chain, dl, args_float[i], MVT::f64); 462 FI = MFI->CreateFixedObject(8, - 8 * (12 - i), true); 463 SDFI = DAG.getFrameIndex(FI, MVT::i64); 464 LS.push_back(DAG.getStore(Chain, dl, argt, SDFI, MachinePointerInfo(), 465 false, false, 0)); 466 } 467 468 //Set up a token factor with all the stack traffic 469 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &LS[0], LS.size()); 470 } 471 472 return Chain; 473 } 474 475 SDValue 476 AlphaTargetLowering::LowerReturn(SDValue Chain, 477 CallingConv::ID CallConv, bool isVarArg, 478 const SmallVectorImpl<ISD::OutputArg> &Outs, 479 const SmallVectorImpl<SDValue> &OutVals, 480 DebugLoc dl, SelectionDAG &DAG) const { 481 482 SDValue Copy = DAG.getCopyToReg(Chain, dl, Alpha::R26, 483 DAG.getNode(AlphaISD::GlobalRetAddr, 484 DebugLoc(), MVT::i64), 485 SDValue()); 486 switch (Outs.size()) { 487 default: 488 llvm_unreachable("Do not know how to return this many arguments!"); 489 case 0: 490 break; 491 //return SDValue(); // ret void is legal 492 case 1: { 493 EVT ArgVT = Outs[0].VT; 494 unsigned ArgReg; 495 if (ArgVT.isInteger()) 496 ArgReg = Alpha::R0; 497 else { 498 assert(ArgVT.isFloatingPoint()); 499 ArgReg = Alpha::F0; 500 } 501 Copy = DAG.getCopyToReg(Copy, dl, ArgReg, 502 OutVals[0], Copy.getValue(1)); 503 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) 504 DAG.getMachineFunction().getRegInfo().addLiveOut(ArgReg); 505 break; 506 } 507 case 2: { 508 EVT ArgVT = Outs[0].VT; 509 unsigned ArgReg1, ArgReg2; 510 if (ArgVT.isInteger()) { 511 ArgReg1 = Alpha::R0; 512 ArgReg2 = Alpha::R1; 513 } else { 514 assert(ArgVT.isFloatingPoint()); 515 ArgReg1 = Alpha::F0; 516 ArgReg2 = Alpha::F1; 517 } 518 Copy = DAG.getCopyToReg(Copy, dl, ArgReg1, 519 OutVals[0], Copy.getValue(1)); 520 if (std::find(DAG.getMachineFunction().getRegInfo().liveout_begin(), 521 DAG.getMachineFunction().getRegInfo().liveout_end(), ArgReg1) 522 == DAG.getMachineFunction().getRegInfo().liveout_end()) 523 DAG.getMachineFunction().getRegInfo().addLiveOut(ArgReg1); 524 Copy = DAG.getCopyToReg(Copy, dl, ArgReg2, 525 OutVals[1], Copy.getValue(1)); 526 if (std::find(DAG.getMachineFunction().getRegInfo().liveout_begin(), 527 DAG.getMachineFunction().getRegInfo().liveout_end(), ArgReg2) 528 == DAG.getMachineFunction().getRegInfo().liveout_end()) 529 DAG.getMachineFunction().getRegInfo().addLiveOut(ArgReg2); 530 break; 531 } 532 } 533 return DAG.getNode(AlphaISD::RET_FLAG, dl, 534 MVT::Other, Copy, Copy.getValue(1)); 535 } 536 537 void AlphaTargetLowering::LowerVAARG(SDNode *N, SDValue &Chain, 538 SDValue &DataPtr, 539 SelectionDAG &DAG) const { 540 Chain = N->getOperand(0); 541 SDValue VAListP = N->getOperand(1); 542 const Value *VAListS = cast<SrcValueSDNode>(N->getOperand(2))->getValue(); 543 DebugLoc dl = N->getDebugLoc(); 544 545 SDValue Base = DAG.getLoad(MVT::i64, dl, Chain, VAListP, 546 MachinePointerInfo(VAListS), 547 false, false, 0); 548 SDValue Tmp = DAG.getNode(ISD::ADD, dl, MVT::i64, VAListP, 549 DAG.getConstant(8, MVT::i64)); 550 SDValue Offset = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Base.getValue(1), 551 Tmp, MachinePointerInfo(), 552 MVT::i32, false, false, 0); 553 DataPtr = DAG.getNode(ISD::ADD, dl, MVT::i64, Base, Offset); 554 if (N->getValueType(0).isFloatingPoint()) 555 { 556 //if fp && Offset < 6*8, then subtract 6*8 from DataPtr 557 SDValue FPDataPtr = DAG.getNode(ISD::SUB, dl, MVT::i64, DataPtr, 558 DAG.getConstant(8*6, MVT::i64)); 559 SDValue CC = DAG.getSetCC(dl, MVT::i64, Offset, 560 DAG.getConstant(8*6, MVT::i64), ISD::SETLT); 561 DataPtr = DAG.getNode(ISD::SELECT, dl, MVT::i64, CC, FPDataPtr, DataPtr); 562 } 563 564 SDValue NewOffset = DAG.getNode(ISD::ADD, dl, MVT::i64, Offset, 565 DAG.getConstant(8, MVT::i64)); 566 Chain = DAG.getTruncStore(Offset.getValue(1), dl, NewOffset, Tmp, 567 MachinePointerInfo(), 568 MVT::i32, false, false, 0); 569 } 570 571 /// LowerOperation - Provide custom lowering hooks for some operations. 572 /// 573 SDValue AlphaTargetLowering::LowerOperation(SDValue Op, 574 SelectionDAG &DAG) const { 575 DebugLoc dl = Op.getDebugLoc(); 576 switch (Op.getOpcode()) { 577 default: llvm_unreachable("Wasn't expecting to be able to lower this!"); 578 case ISD::JumpTable: return LowerJumpTable(Op, DAG); 579 580 case ISD::INTRINSIC_WO_CHAIN: { 581 unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 582 switch (IntNo) { 583 default: break; // Don't custom lower most intrinsics. 584 case Intrinsic::alpha_umulh: 585 return DAG.getNode(ISD::MULHU, dl, MVT::i64, 586 Op.getOperand(1), Op.getOperand(2)); 587 } 588 } 589 590 case ISD::SRL_PARTS: { 591 SDValue ShOpLo = Op.getOperand(0); 592 SDValue ShOpHi = Op.getOperand(1); 593 SDValue ShAmt = Op.getOperand(2); 594 SDValue bm = DAG.getNode(ISD::SUB, dl, MVT::i64, 595 DAG.getConstant(64, MVT::i64), ShAmt); 596 SDValue BMCC = DAG.getSetCC(dl, MVT::i64, bm, 597 DAG.getConstant(0, MVT::i64), ISD::SETLE); 598 // if 64 - shAmt <= 0 599 SDValue Hi_Neg = DAG.getConstant(0, MVT::i64); 600 SDValue ShAmt_Neg = DAG.getNode(ISD::SUB, dl, MVT::i64, 601 DAG.getConstant(0, MVT::i64), bm); 602 SDValue Lo_Neg = DAG.getNode(ISD::SRL, dl, MVT::i64, ShOpHi, ShAmt_Neg); 603 // else 604 SDValue carries = DAG.getNode(ISD::SHL, dl, MVT::i64, ShOpHi, bm); 605 SDValue Hi_Pos = DAG.getNode(ISD::SRL, dl, MVT::i64, ShOpHi, ShAmt); 606 SDValue Lo_Pos = DAG.getNode(ISD::SRL, dl, MVT::i64, ShOpLo, ShAmt); 607 Lo_Pos = DAG.getNode(ISD::OR, dl, MVT::i64, Lo_Pos, carries); 608 // Merge 609 SDValue Hi = DAG.getNode(ISD::SELECT, dl, MVT::i64, BMCC, Hi_Neg, Hi_Pos); 610 SDValue Lo = DAG.getNode(ISD::SELECT, dl, MVT::i64, BMCC, Lo_Neg, Lo_Pos); 611 SDValue Ops[2] = { Lo, Hi }; 612 return DAG.getMergeValues(Ops, 2, dl); 613 } 614 // case ISD::SRA_PARTS: 615 616 // case ISD::SHL_PARTS: 617 618 619 case ISD::SINT_TO_FP: { 620 assert(Op.getOperand(0).getValueType() == MVT::i64 && 621 "Unhandled SINT_TO_FP type in custom expander!"); 622 SDValue LD; 623 bool isDouble = Op.getValueType() == MVT::f64; 624 LD = DAG.getNode(ISD::BITCAST, dl, MVT::f64, Op.getOperand(0)); 625 SDValue FP = DAG.getNode(isDouble?AlphaISD::CVTQT_:AlphaISD::CVTQS_, dl, 626 isDouble?MVT::f64:MVT::f32, LD); 627 return FP; 628 } 629 case ISD::FP_TO_SINT: { 630 bool isDouble = Op.getOperand(0).getValueType() == MVT::f64; 631 SDValue src = Op.getOperand(0); 632 633 if (!isDouble) //Promote 634 src = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, src); 635 636 src = DAG.getNode(AlphaISD::CVTTQ_, dl, MVT::f64, src); 637 638 return DAG.getNode(ISD::BITCAST, dl, MVT::i64, src); 639 } 640 case ISD::ConstantPool: { 641 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op); 642 const Constant *C = CP->getConstVal(); 643 SDValue CPI = DAG.getTargetConstantPool(C, MVT::i64, CP->getAlignment()); 644 // FIXME there isn't really any debug info here 645 646 SDValue Hi = DAG.getNode(AlphaISD::GPRelHi, dl, MVT::i64, CPI, 647 DAG.getGLOBAL_OFFSET_TABLE(MVT::i64)); 648 SDValue Lo = DAG.getNode(AlphaISD::GPRelLo, dl, MVT::i64, CPI, Hi); 649 return Lo; 650 } 651 case ISD::GlobalTLSAddress: 652 llvm_unreachable("TLS not implemented for Alpha."); 653 case ISD::GlobalAddress: { 654 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op); 655 const GlobalValue *GV = GSDN->getGlobal(); 656 SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i64, 657 GSDN->getOffset()); 658 // FIXME there isn't really any debug info here 659 660 // if (!GV->hasWeakLinkage() && !GV->isDeclaration() 661 // && !GV->hasLinkOnceLinkage()) { 662 if (GV->hasLocalLinkage()) { 663 SDValue Hi = DAG.getNode(AlphaISD::GPRelHi, dl, MVT::i64, GA, 664 DAG.getGLOBAL_OFFSET_TABLE(MVT::i64)); 665 SDValue Lo = DAG.getNode(AlphaISD::GPRelLo, dl, MVT::i64, GA, Hi); 666 return Lo; 667 } else 668 return DAG.getNode(AlphaISD::RelLit, dl, MVT::i64, GA, 669 DAG.getGLOBAL_OFFSET_TABLE(MVT::i64)); 670 } 671 case ISD::ExternalSymbol: { 672 return DAG.getNode(AlphaISD::RelLit, dl, MVT::i64, 673 DAG.getTargetExternalSymbol(cast<ExternalSymbolSDNode>(Op) 674 ->getSymbol(), MVT::i64), 675 DAG.getGLOBAL_OFFSET_TABLE(MVT::i64)); 676 } 677 678 case ISD::UREM: 679 case ISD::SREM: 680 //Expand only on constant case 681 if (Op.getOperand(1).getOpcode() == ISD::Constant) { 682 EVT VT = Op.getNode()->getValueType(0); 683 SDValue Tmp1 = Op.getNode()->getOpcode() == ISD::UREM ? 684 BuildUDIV(Op.getNode(), DAG, NULL) : 685 BuildSDIV(Op.getNode(), DAG, NULL); 686 Tmp1 = DAG.getNode(ISD::MUL, dl, VT, Tmp1, Op.getOperand(1)); 687 Tmp1 = DAG.getNode(ISD::SUB, dl, VT, Op.getOperand(0), Tmp1); 688 return Tmp1; 689 } 690 //fall through 691 case ISD::SDIV: 692 case ISD::UDIV: 693 if (Op.getValueType().isInteger()) { 694 if (Op.getOperand(1).getOpcode() == ISD::Constant) 695 return Op.getOpcode() == ISD::SDIV ? BuildSDIV(Op.getNode(), DAG, NULL) 696 : BuildUDIV(Op.getNode(), DAG, NULL); 697 const char* opstr = 0; 698 switch (Op.getOpcode()) { 699 case ISD::UREM: opstr = "__remqu"; break; 700 case ISD::SREM: opstr = "__remq"; break; 701 case ISD::UDIV: opstr = "__divqu"; break; 702 case ISD::SDIV: opstr = "__divq"; break; 703 } 704 SDValue Tmp1 = Op.getOperand(0), 705 Tmp2 = Op.getOperand(1), 706 Addr = DAG.getExternalSymbol(opstr, MVT::i64); 707 return DAG.getNode(AlphaISD::DivCall, dl, MVT::i64, Addr, Tmp1, Tmp2); 708 } 709 break; 710 711 case ISD::VAARG: { 712 SDValue Chain, DataPtr; 713 LowerVAARG(Op.getNode(), Chain, DataPtr, DAG); 714 715 SDValue Result; 716 if (Op.getValueType() == MVT::i32) 717 Result = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Chain, DataPtr, 718 MachinePointerInfo(), MVT::i32, false, false, 0); 719 else 720 Result = DAG.getLoad(Op.getValueType(), dl, Chain, DataPtr, 721 MachinePointerInfo(), 722 false, false, 0); 723 return Result; 724 } 725 case ISD::VACOPY: { 726 SDValue Chain = Op.getOperand(0); 727 SDValue DestP = Op.getOperand(1); 728 SDValue SrcP = Op.getOperand(2); 729 const Value *DestS = cast<SrcValueSDNode>(Op.getOperand(3))->getValue(); 730 const Value *SrcS = cast<SrcValueSDNode>(Op.getOperand(4))->getValue(); 731 732 SDValue Val = DAG.getLoad(getPointerTy(), dl, Chain, SrcP, 733 MachinePointerInfo(SrcS), 734 false, false, 0); 735 SDValue Result = DAG.getStore(Val.getValue(1), dl, Val, DestP, 736 MachinePointerInfo(DestS), 737 false, false, 0); 738 SDValue NP = DAG.getNode(ISD::ADD, dl, MVT::i64, SrcP, 739 DAG.getConstant(8, MVT::i64)); 740 Val = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Result, 741 NP, MachinePointerInfo(), MVT::i32, false, false, 0); 742 SDValue NPD = DAG.getNode(ISD::ADD, dl, MVT::i64, DestP, 743 DAG.getConstant(8, MVT::i64)); 744 return DAG.getTruncStore(Val.getValue(1), dl, Val, NPD, 745 MachinePointerInfo(), MVT::i32, 746 false, false, 0); 747 } 748 case ISD::VASTART: { 749 MachineFunction &MF = DAG.getMachineFunction(); 750 AlphaMachineFunctionInfo *FuncInfo = MF.getInfo<AlphaMachineFunctionInfo>(); 751 752 SDValue Chain = Op.getOperand(0); 753 SDValue VAListP = Op.getOperand(1); 754 const Value *VAListS = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); 755 756 // vastart stores the address of the VarArgsBase and VarArgsOffset 757 SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsBase(), MVT::i64); 758 SDValue S1 = DAG.getStore(Chain, dl, FR, VAListP, 759 MachinePointerInfo(VAListS), false, false, 0); 760 SDValue SA2 = DAG.getNode(ISD::ADD, dl, MVT::i64, VAListP, 761 DAG.getConstant(8, MVT::i64)); 762 return DAG.getTruncStore(S1, dl, 763 DAG.getConstant(FuncInfo->getVarArgsOffset(), 764 MVT::i64), 765 SA2, MachinePointerInfo(), 766 MVT::i32, false, false, 0); 767 } 768 case ISD::RETURNADDR: 769 return DAG.getNode(AlphaISD::GlobalRetAddr, DebugLoc(), MVT::i64); 770 //FIXME: implement 771 case ISD::FRAMEADDR: break; 772 } 773 774 return SDValue(); 775 } 776 777 void AlphaTargetLowering::ReplaceNodeResults(SDNode *N, 778 SmallVectorImpl<SDValue>&Results, 779 SelectionDAG &DAG) const { 780 DebugLoc dl = N->getDebugLoc(); 781 assert(N->getValueType(0) == MVT::i32 && 782 N->getOpcode() == ISD::VAARG && 783 "Unknown node to custom promote!"); 784 785 SDValue Chain, DataPtr; 786 LowerVAARG(N, Chain, DataPtr, DAG); 787 SDValue Res = DAG.getLoad(N->getValueType(0), dl, Chain, DataPtr, 788 MachinePointerInfo(), 789 false, false, 0); 790 Results.push_back(Res); 791 Results.push_back(SDValue(Res.getNode(), 1)); 792 } 793 794 795 //Inline Asm 796 797 /// getConstraintType - Given a constraint letter, return the type of 798 /// constraint it is for this target. 799 AlphaTargetLowering::ConstraintType 800 AlphaTargetLowering::getConstraintType(const std::string &Constraint) const { 801 if (Constraint.size() == 1) { 802 switch (Constraint[0]) { 803 default: break; 804 case 'f': 805 case 'r': 806 return C_RegisterClass; 807 } 808 } 809 return TargetLowering::getConstraintType(Constraint); 810 } 811 812 /// Examine constraint type and operand type and determine a weight value. 813 /// This object must already have been set up with the operand type 814 /// and the current alternative constraint selected. 815 TargetLowering::ConstraintWeight 816 AlphaTargetLowering::getSingleConstraintMatchWeight( 817 AsmOperandInfo &info, const char *constraint) const { 818 ConstraintWeight weight = CW_Invalid; 819 Value *CallOperandVal = info.CallOperandVal; 820 // If we don't have a value, we can't do a match, 821 // but allow it at the lowest weight. 822 if (CallOperandVal == NULL) 823 return CW_Default; 824 // Look at the constraint type. 825 switch (*constraint) { 826 default: 827 weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint); 828 break; 829 case 'f': 830 weight = CW_Register; 831 break; 832 } 833 return weight; 834 } 835 836 /// Given a register class constraint, like 'r', if this corresponds directly 837 /// to an LLVM register class, return a register of 0 and the register class 838 /// pointer. 839 std::pair<unsigned, const TargetRegisterClass*> AlphaTargetLowering:: 840 getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const 841 { 842 if (Constraint.size() == 1) { 843 switch (Constraint[0]) { 844 case 'r': 845 return std::make_pair(0U, Alpha::GPRCRegisterClass); 846 case 'f': 847 return VT == MVT::f64 ? std::make_pair(0U, Alpha::F8RCRegisterClass) : 848 std::make_pair(0U, Alpha::F4RCRegisterClass); 849 } 850 } 851 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); 852 } 853 854 //===----------------------------------------------------------------------===// 855 // Other Lowering Code 856 //===----------------------------------------------------------------------===// 857 858 MachineBasicBlock * 859 AlphaTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 860 MachineBasicBlock *BB) const { 861 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); 862 assert((MI->getOpcode() == Alpha::CAS32 || 863 MI->getOpcode() == Alpha::CAS64 || 864 MI->getOpcode() == Alpha::LAS32 || 865 MI->getOpcode() == Alpha::LAS64 || 866 MI->getOpcode() == Alpha::SWAP32 || 867 MI->getOpcode() == Alpha::SWAP64) && 868 "Unexpected instr type to insert"); 869 870 bool is32 = MI->getOpcode() == Alpha::CAS32 || 871 MI->getOpcode() == Alpha::LAS32 || 872 MI->getOpcode() == Alpha::SWAP32; 873 874 //Load locked store conditional for atomic ops take on the same form 875 //start: 876 //ll 877 //do stuff (maybe branch to exit) 878 //sc 879 //test sc and maybe branck to start 880 //exit: 881 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 882 DebugLoc dl = MI->getDebugLoc(); 883 MachineFunction::iterator It = BB; 884 ++It; 885 886 MachineBasicBlock *thisMBB = BB; 887 MachineFunction *F = BB->getParent(); 888 MachineBasicBlock *llscMBB = F->CreateMachineBasicBlock(LLVM_BB); 889 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); 890 891 sinkMBB->splice(sinkMBB->begin(), thisMBB, 892 llvm::next(MachineBasicBlock::iterator(MI)), 893 thisMBB->end()); 894 sinkMBB->transferSuccessorsAndUpdatePHIs(thisMBB); 895 896 F->insert(It, llscMBB); 897 F->insert(It, sinkMBB); 898 899 BuildMI(thisMBB, dl, TII->get(Alpha::BR)).addMBB(llscMBB); 900 901 unsigned reg_res = MI->getOperand(0).getReg(), 902 reg_ptr = MI->getOperand(1).getReg(), 903 reg_v2 = MI->getOperand(2).getReg(), 904 reg_store = F->getRegInfo().createVirtualRegister(&Alpha::GPRCRegClass); 905 906 BuildMI(llscMBB, dl, TII->get(is32 ? Alpha::LDL_L : Alpha::LDQ_L), 907 reg_res).addImm(0).addReg(reg_ptr); 908 switch (MI->getOpcode()) { 909 case Alpha::CAS32: 910 case Alpha::CAS64: { 911 unsigned reg_cmp 912 = F->getRegInfo().createVirtualRegister(&Alpha::GPRCRegClass); 913 BuildMI(llscMBB, dl, TII->get(Alpha::CMPEQ), reg_cmp) 914 .addReg(reg_v2).addReg(reg_res); 915 BuildMI(llscMBB, dl, TII->get(Alpha::BEQ)) 916 .addImm(0).addReg(reg_cmp).addMBB(sinkMBB); 917 BuildMI(llscMBB, dl, TII->get(Alpha::BISr), reg_store) 918 .addReg(Alpha::R31).addReg(MI->getOperand(3).getReg()); 919 break; 920 } 921 case Alpha::LAS32: 922 case Alpha::LAS64: { 923 BuildMI(llscMBB, dl,TII->get(is32 ? Alpha::ADDLr : Alpha::ADDQr), reg_store) 924 .addReg(reg_res).addReg(reg_v2); 925 break; 926 } 927 case Alpha::SWAP32: 928 case Alpha::SWAP64: { 929 BuildMI(llscMBB, dl, TII->get(Alpha::BISr), reg_store) 930 .addReg(reg_v2).addReg(reg_v2); 931 break; 932 } 933 } 934 BuildMI(llscMBB, dl, TII->get(is32 ? Alpha::STL_C : Alpha::STQ_C), reg_store) 935 .addReg(reg_store).addImm(0).addReg(reg_ptr); 936 BuildMI(llscMBB, dl, TII->get(Alpha::BEQ)) 937 .addImm(0).addReg(reg_store).addMBB(llscMBB); 938 BuildMI(llscMBB, dl, TII->get(Alpha::BR)).addMBB(sinkMBB); 939 940 thisMBB->addSuccessor(llscMBB); 941 llscMBB->addSuccessor(llscMBB); 942 llscMBB->addSuccessor(sinkMBB); 943 MI->eraseFromParent(); // The pseudo instruction is gone now. 944 945 return sinkMBB; 946 } 947 948 bool 949 AlphaTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const { 950 // The Alpha target isn't yet aware of offsets. 951 return false; 952 } 953 954 bool AlphaTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const { 955 if (VT != MVT::f32 && VT != MVT::f64) 956 return false; 957 // +0.0 F31 958 // +0.0f F31 959 // -0.0 -F31 960 // -0.0f -F31 961 return Imm.isZero() || Imm.isNegZero(); 962 } 963