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/MachineJumpTableInfo.h" 25 #include "llvm/CodeGen/MachineModuleInfo.h" 26 #include "llvm/CodeGen/MachineRegisterInfo.h" 27 #include "llvm/CodeGen/SelectionDAG.h" 28 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 29 #include "llvm/IR/DerivedTypes.h" 30 #include "llvm/IR/Function.h" 31 #include "llvm/IR/Module.h" 32 #include "llvm/Support/ErrorHandling.h" 33 #include "llvm/Support/KnownBits.h" 34 using namespace llvm; 35 36 #define DEBUG_TYPE "ve-lower" 37 38 //===----------------------------------------------------------------------===// 39 // Calling Convention Implementation 40 //===----------------------------------------------------------------------===// 41 42 #include "VEGenCallingConv.inc" 43 44 CCAssignFn *getReturnCC(CallingConv::ID CallConv) { 45 switch (CallConv) { 46 default: 47 return RetCC_VE_C; 48 case CallingConv::Fast: 49 return RetCC_VE_Fast; 50 } 51 } 52 53 CCAssignFn *getParamCC(CallingConv::ID CallConv, bool IsVarArg) { 54 if (IsVarArg) 55 return CC_VE2; 56 switch (CallConv) { 57 default: 58 return CC_VE_C; 59 case CallingConv::Fast: 60 return CC_VE_Fast; 61 } 62 } 63 64 bool VETargetLowering::CanLowerReturn( 65 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, 66 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const { 67 CCAssignFn *RetCC = getReturnCC(CallConv); 68 SmallVector<CCValAssign, 16> RVLocs; 69 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context); 70 return CCInfo.CheckReturn(Outs, RetCC); 71 } 72 73 static const MVT AllVectorVTs[] = {MVT::v256i32, MVT::v512i32, MVT::v256i64, 74 MVT::v256f32, MVT::v512f32, MVT::v256f64}; 75 76 static const MVT AllMaskVTs[] = {MVT::v256i1, MVT::v512i1}; 77 78 void VETargetLowering::initRegisterClasses() { 79 // Set up the register classes. 80 addRegisterClass(MVT::i32, &VE::I32RegClass); 81 addRegisterClass(MVT::i64, &VE::I64RegClass); 82 addRegisterClass(MVT::f32, &VE::F32RegClass); 83 addRegisterClass(MVT::f64, &VE::I64RegClass); 84 addRegisterClass(MVT::f128, &VE::F128RegClass); 85 86 if (Subtarget->enableVPU()) { 87 for (MVT VecVT : AllVectorVTs) 88 addRegisterClass(VecVT, &VE::V64RegClass); 89 for (MVT MaskVT : AllMaskVTs) 90 addRegisterClass(MaskVT, &VE::VMRegClass); 91 } 92 } 93 94 void VETargetLowering::initSPUActions() { 95 const auto &TM = getTargetMachine(); 96 /// Load & Store { 97 98 // VE doesn't have i1 sign extending load. 99 for (MVT VT : MVT::integer_valuetypes()) { 100 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote); 101 setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i1, Promote); 102 setLoadExtAction(ISD::EXTLOAD, VT, MVT::i1, Promote); 103 setTruncStoreAction(VT, MVT::i1, Expand); 104 } 105 106 // VE doesn't have floating point extload/truncstore, so expand them. 107 for (MVT FPVT : MVT::fp_valuetypes()) { 108 for (MVT OtherFPVT : MVT::fp_valuetypes()) { 109 setLoadExtAction(ISD::EXTLOAD, FPVT, OtherFPVT, Expand); 110 setTruncStoreAction(FPVT, OtherFPVT, Expand); 111 } 112 } 113 114 // VE doesn't have fp128 load/store, so expand them in custom lower. 115 setOperationAction(ISD::LOAD, MVT::f128, Custom); 116 setOperationAction(ISD::STORE, MVT::f128, Custom); 117 118 /// } Load & Store 119 120 // Custom legalize address nodes into LO/HI parts. 121 MVT PtrVT = MVT::getIntegerVT(TM.getPointerSizeInBits(0)); 122 setOperationAction(ISD::BlockAddress, PtrVT, Custom); 123 setOperationAction(ISD::GlobalAddress, PtrVT, Custom); 124 setOperationAction(ISD::GlobalTLSAddress, PtrVT, Custom); 125 setOperationAction(ISD::ConstantPool, PtrVT, Custom); 126 setOperationAction(ISD::JumpTable, PtrVT, Custom); 127 128 /// VAARG handling { 129 setOperationAction(ISD::VASTART, MVT::Other, Custom); 130 // VAARG needs to be lowered to access with 8 bytes alignment. 131 setOperationAction(ISD::VAARG, MVT::Other, Custom); 132 // Use the default implementation. 133 setOperationAction(ISD::VACOPY, MVT::Other, Expand); 134 setOperationAction(ISD::VAEND, MVT::Other, Expand); 135 /// } VAARG handling 136 137 /// Stack { 138 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom); 139 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Custom); 140 /// } Stack 141 142 /// Branch { 143 144 // VE doesn't have BRCOND 145 setOperationAction(ISD::BRCOND, MVT::Other, Expand); 146 147 // BR_JT is not implemented yet. 148 setOperationAction(ISD::BR_JT, MVT::Other, Expand); 149 150 /// } Branch 151 152 /// Int Ops { 153 for (MVT IntVT : {MVT::i32, MVT::i64}) { 154 // VE has no REM or DIVREM operations. 155 setOperationAction(ISD::UREM, IntVT, Expand); 156 setOperationAction(ISD::SREM, IntVT, Expand); 157 setOperationAction(ISD::SDIVREM, IntVT, Expand); 158 setOperationAction(ISD::UDIVREM, IntVT, Expand); 159 160 // VE has no SHL_PARTS/SRA_PARTS/SRL_PARTS operations. 161 setOperationAction(ISD::SHL_PARTS, IntVT, Expand); 162 setOperationAction(ISD::SRA_PARTS, IntVT, Expand); 163 setOperationAction(ISD::SRL_PARTS, IntVT, Expand); 164 165 // VE has no MULHU/S or U/SMUL_LOHI operations. 166 // TODO: Use MPD instruction to implement SMUL_LOHI for i32 type. 167 setOperationAction(ISD::MULHU, IntVT, Expand); 168 setOperationAction(ISD::MULHS, IntVT, Expand); 169 setOperationAction(ISD::UMUL_LOHI, IntVT, Expand); 170 setOperationAction(ISD::SMUL_LOHI, IntVT, Expand); 171 172 // VE has no CTTZ, ROTL, ROTR operations. 173 setOperationAction(ISD::CTTZ, IntVT, Expand); 174 setOperationAction(ISD::ROTL, IntVT, Expand); 175 setOperationAction(ISD::ROTR, IntVT, Expand); 176 177 // VE has 64 bits instruction which works as i64 BSWAP operation. This 178 // instruction works fine as i32 BSWAP operation with an additional 179 // parameter. Use isel patterns to lower BSWAP. 180 setOperationAction(ISD::BSWAP, IntVT, Legal); 181 182 // VE has only 64 bits instructions which work as i64 BITREVERSE/CTLZ/CTPOP 183 // operations. Use isel patterns for i64, promote for i32. 184 LegalizeAction Act = (IntVT == MVT::i32) ? Promote : Legal; 185 setOperationAction(ISD::BITREVERSE, IntVT, Act); 186 setOperationAction(ISD::CTLZ, IntVT, Act); 187 setOperationAction(ISD::CTLZ_ZERO_UNDEF, IntVT, Act); 188 setOperationAction(ISD::CTPOP, IntVT, Act); 189 190 // VE has only 64 bits instructions which work as i64 AND/OR/XOR operations. 191 // Use isel patterns for i64, promote for i32. 192 setOperationAction(ISD::AND, IntVT, Act); 193 setOperationAction(ISD::OR, IntVT, Act); 194 setOperationAction(ISD::XOR, IntVT, Act); 195 } 196 /// } Int Ops 197 198 /// Conversion { 199 // VE doesn't have instructions for fp<->uint, so expand them by llvm 200 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote); // use i64 201 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Promote); // use i64 202 setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand); 203 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand); 204 205 // fp16 not supported 206 for (MVT FPVT : MVT::fp_valuetypes()) { 207 setOperationAction(ISD::FP16_TO_FP, FPVT, Expand); 208 setOperationAction(ISD::FP_TO_FP16, FPVT, Expand); 209 } 210 /// } Conversion 211 212 /// Floating-point Ops { 213 /// Note: Floating-point operations are fneg, fadd, fsub, fmul, fdiv, frem, 214 /// and fcmp. 215 216 // VE doesn't have following floating point operations. 217 for (MVT VT : MVT::fp_valuetypes()) { 218 setOperationAction(ISD::FNEG, VT, Expand); 219 setOperationAction(ISD::FREM, VT, Expand); 220 } 221 222 // VE doesn't have fdiv of f128. 223 setOperationAction(ISD::FDIV, MVT::f128, Expand); 224 225 for (MVT FPVT : {MVT::f32, MVT::f64}) { 226 // f32 and f64 uses ConstantFP. f128 uses ConstantPool. 227 setOperationAction(ISD::ConstantFP, FPVT, Legal); 228 } 229 /// } Floating-point Ops 230 231 /// Floating-point math functions { 232 233 // VE doesn't have following floating point math functions. 234 for (MVT VT : MVT::fp_valuetypes()) { 235 setOperationAction(ISD::FABS, VT, Expand); 236 setOperationAction(ISD::FCOPYSIGN, VT, Expand); 237 setOperationAction(ISD::FCOS, VT, Expand); 238 setOperationAction(ISD::FSIN, VT, Expand); 239 setOperationAction(ISD::FSQRT, VT, Expand); 240 } 241 242 /// } Floating-point math functions 243 244 /// Atomic instructions { 245 246 setMaxAtomicSizeInBitsSupported(64); 247 setMinCmpXchgSizeInBits(32); 248 setSupportsUnalignedAtomics(false); 249 250 // Use custom inserter for ATOMIC_FENCE. 251 setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom); 252 253 /// } Atomic isntructions 254 } 255 256 void VETargetLowering::initVPUActions() { 257 for (MVT LegalVecVT : AllVectorVTs) { 258 setOperationAction(ISD::BUILD_VECTOR, LegalVecVT, Custom); 259 // Translate all vector instructions with legal element types to VVP_* 260 // nodes. 261 // TODO We will custom-widen into VVP_* nodes in the future. While we are 262 // buildling the infrastructure for this, we only do this for legal vector 263 // VTs. 264 #define ADD_VVP_OP(VVP_NAME, ISD_NAME) \ 265 setOperationAction(ISD::ISD_NAME, LegalVecVT, Custom); 266 #include "VVPNodes.def" 267 } 268 } 269 270 SDValue 271 VETargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, 272 bool IsVarArg, 273 const SmallVectorImpl<ISD::OutputArg> &Outs, 274 const SmallVectorImpl<SDValue> &OutVals, 275 const SDLoc &DL, SelectionDAG &DAG) const { 276 // CCValAssign - represent the assignment of the return value to locations. 277 SmallVector<CCValAssign, 16> RVLocs; 278 279 // CCState - Info about the registers and stack slot. 280 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs, 281 *DAG.getContext()); 282 283 // Analyze return values. 284 CCInfo.AnalyzeReturn(Outs, getReturnCC(CallConv)); 285 286 SDValue Flag; 287 SmallVector<SDValue, 4> RetOps(1, Chain); 288 289 // Copy the result values into the output registers. 290 for (unsigned i = 0; i != RVLocs.size(); ++i) { 291 CCValAssign &VA = RVLocs[i]; 292 assert(VA.isRegLoc() && "Can only return in registers!"); 293 SDValue OutVal = OutVals[i]; 294 295 // Integer return values must be sign or zero extended by the callee. 296 switch (VA.getLocInfo()) { 297 case CCValAssign::Full: 298 break; 299 case CCValAssign::SExt: 300 OutVal = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), OutVal); 301 break; 302 case CCValAssign::ZExt: 303 OutVal = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), OutVal); 304 break; 305 case CCValAssign::AExt: 306 OutVal = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), OutVal); 307 break; 308 case CCValAssign::BCvt: { 309 // Convert a float return value to i64 with padding. 310 // 63 31 0 311 // +------+------+ 312 // | float| 0 | 313 // +------+------+ 314 assert(VA.getLocVT() == MVT::i64); 315 assert(VA.getValVT() == MVT::f32); 316 SDValue Undef = SDValue( 317 DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::i64), 0); 318 SDValue Sub_f32 = DAG.getTargetConstant(VE::sub_f32, DL, MVT::i32); 319 OutVal = SDValue(DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, DL, 320 MVT::i64, Undef, OutVal, Sub_f32), 321 0); 322 break; 323 } 324 default: 325 llvm_unreachable("Unknown loc info!"); 326 } 327 328 assert(!VA.needsCustom() && "Unexpected custom lowering"); 329 330 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVal, Flag); 331 332 // Guarantee that all emitted copies are stuck together with flags. 333 Flag = Chain.getValue(1); 334 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); 335 } 336 337 RetOps[0] = Chain; // Update chain. 338 339 // Add the flag if we have it. 340 if (Flag.getNode()) 341 RetOps.push_back(Flag); 342 343 return DAG.getNode(VEISD::RET_FLAG, DL, MVT::Other, RetOps); 344 } 345 346 SDValue VETargetLowering::LowerFormalArguments( 347 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, 348 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL, 349 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { 350 MachineFunction &MF = DAG.getMachineFunction(); 351 352 // Get the base offset of the incoming arguments stack space. 353 unsigned ArgsBaseOffset = Subtarget->getRsaSize(); 354 // Get the size of the preserved arguments area 355 unsigned ArgsPreserved = 64; 356 357 // Analyze arguments according to CC_VE. 358 SmallVector<CCValAssign, 16> ArgLocs; 359 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs, 360 *DAG.getContext()); 361 // Allocate the preserved area first. 362 CCInfo.AllocateStack(ArgsPreserved, Align(8)); 363 // We already allocated the preserved area, so the stack offset computed 364 // by CC_VE would be correct now. 365 CCInfo.AnalyzeFormalArguments(Ins, getParamCC(CallConv, false)); 366 367 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 368 CCValAssign &VA = ArgLocs[i]; 369 if (VA.isRegLoc()) { 370 // This argument is passed in a register. 371 // All integer register arguments are promoted by the caller to i64. 372 373 // Create a virtual register for the promoted live-in value. 374 unsigned VReg = 375 MF.addLiveIn(VA.getLocReg(), getRegClassFor(VA.getLocVT())); 376 SDValue Arg = DAG.getCopyFromReg(Chain, DL, VReg, VA.getLocVT()); 377 378 // Get the high bits for i32 struct elements. 379 if (VA.getValVT() == MVT::i32 && VA.needsCustom()) 380 Arg = DAG.getNode(ISD::SRL, DL, VA.getLocVT(), Arg, 381 DAG.getConstant(32, DL, MVT::i32)); 382 383 // The caller promoted the argument, so insert an Assert?ext SDNode so we 384 // won't promote the value again in this function. 385 switch (VA.getLocInfo()) { 386 case CCValAssign::SExt: 387 Arg = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), Arg, 388 DAG.getValueType(VA.getValVT())); 389 break; 390 case CCValAssign::ZExt: 391 Arg = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), Arg, 392 DAG.getValueType(VA.getValVT())); 393 break; 394 case CCValAssign::BCvt: { 395 // Extract a float argument from i64 with padding. 396 // 63 31 0 397 // +------+------+ 398 // | float| 0 | 399 // +------+------+ 400 assert(VA.getLocVT() == MVT::i64); 401 assert(VA.getValVT() == MVT::f32); 402 SDValue Sub_f32 = DAG.getTargetConstant(VE::sub_f32, DL, MVT::i32); 403 Arg = SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, 404 MVT::f32, Arg, Sub_f32), 405 0); 406 break; 407 } 408 default: 409 break; 410 } 411 412 // Truncate the register down to the argument type. 413 if (VA.isExtInLoc()) 414 Arg = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Arg); 415 416 InVals.push_back(Arg); 417 continue; 418 } 419 420 // The registers are exhausted. This argument was passed on the stack. 421 assert(VA.isMemLoc()); 422 // The CC_VE_Full/Half functions compute stack offsets relative to the 423 // beginning of the arguments area at %fp + the size of reserved area. 424 unsigned Offset = VA.getLocMemOffset() + ArgsBaseOffset; 425 unsigned ValSize = VA.getValVT().getSizeInBits() / 8; 426 427 // Adjust offset for a float argument by adding 4 since the argument is 428 // stored in 8 bytes buffer with offset like below. LLVM generates 429 // 4 bytes load instruction, so need to adjust offset here. This 430 // adjustment is required in only LowerFormalArguments. In LowerCall, 431 // a float argument is converted to i64 first, and stored as 8 bytes 432 // data, which is required by ABI, so no need for adjustment. 433 // 0 4 434 // +------+------+ 435 // | empty| float| 436 // +------+------+ 437 if (VA.getValVT() == MVT::f32) 438 Offset += 4; 439 440 int FI = MF.getFrameInfo().CreateFixedObject(ValSize, Offset, true); 441 InVals.push_back( 442 DAG.getLoad(VA.getValVT(), DL, Chain, 443 DAG.getFrameIndex(FI, getPointerTy(MF.getDataLayout())), 444 MachinePointerInfo::getFixedStack(MF, FI))); 445 } 446 447 if (!IsVarArg) 448 return Chain; 449 450 // This function takes variable arguments, some of which may have been passed 451 // in registers %s0-%s8. 452 // 453 // The va_start intrinsic needs to know the offset to the first variable 454 // argument. 455 // TODO: need to calculate offset correctly once we support f128. 456 unsigned ArgOffset = ArgLocs.size() * 8; 457 VEMachineFunctionInfo *FuncInfo = MF.getInfo<VEMachineFunctionInfo>(); 458 // Skip the reserved area at the top of stack. 459 FuncInfo->setVarArgsFrameOffset(ArgOffset + ArgsBaseOffset); 460 461 return Chain; 462 } 463 464 // FIXME? Maybe this could be a TableGen attribute on some registers and 465 // this table could be generated automatically from RegInfo. 466 Register VETargetLowering::getRegisterByName(const char *RegName, LLT VT, 467 const MachineFunction &MF) const { 468 Register Reg = StringSwitch<Register>(RegName) 469 .Case("sp", VE::SX11) // Stack pointer 470 .Case("fp", VE::SX9) // Frame pointer 471 .Case("sl", VE::SX8) // Stack limit 472 .Case("lr", VE::SX10) // Link register 473 .Case("tp", VE::SX14) // Thread pointer 474 .Case("outer", VE::SX12) // Outer regiser 475 .Case("info", VE::SX17) // Info area register 476 .Case("got", VE::SX15) // Global offset table register 477 .Case("plt", VE::SX16) // Procedure linkage table register 478 .Default(0); 479 480 if (Reg) 481 return Reg; 482 483 report_fatal_error("Invalid register name global variable"); 484 } 485 486 //===----------------------------------------------------------------------===// 487 // TargetLowering Implementation 488 //===----------------------------------------------------------------------===// 489 490 SDValue VETargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, 491 SmallVectorImpl<SDValue> &InVals) const { 492 SelectionDAG &DAG = CLI.DAG; 493 SDLoc DL = CLI.DL; 494 SDValue Chain = CLI.Chain; 495 auto PtrVT = getPointerTy(DAG.getDataLayout()); 496 497 // VE target does not yet support tail call optimization. 498 CLI.IsTailCall = false; 499 500 // Get the base offset of the outgoing arguments stack space. 501 unsigned ArgsBaseOffset = Subtarget->getRsaSize(); 502 // Get the size of the preserved arguments area 503 unsigned ArgsPreserved = 8 * 8u; 504 505 // Analyze operands of the call, assigning locations to each operand. 506 SmallVector<CCValAssign, 16> ArgLocs; 507 CCState CCInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), ArgLocs, 508 *DAG.getContext()); 509 // Allocate the preserved area first. 510 CCInfo.AllocateStack(ArgsPreserved, Align(8)); 511 // We already allocated the preserved area, so the stack offset computed 512 // by CC_VE would be correct now. 513 CCInfo.AnalyzeCallOperands(CLI.Outs, getParamCC(CLI.CallConv, false)); 514 515 // VE requires to use both register and stack for varargs or no-prototyped 516 // functions. 517 bool UseBoth = CLI.IsVarArg; 518 519 // Analyze operands again if it is required to store BOTH. 520 SmallVector<CCValAssign, 16> ArgLocs2; 521 CCState CCInfo2(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), 522 ArgLocs2, *DAG.getContext()); 523 if (UseBoth) 524 CCInfo2.AnalyzeCallOperands(CLI.Outs, getParamCC(CLI.CallConv, true)); 525 526 // Get the size of the outgoing arguments stack space requirement. 527 unsigned ArgsSize = CCInfo.getNextStackOffset(); 528 529 // Keep stack frames 16-byte aligned. 530 ArgsSize = alignTo(ArgsSize, 16); 531 532 // Adjust the stack pointer to make room for the arguments. 533 // FIXME: Use hasReservedCallFrame to avoid %sp adjustments around all calls 534 // with more than 6 arguments. 535 Chain = DAG.getCALLSEQ_START(Chain, ArgsSize, 0, DL); 536 537 // Collect the set of registers to pass to the function and their values. 538 // This will be emitted as a sequence of CopyToReg nodes glued to the call 539 // instruction. 540 SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass; 541 542 // Collect chains from all the memory opeations that copy arguments to the 543 // stack. They must follow the stack pointer adjustment above and precede the 544 // call instruction itself. 545 SmallVector<SDValue, 8> MemOpChains; 546 547 // VE needs to get address of callee function in a register 548 // So, prepare to copy it to SX12 here. 549 550 // If the callee is a GlobalAddress node (quite common, every direct call is) 551 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 552 // Likewise ExternalSymbol -> TargetExternalSymbol. 553 SDValue Callee = CLI.Callee; 554 555 bool IsPICCall = isPositionIndependent(); 556 557 // PC-relative references to external symbols should go through $stub. 558 // If so, we need to prepare GlobalBaseReg first. 559 const TargetMachine &TM = DAG.getTarget(); 560 const Module *Mod = DAG.getMachineFunction().getFunction().getParent(); 561 const GlobalValue *GV = nullptr; 562 auto *CalleeG = dyn_cast<GlobalAddressSDNode>(Callee); 563 if (CalleeG) 564 GV = CalleeG->getGlobal(); 565 bool Local = TM.shouldAssumeDSOLocal(*Mod, GV); 566 bool UsePlt = !Local; 567 MachineFunction &MF = DAG.getMachineFunction(); 568 569 // Turn GlobalAddress/ExternalSymbol node into a value node 570 // containing the address of them here. 571 if (CalleeG) { 572 if (IsPICCall) { 573 if (UsePlt) 574 Subtarget->getInstrInfo()->getGlobalBaseReg(&MF); 575 Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, 0); 576 Callee = DAG.getNode(VEISD::GETFUNPLT, DL, PtrVT, Callee); 577 } else { 578 Callee = 579 makeHiLoPair(Callee, VEMCExpr::VK_VE_HI32, VEMCExpr::VK_VE_LO32, DAG); 580 } 581 } else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) { 582 if (IsPICCall) { 583 if (UsePlt) 584 Subtarget->getInstrInfo()->getGlobalBaseReg(&MF); 585 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, 0); 586 Callee = DAG.getNode(VEISD::GETFUNPLT, DL, PtrVT, Callee); 587 } else { 588 Callee = 589 makeHiLoPair(Callee, VEMCExpr::VK_VE_HI32, VEMCExpr::VK_VE_LO32, DAG); 590 } 591 } 592 593 RegsToPass.push_back(std::make_pair(VE::SX12, Callee)); 594 595 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 596 CCValAssign &VA = ArgLocs[i]; 597 SDValue Arg = CLI.OutVals[i]; 598 599 // Promote the value if needed. 600 switch (VA.getLocInfo()) { 601 default: 602 llvm_unreachable("Unknown location info!"); 603 case CCValAssign::Full: 604 break; 605 case CCValAssign::SExt: 606 Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Arg); 607 break; 608 case CCValAssign::ZExt: 609 Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Arg); 610 break; 611 case CCValAssign::AExt: 612 Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg); 613 break; 614 case CCValAssign::BCvt: { 615 // Convert a float argument to i64 with padding. 616 // 63 31 0 617 // +------+------+ 618 // | float| 0 | 619 // +------+------+ 620 assert(VA.getLocVT() == MVT::i64); 621 assert(VA.getValVT() == MVT::f32); 622 SDValue Undef = SDValue( 623 DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::i64), 0); 624 SDValue Sub_f32 = DAG.getTargetConstant(VE::sub_f32, DL, MVT::i32); 625 Arg = SDValue(DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, DL, 626 MVT::i64, Undef, Arg, Sub_f32), 627 0); 628 break; 629 } 630 } 631 632 if (VA.isRegLoc()) { 633 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 634 if (!UseBoth) 635 continue; 636 VA = ArgLocs2[i]; 637 } 638 639 assert(VA.isMemLoc()); 640 641 // Create a store off the stack pointer for this argument. 642 SDValue StackPtr = DAG.getRegister(VE::SX11, PtrVT); 643 // The argument area starts at %fp/%sp + the size of reserved area. 644 SDValue PtrOff = 645 DAG.getIntPtrConstant(VA.getLocMemOffset() + ArgsBaseOffset, DL); 646 PtrOff = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr, PtrOff); 647 MemOpChains.push_back( 648 DAG.getStore(Chain, DL, Arg, PtrOff, MachinePointerInfo())); 649 } 650 651 // Emit all stores, make sure they occur before the call. 652 if (!MemOpChains.empty()) 653 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains); 654 655 // Build a sequence of CopyToReg nodes glued together with token chain and 656 // glue operands which copy the outgoing args into registers. The InGlue is 657 // necessary since all emitted instructions must be stuck together in order 658 // to pass the live physical registers. 659 SDValue InGlue; 660 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 661 Chain = DAG.getCopyToReg(Chain, DL, RegsToPass[i].first, 662 RegsToPass[i].second, InGlue); 663 InGlue = Chain.getValue(1); 664 } 665 666 // Build the operands for the call instruction itself. 667 SmallVector<SDValue, 8> Ops; 668 Ops.push_back(Chain); 669 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 670 Ops.push_back(DAG.getRegister(RegsToPass[i].first, 671 RegsToPass[i].second.getValueType())); 672 673 // Add a register mask operand representing the call-preserved registers. 674 const VERegisterInfo *TRI = Subtarget->getRegisterInfo(); 675 const uint32_t *Mask = 676 TRI->getCallPreservedMask(DAG.getMachineFunction(), CLI.CallConv); 677 assert(Mask && "Missing call preserved mask for calling convention"); 678 Ops.push_back(DAG.getRegisterMask(Mask)); 679 680 // Make sure the CopyToReg nodes are glued to the call instruction which 681 // consumes the registers. 682 if (InGlue.getNode()) 683 Ops.push_back(InGlue); 684 685 // Now the call itself. 686 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 687 Chain = DAG.getNode(VEISD::CALL, DL, NodeTys, Ops); 688 InGlue = Chain.getValue(1); 689 690 // Revert the stack pointer immediately after the call. 691 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(ArgsSize, DL, true), 692 DAG.getIntPtrConstant(0, DL, true), InGlue, DL); 693 InGlue = Chain.getValue(1); 694 695 // Now extract the return values. This is more or less the same as 696 // LowerFormalArguments. 697 698 // Assign locations to each value returned by this call. 699 SmallVector<CCValAssign, 16> RVLocs; 700 CCState RVInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), RVLocs, 701 *DAG.getContext()); 702 703 // Set inreg flag manually for codegen generated library calls that 704 // return float. 705 if (CLI.Ins.size() == 1 && CLI.Ins[0].VT == MVT::f32 && !CLI.CB) 706 CLI.Ins[0].Flags.setInReg(); 707 708 RVInfo.AnalyzeCallResult(CLI.Ins, getReturnCC(CLI.CallConv)); 709 710 // Copy all of the result registers out of their specified physreg. 711 for (unsigned i = 0; i != RVLocs.size(); ++i) { 712 CCValAssign &VA = RVLocs[i]; 713 unsigned Reg = VA.getLocReg(); 714 715 // When returning 'inreg {i32, i32 }', two consecutive i32 arguments can 716 // reside in the same register in the high and low bits. Reuse the 717 // CopyFromReg previous node to avoid duplicate copies. 718 SDValue RV; 719 if (RegisterSDNode *SrcReg = dyn_cast<RegisterSDNode>(Chain.getOperand(1))) 720 if (SrcReg->getReg() == Reg && Chain->getOpcode() == ISD::CopyFromReg) 721 RV = Chain.getValue(0); 722 723 // But usually we'll create a new CopyFromReg for a different register. 724 if (!RV.getNode()) { 725 RV = DAG.getCopyFromReg(Chain, DL, Reg, RVLocs[i].getLocVT(), InGlue); 726 Chain = RV.getValue(1); 727 InGlue = Chain.getValue(2); 728 } 729 730 // Get the high bits for i32 struct elements. 731 if (VA.getValVT() == MVT::i32 && VA.needsCustom()) 732 RV = DAG.getNode(ISD::SRL, DL, VA.getLocVT(), RV, 733 DAG.getConstant(32, DL, MVT::i32)); 734 735 // The callee promoted the return value, so insert an Assert?ext SDNode so 736 // we won't promote the value again in this function. 737 switch (VA.getLocInfo()) { 738 case CCValAssign::SExt: 739 RV = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), RV, 740 DAG.getValueType(VA.getValVT())); 741 break; 742 case CCValAssign::ZExt: 743 RV = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), RV, 744 DAG.getValueType(VA.getValVT())); 745 break; 746 case CCValAssign::BCvt: { 747 // Extract a float return value from i64 with padding. 748 // 63 31 0 749 // +------+------+ 750 // | float| 0 | 751 // +------+------+ 752 assert(VA.getLocVT() == MVT::i64); 753 assert(VA.getValVT() == MVT::f32); 754 SDValue Sub_f32 = DAG.getTargetConstant(VE::sub_f32, DL, MVT::i32); 755 RV = SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, 756 MVT::f32, RV, Sub_f32), 757 0); 758 break; 759 } 760 default: 761 break; 762 } 763 764 // Truncate the register down to the return value type. 765 if (VA.isExtInLoc()) 766 RV = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), RV); 767 768 InVals.push_back(RV); 769 } 770 771 return Chain; 772 } 773 774 bool VETargetLowering::isOffsetFoldingLegal( 775 const GlobalAddressSDNode *GA) const { 776 // VE uses 64 bit addressing, so we need multiple instructions to generate 777 // an address. Folding address with offset increases the number of 778 // instructions, so that we disable it here. Offsets will be folded in 779 // the DAG combine later if it worth to do so. 780 return false; 781 } 782 783 /// isFPImmLegal - Returns true if the target can instruction select the 784 /// specified FP immediate natively. If false, the legalizer will 785 /// materialize the FP immediate as a load from a constant pool. 786 bool VETargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT, 787 bool ForCodeSize) const { 788 return VT == MVT::f32 || VT == MVT::f64; 789 } 790 791 /// Determine if the target supports unaligned memory accesses. 792 /// 793 /// This function returns true if the target allows unaligned memory accesses 794 /// of the specified type in the given address space. If true, it also returns 795 /// whether the unaligned memory access is "fast" in the last argument by 796 /// reference. This is used, for example, in situations where an array 797 /// copy/move/set is converted to a sequence of store operations. Its use 798 /// helps to ensure that such replacements don't generate code that causes an 799 /// alignment error (trap) on the target machine. 800 bool VETargetLowering::allowsMisalignedMemoryAccesses(EVT VT, 801 unsigned AddrSpace, 802 unsigned Align, 803 MachineMemOperand::Flags, 804 bool *Fast) const { 805 if (Fast) { 806 // It's fast anytime on VE 807 *Fast = true; 808 } 809 return true; 810 } 811 812 VETargetLowering::VETargetLowering(const TargetMachine &TM, 813 const VESubtarget &STI) 814 : TargetLowering(TM), Subtarget(&STI) { 815 // Instructions which use registers as conditionals examine all the 816 // bits (as does the pseudo SELECT_CC expansion). I don't think it 817 // matters much whether it's ZeroOrOneBooleanContent, or 818 // ZeroOrNegativeOneBooleanContent, so, arbitrarily choose the 819 // former. 820 setBooleanContents(ZeroOrOneBooleanContent); 821 setBooleanVectorContents(ZeroOrOneBooleanContent); 822 823 initRegisterClasses(); 824 initSPUActions(); 825 initVPUActions(); 826 827 setStackPointerRegisterToSaveRestore(VE::SX11); 828 829 // We have target-specific dag combine patterns for the following nodes: 830 setTargetDAGCombine(ISD::TRUNCATE); 831 832 // Set function alignment to 16 bytes 833 setMinFunctionAlignment(Align(16)); 834 835 // VE stores all argument by 8 bytes alignment 836 setMinStackArgumentAlignment(Align(8)); 837 838 computeRegisterProperties(Subtarget->getRegisterInfo()); 839 } 840 841 const char *VETargetLowering::getTargetNodeName(unsigned Opcode) const { 842 #define TARGET_NODE_CASE(NAME) \ 843 case VEISD::NAME: \ 844 return "VEISD::" #NAME; 845 switch ((VEISD::NodeType)Opcode) { 846 case VEISD::FIRST_NUMBER: 847 break; 848 TARGET_NODE_CASE(Lo) 849 TARGET_NODE_CASE(Hi) 850 TARGET_NODE_CASE(GETFUNPLT) 851 TARGET_NODE_CASE(GETSTACKTOP) 852 TARGET_NODE_CASE(GETTLSADDR) 853 TARGET_NODE_CASE(MEMBARRIER) 854 TARGET_NODE_CASE(CALL) 855 TARGET_NODE_CASE(VEC_BROADCAST) 856 TARGET_NODE_CASE(RET_FLAG) 857 TARGET_NODE_CASE(GLOBAL_BASE_REG) 858 859 // Register the VVP_* SDNodes. 860 #define ADD_VVP_OP(VVP_NAME, ...) TARGET_NODE_CASE(VVP_NAME) 861 #include "VVPNodes.def" 862 } 863 #undef TARGET_NODE_CASE 864 return nullptr; 865 } 866 867 EVT VETargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &, 868 EVT VT) const { 869 return MVT::i32; 870 } 871 872 // Convert to a target node and set target flags. 873 SDValue VETargetLowering::withTargetFlags(SDValue Op, unsigned TF, 874 SelectionDAG &DAG) const { 875 if (const GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op)) 876 return DAG.getTargetGlobalAddress(GA->getGlobal(), SDLoc(GA), 877 GA->getValueType(0), GA->getOffset(), TF); 878 879 if (const BlockAddressSDNode *BA = dyn_cast<BlockAddressSDNode>(Op)) 880 return DAG.getTargetBlockAddress(BA->getBlockAddress(), Op.getValueType(), 881 0, TF); 882 883 if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op)) 884 return DAG.getTargetConstantPool(CP->getConstVal(), CP->getValueType(0), 885 CP->getAlign(), CP->getOffset(), TF); 886 887 if (const ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Op)) 888 return DAG.getTargetExternalSymbol(ES->getSymbol(), ES->getValueType(0), 889 TF); 890 891 if (const JumpTableSDNode *JT = dyn_cast<JumpTableSDNode>(Op)) 892 return DAG.getTargetJumpTable(JT->getIndex(), JT->getValueType(0), TF); 893 894 llvm_unreachable("Unhandled address SDNode"); 895 } 896 897 // Split Op into high and low parts according to HiTF and LoTF. 898 // Return an ADD node combining the parts. 899 SDValue VETargetLowering::makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF, 900 SelectionDAG &DAG) const { 901 SDLoc DL(Op); 902 EVT VT = Op.getValueType(); 903 SDValue Hi = DAG.getNode(VEISD::Hi, DL, VT, withTargetFlags(Op, HiTF, DAG)); 904 SDValue Lo = DAG.getNode(VEISD::Lo, DL, VT, withTargetFlags(Op, LoTF, DAG)); 905 return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo); 906 } 907 908 // Build SDNodes for producing an address from a GlobalAddress, ConstantPool, 909 // or ExternalSymbol SDNode. 910 SDValue VETargetLowering::makeAddress(SDValue Op, SelectionDAG &DAG) const { 911 SDLoc DL(Op); 912 EVT PtrVT = Op.getValueType(); 913 914 // Handle PIC mode first. VE needs a got load for every variable! 915 if (isPositionIndependent()) { 916 // GLOBAL_BASE_REG codegen'ed with call. Inform MFI that this 917 // function has calls. 918 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); 919 MFI.setHasCalls(true); 920 auto GlobalN = dyn_cast<GlobalAddressSDNode>(Op); 921 922 if (isa<ConstantPoolSDNode>(Op) || isa<JumpTableSDNode>(Op) || 923 (GlobalN && GlobalN->getGlobal()->hasLocalLinkage())) { 924 // Create following instructions for local linkage PIC code. 925 // lea %reg, label@gotoff_lo 926 // and %reg, %reg, (32)0 927 // lea.sl %reg, label@gotoff_hi(%reg, %got) 928 SDValue HiLo = makeHiLoPair(Op, VEMCExpr::VK_VE_GOTOFF_HI32, 929 VEMCExpr::VK_VE_GOTOFF_LO32, DAG); 930 SDValue GlobalBase = DAG.getNode(VEISD::GLOBAL_BASE_REG, DL, PtrVT); 931 return DAG.getNode(ISD::ADD, DL, PtrVT, GlobalBase, HiLo); 932 } 933 // Create following instructions for not local linkage PIC code. 934 // lea %reg, label@got_lo 935 // and %reg, %reg, (32)0 936 // lea.sl %reg, label@got_hi(%reg) 937 // ld %reg, (%reg, %got) 938 SDValue HiLo = makeHiLoPair(Op, VEMCExpr::VK_VE_GOT_HI32, 939 VEMCExpr::VK_VE_GOT_LO32, DAG); 940 SDValue GlobalBase = DAG.getNode(VEISD::GLOBAL_BASE_REG, DL, PtrVT); 941 SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, PtrVT, GlobalBase, HiLo); 942 return DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), AbsAddr, 943 MachinePointerInfo::getGOT(DAG.getMachineFunction())); 944 } 945 946 // This is one of the absolute code models. 947 switch (getTargetMachine().getCodeModel()) { 948 default: 949 llvm_unreachable("Unsupported absolute code model"); 950 case CodeModel::Small: 951 case CodeModel::Medium: 952 case CodeModel::Large: 953 // abs64. 954 return makeHiLoPair(Op, VEMCExpr::VK_VE_HI32, VEMCExpr::VK_VE_LO32, DAG); 955 } 956 } 957 958 /// Custom Lower { 959 960 // The mappings for emitLeading/TrailingFence for VE is designed by following 961 // http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html 962 Instruction *VETargetLowering::emitLeadingFence(IRBuilder<> &Builder, 963 Instruction *Inst, 964 AtomicOrdering Ord) const { 965 switch (Ord) { 966 case AtomicOrdering::NotAtomic: 967 case AtomicOrdering::Unordered: 968 llvm_unreachable("Invalid fence: unordered/non-atomic"); 969 case AtomicOrdering::Monotonic: 970 case AtomicOrdering::Acquire: 971 return nullptr; // Nothing to do 972 case AtomicOrdering::Release: 973 case AtomicOrdering::AcquireRelease: 974 return Builder.CreateFence(AtomicOrdering::Release); 975 case AtomicOrdering::SequentiallyConsistent: 976 if (!Inst->hasAtomicStore()) 977 return nullptr; // Nothing to do 978 return Builder.CreateFence(AtomicOrdering::SequentiallyConsistent); 979 } 980 llvm_unreachable("Unknown fence ordering in emitLeadingFence"); 981 } 982 983 Instruction *VETargetLowering::emitTrailingFence(IRBuilder<> &Builder, 984 Instruction *Inst, 985 AtomicOrdering Ord) const { 986 switch (Ord) { 987 case AtomicOrdering::NotAtomic: 988 case AtomicOrdering::Unordered: 989 llvm_unreachable("Invalid fence: unordered/not-atomic"); 990 case AtomicOrdering::Monotonic: 991 case AtomicOrdering::Release: 992 return nullptr; // Nothing to do 993 case AtomicOrdering::Acquire: 994 case AtomicOrdering::AcquireRelease: 995 return Builder.CreateFence(AtomicOrdering::Acquire); 996 case AtomicOrdering::SequentiallyConsistent: 997 return Builder.CreateFence(AtomicOrdering::SequentiallyConsistent); 998 } 999 llvm_unreachable("Unknown fence ordering in emitTrailingFence"); 1000 } 1001 1002 SDValue VETargetLowering::lowerATOMIC_FENCE(SDValue Op, 1003 SelectionDAG &DAG) const { 1004 SDLoc DL(Op); 1005 AtomicOrdering FenceOrdering = static_cast<AtomicOrdering>( 1006 cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue()); 1007 SyncScope::ID FenceSSID = static_cast<SyncScope::ID>( 1008 cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue()); 1009 1010 // VE uses Release consistency, so need a fence instruction if it is a 1011 // cross-thread fence. 1012 if (FenceSSID == SyncScope::System) { 1013 switch (FenceOrdering) { 1014 case AtomicOrdering::NotAtomic: 1015 case AtomicOrdering::Unordered: 1016 case AtomicOrdering::Monotonic: 1017 // No need to generate fencem instruction here. 1018 break; 1019 case AtomicOrdering::Acquire: 1020 // Generate "fencem 2" as acquire fence. 1021 return SDValue(DAG.getMachineNode(VE::FENCEM, DL, MVT::Other, 1022 DAG.getTargetConstant(2, DL, MVT::i32), 1023 Op.getOperand(0)), 1024 0); 1025 case AtomicOrdering::Release: 1026 // Generate "fencem 1" as release fence. 1027 return SDValue(DAG.getMachineNode(VE::FENCEM, DL, MVT::Other, 1028 DAG.getTargetConstant(1, DL, MVT::i32), 1029 Op.getOperand(0)), 1030 0); 1031 case AtomicOrdering::AcquireRelease: 1032 case AtomicOrdering::SequentiallyConsistent: 1033 // Generate "fencem 3" as acq_rel and seq_cst fence. 1034 // FIXME: "fencem 3" doesn't wait for for PCIe deveices accesses, 1035 // so seq_cst may require more instruction for them. 1036 return SDValue(DAG.getMachineNode(VE::FENCEM, DL, MVT::Other, 1037 DAG.getTargetConstant(3, DL, MVT::i32), 1038 Op.getOperand(0)), 1039 0); 1040 } 1041 } 1042 1043 // MEMBARRIER is a compiler barrier; it codegens to a no-op. 1044 return DAG.getNode(VEISD::MEMBARRIER, DL, MVT::Other, Op.getOperand(0)); 1045 } 1046 1047 SDValue VETargetLowering::lowerGlobalAddress(SDValue Op, 1048 SelectionDAG &DAG) const { 1049 return makeAddress(Op, DAG); 1050 } 1051 1052 SDValue VETargetLowering::lowerBlockAddress(SDValue Op, 1053 SelectionDAG &DAG) const { 1054 return makeAddress(Op, DAG); 1055 } 1056 1057 SDValue VETargetLowering::lowerConstantPool(SDValue Op, 1058 SelectionDAG &DAG) const { 1059 return makeAddress(Op, DAG); 1060 } 1061 1062 SDValue 1063 VETargetLowering::lowerToTLSGeneralDynamicModel(SDValue Op, 1064 SelectionDAG &DAG) const { 1065 SDLoc DL(Op); 1066 1067 // Generate the following code: 1068 // t1: ch,glue = callseq_start t0, 0, 0 1069 // t2: i64,ch,glue = VEISD::GETTLSADDR t1, label, t1:1 1070 // t3: ch,glue = callseq_end t2, 0, 0, t2:2 1071 // t4: i64,ch,glue = CopyFromReg t3, Register:i64 $sx0, t3:1 1072 SDValue Label = withTargetFlags(Op, 0, DAG); 1073 EVT PtrVT = Op.getValueType(); 1074 1075 // Lowering the machine isd will make sure everything is in the right 1076 // location. 1077 SDValue Chain = DAG.getEntryNode(); 1078 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 1079 const uint32_t *Mask = Subtarget->getRegisterInfo()->getCallPreservedMask( 1080 DAG.getMachineFunction(), CallingConv::C); 1081 Chain = DAG.getCALLSEQ_START(Chain, 64, 0, DL); 1082 SDValue Args[] = {Chain, Label, DAG.getRegisterMask(Mask), Chain.getValue(1)}; 1083 Chain = DAG.getNode(VEISD::GETTLSADDR, DL, NodeTys, Args); 1084 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(64, DL, true), 1085 DAG.getIntPtrConstant(0, DL, true), 1086 Chain.getValue(1), DL); 1087 Chain = DAG.getCopyFromReg(Chain, DL, VE::SX0, PtrVT, Chain.getValue(1)); 1088 1089 // GETTLSADDR will be codegen'ed as call. Inform MFI that function has calls. 1090 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); 1091 MFI.setHasCalls(true); 1092 1093 // Also generate code to prepare a GOT register if it is PIC. 1094 if (isPositionIndependent()) { 1095 MachineFunction &MF = DAG.getMachineFunction(); 1096 Subtarget->getInstrInfo()->getGlobalBaseReg(&MF); 1097 } 1098 1099 return Chain; 1100 } 1101 1102 SDValue VETargetLowering::lowerGlobalTLSAddress(SDValue Op, 1103 SelectionDAG &DAG) const { 1104 // The current implementation of nld (2.26) doesn't allow local exec model 1105 // code described in VE-tls_v1.1.pdf (*1) as its input. Instead, we always 1106 // generate the general dynamic model code sequence. 1107 // 1108 // *1: https://www.nec.com/en/global/prod/hpc/aurora/document/VE-tls_v1.1.pdf 1109 return lowerToTLSGeneralDynamicModel(Op, DAG); 1110 } 1111 1112 SDValue VETargetLowering::lowerJumpTable(SDValue Op, SelectionDAG &DAG) const { 1113 return makeAddress(Op, DAG); 1114 } 1115 1116 // Lower a f128 load into two f64 loads. 1117 static SDValue lowerLoadF128(SDValue Op, SelectionDAG &DAG) { 1118 SDLoc DL(Op); 1119 LoadSDNode *LdNode = dyn_cast<LoadSDNode>(Op.getNode()); 1120 assert(LdNode && LdNode->getOffset().isUndef() && "Unexpected node type"); 1121 unsigned Alignment = LdNode->getAlign().value(); 1122 if (Alignment > 8) 1123 Alignment = 8; 1124 1125 SDValue Lo64 = 1126 DAG.getLoad(MVT::f64, DL, LdNode->getChain(), LdNode->getBasePtr(), 1127 LdNode->getPointerInfo(), Alignment, 1128 LdNode->isVolatile() ? MachineMemOperand::MOVolatile 1129 : MachineMemOperand::MONone); 1130 EVT AddrVT = LdNode->getBasePtr().getValueType(); 1131 SDValue HiPtr = DAG.getNode(ISD::ADD, DL, AddrVT, LdNode->getBasePtr(), 1132 DAG.getConstant(8, DL, AddrVT)); 1133 SDValue Hi64 = 1134 DAG.getLoad(MVT::f64, DL, LdNode->getChain(), HiPtr, 1135 LdNode->getPointerInfo(), Alignment, 1136 LdNode->isVolatile() ? MachineMemOperand::MOVolatile 1137 : MachineMemOperand::MONone); 1138 1139 SDValue SubRegEven = DAG.getTargetConstant(VE::sub_even, DL, MVT::i32); 1140 SDValue SubRegOdd = DAG.getTargetConstant(VE::sub_odd, DL, MVT::i32); 1141 1142 // VE stores Hi64 to 8(addr) and Lo64 to 0(addr) 1143 SDNode *InFP128 = 1144 DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::f128); 1145 InFP128 = DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, DL, MVT::f128, 1146 SDValue(InFP128, 0), Hi64, SubRegEven); 1147 InFP128 = DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, DL, MVT::f128, 1148 SDValue(InFP128, 0), Lo64, SubRegOdd); 1149 SDValue OutChains[2] = {SDValue(Lo64.getNode(), 1), 1150 SDValue(Hi64.getNode(), 1)}; 1151 SDValue OutChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains); 1152 SDValue Ops[2] = {SDValue(InFP128, 0), OutChain}; 1153 return DAG.getMergeValues(Ops, DL); 1154 } 1155 1156 SDValue VETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const { 1157 LoadSDNode *LdNode = cast<LoadSDNode>(Op.getNode()); 1158 1159 SDValue BasePtr = LdNode->getBasePtr(); 1160 if (isa<FrameIndexSDNode>(BasePtr.getNode())) { 1161 // Do not expand store instruction with frame index here because of 1162 // dependency problems. We expand it later in eliminateFrameIndex(). 1163 return Op; 1164 } 1165 1166 EVT MemVT = LdNode->getMemoryVT(); 1167 if (MemVT == MVT::f128) 1168 return lowerLoadF128(Op, DAG); 1169 1170 return Op; 1171 } 1172 1173 // Lower a f128 store into two f64 stores. 1174 static SDValue lowerStoreF128(SDValue Op, SelectionDAG &DAG) { 1175 SDLoc DL(Op); 1176 StoreSDNode *StNode = dyn_cast<StoreSDNode>(Op.getNode()); 1177 assert(StNode && StNode->getOffset().isUndef() && "Unexpected node type"); 1178 1179 SDValue SubRegEven = DAG.getTargetConstant(VE::sub_even, DL, MVT::i32); 1180 SDValue SubRegOdd = DAG.getTargetConstant(VE::sub_odd, DL, MVT::i32); 1181 1182 SDNode *Hi64 = DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, MVT::i64, 1183 StNode->getValue(), SubRegEven); 1184 SDNode *Lo64 = DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, MVT::i64, 1185 StNode->getValue(), SubRegOdd); 1186 1187 unsigned Alignment = StNode->getAlign().value(); 1188 if (Alignment > 8) 1189 Alignment = 8; 1190 1191 // VE stores Hi64 to 8(addr) and Lo64 to 0(addr) 1192 SDValue OutChains[2]; 1193 OutChains[0] = 1194 DAG.getStore(StNode->getChain(), DL, SDValue(Lo64, 0), 1195 StNode->getBasePtr(), MachinePointerInfo(), Alignment, 1196 StNode->isVolatile() ? MachineMemOperand::MOVolatile 1197 : MachineMemOperand::MONone); 1198 EVT AddrVT = StNode->getBasePtr().getValueType(); 1199 SDValue HiPtr = DAG.getNode(ISD::ADD, DL, AddrVT, StNode->getBasePtr(), 1200 DAG.getConstant(8, DL, AddrVT)); 1201 OutChains[1] = 1202 DAG.getStore(StNode->getChain(), DL, SDValue(Hi64, 0), HiPtr, 1203 MachinePointerInfo(), Alignment, 1204 StNode->isVolatile() ? MachineMemOperand::MOVolatile 1205 : MachineMemOperand::MONone); 1206 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains); 1207 } 1208 1209 SDValue VETargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const { 1210 StoreSDNode *StNode = cast<StoreSDNode>(Op.getNode()); 1211 assert(StNode && StNode->getOffset().isUndef() && "Unexpected node type"); 1212 1213 SDValue BasePtr = StNode->getBasePtr(); 1214 if (isa<FrameIndexSDNode>(BasePtr.getNode())) { 1215 // Do not expand store instruction with frame index here because of 1216 // dependency problems. We expand it later in eliminateFrameIndex(). 1217 return Op; 1218 } 1219 1220 EVT MemVT = StNode->getMemoryVT(); 1221 if (MemVT == MVT::f128) 1222 return lowerStoreF128(Op, DAG); 1223 1224 // Otherwise, ask llvm to expand it. 1225 return SDValue(); 1226 } 1227 1228 SDValue VETargetLowering::lowerVASTART(SDValue Op, SelectionDAG &DAG) const { 1229 MachineFunction &MF = DAG.getMachineFunction(); 1230 VEMachineFunctionInfo *FuncInfo = MF.getInfo<VEMachineFunctionInfo>(); 1231 auto PtrVT = getPointerTy(DAG.getDataLayout()); 1232 1233 // Need frame address to find the address of VarArgsFrameIndex. 1234 MF.getFrameInfo().setFrameAddressIsTaken(true); 1235 1236 // vastart just stores the address of the VarArgsFrameIndex slot into the 1237 // memory location argument. 1238 SDLoc DL(Op); 1239 SDValue Offset = 1240 DAG.getNode(ISD::ADD, DL, PtrVT, DAG.getRegister(VE::SX9, PtrVT), 1241 DAG.getIntPtrConstant(FuncInfo->getVarArgsFrameOffset(), DL)); 1242 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); 1243 return DAG.getStore(Op.getOperand(0), DL, Offset, Op.getOperand(1), 1244 MachinePointerInfo(SV)); 1245 } 1246 1247 SDValue VETargetLowering::lowerVAARG(SDValue Op, SelectionDAG &DAG) const { 1248 SDNode *Node = Op.getNode(); 1249 EVT VT = Node->getValueType(0); 1250 SDValue InChain = Node->getOperand(0); 1251 SDValue VAListPtr = Node->getOperand(1); 1252 EVT PtrVT = VAListPtr.getValueType(); 1253 const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue(); 1254 SDLoc DL(Node); 1255 SDValue VAList = 1256 DAG.getLoad(PtrVT, DL, InChain, VAListPtr, MachinePointerInfo(SV)); 1257 SDValue Chain = VAList.getValue(1); 1258 SDValue NextPtr; 1259 1260 if (VT == MVT::f128) { 1261 // VE f128 values must be stored with 16 bytes alignment. We doesn't 1262 // know the actual alignment of VAList, so we take alignment of it 1263 // dyanmically. 1264 int Align = 16; 1265 VAList = DAG.getNode(ISD::ADD, DL, PtrVT, VAList, 1266 DAG.getConstant(Align - 1, DL, PtrVT)); 1267 VAList = DAG.getNode(ISD::AND, DL, PtrVT, VAList, 1268 DAG.getConstant(-Align, DL, PtrVT)); 1269 // Increment the pointer, VAList, by 16 to the next vaarg. 1270 NextPtr = 1271 DAG.getNode(ISD::ADD, DL, PtrVT, VAList, DAG.getIntPtrConstant(16, DL)); 1272 } else if (VT == MVT::f32) { 1273 // float --> need special handling like below. 1274 // 0 4 1275 // +------+------+ 1276 // | empty| float| 1277 // +------+------+ 1278 // Increment the pointer, VAList, by 8 to the next vaarg. 1279 NextPtr = 1280 DAG.getNode(ISD::ADD, DL, PtrVT, VAList, DAG.getIntPtrConstant(8, DL)); 1281 // Then, adjust VAList. 1282 unsigned InternalOffset = 4; 1283 VAList = DAG.getNode(ISD::ADD, DL, PtrVT, VAList, 1284 DAG.getConstant(InternalOffset, DL, PtrVT)); 1285 } else { 1286 // Increment the pointer, VAList, by 8 to the next vaarg. 1287 NextPtr = 1288 DAG.getNode(ISD::ADD, DL, PtrVT, VAList, DAG.getIntPtrConstant(8, DL)); 1289 } 1290 1291 // Store the incremented VAList to the legalized pointer. 1292 InChain = DAG.getStore(Chain, DL, NextPtr, VAListPtr, MachinePointerInfo(SV)); 1293 1294 // Load the actual argument out of the pointer VAList. 1295 // We can't count on greater alignment than the word size. 1296 return DAG.getLoad(VT, DL, InChain, VAList, MachinePointerInfo(), 1297 std::min(PtrVT.getSizeInBits(), VT.getSizeInBits()) / 8); 1298 } 1299 1300 SDValue VETargetLowering::lowerDYNAMIC_STACKALLOC(SDValue Op, 1301 SelectionDAG &DAG) const { 1302 // Generate following code. 1303 // (void)__llvm_grow_stack(size); 1304 // ret = GETSTACKTOP; // pseudo instruction 1305 SDLoc DL(Op); 1306 1307 // Get the inputs. 1308 SDNode *Node = Op.getNode(); 1309 SDValue Chain = Op.getOperand(0); 1310 SDValue Size = Op.getOperand(1); 1311 MaybeAlign Alignment(Op.getConstantOperandVal(2)); 1312 EVT VT = Node->getValueType(0); 1313 1314 // Chain the dynamic stack allocation so that it doesn't modify the stack 1315 // pointer when other instructions are using the stack. 1316 Chain = DAG.getCALLSEQ_START(Chain, 0, 0, DL); 1317 1318 const TargetFrameLowering &TFI = *Subtarget->getFrameLowering(); 1319 Align StackAlign = TFI.getStackAlign(); 1320 bool NeedsAlign = Alignment.valueOrOne() > StackAlign; 1321 1322 // Prepare arguments 1323 TargetLowering::ArgListTy Args; 1324 TargetLowering::ArgListEntry Entry; 1325 Entry.Node = Size; 1326 Entry.Ty = Entry.Node.getValueType().getTypeForEVT(*DAG.getContext()); 1327 Args.push_back(Entry); 1328 if (NeedsAlign) { 1329 Entry.Node = DAG.getConstant(~(Alignment->value() - 1ULL), DL, VT); 1330 Entry.Ty = Entry.Node.getValueType().getTypeForEVT(*DAG.getContext()); 1331 Args.push_back(Entry); 1332 } 1333 Type *RetTy = Type::getVoidTy(*DAG.getContext()); 1334 1335 EVT PtrVT = Op.getValueType(); 1336 SDValue Callee; 1337 if (NeedsAlign) { 1338 Callee = DAG.getTargetExternalSymbol("__ve_grow_stack_align", PtrVT, 0); 1339 } else { 1340 Callee = DAG.getTargetExternalSymbol("__ve_grow_stack", PtrVT, 0); 1341 } 1342 1343 TargetLowering::CallLoweringInfo CLI(DAG); 1344 CLI.setDebugLoc(DL) 1345 .setChain(Chain) 1346 .setCallee(CallingConv::PreserveAll, RetTy, Callee, std::move(Args)) 1347 .setDiscardResult(true); 1348 std::pair<SDValue, SDValue> pair = LowerCallTo(CLI); 1349 Chain = pair.second; 1350 SDValue Result = DAG.getNode(VEISD::GETSTACKTOP, DL, VT, Chain); 1351 if (NeedsAlign) { 1352 Result = DAG.getNode(ISD::ADD, DL, VT, Result, 1353 DAG.getConstant((Alignment->value() - 1ULL), DL, VT)); 1354 Result = DAG.getNode(ISD::AND, DL, VT, Result, 1355 DAG.getConstant(~(Alignment->value() - 1ULL), DL, VT)); 1356 } 1357 // Chain = Result.getValue(1); 1358 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(0, DL, true), 1359 DAG.getIntPtrConstant(0, DL, true), SDValue(), DL); 1360 1361 SDValue Ops[2] = {Result, Chain}; 1362 return DAG.getMergeValues(Ops, DL); 1363 } 1364 1365 static SDValue getSplatValue(SDNode *N) { 1366 if (auto *BuildVec = dyn_cast<BuildVectorSDNode>(N)) { 1367 return BuildVec->getSplatValue(); 1368 } 1369 return SDValue(); 1370 } 1371 1372 SDValue VETargetLowering::lowerBUILD_VECTOR(SDValue Op, 1373 SelectionDAG &DAG) const { 1374 SDLoc DL(Op); 1375 unsigned NumEls = Op.getValueType().getVectorNumElements(); 1376 MVT ElemVT = Op.getSimpleValueType().getVectorElementType(); 1377 1378 if (SDValue ScalarV = getSplatValue(Op.getNode())) { 1379 // lower to VEC_BROADCAST 1380 MVT LegalResVT = MVT::getVectorVT(ElemVT, 256); 1381 1382 auto AVL = DAG.getConstant(NumEls, DL, MVT::i32); 1383 return DAG.getNode(VEISD::VEC_BROADCAST, DL, LegalResVT, Op.getOperand(0), 1384 AVL); 1385 } 1386 1387 // Expand 1388 return SDValue(); 1389 } 1390 1391 SDValue VETargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { 1392 switch (Op.getOpcode()) { 1393 default: 1394 llvm_unreachable("Should not custom lower this!"); 1395 case ISD::ATOMIC_FENCE: 1396 return lowerATOMIC_FENCE(Op, DAG); 1397 case ISD::BlockAddress: 1398 return lowerBlockAddress(Op, DAG); 1399 case ISD::ConstantPool: 1400 return lowerConstantPool(Op, DAG); 1401 case ISD::DYNAMIC_STACKALLOC: 1402 return lowerDYNAMIC_STACKALLOC(Op, DAG); 1403 case ISD::GlobalAddress: 1404 return lowerGlobalAddress(Op, DAG); 1405 case ISD::GlobalTLSAddress: 1406 return lowerGlobalTLSAddress(Op, DAG); 1407 case ISD::JumpTable: 1408 return lowerJumpTable(Op, DAG); 1409 case ISD::LOAD: 1410 return lowerLOAD(Op, DAG); 1411 case ISD::BUILD_VECTOR: 1412 return lowerBUILD_VECTOR(Op, DAG); 1413 case ISD::STORE: 1414 return lowerSTORE(Op, DAG); 1415 case ISD::VASTART: 1416 return lowerVASTART(Op, DAG); 1417 case ISD::VAARG: 1418 return lowerVAARG(Op, DAG); 1419 1420 #define ADD_BINARY_VVP_OP(VVP_NAME, ISD_NAME) case ISD::ISD_NAME: 1421 #include "VVPNodes.def" 1422 return lowerToVVP(Op, DAG); 1423 } 1424 } 1425 /// } Custom Lower 1426 1427 /// JumpTable for VE. 1428 /// 1429 /// VE cannot generate relocatable symbol in jump table. VE cannot 1430 /// generate expressions using symbols in both text segment and data 1431 /// segment like below. 1432 /// .4byte .LBB0_2-.LJTI0_0 1433 /// So, we generate offset from the top of function like below as 1434 /// a custom label. 1435 /// .4byte .LBB0_2-<function name> 1436 1437 unsigned VETargetLowering::getJumpTableEncoding() const { 1438 // Use custom label for PIC. 1439 if (isPositionIndependent()) 1440 return MachineJumpTableInfo::EK_Custom32; 1441 1442 // Otherwise, use the normal jump table encoding heuristics. 1443 return TargetLowering::getJumpTableEncoding(); 1444 } 1445 1446 const MCExpr *VETargetLowering::LowerCustomJumpTableEntry( 1447 const MachineJumpTableInfo *MJTI, const MachineBasicBlock *MBB, 1448 unsigned Uid, MCContext &Ctx) const { 1449 assert(isPositionIndependent()); 1450 1451 // Generate custom label for PIC like below. 1452 // .4bytes .LBB0_2-<function name> 1453 const auto *Value = MCSymbolRefExpr::create(MBB->getSymbol(), Ctx); 1454 MCSymbol *Sym = Ctx.getOrCreateSymbol(MBB->getParent()->getName().data()); 1455 const auto *Base = MCSymbolRefExpr::create(Sym, Ctx); 1456 return MCBinaryExpr::createSub(Value, Base, Ctx); 1457 } 1458 1459 SDValue VETargetLowering::getPICJumpTableRelocBase(SDValue Table, 1460 SelectionDAG &DAG) const { 1461 assert(isPositionIndependent()); 1462 SDLoc DL(Table); 1463 Function *Function = &DAG.getMachineFunction().getFunction(); 1464 assert(Function != nullptr); 1465 auto PtrTy = getPointerTy(DAG.getDataLayout(), Function->getAddressSpace()); 1466 1467 // In the jump table, we have following values in PIC mode. 1468 // .4bytes .LBB0_2-<function name> 1469 // We need to add this value and the address of this function to generate 1470 // .LBB0_2 label correctly under PIC mode. So, we want to generate following 1471 // instructions: 1472 // lea %reg, fun@gotoff_lo 1473 // and %reg, %reg, (32)0 1474 // lea.sl %reg, fun@gotoff_hi(%reg, %got) 1475 // In order to do so, we need to genarate correctly marked DAG node using 1476 // makeHiLoPair. 1477 SDValue Op = DAG.getGlobalAddress(Function, DL, PtrTy); 1478 SDValue HiLo = makeHiLoPair(Op, VEMCExpr::VK_VE_GOTOFF_HI32, 1479 VEMCExpr::VK_VE_GOTOFF_LO32, DAG); 1480 SDValue GlobalBase = DAG.getNode(VEISD::GLOBAL_BASE_REG, DL, PtrTy); 1481 return DAG.getNode(ISD::ADD, DL, PtrTy, GlobalBase, HiLo); 1482 } 1483 1484 static bool isI32Insn(const SDNode *User, const SDNode *N) { 1485 switch (User->getOpcode()) { 1486 default: 1487 return false; 1488 case ISD::ADD: 1489 case ISD::SUB: 1490 case ISD::MUL: 1491 case ISD::SDIV: 1492 case ISD::UDIV: 1493 case ISD::SETCC: 1494 case ISD::SMIN: 1495 case ISD::SMAX: 1496 case ISD::SHL: 1497 case ISD::SRA: 1498 case ISD::BSWAP: 1499 case ISD::SINT_TO_FP: 1500 case ISD::UINT_TO_FP: 1501 case ISD::BR_CC: 1502 case ISD::BITCAST: 1503 case ISD::ATOMIC_CMP_SWAP: 1504 case ISD::ATOMIC_SWAP: 1505 return true; 1506 case ISD::SRL: 1507 if (N->getOperand(0).getOpcode() != ISD::SRL) 1508 return true; 1509 // (srl (trunc (srl ...))) may be optimized by combining srl, so 1510 // doesn't optimize trunc now. 1511 return false; 1512 case ISD::SELECT_CC: 1513 if (User->getOperand(2).getNode() != N && 1514 User->getOperand(3).getNode() != N) 1515 return true; 1516 LLVM_FALLTHROUGH; 1517 case ISD::AND: 1518 case ISD::OR: 1519 case ISD::XOR: 1520 case ISD::SELECT: 1521 case ISD::CopyToReg: 1522 // Check all use of selections, bit operations, and copies. If all of them 1523 // are safe, optimize truncate to extract_subreg. 1524 for (SDNode::use_iterator UI = User->use_begin(), UE = User->use_end(); 1525 UI != UE; ++UI) { 1526 switch ((*UI)->getOpcode()) { 1527 default: 1528 // If the use is an instruction which treats the source operand as i32, 1529 // it is safe to avoid truncate here. 1530 if (isI32Insn(*UI, N)) 1531 continue; 1532 break; 1533 case ISD::ANY_EXTEND: 1534 case ISD::SIGN_EXTEND: 1535 case ISD::ZERO_EXTEND: { 1536 // Special optimizations to the combination of ext and trunc. 1537 // (ext ... (select ... (trunc ...))) is safe to avoid truncate here 1538 // since this truncate instruction clears higher 32 bits which is filled 1539 // by one of ext instructions later. 1540 assert(N->getValueType(0) == MVT::i32 && 1541 "find truncate to not i32 integer"); 1542 if (User->getOpcode() == ISD::SELECT_CC || 1543 User->getOpcode() == ISD::SELECT) 1544 continue; 1545 break; 1546 } 1547 } 1548 return false; 1549 } 1550 return true; 1551 } 1552 } 1553 1554 // Optimize TRUNCATE in DAG combining. Optimizing it in CUSTOM lower is 1555 // sometime too early. Optimizing it in DAG pattern matching in VEInstrInfo.td 1556 // is sometime too late. So, doing it at here. 1557 SDValue VETargetLowering::combineTRUNCATE(SDNode *N, 1558 DAGCombinerInfo &DCI) const { 1559 assert(N->getOpcode() == ISD::TRUNCATE && 1560 "Should be called with a TRUNCATE node"); 1561 1562 SelectionDAG &DAG = DCI.DAG; 1563 SDLoc DL(N); 1564 EVT VT = N->getValueType(0); 1565 1566 // We prefer to do this when all types are legal. 1567 if (!DCI.isAfterLegalizeDAG()) 1568 return SDValue(); 1569 1570 // Skip combine TRUNCATE atm if the operand of TRUNCATE might be a constant. 1571 if (N->getOperand(0)->getOpcode() == ISD::SELECT_CC && 1572 isa<ConstantSDNode>(N->getOperand(0)->getOperand(0)) && 1573 isa<ConstantSDNode>(N->getOperand(0)->getOperand(1))) 1574 return SDValue(); 1575 1576 // Check all use of this TRUNCATE. 1577 for (SDNode::use_iterator UI = N->use_begin(), UE = N->use_end(); UI != UE; 1578 ++UI) { 1579 SDNode *User = *UI; 1580 1581 // Make sure that we're not going to replace TRUNCATE for non i32 1582 // instructions. 1583 // 1584 // FIXME: Although we could sometimes handle this, and it does occur in 1585 // practice that one of the condition inputs to the select is also one of 1586 // the outputs, we currently can't deal with this. 1587 if (isI32Insn(User, N)) 1588 continue; 1589 1590 return SDValue(); 1591 } 1592 1593 SDValue SubI32 = DAG.getTargetConstant(VE::sub_i32, DL, MVT::i32); 1594 return SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, VT, 1595 N->getOperand(0), SubI32), 1596 0); 1597 } 1598 1599 SDValue VETargetLowering::PerformDAGCombine(SDNode *N, 1600 DAGCombinerInfo &DCI) const { 1601 switch (N->getOpcode()) { 1602 default: 1603 break; 1604 case ISD::TRUNCATE: 1605 return combineTRUNCATE(N, DCI); 1606 } 1607 1608 return SDValue(); 1609 } 1610 1611 //===----------------------------------------------------------------------===// 1612 // VE Inline Assembly Support 1613 //===----------------------------------------------------------------------===// 1614 1615 VETargetLowering::ConstraintType 1616 VETargetLowering::getConstraintType(StringRef Constraint) const { 1617 if (Constraint.size() == 1) { 1618 switch (Constraint[0]) { 1619 default: 1620 break; 1621 case 'v': // vector registers 1622 return C_RegisterClass; 1623 } 1624 } 1625 return TargetLowering::getConstraintType(Constraint); 1626 } 1627 1628 std::pair<unsigned, const TargetRegisterClass *> 1629 VETargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 1630 StringRef Constraint, 1631 MVT VT) const { 1632 const TargetRegisterClass *RC = nullptr; 1633 if (Constraint.size() == 1) { 1634 switch (Constraint[0]) { 1635 default: 1636 return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); 1637 case 'r': 1638 RC = &VE::I64RegClass; 1639 break; 1640 case 'v': 1641 RC = &VE::V64RegClass; 1642 break; 1643 } 1644 return std::make_pair(0U, RC); 1645 } 1646 1647 return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); 1648 } 1649 1650 //===----------------------------------------------------------------------===// 1651 // VE Target Optimization Support 1652 //===----------------------------------------------------------------------===// 1653 1654 unsigned VETargetLowering::getMinimumJumpTableEntries() const { 1655 // Specify 8 for PIC model to relieve the impact of PIC load instructions. 1656 if (isJumpTableRelative()) 1657 return 8; 1658 1659 return TargetLowering::getMinimumJumpTableEntries(); 1660 } 1661 1662 bool VETargetLowering::hasAndNot(SDValue Y) const { 1663 EVT VT = Y.getValueType(); 1664 1665 // VE doesn't have vector and not instruction. 1666 if (VT.isVector()) 1667 return false; 1668 1669 // VE allows different immediate values for X and Y where ~X & Y. 1670 // Only simm7 works for X, and only mimm works for Y on VE. However, this 1671 // function is used to check whether an immediate value is OK for and-not 1672 // instruction as both X and Y. Generating additional instruction to 1673 // retrieve an immediate value is no good since the purpose of this 1674 // function is to convert a series of 3 instructions to another series of 1675 // 3 instructions with better parallelism. Therefore, we return false 1676 // for all immediate values now. 1677 // FIXME: Change hasAndNot function to have two operands to make it work 1678 // correctly with Aurora VE. 1679 if (isa<ConstantSDNode>(Y)) 1680 return false; 1681 1682 // It's ok for generic registers. 1683 return true; 1684 } 1685 1686 /// \returns the VVP_* SDNode opcode corresponsing to \p OC. 1687 static Optional<unsigned> getVVPOpcode(unsigned OC) { 1688 switch (OC) { 1689 #define ADD_VVP_OP(VVPNAME, SDNAME) \ 1690 case VEISD::VVPNAME: \ 1691 case ISD::SDNAME: \ 1692 return VEISD::VVPNAME; 1693 #include "VVPNodes.def" 1694 } 1695 return None; 1696 } 1697 1698 SDValue VETargetLowering::lowerToVVP(SDValue Op, SelectionDAG &DAG) const { 1699 // Can we represent this as a VVP node. 1700 auto OCOpt = getVVPOpcode(Op->getOpcode()); 1701 if (!OCOpt.hasValue()) 1702 return SDValue(); 1703 unsigned VVPOC = OCOpt.getValue(); 1704 1705 // The representative and legalized vector type of this operation. 1706 EVT OpVecVT = Op.getValueType(); 1707 EVT LegalVecVT = getTypeToTransformTo(*DAG.getContext(), OpVecVT); 1708 1709 // Materialize the VL parameter. 1710 SDLoc DL(Op); 1711 SDValue AVL = DAG.getConstant(OpVecVT.getVectorNumElements(), DL, MVT::i32); 1712 MVT MaskVT = MVT::v256i1; 1713 SDValue ConstTrue = DAG.getConstant(1, DL, MVT::i32); 1714 SDValue Mask = DAG.getNode(VEISD::VEC_BROADCAST, DL, MaskVT, 1715 ConstTrue); // emit a VEISD::VEC_BROADCAST here. 1716 1717 // Categories we are interested in. 1718 bool IsBinaryOp = false; 1719 1720 switch (VVPOC) { 1721 #define ADD_BINARY_VVP_OP(VVPNAME, ...) \ 1722 case VEISD::VVPNAME: \ 1723 IsBinaryOp = true; \ 1724 break; 1725 #include "VVPNodes.def" 1726 } 1727 1728 if (IsBinaryOp) { 1729 assert(LegalVecVT.isSimple()); 1730 return DAG.getNode(VVPOC, DL, LegalVecVT, Op->getOperand(0), 1731 Op->getOperand(1), Mask, AVL); 1732 } 1733 llvm_unreachable("lowerToVVP called for unexpected SDNode."); 1734 } 1735