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