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