1 //===- ARCISelLowering.cpp - ARC DAG Lowering Impl --------------*- C++ -*-===// 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 ARCTargetLowering class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "ARCISelLowering.h" 14 #include "ARC.h" 15 #include "ARCMachineFunctionInfo.h" 16 #include "ARCSubtarget.h" 17 #include "ARCTargetMachine.h" 18 #include "MCTargetDesc/ARCInfo.h" 19 #include "llvm/CodeGen/CallingConvLower.h" 20 #include "llvm/CodeGen/MachineFrameInfo.h" 21 #include "llvm/CodeGen/MachineFunction.h" 22 #include "llvm/CodeGen/MachineInstrBuilder.h" 23 #include "llvm/CodeGen/MachineJumpTableInfo.h" 24 #include "llvm/CodeGen/MachineRegisterInfo.h" 25 #include "llvm/CodeGen/ValueTypes.h" 26 #include "llvm/IR/CallingConv.h" 27 #include "llvm/IR/Intrinsics.h" 28 #include "llvm/Support/Debug.h" 29 #include <algorithm> 30 31 #define DEBUG_TYPE "arc-lower" 32 33 using namespace llvm; 34 35 static SDValue lowerCallResult(SDValue Chain, SDValue InGlue, 36 const SmallVectorImpl<CCValAssign> &RVLocs, 37 SDLoc dl, SelectionDAG &DAG, 38 SmallVectorImpl<SDValue> &InVals); 39 40 static ARCCC::CondCode ISDCCtoARCCC(ISD::CondCode isdCC) { 41 switch (isdCC) { 42 case ISD::SETUEQ: 43 return ARCCC::EQ; 44 case ISD::SETUGT: 45 return ARCCC::HI; 46 case ISD::SETUGE: 47 return ARCCC::HS; 48 case ISD::SETULT: 49 return ARCCC::LO; 50 case ISD::SETULE: 51 return ARCCC::LS; 52 case ISD::SETUNE: 53 return ARCCC::NE; 54 case ISD::SETEQ: 55 return ARCCC::EQ; 56 case ISD::SETGT: 57 return ARCCC::GT; 58 case ISD::SETGE: 59 return ARCCC::GE; 60 case ISD::SETLT: 61 return ARCCC::LT; 62 case ISD::SETLE: 63 return ARCCC::LE; 64 case ISD::SETNE: 65 return ARCCC::NE; 66 default: 67 llvm_unreachable("Unhandled ISDCC code."); 68 } 69 } 70 71 void ARCTargetLowering::ReplaceNodeResults(SDNode *N, 72 SmallVectorImpl<SDValue> &Results, 73 SelectionDAG &DAG) const { 74 LLVM_DEBUG(dbgs() << "[ARC-ISEL] ReplaceNodeResults "); 75 LLVM_DEBUG(N->dump(&DAG)); 76 LLVM_DEBUG(dbgs() << "; use_count=" << N->use_size() << "\n"); 77 78 switch (N->getOpcode()) { 79 case ISD::READCYCLECOUNTER: 80 if (N->getValueType(0) == MVT::i64) { 81 // We read the TIMER0 and zero-extend it to 64-bits as the intrinsic 82 // requires. 83 SDValue V = 84 DAG.getNode(ISD::READCYCLECOUNTER, SDLoc(N), 85 DAG.getVTList(MVT::i32, MVT::Other), N->getOperand(0)); 86 SDValue Op = DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N), MVT::i64, V); 87 Results.push_back(Op); 88 Results.push_back(V.getValue(1)); 89 } 90 break; 91 default: 92 break; 93 } 94 } 95 96 ARCTargetLowering::ARCTargetLowering(const TargetMachine &TM, 97 const ARCSubtarget &Subtarget) 98 : TargetLowering(TM), Subtarget(Subtarget) { 99 // Set up the register classes. 100 addRegisterClass(MVT::i32, &ARC::GPR32RegClass); 101 102 // Compute derived properties from the register classes 103 computeRegisterProperties(Subtarget.getRegisterInfo()); 104 105 setStackPointerRegisterToSaveRestore(ARC::SP); 106 107 setSchedulingPreference(Sched::Source); 108 109 // Use i32 for setcc operations results (slt, sgt, ...). 110 setBooleanContents(ZeroOrOneBooleanContent); 111 setBooleanVectorContents(ZeroOrOneBooleanContent); 112 113 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc) 114 setOperationAction(Opc, MVT::i32, Expand); 115 116 // Operations to get us off of the ground. 117 // Basic. 118 setOperationAction(ISD::ADD, MVT::i32, Legal); 119 setOperationAction(ISD::SUB, MVT::i32, Legal); 120 setOperationAction(ISD::AND, MVT::i32, Legal); 121 setOperationAction(ISD::SMAX, MVT::i32, Legal); 122 setOperationAction(ISD::SMIN, MVT::i32, Legal); 123 124 setOperationAction(ISD::ADDC, MVT::i32, Legal); 125 setOperationAction(ISD::ADDE, MVT::i32, Legal); 126 setOperationAction(ISD::SUBC, MVT::i32, Legal); 127 setOperationAction(ISD::SUBE, MVT::i32, Legal); 128 129 // Need barrel shifter. 130 setOperationAction(ISD::SHL, MVT::i32, Legal); 131 setOperationAction(ISD::SRA, MVT::i32, Legal); 132 setOperationAction(ISD::SRL, MVT::i32, Legal); 133 setOperationAction(ISD::ROTR, MVT::i32, Legal); 134 135 setOperationAction(ISD::Constant, MVT::i32, Legal); 136 setOperationAction(ISD::UNDEF, MVT::i32, Legal); 137 138 // Need multiplier 139 setOperationAction(ISD::MUL, MVT::i32, Legal); 140 setOperationAction(ISD::MULHS, MVT::i32, Legal); 141 setOperationAction(ISD::MULHU, MVT::i32, Legal); 142 setOperationAction(ISD::LOAD, MVT::i32, Legal); 143 setOperationAction(ISD::STORE, MVT::i32, Legal); 144 145 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); 146 setOperationAction(ISD::BR_CC, MVT::i32, Custom); 147 setOperationAction(ISD::BRCOND, MVT::Other, Expand); 148 setOperationAction(ISD::BR_JT, MVT::Other, Expand); 149 setOperationAction(ISD::JumpTable, MVT::i32, Custom); 150 151 // Have pseudo instruction for frame addresses. 152 setOperationAction(ISD::FRAMEADDR, MVT::i32, Legal); 153 // Custom lower global addresses. 154 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); 155 156 // Expand var-args ops. 157 setOperationAction(ISD::VASTART, MVT::Other, Custom); 158 setOperationAction(ISD::VAEND, MVT::Other, Expand); 159 setOperationAction(ISD::VAARG, MVT::Other, Expand); 160 setOperationAction(ISD::VACOPY, MVT::Other, Expand); 161 162 // Other expansions 163 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); 164 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); 165 166 // Sign extend inreg 167 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Custom); 168 169 // TODO: Predicate these with `options.hasBitScan() ? Legal : Expand` 170 // when the HasBitScan predicate is available. 171 setOperationAction(ISD::CTLZ, MVT::i32, Legal); 172 setOperationAction(ISD::CTTZ, MVT::i32, Legal); 173 174 setOperationAction(ISD::READCYCLECOUNTER, MVT::i32, Legal); 175 setOperationAction(ISD::READCYCLECOUNTER, MVT::i64, 176 isTypeLegal(MVT::i64) ? Legal : Custom); 177 } 178 179 const char *ARCTargetLowering::getTargetNodeName(unsigned Opcode) const { 180 switch (Opcode) { 181 case ARCISD::BL: 182 return "ARCISD::BL"; 183 case ARCISD::CMOV: 184 return "ARCISD::CMOV"; 185 case ARCISD::CMP: 186 return "ARCISD::CMP"; 187 case ARCISD::BRcc: 188 return "ARCISD::BRcc"; 189 case ARCISD::RET: 190 return "ARCISD::RET"; 191 case ARCISD::GAWRAPPER: 192 return "ARCISD::GAWRAPPER"; 193 } 194 return nullptr; 195 } 196 197 //===----------------------------------------------------------------------===// 198 // Misc Lower Operation implementation 199 //===----------------------------------------------------------------------===// 200 201 SDValue ARCTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const { 202 SDValue LHS = Op.getOperand(0); 203 SDValue RHS = Op.getOperand(1); 204 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 205 SDValue TVal = Op.getOperand(2); 206 SDValue FVal = Op.getOperand(3); 207 SDLoc dl(Op); 208 ARCCC::CondCode ArcCC = ISDCCtoARCCC(CC); 209 assert(LHS.getValueType() == MVT::i32 && "Only know how to SELECT_CC i32"); 210 SDValue Cmp = DAG.getNode(ARCISD::CMP, dl, MVT::Glue, LHS, RHS); 211 return DAG.getNode(ARCISD::CMOV, dl, TVal.getValueType(), TVal, FVal, 212 DAG.getConstant(ArcCC, dl, MVT::i32), Cmp); 213 } 214 215 SDValue ARCTargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op, 216 SelectionDAG &DAG) const { 217 SDValue Op0 = Op.getOperand(0); 218 SDLoc dl(Op); 219 assert(Op.getValueType() == MVT::i32 && 220 "Unhandled target sign_extend_inreg."); 221 // These are legal 222 unsigned Width = cast<VTSDNode>(Op.getOperand(1))->getVT().getSizeInBits(); 223 if (Width == 16 || Width == 8) 224 return Op; 225 if (Width >= 32) { 226 return {}; 227 } 228 SDValue LS = DAG.getNode(ISD::SHL, dl, MVT::i32, Op0, 229 DAG.getConstant(32 - Width, dl, MVT::i32)); 230 SDValue SR = DAG.getNode(ISD::SRA, dl, MVT::i32, LS, 231 DAG.getConstant(32 - Width, dl, MVT::i32)); 232 return SR; 233 } 234 235 SDValue ARCTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const { 236 SDValue Chain = Op.getOperand(0); 237 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); 238 SDValue LHS = Op.getOperand(2); 239 SDValue RHS = Op.getOperand(3); 240 SDValue Dest = Op.getOperand(4); 241 SDLoc dl(Op); 242 ARCCC::CondCode arcCC = ISDCCtoARCCC(CC); 243 assert(LHS.getValueType() == MVT::i32 && "Only know how to BR_CC i32"); 244 return DAG.getNode(ARCISD::BRcc, dl, MVT::Other, Chain, Dest, LHS, RHS, 245 DAG.getConstant(arcCC, dl, MVT::i32)); 246 } 247 248 SDValue ARCTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) const { 249 auto *N = cast<JumpTableSDNode>(Op); 250 SDValue GA = DAG.getTargetJumpTable(N->getIndex(), MVT::i32); 251 return DAG.getNode(ARCISD::GAWRAPPER, SDLoc(N), MVT::i32, GA); 252 } 253 254 #include "ARCGenCallingConv.inc" 255 256 //===----------------------------------------------------------------------===// 257 // Call Calling Convention Implementation 258 //===----------------------------------------------------------------------===// 259 260 /// ARC call implementation 261 SDValue ARCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, 262 SmallVectorImpl<SDValue> &InVals) const { 263 SelectionDAG &DAG = CLI.DAG; 264 SDLoc &dl = CLI.DL; 265 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs; 266 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals; 267 SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins; 268 SDValue Chain = CLI.Chain; 269 SDValue Callee = CLI.Callee; 270 CallingConv::ID CallConv = CLI.CallConv; 271 bool IsVarArg = CLI.IsVarArg; 272 bool &IsTailCall = CLI.IsTailCall; 273 274 IsTailCall = false; // Do not support tail calls yet. 275 276 SmallVector<CCValAssign, 16> ArgLocs; 277 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs, 278 *DAG.getContext()); 279 280 CCInfo.AnalyzeCallOperands(Outs, CC_ARC); 281 282 SmallVector<CCValAssign, 16> RVLocs; 283 // Analyze return values to determine the number of bytes of stack required. 284 CCState RetCCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs, 285 *DAG.getContext()); 286 RetCCInfo.AllocateStack(CCInfo.getStackSize(), Align(4)); 287 RetCCInfo.AnalyzeCallResult(Ins, RetCC_ARC); 288 289 // Get a count of how many bytes are to be pushed on the stack. 290 unsigned NumBytes = RetCCInfo.getStackSize(); 291 292 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, dl); 293 294 SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; 295 SmallVector<SDValue, 12> MemOpChains; 296 297 SDValue StackPtr; 298 // Walk the register/memloc assignments, inserting copies/loads. 299 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 300 CCValAssign &VA = ArgLocs[i]; 301 SDValue Arg = OutVals[i]; 302 303 // Promote the value if needed. 304 switch (VA.getLocInfo()) { 305 default: 306 llvm_unreachable("Unknown loc info!"); 307 case CCValAssign::Full: 308 break; 309 case CCValAssign::SExt: 310 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 311 break; 312 case CCValAssign::ZExt: 313 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 314 break; 315 case CCValAssign::AExt: 316 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 317 break; 318 } 319 320 // Arguments that can be passed on register must be kept at 321 // RegsToPass vector 322 if (VA.isRegLoc()) { 323 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 324 } else { 325 assert(VA.isMemLoc() && "Must be register or memory argument."); 326 if (!StackPtr.getNode()) 327 StackPtr = DAG.getCopyFromReg(Chain, dl, ARC::SP, 328 getPointerTy(DAG.getDataLayout())); 329 // Calculate the stack position. 330 SDValue SOffset = DAG.getIntPtrConstant(VA.getLocMemOffset(), dl); 331 SDValue PtrOff = DAG.getNode( 332 ISD::ADD, dl, getPointerTy(DAG.getDataLayout()), StackPtr, SOffset); 333 334 SDValue Store = 335 DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()); 336 MemOpChains.push_back(Store); 337 IsTailCall = false; 338 } 339 } 340 341 // Transform all store nodes into one single node because 342 // all store nodes are independent of each other. 343 if (!MemOpChains.empty()) 344 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains); 345 346 // Build a sequence of copy-to-reg nodes chained together with token 347 // chain and flag operands which copy the outgoing args into registers. 348 // The Glue in necessary since all emitted instructions must be 349 // stuck together. 350 SDValue Glue; 351 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 352 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 353 RegsToPass[i].second, Glue); 354 Glue = Chain.getValue(1); 355 } 356 357 // If the callee is a GlobalAddress node (quite common, every direct call is) 358 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 359 // Likewise ExternalSymbol -> TargetExternalSymbol. 360 bool IsDirect = true; 361 if (auto *G = dyn_cast<GlobalAddressSDNode>(Callee)) 362 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32); 363 else if (auto *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 364 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32); 365 else 366 IsDirect = false; 367 // Branch + Link = #chain, #target_address, #opt_in_flags... 368 // = Chain, Callee, Reg#1, Reg#2, ... 369 // 370 // Returns a chain & a glue for retval copy to use. 371 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 372 SmallVector<SDValue, 8> Ops; 373 Ops.push_back(Chain); 374 Ops.push_back(Callee); 375 376 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 377 Ops.push_back(DAG.getRegister(RegsToPass[i].first, 378 RegsToPass[i].second.getValueType())); 379 380 // Add a register mask operand representing the call-preserved registers. 381 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); 382 const uint32_t *Mask = 383 TRI->getCallPreservedMask(DAG.getMachineFunction(), CallConv); 384 assert(Mask && "Missing call preserved mask for calling convention"); 385 Ops.push_back(DAG.getRegisterMask(Mask)); 386 387 if (Glue.getNode()) 388 Ops.push_back(Glue); 389 390 Chain = DAG.getNode(IsDirect ? ARCISD::BL : ARCISD::JL, dl, NodeTys, Ops); 391 Glue = Chain.getValue(1); 392 393 // Create the CALLSEQ_END node. 394 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, Glue, dl); 395 Glue = Chain.getValue(1); 396 397 // Handle result values, copying them out of physregs into vregs that we 398 // return. 399 if (IsTailCall) 400 return Chain; 401 return lowerCallResult(Chain, Glue, RVLocs, dl, DAG, InVals); 402 } 403 404 /// Lower the result values of a call into the appropriate copies out of 405 /// physical registers / memory locations. 406 static SDValue lowerCallResult(SDValue Chain, SDValue Glue, 407 const SmallVectorImpl<CCValAssign> &RVLocs, 408 SDLoc dl, SelectionDAG &DAG, 409 SmallVectorImpl<SDValue> &InVals) { 410 SmallVector<std::pair<int, unsigned>, 4> ResultMemLocs; 411 // Copy results out of physical registers. 412 for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) { 413 const CCValAssign &VA = RVLocs[i]; 414 if (VA.isRegLoc()) { 415 SDValue RetValue; 416 RetValue = 417 DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), VA.getValVT(), Glue); 418 Chain = RetValue.getValue(1); 419 Glue = RetValue.getValue(2); 420 InVals.push_back(RetValue); 421 } else { 422 assert(VA.isMemLoc() && "Must be memory location."); 423 ResultMemLocs.push_back( 424 std::make_pair(VA.getLocMemOffset(), InVals.size())); 425 426 // Reserve space for this result. 427 InVals.push_back(SDValue()); 428 } 429 } 430 431 // Copy results out of memory. 432 SmallVector<SDValue, 4> MemOpChains; 433 for (unsigned i = 0, e = ResultMemLocs.size(); i != e; ++i) { 434 int Offset = ResultMemLocs[i].first; 435 unsigned Index = ResultMemLocs[i].second; 436 SDValue StackPtr = DAG.getRegister(ARC::SP, MVT::i32); 437 SDValue SpLoc = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, 438 DAG.getConstant(Offset, dl, MVT::i32)); 439 SDValue Load = 440 DAG.getLoad(MVT::i32, dl, Chain, SpLoc, MachinePointerInfo()); 441 InVals[Index] = Load; 442 MemOpChains.push_back(Load.getValue(1)); 443 } 444 445 // Transform all loads nodes into one single node because 446 // all load nodes are independent of each other. 447 if (!MemOpChains.empty()) 448 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains); 449 450 return Chain; 451 } 452 453 //===----------------------------------------------------------------------===// 454 // Formal Arguments Calling Convention Implementation 455 //===----------------------------------------------------------------------===// 456 457 namespace { 458 459 struct ArgDataPair { 460 SDValue SDV; 461 ISD::ArgFlagsTy Flags; 462 }; 463 464 } // end anonymous namespace 465 466 /// ARC formal arguments implementation 467 SDValue ARCTargetLowering::LowerFormalArguments( 468 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, 469 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl, 470 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { 471 switch (CallConv) { 472 default: 473 llvm_unreachable("Unsupported calling convention"); 474 case CallingConv::C: 475 case CallingConv::Fast: 476 return LowerCallArguments(Chain, CallConv, IsVarArg, Ins, dl, DAG, InVals); 477 } 478 } 479 480 /// Transform physical registers into virtual registers, and generate load 481 /// operations for argument places on the stack. 482 SDValue ARCTargetLowering::LowerCallArguments( 483 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, 484 const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc dl, SelectionDAG &DAG, 485 SmallVectorImpl<SDValue> &InVals) const { 486 MachineFunction &MF = DAG.getMachineFunction(); 487 MachineFrameInfo &MFI = MF.getFrameInfo(); 488 MachineRegisterInfo &RegInfo = MF.getRegInfo(); 489 auto *AFI = MF.getInfo<ARCFunctionInfo>(); 490 491 // Assign locations to all of the incoming arguments. 492 SmallVector<CCValAssign, 16> ArgLocs; 493 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs, 494 *DAG.getContext()); 495 496 CCInfo.AnalyzeFormalArguments(Ins, CC_ARC); 497 498 unsigned StackSlotSize = 4; 499 500 if (!IsVarArg) 501 AFI->setReturnStackOffset(CCInfo.getStackSize()); 502 503 // All getCopyFromReg ops must precede any getMemcpys to prevent the 504 // scheduler clobbering a register before it has been copied. 505 // The stages are: 506 // 1. CopyFromReg (and load) arg & vararg registers. 507 // 2. Chain CopyFromReg nodes into a TokenFactor. 508 // 3. Memcpy 'byVal' args & push final InVals. 509 // 4. Chain mem ops nodes into a TokenFactor. 510 SmallVector<SDValue, 4> CFRegNode; 511 SmallVector<ArgDataPair, 4> ArgData; 512 SmallVector<SDValue, 4> MemOps; 513 514 // 1a. CopyFromReg (and load) arg registers. 515 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 516 CCValAssign &VA = ArgLocs[i]; 517 SDValue ArgIn; 518 519 if (VA.isRegLoc()) { 520 // Arguments passed in registers 521 EVT RegVT = VA.getLocVT(); 522 switch (RegVT.getSimpleVT().SimpleTy) { 523 default: { 524 LLVM_DEBUG(errs() << "LowerFormalArguments Unhandled argument type: " 525 << (unsigned)RegVT.getSimpleVT().SimpleTy << "\n"); 526 llvm_unreachable("Unhandled LowerFormalArguments type."); 527 } 528 case MVT::i32: 529 unsigned VReg = RegInfo.createVirtualRegister(&ARC::GPR32RegClass); 530 RegInfo.addLiveIn(VA.getLocReg(), VReg); 531 ArgIn = DAG.getCopyFromReg(Chain, dl, VReg, RegVT); 532 CFRegNode.push_back(ArgIn.getValue(ArgIn->getNumValues() - 1)); 533 } 534 } else { 535 // Only arguments passed on the stack should make it here. 536 assert(VA.isMemLoc()); 537 // Load the argument to a virtual register 538 unsigned ObjSize = VA.getLocVT().getStoreSize(); 539 assert((ObjSize <= StackSlotSize) && "Unhandled argument"); 540 541 // Create the frame index object for this incoming parameter... 542 int FI = MFI.CreateFixedObject(ObjSize, VA.getLocMemOffset(), true); 543 544 // Create the SelectionDAG nodes corresponding to a load 545 // from this parameter 546 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); 547 ArgIn = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, 548 MachinePointerInfo::getFixedStack(MF, FI)); 549 } 550 const ArgDataPair ADP = {ArgIn, Ins[i].Flags}; 551 ArgData.push_back(ADP); 552 } 553 554 // 1b. CopyFromReg vararg registers. 555 if (IsVarArg) { 556 // Argument registers 557 static const MCPhysReg ArgRegs[] = {ARC::R0, ARC::R1, ARC::R2, ARC::R3, 558 ARC::R4, ARC::R5, ARC::R6, ARC::R7}; 559 auto *AFI = MF.getInfo<ARCFunctionInfo>(); 560 unsigned FirstVAReg = CCInfo.getFirstUnallocated(ArgRegs); 561 if (FirstVAReg < std::size(ArgRegs)) { 562 int Offset = 0; 563 // Save remaining registers, storing higher register numbers at a higher 564 // address 565 // There are (std::size(ArgRegs) - FirstVAReg) registers which 566 // need to be saved. 567 int VarFI = MFI.CreateFixedObject((std::size(ArgRegs) - FirstVAReg) * 4, 568 CCInfo.getStackSize(), true); 569 AFI->setVarArgsFrameIndex(VarFI); 570 SDValue FIN = DAG.getFrameIndex(VarFI, MVT::i32); 571 for (unsigned i = FirstVAReg; i < std::size(ArgRegs); i++) { 572 // Move argument from phys reg -> virt reg 573 unsigned VReg = RegInfo.createVirtualRegister(&ARC::GPR32RegClass); 574 RegInfo.addLiveIn(ArgRegs[i], VReg); 575 SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32); 576 CFRegNode.push_back(Val.getValue(Val->getNumValues() - 1)); 577 SDValue VAObj = DAG.getNode(ISD::ADD, dl, MVT::i32, FIN, 578 DAG.getConstant(Offset, dl, MVT::i32)); 579 // Move argument from virt reg -> stack 580 SDValue Store = 581 DAG.getStore(Val.getValue(1), dl, Val, VAObj, MachinePointerInfo()); 582 MemOps.push_back(Store); 583 Offset += 4; 584 } 585 } else { 586 llvm_unreachable("Too many var args parameters."); 587 } 588 } 589 590 // 2. Chain CopyFromReg nodes into a TokenFactor. 591 if (!CFRegNode.empty()) 592 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, CFRegNode); 593 594 // 3. Memcpy 'byVal' args & push final InVals. 595 // Aggregates passed "byVal" need to be copied by the callee. 596 // The callee will use a pointer to this copy, rather than the original 597 // pointer. 598 for (const auto &ArgDI : ArgData) { 599 if (ArgDI.Flags.isByVal() && ArgDI.Flags.getByValSize()) { 600 unsigned Size = ArgDI.Flags.getByValSize(); 601 Align Alignment = 602 std::max(Align(StackSlotSize), ArgDI.Flags.getNonZeroByValAlign()); 603 // Create a new object on the stack and copy the pointee into it. 604 int FI = MFI.CreateStackObject(Size, Alignment, false); 605 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); 606 InVals.push_back(FIN); 607 MemOps.push_back(DAG.getMemcpy( 608 Chain, dl, FIN, ArgDI.SDV, DAG.getConstant(Size, dl, MVT::i32), 609 Alignment, false, false, false, MachinePointerInfo(), 610 MachinePointerInfo())); 611 } else { 612 InVals.push_back(ArgDI.SDV); 613 } 614 } 615 616 // 4. Chain mem ops nodes into a TokenFactor. 617 if (!MemOps.empty()) { 618 MemOps.push_back(Chain); 619 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOps); 620 } 621 622 return Chain; 623 } 624 625 //===----------------------------------------------------------------------===// 626 // Return Value Calling Convention Implementation 627 //===----------------------------------------------------------------------===// 628 629 bool ARCTargetLowering::CanLowerReturn( 630 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, 631 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const { 632 SmallVector<CCValAssign, 16> RVLocs; 633 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context); 634 if (!CCInfo.CheckReturn(Outs, RetCC_ARC)) 635 return false; 636 if (CCInfo.getStackSize() != 0 && IsVarArg) 637 return false; 638 return true; 639 } 640 641 SDValue 642 ARCTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, 643 bool IsVarArg, 644 const SmallVectorImpl<ISD::OutputArg> &Outs, 645 const SmallVectorImpl<SDValue> &OutVals, 646 const SDLoc &dl, SelectionDAG &DAG) const { 647 auto *AFI = DAG.getMachineFunction().getInfo<ARCFunctionInfo>(); 648 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); 649 650 // CCValAssign - represent the assignment of 651 // the return value to a location 652 SmallVector<CCValAssign, 16> RVLocs; 653 654 // CCState - Info about the registers and stack slot. 655 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs, 656 *DAG.getContext()); 657 658 // Analyze return values. 659 if (!IsVarArg) 660 CCInfo.AllocateStack(AFI->getReturnStackOffset(), Align(4)); 661 662 CCInfo.AnalyzeReturn(Outs, RetCC_ARC); 663 664 SDValue Glue; 665 SmallVector<SDValue, 4> RetOps(1, Chain); 666 SmallVector<SDValue, 4> MemOpChains; 667 // Handle return values that must be copied to memory. 668 for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) { 669 CCValAssign &VA = RVLocs[i]; 670 if (VA.isRegLoc()) 671 continue; 672 assert(VA.isMemLoc()); 673 if (IsVarArg) { 674 report_fatal_error("Can't return value from vararg function in memory"); 675 } 676 677 int Offset = VA.getLocMemOffset(); 678 unsigned ObjSize = VA.getLocVT().getStoreSize(); 679 // Create the frame index object for the memory location. 680 int FI = MFI.CreateFixedObject(ObjSize, Offset, false); 681 682 // Create a SelectionDAG node corresponding to a store 683 // to this memory location. 684 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); 685 MemOpChains.push_back(DAG.getStore( 686 Chain, dl, OutVals[i], FIN, 687 MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI))); 688 } 689 690 // Transform all store nodes into one single node because 691 // all stores are independent of each other. 692 if (!MemOpChains.empty()) 693 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains); 694 695 // Now handle return values copied to registers. 696 for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) { 697 CCValAssign &VA = RVLocs[i]; 698 if (!VA.isRegLoc()) 699 continue; 700 // Copy the result values into the output registers. 701 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), OutVals[i], Glue); 702 703 // guarantee that all emitted copies are 704 // stuck together, avoiding something bad 705 Glue = Chain.getValue(1); 706 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); 707 } 708 709 RetOps[0] = Chain; // Update chain. 710 711 // Add the glue if we have it. 712 if (Glue.getNode()) 713 RetOps.push_back(Glue); 714 715 // What to do with the RetOps? 716 return DAG.getNode(ARCISD::RET, dl, MVT::Other, RetOps); 717 } 718 719 //===----------------------------------------------------------------------===// 720 // Target Optimization Hooks 721 //===----------------------------------------------------------------------===// 722 723 SDValue ARCTargetLowering::PerformDAGCombine(SDNode *N, 724 DAGCombinerInfo &DCI) const { 725 return {}; 726 } 727 728 //===----------------------------------------------------------------------===// 729 // Addressing mode description hooks 730 //===----------------------------------------------------------------------===// 731 732 /// Return true if the addressing mode represented by AM is legal for this 733 /// target, for a load/store of the specified type. 734 bool ARCTargetLowering::isLegalAddressingMode(const DataLayout &DL, 735 const AddrMode &AM, Type *Ty, 736 unsigned AS, 737 Instruction *I) const { 738 return AM.Scale == 0; 739 } 740 741 // Don't emit tail calls for the time being. 742 bool ARCTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const { 743 return false; 744 } 745 746 SDValue ARCTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { 747 const ARCRegisterInfo &ARI = *Subtarget.getRegisterInfo(); 748 MachineFunction &MF = DAG.getMachineFunction(); 749 MachineFrameInfo &MFI = MF.getFrameInfo(); 750 MFI.setFrameAddressIsTaken(true); 751 752 EVT VT = Op.getValueType(); 753 SDLoc dl(Op); 754 assert(cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() == 0 && 755 "Only support lowering frame addr of current frame."); 756 Register FrameReg = ARI.getFrameRegister(MF); 757 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT); 758 } 759 760 SDValue ARCTargetLowering::LowerGlobalAddress(SDValue Op, 761 SelectionDAG &DAG) const { 762 const GlobalAddressSDNode *GN = cast<GlobalAddressSDNode>(Op); 763 const GlobalValue *GV = GN->getGlobal(); 764 SDLoc dl(GN); 765 int64_t Offset = GN->getOffset(); 766 SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, Offset); 767 return DAG.getNode(ARCISD::GAWRAPPER, dl, MVT::i32, GA); 768 } 769 770 static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) { 771 MachineFunction &MF = DAG.getMachineFunction(); 772 auto *FuncInfo = MF.getInfo<ARCFunctionInfo>(); 773 774 // vastart just stores the address of the VarArgsFrameIndex slot into the 775 // memory location argument. 776 SDLoc dl(Op); 777 EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout()); 778 SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT); 779 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); 780 return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), 781 MachinePointerInfo(SV)); 782 } 783 784 SDValue ARCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { 785 switch (Op.getOpcode()) { 786 case ISD::GlobalAddress: 787 return LowerGlobalAddress(Op, DAG); 788 case ISD::FRAMEADDR: 789 return LowerFRAMEADDR(Op, DAG); 790 case ISD::SELECT_CC: 791 return LowerSELECT_CC(Op, DAG); 792 case ISD::BR_CC: 793 return LowerBR_CC(Op, DAG); 794 case ISD::SIGN_EXTEND_INREG: 795 return LowerSIGN_EXTEND_INREG(Op, DAG); 796 case ISD::JumpTable: 797 return LowerJumpTable(Op, DAG); 798 case ISD::VASTART: 799 return LowerVASTART(Op, DAG); 800 case ISD::READCYCLECOUNTER: 801 // As of LLVM 3.8, the lowering code insists that we customize it even 802 // though we've declared the i32 version as legal. This is because it only 803 // thinks i64 is the truly supported version. We've already converted the 804 // i64 version to a widened i32. 805 assert(Op.getSimpleValueType() == MVT::i32); 806 return Op; 807 default: 808 llvm_unreachable("unimplemented operand"); 809 } 810 } 811