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