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