1 //===-- VEISelLowering.cpp - VE DAG Lowering Implementation ---------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements the interfaces that VE uses to lower LLVM code into a 10 // selection DAG. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "VEISelLowering.h" 15 #include "MCTargetDesc/VEMCExpr.h" 16 #include "VEMachineFunctionInfo.h" 17 #include "VERegisterInfo.h" 18 #include "VETargetMachine.h" 19 #include "llvm/ADT/StringSwitch.h" 20 #include "llvm/CodeGen/CallingConvLower.h" 21 #include "llvm/CodeGen/MachineFrameInfo.h" 22 #include "llvm/CodeGen/MachineFunction.h" 23 #include "llvm/CodeGen/MachineInstrBuilder.h" 24 #include "llvm/CodeGen/MachineModuleInfo.h" 25 #include "llvm/CodeGen/MachineRegisterInfo.h" 26 #include "llvm/CodeGen/SelectionDAG.h" 27 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 28 #include "llvm/IR/DerivedTypes.h" 29 #include "llvm/IR/Function.h" 30 #include "llvm/IR/Module.h" 31 #include "llvm/Support/ErrorHandling.h" 32 #include "llvm/Support/KnownBits.h" 33 using namespace llvm; 34 35 #define DEBUG_TYPE "ve-lower" 36 37 //===----------------------------------------------------------------------===// 38 // Calling Convention Implementation 39 //===----------------------------------------------------------------------===// 40 41 static bool allocateFloat(unsigned ValNo, MVT ValVT, MVT LocVT, 42 CCValAssign::LocInfo LocInfo, 43 ISD::ArgFlagsTy ArgFlags, CCState &State) { 44 switch (LocVT.SimpleTy) { 45 case MVT::f32: { 46 // Allocate stack like below 47 // 0 4 48 // +------+------+ 49 // | empty| float| 50 // +------+------+ 51 // Use align=8 for dummy area to align the beginning of these 2 area. 52 State.AllocateStack(4, 8); // for empty area 53 // Use align=4 for value to place it at just after the dummy area. 54 unsigned Offset = State.AllocateStack(4, 4); // for float value area 55 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); 56 return true; 57 } 58 default: 59 return false; 60 } 61 } 62 63 #include "VEGenCallingConv.inc" 64 65 bool VETargetLowering::CanLowerReturn( 66 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, 67 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const { 68 CCAssignFn *RetCC = RetCC_VE; 69 SmallVector<CCValAssign, 16> RVLocs; 70 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context); 71 return CCInfo.CheckReturn(Outs, RetCC); 72 } 73 74 SDValue 75 VETargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, 76 bool IsVarArg, 77 const SmallVectorImpl<ISD::OutputArg> &Outs, 78 const SmallVectorImpl<SDValue> &OutVals, 79 const SDLoc &DL, SelectionDAG &DAG) const { 80 // CCValAssign - represent the assignment of the return value to locations. 81 SmallVector<CCValAssign, 16> RVLocs; 82 83 // CCState - Info about the registers and stack slot. 84 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs, 85 *DAG.getContext()); 86 87 // Analyze return values. 88 CCInfo.AnalyzeReturn(Outs, RetCC_VE); 89 90 SDValue Flag; 91 SmallVector<SDValue, 4> RetOps(1, Chain); 92 93 // Copy the result values into the output registers. 94 for (unsigned i = 0; i != RVLocs.size(); ++i) { 95 CCValAssign &VA = RVLocs[i]; 96 assert(VA.isRegLoc() && "Can only return in registers!"); 97 SDValue OutVal = OutVals[i]; 98 99 // Integer return values must be sign or zero extended by the callee. 100 switch (VA.getLocInfo()) { 101 case CCValAssign::Full: 102 break; 103 case CCValAssign::SExt: 104 OutVal = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), OutVal); 105 break; 106 case CCValAssign::ZExt: 107 OutVal = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), OutVal); 108 break; 109 case CCValAssign::AExt: 110 OutVal = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), OutVal); 111 break; 112 default: 113 llvm_unreachable("Unknown loc info!"); 114 } 115 116 assert(!VA.needsCustom() && "Unexpected custom lowering"); 117 118 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVal, Flag); 119 120 // Guarantee that all emitted copies are stuck together with flags. 121 Flag = Chain.getValue(1); 122 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); 123 } 124 125 RetOps[0] = Chain; // Update chain. 126 127 // Add the flag if we have it. 128 if (Flag.getNode()) 129 RetOps.push_back(Flag); 130 131 return DAG.getNode(VEISD::RET_FLAG, DL, MVT::Other, RetOps); 132 } 133 134 SDValue VETargetLowering::LowerFormalArguments( 135 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, 136 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL, 137 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { 138 MachineFunction &MF = DAG.getMachineFunction(); 139 140 // Get the base offset of the incoming arguments stack space. 141 unsigned ArgsBaseOffset = 176; 142 // Get the size of the preserved arguments area 143 unsigned ArgsPreserved = 64; 144 145 // Analyze arguments according to CC_VE. 146 SmallVector<CCValAssign, 16> ArgLocs; 147 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs, 148 *DAG.getContext()); 149 // Allocate the preserved area first. 150 CCInfo.AllocateStack(ArgsPreserved, 8); 151 // We already allocated the preserved area, so the stack offset computed 152 // by CC_VE would be correct now. 153 CCInfo.AnalyzeFormalArguments(Ins, CC_VE); 154 155 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 156 CCValAssign &VA = ArgLocs[i]; 157 if (VA.isRegLoc()) { 158 // This argument is passed in a register. 159 // All integer register arguments are promoted by the caller to i64. 160 161 // Create a virtual register for the promoted live-in value. 162 unsigned VReg = 163 MF.addLiveIn(VA.getLocReg(), getRegClassFor(VA.getLocVT())); 164 SDValue Arg = DAG.getCopyFromReg(Chain, DL, VReg, VA.getLocVT()); 165 166 // Get the high bits for i32 struct elements. 167 if (VA.getValVT() == MVT::i32 && VA.needsCustom()) 168 Arg = DAG.getNode(ISD::SRL, DL, VA.getLocVT(), Arg, 169 DAG.getConstant(32, DL, MVT::i32)); 170 171 // The caller promoted the argument, so insert an Assert?ext SDNode so we 172 // won't promote the value again in this function. 173 switch (VA.getLocInfo()) { 174 case CCValAssign::SExt: 175 Arg = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), Arg, 176 DAG.getValueType(VA.getValVT())); 177 break; 178 case CCValAssign::ZExt: 179 Arg = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), Arg, 180 DAG.getValueType(VA.getValVT())); 181 break; 182 default: 183 break; 184 } 185 186 // Truncate the register down to the argument type. 187 if (VA.isExtInLoc()) 188 Arg = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Arg); 189 190 InVals.push_back(Arg); 191 continue; 192 } 193 194 // The registers are exhausted. This argument was passed on the stack. 195 assert(VA.isMemLoc()); 196 // The CC_VE_Full/Half functions compute stack offsets relative to the 197 // beginning of the arguments area at %fp+176. 198 unsigned Offset = VA.getLocMemOffset() + ArgsBaseOffset; 199 unsigned ValSize = VA.getValVT().getSizeInBits() / 8; 200 int FI = MF.getFrameInfo().CreateFixedObject(ValSize, Offset, true); 201 InVals.push_back( 202 DAG.getLoad(VA.getValVT(), DL, Chain, 203 DAG.getFrameIndex(FI, getPointerTy(MF.getDataLayout())), 204 MachinePointerInfo::getFixedStack(MF, FI))); 205 } 206 207 if (!IsVarArg) 208 return Chain; 209 210 // This function takes variable arguments, some of which may have been passed 211 // in registers %s0-%s8. 212 // 213 // The va_start intrinsic needs to know the offset to the first variable 214 // argument. 215 // TODO: need to calculate offset correctly once we support f128. 216 unsigned ArgOffset = ArgLocs.size() * 8; 217 VEMachineFunctionInfo *FuncInfo = MF.getInfo<VEMachineFunctionInfo>(); 218 // Skip the 176 bytes of register save area. 219 FuncInfo->setVarArgsFrameOffset(ArgOffset + ArgsBaseOffset); 220 221 return Chain; 222 } 223 224 // FIXME? Maybe this could be a TableGen attribute on some registers and 225 // this table could be generated automatically from RegInfo. 226 Register VETargetLowering::getRegisterByName(const char *RegName, LLT VT, 227 const MachineFunction &MF) const { 228 Register Reg = StringSwitch<Register>(RegName) 229 .Case("sp", VE::SX11) // Stack pointer 230 .Case("fp", VE::SX9) // Frame pointer 231 .Case("sl", VE::SX8) // Stack limit 232 .Case("lr", VE::SX10) // Link regsiter 233 .Case("tp", VE::SX14) // Thread pointer 234 .Case("outer", VE::SX12) // Outer regiser 235 .Case("info", VE::SX17) // Info area register 236 .Case("got", VE::SX15) // Global offset table register 237 .Case("plt", VE::SX16) // Procedure linkage table register 238 .Default(0); 239 240 if (Reg) 241 return Reg; 242 243 report_fatal_error("Invalid register name global variable"); 244 } 245 246 //===----------------------------------------------------------------------===// 247 // TargetLowering Implementation 248 //===----------------------------------------------------------------------===// 249 250 SDValue VETargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, 251 SmallVectorImpl<SDValue> &InVals) const { 252 SelectionDAG &DAG = CLI.DAG; 253 SDLoc DL = CLI.DL; 254 SDValue Chain = CLI.Chain; 255 auto PtrVT = getPointerTy(DAG.getDataLayout()); 256 257 // VE target does not yet support tail call optimization. 258 CLI.IsTailCall = false; 259 260 // Get the base offset of the outgoing arguments stack space. 261 unsigned ArgsBaseOffset = 176; 262 // Get the size of the preserved arguments area 263 unsigned ArgsPreserved = 8 * 8u; 264 265 // Analyze operands of the call, assigning locations to each operand. 266 SmallVector<CCValAssign, 16> ArgLocs; 267 CCState CCInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), ArgLocs, 268 *DAG.getContext()); 269 // Allocate the preserved area first. 270 CCInfo.AllocateStack(ArgsPreserved, 8); 271 // We already allocated the preserved area, so the stack offset computed 272 // by CC_VE would be correct now. 273 CCInfo.AnalyzeCallOperands(CLI.Outs, CC_VE); 274 275 // VE requires to use both register and stack for varargs or no-prototyped 276 // functions. 277 bool UseBoth = CLI.IsVarArg; 278 279 // Analyze operands again if it is required to store BOTH. 280 SmallVector<CCValAssign, 16> ArgLocs2; 281 CCState CCInfo2(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), 282 ArgLocs2, *DAG.getContext()); 283 if (UseBoth) 284 CCInfo2.AnalyzeCallOperands(CLI.Outs, CC_VE2); 285 286 // Get the size of the outgoing arguments stack space requirement. 287 unsigned ArgsSize = CCInfo.getNextStackOffset(); 288 289 // Keep stack frames 16-byte aligned. 290 ArgsSize = alignTo(ArgsSize, 16); 291 292 // Adjust the stack pointer to make room for the arguments. 293 // FIXME: Use hasReservedCallFrame to avoid %sp adjustments around all calls 294 // with more than 6 arguments. 295 Chain = DAG.getCALLSEQ_START(Chain, ArgsSize, 0, DL); 296 297 // Collect the set of registers to pass to the function and their values. 298 // This will be emitted as a sequence of CopyToReg nodes glued to the call 299 // instruction. 300 SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass; 301 302 // Collect chains from all the memory opeations that copy arguments to the 303 // stack. They must follow the stack pointer adjustment above and precede the 304 // call instruction itself. 305 SmallVector<SDValue, 8> MemOpChains; 306 307 // VE needs to get address of callee function in a register 308 // So, prepare to copy it to SX12 here. 309 310 // If the callee is a GlobalAddress node (quite common, every direct call is) 311 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 312 // Likewise ExternalSymbol -> TargetExternalSymbol. 313 SDValue Callee = CLI.Callee; 314 315 assert(!isPositionIndependent() && "TODO PIC"); 316 317 // Turn GlobalAddress/ExternalSymbol node into a value node 318 // containing the address of them here. 319 if (isa<GlobalAddressSDNode>(Callee)) { 320 Callee = 321 makeHiLoPair(Callee, VEMCExpr::VK_VE_HI32, VEMCExpr::VK_VE_LO32, DAG); 322 } else if (isa<ExternalSymbolSDNode>(Callee)) { 323 Callee = 324 makeHiLoPair(Callee, VEMCExpr::VK_VE_HI32, VEMCExpr::VK_VE_LO32, DAG); 325 } 326 327 RegsToPass.push_back(std::make_pair(VE::SX12, Callee)); 328 329 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 330 CCValAssign &VA = ArgLocs[i]; 331 SDValue Arg = CLI.OutVals[i]; 332 333 // Promote the value if needed. 334 switch (VA.getLocInfo()) { 335 default: 336 llvm_unreachable("Unknown location info!"); 337 case CCValAssign::Full: 338 break; 339 case CCValAssign::SExt: 340 Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Arg); 341 break; 342 case CCValAssign::ZExt: 343 Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Arg); 344 break; 345 case CCValAssign::AExt: 346 Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg); 347 break; 348 } 349 350 if (VA.isRegLoc()) { 351 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 352 if (!UseBoth) 353 continue; 354 VA = ArgLocs2[i]; 355 } 356 357 assert(VA.isMemLoc()); 358 359 // Create a store off the stack pointer for this argument. 360 SDValue StackPtr = DAG.getRegister(VE::SX11, PtrVT); 361 // The argument area starts at %fp+176 in the callee frame, 362 // %sp+176 in ours. 363 SDValue PtrOff = 364 DAG.getIntPtrConstant(VA.getLocMemOffset() + ArgsBaseOffset, DL); 365 PtrOff = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr, PtrOff); 366 MemOpChains.push_back( 367 DAG.getStore(Chain, DL, Arg, PtrOff, MachinePointerInfo())); 368 } 369 370 // Emit all stores, make sure they occur before the call. 371 if (!MemOpChains.empty()) 372 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains); 373 374 // Build a sequence of CopyToReg nodes glued together with token chain and 375 // glue operands which copy the outgoing args into registers. The InGlue is 376 // necessary since all emitted instructions must be stuck together in order 377 // to pass the live physical registers. 378 SDValue InGlue; 379 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 380 Chain = DAG.getCopyToReg(Chain, DL, RegsToPass[i].first, 381 RegsToPass[i].second, InGlue); 382 InGlue = Chain.getValue(1); 383 } 384 385 // Build the operands for the call instruction itself. 386 SmallVector<SDValue, 8> Ops; 387 Ops.push_back(Chain); 388 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 389 Ops.push_back(DAG.getRegister(RegsToPass[i].first, 390 RegsToPass[i].second.getValueType())); 391 392 // Add a register mask operand representing the call-preserved registers. 393 const VERegisterInfo *TRI = Subtarget->getRegisterInfo(); 394 const uint32_t *Mask = 395 TRI->getCallPreservedMask(DAG.getMachineFunction(), CLI.CallConv); 396 assert(Mask && "Missing call preserved mask for calling convention"); 397 Ops.push_back(DAG.getRegisterMask(Mask)); 398 399 // Make sure the CopyToReg nodes are glued to the call instruction which 400 // consumes the registers. 401 if (InGlue.getNode()) 402 Ops.push_back(InGlue); 403 404 // Now the call itself. 405 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 406 Chain = DAG.getNode(VEISD::CALL, DL, NodeTys, Ops); 407 InGlue = Chain.getValue(1); 408 409 // Revert the stack pointer immediately after the call. 410 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(ArgsSize, DL, true), 411 DAG.getIntPtrConstant(0, DL, true), InGlue, DL); 412 InGlue = Chain.getValue(1); 413 414 // Now extract the return values. This is more or less the same as 415 // LowerFormalArguments. 416 417 // Assign locations to each value returned by this call. 418 SmallVector<CCValAssign, 16> RVLocs; 419 CCState RVInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), RVLocs, 420 *DAG.getContext()); 421 422 // Set inreg flag manually for codegen generated library calls that 423 // return float. 424 if (CLI.Ins.size() == 1 && CLI.Ins[0].VT == MVT::f32 && !CLI.CS) 425 CLI.Ins[0].Flags.setInReg(); 426 427 RVInfo.AnalyzeCallResult(CLI.Ins, RetCC_VE); 428 429 // Copy all of the result registers out of their specified physreg. 430 for (unsigned i = 0; i != RVLocs.size(); ++i) { 431 CCValAssign &VA = RVLocs[i]; 432 unsigned Reg = VA.getLocReg(); 433 434 // When returning 'inreg {i32, i32 }', two consecutive i32 arguments can 435 // reside in the same register in the high and low bits. Reuse the 436 // CopyFromReg previous node to avoid duplicate copies. 437 SDValue RV; 438 if (RegisterSDNode *SrcReg = dyn_cast<RegisterSDNode>(Chain.getOperand(1))) 439 if (SrcReg->getReg() == Reg && Chain->getOpcode() == ISD::CopyFromReg) 440 RV = Chain.getValue(0); 441 442 // But usually we'll create a new CopyFromReg for a different register. 443 if (!RV.getNode()) { 444 RV = DAG.getCopyFromReg(Chain, DL, Reg, RVLocs[i].getLocVT(), InGlue); 445 Chain = RV.getValue(1); 446 InGlue = Chain.getValue(2); 447 } 448 449 // Get the high bits for i32 struct elements. 450 if (VA.getValVT() == MVT::i32 && VA.needsCustom()) 451 RV = DAG.getNode(ISD::SRL, DL, VA.getLocVT(), RV, 452 DAG.getConstant(32, DL, MVT::i32)); 453 454 // The callee promoted the return value, so insert an Assert?ext SDNode so 455 // we won't promote the value again in this function. 456 switch (VA.getLocInfo()) { 457 case CCValAssign::SExt: 458 RV = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), RV, 459 DAG.getValueType(VA.getValVT())); 460 break; 461 case CCValAssign::ZExt: 462 RV = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), RV, 463 DAG.getValueType(VA.getValVT())); 464 break; 465 default: 466 break; 467 } 468 469 // Truncate the register down to the return value type. 470 if (VA.isExtInLoc()) 471 RV = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), RV); 472 473 InVals.push_back(RV); 474 } 475 476 return Chain; 477 } 478 479 /// isFPImmLegal - Returns true if the target can instruction select the 480 /// specified FP immediate natively. If false, the legalizer will 481 /// materialize the FP immediate as a load from a constant pool. 482 bool VETargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT, 483 bool ForCodeSize) const { 484 return VT == MVT::f32 || VT == MVT::f64; 485 } 486 487 /// Determine if the target supports unaligned memory accesses. 488 /// 489 /// This function returns true if the target allows unaligned memory accesses 490 /// of the specified type in the given address space. If true, it also returns 491 /// whether the unaligned memory access is "fast" in the last argument by 492 /// reference. This is used, for example, in situations where an array 493 /// copy/move/set is converted to a sequence of store operations. Its use 494 /// helps to ensure that such replacements don't generate code that causes an 495 /// alignment error (trap) on the target machine. 496 bool VETargetLowering::allowsMisalignedMemoryAccesses(EVT VT, 497 unsigned AddrSpace, 498 unsigned Align, 499 MachineMemOperand::Flags, 500 bool *Fast) const { 501 if (Fast) { 502 // It's fast anytime on VE 503 *Fast = true; 504 } 505 return true; 506 } 507 508 VETargetLowering::VETargetLowering(const TargetMachine &TM, 509 const VESubtarget &STI) 510 : TargetLowering(TM), Subtarget(&STI) { 511 // Instructions which use registers as conditionals examine all the 512 // bits (as does the pseudo SELECT_CC expansion). I don't think it 513 // matters much whether it's ZeroOrOneBooleanContent, or 514 // ZeroOrNegativeOneBooleanContent, so, arbitrarily choose the 515 // former. 516 setBooleanContents(ZeroOrOneBooleanContent); 517 setBooleanVectorContents(ZeroOrOneBooleanContent); 518 519 // Set up the register classes. 520 addRegisterClass(MVT::i32, &VE::I32RegClass); 521 addRegisterClass(MVT::i64, &VE::I64RegClass); 522 addRegisterClass(MVT::f32, &VE::F32RegClass); 523 addRegisterClass(MVT::f64, &VE::I64RegClass); 524 525 /// Load & Store { 526 // Turn FP extload into load/fpextend 527 for (MVT VT : MVT::fp_valuetypes()) { 528 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f32, Expand); 529 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f64, Expand); 530 } 531 532 // VE doesn't have i1 sign extending load 533 for (MVT VT : MVT::integer_valuetypes()) { 534 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote); 535 setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i1, Promote); 536 setLoadExtAction(ISD::EXTLOAD, VT, MVT::i1, Promote); 537 setTruncStoreAction(VT, MVT::i1, Expand); 538 } 539 540 // Turn FP truncstore into trunc + store. 541 setTruncStoreAction(MVT::f64, MVT::f32, Expand); 542 /// } Load & Store 543 544 // Custom legalize address nodes into LO/HI parts. 545 MVT PtrVT = MVT::getIntegerVT(TM.getPointerSizeInBits(0)); 546 setOperationAction(ISD::BlockAddress, PtrVT, Custom); 547 setOperationAction(ISD::GlobalAddress, PtrVT, Custom); 548 549 /// VAARG handling { 550 setOperationAction(ISD::VASTART, MVT::Other, Custom); 551 // VAARG needs to be lowered to access with 8 bytes alignment. 552 setOperationAction(ISD::VAARG, MVT::Other, Custom); 553 // Use the default implementation. 554 setOperationAction(ISD::VACOPY, MVT::Other, Expand); 555 setOperationAction(ISD::VAEND, MVT::Other, Expand); 556 /// } VAARG handling 557 558 // VE has no REM or DIVREM operations. 559 for (MVT IntVT : MVT::integer_valuetypes()) { 560 setOperationAction(ISD::UREM, IntVT, Expand); 561 setOperationAction(ISD::SREM, IntVT, Expand); 562 setOperationAction(ISD::SDIVREM, IntVT, Expand); 563 setOperationAction(ISD::UDIVREM, IntVT, Expand); 564 } 565 566 // VE doesn't have instructions for fp<->uint, so expand them by llvm 567 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote); // use i64 568 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Promote); // use i64 569 setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand); 570 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand); 571 572 setStackPointerRegisterToSaveRestore(VE::SX11); 573 574 // Set function alignment to 16 bytes 575 setMinFunctionAlignment(Align(16)); 576 577 // VE stores all argument by 8 bytes alignment 578 setMinStackArgumentAlignment(Align(8)); 579 580 computeRegisterProperties(Subtarget->getRegisterInfo()); 581 } 582 583 const char *VETargetLowering::getTargetNodeName(unsigned Opcode) const { 584 #define TARGET_NODE_CASE(NAME) \ 585 case VEISD::NAME: \ 586 return "VEISD::" #NAME; 587 switch ((VEISD::NodeType)Opcode) { 588 case VEISD::FIRST_NUMBER: 589 break; 590 TARGET_NODE_CASE(Lo) 591 TARGET_NODE_CASE(Hi) 592 TARGET_NODE_CASE(CALL) 593 TARGET_NODE_CASE(RET_FLAG) 594 } 595 #undef TARGET_NODE_CASE 596 return nullptr; 597 } 598 599 EVT VETargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &, 600 EVT VT) const { 601 return MVT::i32; 602 } 603 604 // Convert to a target node and set target flags. 605 SDValue VETargetLowering::withTargetFlags(SDValue Op, unsigned TF, 606 SelectionDAG &DAG) const { 607 if (const GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op)) 608 return DAG.getTargetGlobalAddress(GA->getGlobal(), SDLoc(GA), 609 GA->getValueType(0), GA->getOffset(), TF); 610 611 if (const BlockAddressSDNode *BA = dyn_cast<BlockAddressSDNode>(Op)) 612 return DAG.getTargetBlockAddress(BA->getBlockAddress(), Op.getValueType(), 613 0, TF); 614 615 llvm_unreachable("Unhandled address SDNode"); 616 } 617 618 // Split Op into high and low parts according to HiTF and LoTF. 619 // Return an ADD node combining the parts. 620 SDValue VETargetLowering::makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF, 621 SelectionDAG &DAG) const { 622 SDLoc DL(Op); 623 EVT VT = Op.getValueType(); 624 SDValue Hi = DAG.getNode(VEISD::Hi, DL, VT, withTargetFlags(Op, HiTF, DAG)); 625 SDValue Lo = DAG.getNode(VEISD::Lo, DL, VT, withTargetFlags(Op, LoTF, DAG)); 626 return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo); 627 } 628 629 // Build SDNodes for producing an address from a GlobalAddress, ConstantPool, 630 // or ExternalSymbol SDNode. 631 SDValue VETargetLowering::makeAddress(SDValue Op, SelectionDAG &DAG) const { 632 SDLoc DL(Op); 633 634 assert(!isPositionIndependent() && "TODO implement PIC"); 635 636 // This is one of the absolute code models. 637 switch (getTargetMachine().getCodeModel()) { 638 default: 639 llvm_unreachable("Unsupported absolute code model"); 640 case CodeModel::Small: 641 case CodeModel::Medium: 642 case CodeModel::Large: 643 // abs64. 644 return makeHiLoPair(Op, VEMCExpr::VK_VE_HI32, VEMCExpr::VK_VE_LO32, DAG); 645 } 646 } 647 648 /// Custom Lower { 649 650 SDValue VETargetLowering::LowerGlobalAddress(SDValue Op, 651 SelectionDAG &DAG) const { 652 return makeAddress(Op, DAG); 653 } 654 655 SDValue VETargetLowering::LowerBlockAddress(SDValue Op, 656 SelectionDAG &DAG) const { 657 return makeAddress(Op, DAG); 658 } 659 660 SDValue VETargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const { 661 MachineFunction &MF = DAG.getMachineFunction(); 662 VEMachineFunctionInfo *FuncInfo = MF.getInfo<VEMachineFunctionInfo>(); 663 auto PtrVT = getPointerTy(DAG.getDataLayout()); 664 665 // Need frame address to find the address of VarArgsFrameIndex. 666 MF.getFrameInfo().setFrameAddressIsTaken(true); 667 668 // vastart just stores the address of the VarArgsFrameIndex slot into the 669 // memory location argument. 670 SDLoc DL(Op); 671 SDValue Offset = 672 DAG.getNode(ISD::ADD, DL, PtrVT, DAG.getRegister(VE::SX9, PtrVT), 673 DAG.getIntPtrConstant(FuncInfo->getVarArgsFrameOffset(), DL)); 674 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); 675 return DAG.getStore(Op.getOperand(0), DL, Offset, Op.getOperand(1), 676 MachinePointerInfo(SV)); 677 } 678 679 SDValue VETargetLowering::LowerVAARG(SDValue Op, SelectionDAG &DAG) const { 680 SDNode *Node = Op.getNode(); 681 EVT VT = Node->getValueType(0); 682 SDValue InChain = Node->getOperand(0); 683 SDValue VAListPtr = Node->getOperand(1); 684 EVT PtrVT = VAListPtr.getValueType(); 685 const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue(); 686 SDLoc DL(Node); 687 SDValue VAList = 688 DAG.getLoad(PtrVT, DL, InChain, VAListPtr, MachinePointerInfo(SV)); 689 SDValue Chain = VAList.getValue(1); 690 SDValue NextPtr; 691 692 if (VT == MVT::f32) { 693 // float --> need special handling like below. 694 // 0 4 695 // +------+------+ 696 // | empty| float| 697 // +------+------+ 698 // Increment the pointer, VAList, by 8 to the next vaarg. 699 NextPtr = 700 DAG.getNode(ISD::ADD, DL, PtrVT, VAList, DAG.getIntPtrConstant(8, DL)); 701 // Then, adjust VAList. 702 unsigned InternalOffset = 4; 703 VAList = DAG.getNode(ISD::ADD, DL, PtrVT, VAList, 704 DAG.getConstant(InternalOffset, DL, PtrVT)); 705 } else { 706 // Increment the pointer, VAList, by 8 to the next vaarg. 707 NextPtr = 708 DAG.getNode(ISD::ADD, DL, PtrVT, VAList, DAG.getIntPtrConstant(8, DL)); 709 } 710 711 // Store the incremented VAList to the legalized pointer. 712 InChain = DAG.getStore(Chain, DL, NextPtr, VAListPtr, MachinePointerInfo(SV)); 713 714 // Load the actual argument out of the pointer VAList. 715 // We can't count on greater alignment than the word size. 716 return DAG.getLoad(VT, DL, InChain, VAList, MachinePointerInfo(), 717 std::min(PtrVT.getSizeInBits(), VT.getSizeInBits()) / 8); 718 } 719 720 SDValue VETargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { 721 switch (Op.getOpcode()) { 722 default: 723 llvm_unreachable("Should not custom lower this!"); 724 case ISD::BlockAddress: 725 return LowerBlockAddress(Op, DAG); 726 case ISD::GlobalAddress: 727 return LowerGlobalAddress(Op, DAG); 728 case ISD::VASTART: 729 return LowerVASTART(Op, DAG); 730 case ISD::VAARG: 731 return LowerVAARG(Op, DAG); 732 } 733 } 734 /// } Custom Lower 735