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 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.getNextStackOffset(), 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.getNextStackOffset(); 291 auto PtrVT = getPointerTy(DAG.getDataLayout()); 292 293 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, dl); 294 295 SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; 296 SmallVector<SDValue, 12> MemOpChains; 297 298 SDValue StackPtr; 299 // Walk the register/memloc assignments, inserting copies/loads. 300 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 301 CCValAssign &VA = ArgLocs[i]; 302 SDValue Arg = OutVals[i]; 303 304 // Promote the value if needed. 305 switch (VA.getLocInfo()) { 306 default: 307 llvm_unreachable("Unknown loc info!"); 308 case CCValAssign::Full: 309 break; 310 case CCValAssign::SExt: 311 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 312 break; 313 case CCValAssign::ZExt: 314 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 315 break; 316 case CCValAssign::AExt: 317 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 318 break; 319 } 320 321 // Arguments that can be passed on register must be kept at 322 // RegsToPass vector 323 if (VA.isRegLoc()) { 324 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 325 } else { 326 assert(VA.isMemLoc() && "Must be register or memory argument."); 327 if (!StackPtr.getNode()) 328 StackPtr = DAG.getCopyFromReg(Chain, dl, ARC::SP, 329 getPointerTy(DAG.getDataLayout())); 330 // Calculate the stack position. 331 SDValue SOffset = DAG.getIntPtrConstant(VA.getLocMemOffset(), dl); 332 SDValue PtrOff = DAG.getNode( 333 ISD::ADD, dl, getPointerTy(DAG.getDataLayout()), StackPtr, SOffset); 334 335 SDValue Store = 336 DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()); 337 MemOpChains.push_back(Store); 338 IsTailCall = false; 339 } 340 } 341 342 // Transform all store nodes into one single node because 343 // all store nodes are independent of each other. 344 if (!MemOpChains.empty()) 345 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains); 346 347 // Build a sequence of copy-to-reg nodes chained together with token 348 // chain and flag operands which copy the outgoing args into registers. 349 // The InFlag in necessary since all emitted instructions must be 350 // stuck together. 351 SDValue Glue; 352 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 353 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 354 RegsToPass[i].second, Glue); 355 Glue = Chain.getValue(1); 356 } 357 358 // If the callee is a GlobalAddress node (quite common, every direct call is) 359 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 360 // Likewise ExternalSymbol -> TargetExternalSymbol. 361 bool IsDirect = true; 362 if (auto *G = dyn_cast<GlobalAddressSDNode>(Callee)) 363 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32); 364 else if (auto *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 365 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32); 366 else 367 IsDirect = false; 368 // Branch + Link = #chain, #target_address, #opt_in_flags... 369 // = Chain, Callee, Reg#1, Reg#2, ... 370 // 371 // Returns a chain & a flag for retval copy to use. 372 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 373 SmallVector<SDValue, 8> Ops; 374 Ops.push_back(Chain); 375 Ops.push_back(Callee); 376 377 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 378 Ops.push_back(DAG.getRegister(RegsToPass[i].first, 379 RegsToPass[i].second.getValueType())); 380 381 // Add a register mask operand representing the call-preserved registers. 382 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); 383 const uint32_t *Mask = 384 TRI->getCallPreservedMask(DAG.getMachineFunction(), CallConv); 385 assert(Mask && "Missing call preserved mask for calling convention"); 386 Ops.push_back(DAG.getRegisterMask(Mask)); 387 388 if (Glue.getNode()) 389 Ops.push_back(Glue); 390 391 Chain = DAG.getNode(IsDirect ? ARCISD::BL : ARCISD::JL, dl, NodeTys, Ops); 392 Glue = Chain.getValue(1); 393 394 // Create the CALLSEQ_END node. 395 Chain = DAG.getCALLSEQ_END(Chain, DAG.getConstant(NumBytes, dl, PtrVT, true), 396 DAG.getConstant(0, dl, PtrVT, true), Glue, dl); 397 Glue = Chain.getValue(1); 398 399 // Handle result values, copying them out of physregs into vregs that we 400 // return. 401 if (IsTailCall) 402 return Chain; 403 return lowerCallResult(Chain, Glue, RVLocs, dl, DAG, InVals); 404 } 405 406 /// Lower the result values of a call into the appropriate copies out of 407 /// physical registers / memory locations. 408 static SDValue lowerCallResult(SDValue Chain, SDValue Glue, 409 const SmallVectorImpl<CCValAssign> &RVLocs, 410 SDLoc dl, SelectionDAG &DAG, 411 SmallVectorImpl<SDValue> &InVals) { 412 SmallVector<std::pair<int, unsigned>, 4> ResultMemLocs; 413 // Copy results out of physical registers. 414 for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) { 415 const CCValAssign &VA = RVLocs[i]; 416 if (VA.isRegLoc()) { 417 SDValue RetValue; 418 RetValue = 419 DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), VA.getValVT(), Glue); 420 Chain = RetValue.getValue(1); 421 Glue = RetValue.getValue(2); 422 InVals.push_back(RetValue); 423 } else { 424 assert(VA.isMemLoc() && "Must be memory location."); 425 ResultMemLocs.push_back( 426 std::make_pair(VA.getLocMemOffset(), InVals.size())); 427 428 // Reserve space for this result. 429 InVals.push_back(SDValue()); 430 } 431 } 432 433 // Copy results out of memory. 434 SmallVector<SDValue, 4> MemOpChains; 435 for (unsigned i = 0, e = ResultMemLocs.size(); i != e; ++i) { 436 int Offset = ResultMemLocs[i].first; 437 unsigned Index = ResultMemLocs[i].second; 438 SDValue StackPtr = DAG.getRegister(ARC::SP, MVT::i32); 439 SDValue SpLoc = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, 440 DAG.getConstant(Offset, dl, MVT::i32)); 441 SDValue Load = 442 DAG.getLoad(MVT::i32, dl, Chain, SpLoc, MachinePointerInfo()); 443 InVals[Index] = Load; 444 MemOpChains.push_back(Load.getValue(1)); 445 } 446 447 // Transform all loads nodes into one single node because 448 // all load nodes are independent of each other. 449 if (!MemOpChains.empty()) 450 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains); 451 452 return Chain; 453 } 454 455 //===----------------------------------------------------------------------===// 456 // Formal Arguments Calling Convention Implementation 457 //===----------------------------------------------------------------------===// 458 459 namespace { 460 461 struct ArgDataPair { 462 SDValue SDV; 463 ISD::ArgFlagsTy Flags; 464 }; 465 466 } // end anonymous namespace 467 468 /// ARC formal arguments implementation 469 SDValue ARCTargetLowering::LowerFormalArguments( 470 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, 471 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl, 472 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { 473 switch (CallConv) { 474 default: 475 llvm_unreachable("Unsupported calling convention"); 476 case CallingConv::C: 477 case CallingConv::Fast: 478 return LowerCallArguments(Chain, CallConv, IsVarArg, Ins, dl, DAG, InVals); 479 } 480 } 481 482 /// Transform physical registers into virtual registers, and generate load 483 /// operations for argument places on the stack. 484 SDValue ARCTargetLowering::LowerCallArguments( 485 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, 486 const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc dl, SelectionDAG &DAG, 487 SmallVectorImpl<SDValue> &InVals) const { 488 MachineFunction &MF = DAG.getMachineFunction(); 489 MachineFrameInfo &MFI = MF.getFrameInfo(); 490 MachineRegisterInfo &RegInfo = MF.getRegInfo(); 491 auto *AFI = MF.getInfo<ARCFunctionInfo>(); 492 493 // Assign locations to all of the incoming arguments. 494 SmallVector<CCValAssign, 16> ArgLocs; 495 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs, 496 *DAG.getContext()); 497 498 CCInfo.AnalyzeFormalArguments(Ins, CC_ARC); 499 500 unsigned StackSlotSize = 4; 501 502 if (!IsVarArg) 503 AFI->setReturnStackOffset(CCInfo.getNextStackOffset()); 504 505 // All getCopyFromReg ops must precede any getMemcpys to prevent the 506 // scheduler clobbering a register before it has been copied. 507 // The stages are: 508 // 1. CopyFromReg (and load) arg & vararg registers. 509 // 2. Chain CopyFromReg nodes into a TokenFactor. 510 // 3. Memcpy 'byVal' args & push final InVals. 511 // 4. Chain mem ops nodes into a TokenFactor. 512 SmallVector<SDValue, 4> CFRegNode; 513 SmallVector<ArgDataPair, 4> ArgData; 514 SmallVector<SDValue, 4> MemOps; 515 516 // 1a. CopyFromReg (and load) arg registers. 517 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 518 CCValAssign &VA = ArgLocs[i]; 519 SDValue ArgIn; 520 521 if (VA.isRegLoc()) { 522 // Arguments passed in registers 523 EVT RegVT = VA.getLocVT(); 524 switch (RegVT.getSimpleVT().SimpleTy) { 525 default: { 526 LLVM_DEBUG(errs() << "LowerFormalArguments Unhandled argument type: " 527 << (unsigned)RegVT.getSimpleVT().SimpleTy << "\n"); 528 llvm_unreachable("Unhandled LowerFormalArguments type."); 529 } 530 case MVT::i32: 531 unsigned VReg = RegInfo.createVirtualRegister(&ARC::GPR32RegClass); 532 RegInfo.addLiveIn(VA.getLocReg(), VReg); 533 ArgIn = DAG.getCopyFromReg(Chain, dl, VReg, RegVT); 534 CFRegNode.push_back(ArgIn.getValue(ArgIn->getNumValues() - 1)); 535 } 536 } else { 537 // Only arguments passed on the stack should make it here. 538 assert(VA.isMemLoc()); 539 // Load the argument to a virtual register 540 unsigned ObjSize = VA.getLocVT().getStoreSize(); 541 assert((ObjSize <= StackSlotSize) && "Unhandled argument"); 542 543 // Create the frame index object for this incoming parameter... 544 int FI = MFI.CreateFixedObject(ObjSize, VA.getLocMemOffset(), true); 545 546 // Create the SelectionDAG nodes corresponding to a load 547 // from this parameter 548 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); 549 ArgIn = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, 550 MachinePointerInfo::getFixedStack(MF, FI)); 551 } 552 const ArgDataPair ADP = {ArgIn, Ins[i].Flags}; 553 ArgData.push_back(ADP); 554 } 555 556 // 1b. CopyFromReg vararg registers. 557 if (IsVarArg) { 558 // Argument registers 559 static const MCPhysReg ArgRegs[] = {ARC::R0, ARC::R1, ARC::R2, ARC::R3, 560 ARC::R4, ARC::R5, ARC::R6, ARC::R7}; 561 auto *AFI = MF.getInfo<ARCFunctionInfo>(); 562 unsigned FirstVAReg = CCInfo.getFirstUnallocated(ArgRegs); 563 if (FirstVAReg < array_lengthof(ArgRegs)) { 564 int Offset = 0; 565 // Save remaining registers, storing higher register numbers at a higher 566 // address 567 // There are (array_lengthof(ArgRegs) - FirstVAReg) registers which 568 // need to be saved. 569 int VarFI = 570 MFI.CreateFixedObject((array_lengthof(ArgRegs) - FirstVAReg) * 4, 571 CCInfo.getNextStackOffset(), true); 572 AFI->setVarArgsFrameIndex(VarFI); 573 SDValue FIN = DAG.getFrameIndex(VarFI, MVT::i32); 574 for (unsigned i = FirstVAReg; i < array_lengthof(ArgRegs); i++) { 575 // Move argument from phys reg -> virt reg 576 unsigned VReg = RegInfo.createVirtualRegister(&ARC::GPR32RegClass); 577 RegInfo.addLiveIn(ArgRegs[i], VReg); 578 SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32); 579 CFRegNode.push_back(Val.getValue(Val->getNumValues() - 1)); 580 SDValue VAObj = DAG.getNode(ISD::ADD, dl, MVT::i32, FIN, 581 DAG.getConstant(Offset, dl, MVT::i32)); 582 // Move argument from virt reg -> stack 583 SDValue Store = 584 DAG.getStore(Val.getValue(1), dl, Val, VAObj, MachinePointerInfo()); 585 MemOps.push_back(Store); 586 Offset += 4; 587 } 588 } else { 589 llvm_unreachable("Too many var args parameters."); 590 } 591 } 592 593 // 2. Chain CopyFromReg nodes into a TokenFactor. 594 if (!CFRegNode.empty()) 595 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, CFRegNode); 596 597 // 3. Memcpy 'byVal' args & push final InVals. 598 // Aggregates passed "byVal" need to be copied by the callee. 599 // The callee will use a pointer to this copy, rather than the original 600 // pointer. 601 for (const auto &ArgDI : ArgData) { 602 if (ArgDI.Flags.isByVal() && ArgDI.Flags.getByValSize()) { 603 unsigned Size = ArgDI.Flags.getByValSize(); 604 Align Alignment = 605 std::max(Align(StackSlotSize), ArgDI.Flags.getNonZeroByValAlign()); 606 // Create a new object on the stack and copy the pointee into it. 607 int FI = MFI.CreateStackObject(Size, Alignment, false); 608 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); 609 InVals.push_back(FIN); 610 MemOps.push_back(DAG.getMemcpy( 611 Chain, dl, FIN, ArgDI.SDV, DAG.getConstant(Size, dl, MVT::i32), 612 Alignment, false, false, false, MachinePointerInfo(), 613 MachinePointerInfo())); 614 } else { 615 InVals.push_back(ArgDI.SDV); 616 } 617 } 618 619 // 4. Chain mem ops nodes into a TokenFactor. 620 if (!MemOps.empty()) { 621 MemOps.push_back(Chain); 622 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOps); 623 } 624 625 return Chain; 626 } 627 628 //===----------------------------------------------------------------------===// 629 // Return Value Calling Convention Implementation 630 //===----------------------------------------------------------------------===// 631 632 bool ARCTargetLowering::CanLowerReturn( 633 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, 634 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const { 635 SmallVector<CCValAssign, 16> RVLocs; 636 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context); 637 if (!CCInfo.CheckReturn(Outs, RetCC_ARC)) 638 return false; 639 if (CCInfo.getNextStackOffset() != 0 && IsVarArg) 640 return false; 641 return true; 642 } 643 644 SDValue 645 ARCTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, 646 bool IsVarArg, 647 const SmallVectorImpl<ISD::OutputArg> &Outs, 648 const SmallVectorImpl<SDValue> &OutVals, 649 const SDLoc &dl, SelectionDAG &DAG) const { 650 auto *AFI = DAG.getMachineFunction().getInfo<ARCFunctionInfo>(); 651 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); 652 653 // CCValAssign - represent the assignment of 654 // the return value to a location 655 SmallVector<CCValAssign, 16> RVLocs; 656 657 // CCState - Info about the registers and stack slot. 658 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs, 659 *DAG.getContext()); 660 661 // Analyze return values. 662 if (!IsVarArg) 663 CCInfo.AllocateStack(AFI->getReturnStackOffset(), Align(4)); 664 665 CCInfo.AnalyzeReturn(Outs, RetCC_ARC); 666 667 SDValue Flag; 668 SmallVector<SDValue, 4> RetOps(1, Chain); 669 SmallVector<SDValue, 4> MemOpChains; 670 // Handle return values that must be copied to memory. 671 for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) { 672 CCValAssign &VA = RVLocs[i]; 673 if (VA.isRegLoc()) 674 continue; 675 assert(VA.isMemLoc()); 676 if (IsVarArg) { 677 report_fatal_error("Can't return value from vararg function in memory"); 678 } 679 680 int Offset = VA.getLocMemOffset(); 681 unsigned ObjSize = VA.getLocVT().getStoreSize(); 682 // Create the frame index object for the memory location. 683 int FI = MFI.CreateFixedObject(ObjSize, Offset, false); 684 685 // Create a SelectionDAG node corresponding to a store 686 // to this memory location. 687 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); 688 MemOpChains.push_back(DAG.getStore( 689 Chain, dl, OutVals[i], FIN, 690 MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI))); 691 } 692 693 // Transform all store nodes into one single node because 694 // all stores are independent of each other. 695 if (!MemOpChains.empty()) 696 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains); 697 698 // Now handle return values copied to registers. 699 for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) { 700 CCValAssign &VA = RVLocs[i]; 701 if (!VA.isRegLoc()) 702 continue; 703 // Copy the result values into the output registers. 704 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), OutVals[i], Flag); 705 706 // guarantee that all emitted copies are 707 // stuck together, avoiding something bad 708 Flag = Chain.getValue(1); 709 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); 710 } 711 712 RetOps[0] = Chain; // Update chain. 713 714 // Add the flag if we have it. 715 if (Flag.getNode()) 716 RetOps.push_back(Flag); 717 718 // What to do with the RetOps? 719 return DAG.getNode(ARCISD::RET, dl, MVT::Other, RetOps); 720 } 721 722 //===----------------------------------------------------------------------===// 723 // Target Optimization Hooks 724 //===----------------------------------------------------------------------===// 725 726 SDValue ARCTargetLowering::PerformDAGCombine(SDNode *N, 727 DAGCombinerInfo &DCI) const { 728 return {}; 729 } 730 731 //===----------------------------------------------------------------------===// 732 // Addressing mode description hooks 733 //===----------------------------------------------------------------------===// 734 735 /// Return true if the addressing mode represented by AM is legal for this 736 /// target, for a load/store of the specified type. 737 bool ARCTargetLowering::isLegalAddressingMode(const DataLayout &DL, 738 const AddrMode &AM, Type *Ty, 739 unsigned AS, 740 Instruction *I) const { 741 return AM.Scale == 0; 742 } 743 744 // Don't emit tail calls for the time being. 745 bool ARCTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const { 746 return false; 747 } 748 749 SDValue ARCTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { 750 const ARCRegisterInfo &ARI = *Subtarget.getRegisterInfo(); 751 MachineFunction &MF = DAG.getMachineFunction(); 752 MachineFrameInfo &MFI = MF.getFrameInfo(); 753 MFI.setFrameAddressIsTaken(true); 754 755 EVT VT = Op.getValueType(); 756 SDLoc dl(Op); 757 assert(cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() == 0 && 758 "Only support lowering frame addr of current frame."); 759 Register FrameReg = ARI.getFrameRegister(MF); 760 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT); 761 } 762 763 SDValue ARCTargetLowering::LowerGlobalAddress(SDValue Op, 764 SelectionDAG &DAG) const { 765 const GlobalAddressSDNode *GN = cast<GlobalAddressSDNode>(Op); 766 const GlobalValue *GV = GN->getGlobal(); 767 SDLoc dl(GN); 768 int64_t Offset = GN->getOffset(); 769 SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, Offset); 770 return DAG.getNode(ARCISD::GAWRAPPER, dl, MVT::i32, GA); 771 } 772 773 static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) { 774 MachineFunction &MF = DAG.getMachineFunction(); 775 auto *FuncInfo = MF.getInfo<ARCFunctionInfo>(); 776 777 // vastart just stores the address of the VarArgsFrameIndex slot into the 778 // memory location argument. 779 SDLoc dl(Op); 780 EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout()); 781 SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT); 782 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); 783 return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), 784 MachinePointerInfo(SV)); 785 } 786 787 SDValue ARCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { 788 switch (Op.getOpcode()) { 789 case ISD::GlobalAddress: 790 return LowerGlobalAddress(Op, DAG); 791 case ISD::FRAMEADDR: 792 return LowerFRAMEADDR(Op, DAG); 793 case ISD::SELECT_CC: 794 return LowerSELECT_CC(Op, DAG); 795 case ISD::BR_CC: 796 return LowerBR_CC(Op, DAG); 797 case ISD::SIGN_EXTEND_INREG: 798 return LowerSIGN_EXTEND_INREG(Op, DAG); 799 case ISD::JumpTable: 800 return LowerJumpTable(Op, DAG); 801 case ISD::VASTART: 802 return LowerVASTART(Op, DAG); 803 case ISD::READCYCLECOUNTER: 804 // As of LLVM 3.8, the lowering code insists that we customize it even 805 // though we've declared the i32 version as legal. This is because it only 806 // thinks i64 is the truly supported version. We've already converted the 807 // i64 version to a widened i32. 808 assert(Op.getSimpleValueType() == MVT::i32); 809 return Op; 810 default: 811 llvm_unreachable("unimplemented operand"); 812 } 813 } 814