1688 lines · cpp
1//===- XtensaISelLowering.cpp - Xtensa DAG Lowering Implementation --------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines the interfaces that Xtensa uses to lower LLVM code into a10// selection DAG.11//12//===----------------------------------------------------------------------===//13 14#include "XtensaISelLowering.h"15#include "XtensaConstantPoolValue.h"16#include "XtensaInstrInfo.h"17#include "XtensaMachineFunctionInfo.h"18#include "XtensaSelectionDAGInfo.h"19#include "XtensaSubtarget.h"20#include "XtensaTargetMachine.h"21#include "llvm/CodeGen/CallingConvLower.h"22#include "llvm/CodeGen/MachineFrameInfo.h"23#include "llvm/CodeGen/MachineInstrBuilder.h"24#include "llvm/CodeGen/MachineJumpTableInfo.h"25#include "llvm/CodeGen/MachineRegisterInfo.h"26#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"27#include "llvm/IR/GlobalVariable.h"28#include "llvm/Support/Debug.h"29#include "llvm/Support/ErrorHandling.h"30#include "llvm/Support/MathExtras.h"31#include "llvm/Support/raw_ostream.h"32#include <deque>33 34using namespace llvm;35 36#define DEBUG_TYPE "xtensa-lower"37 38// Return true if we must use long (in fact, indirect) function call.39// It's simplified version, production implimentation must40// resolve a functions in ROM (usually glibc functions)41static bool isLongCall(const char *str) {42 // Currently always use long calls43 return true;44}45 46// The calling conventions in XtensaCallingConv.td are described in terms of the47// callee's register window. This function translates registers to the48// corresponding caller window %o register.49static unsigned toCallerWindow(unsigned Reg) {50 if (Reg >= Xtensa::A2 && Reg <= Xtensa::A7)51 return Reg - Xtensa::A2 + Xtensa::A10;52 return Reg;53}54 55XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,56 const XtensaSubtarget &STI)57 : TargetLowering(TM, STI), Subtarget(STI) {58 MVT PtrVT = MVT::i32;59 // Set up the register classes.60 addRegisterClass(MVT::i32, &Xtensa::ARRegClass);61 62 if (Subtarget.hasSingleFloat()) {63 addRegisterClass(MVT::f32, &Xtensa::FPRRegClass);64 }65 66 if (Subtarget.hasBoolean()) {67 addRegisterClass(MVT::v1i1, &Xtensa::BRRegClass);68 }69 70 // Set up special registers.71 setStackPointerRegisterToSaveRestore(Xtensa::SP);72 73 setSchedulingPreference(Sched::RegPressure);74 75 setMinFunctionAlignment(Align(4));76 77 setOperationAction(ISD::Constant, MVT::i32, Custom);78 setOperationAction(ISD::Constant, MVT::i64, Expand);79 setOperationAction(ISD::ConstantFP, MVT::f32, Expand);80 setOperationAction(ISD::ConstantFP, MVT::f64, Expand);81 82 setBooleanContents(ZeroOrOneBooleanContent);83 84 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);85 setOperationAction(ISD::SIGN_EXTEND_INREG, {MVT::i8, MVT::i16},86 Subtarget.hasSEXT() ? Legal : Expand);87 88 setOperationAction(ISD::BITCAST, MVT::i32, Expand);89 setOperationAction(ISD::BITCAST, MVT::f32, Expand);90 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);91 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Expand);92 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);93 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Expand);94 95 // No sign extend instructions for i1 and sign extend load i896 for (MVT VT : MVT::integer_valuetypes()) {97 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote);98 setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i1, Promote);99 setLoadExtAction(ISD::EXTLOAD, VT, MVT::i1, Promote);100 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i8, Expand);101 }102 103 setOperationAction(ISD::ConstantPool, PtrVT, Custom);104 setOperationAction(ISD::GlobalAddress, PtrVT, Custom);105 setOperationAction(ISD::GlobalTLSAddress, PtrVT, Custom);106 setOperationAction(ISD::BlockAddress, PtrVT, Custom);107 setOperationAction(ISD::JumpTable, PtrVT, Custom);108 109 // Expand jump table branches as address arithmetic followed by an110 // indirect jump.111 setOperationAction(ISD::BR_JT, MVT::Other, Custom);112 113 setOperationAction(ISD::BR_CC, MVT::i32, Legal);114 setOperationAction(ISD::BR_CC, MVT::i64, Expand);115 116 setOperationAction(ISD::SELECT, MVT::i32, Expand);117 setOperationAction(ISD::SELECT, MVT::f32, Expand);118 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);119 120 if (Subtarget.hasSingleFloat()) {121 setOperationAction(ISD::BR_CC, MVT::f32, Legal);122 setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);123 } else {124 setOperationAction(ISD::BR_CC, MVT::f32, Expand);125 setOperationAction(ISD::SELECT_CC, MVT::f32, Expand);126 }127 128 setOperationAction(ISD::SETCC, MVT::i32, Expand);129 setOperationAction(ISD::SETCC, MVT::f32, Expand);130 131 setCondCodeAction(ISD::SETGT, MVT::i32, Expand);132 setCondCodeAction(ISD::SETLE, MVT::i32, Expand);133 setCondCodeAction(ISD::SETUGT, MVT::i32, Expand);134 setCondCodeAction(ISD::SETULE, MVT::i32, Expand);135 136 if (Subtarget.hasMul32())137 setOperationAction(ISD::MUL, MVT::i32, Legal);138 else139 setOperationAction(ISD::MUL, MVT::i32, Expand);140 141 if (Subtarget.hasMul32High()) {142 setOperationAction(ISD::MULHU, MVT::i32, Legal);143 setOperationAction(ISD::MULHS, MVT::i32, Legal);144 } else {145 setOperationAction(ISD::MULHU, MVT::i32, Expand);146 setOperationAction(ISD::MULHS, MVT::i32, Expand);147 }148 149 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);150 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);151 152 if (Subtarget.hasDiv32()) {153 setOperationAction(ISD::SDIV, MVT::i32, Legal);154 setOperationAction(ISD::UDIV, MVT::i32, Legal);155 setOperationAction(ISD::SREM, MVT::i32, Legal);156 setOperationAction(ISD::UREM, MVT::i32, Legal);157 } else {158 setOperationAction(ISD::SDIV, MVT::i32, Expand);159 setOperationAction(ISD::UDIV, MVT::i32, Expand);160 setOperationAction(ISD::SREM, MVT::i32, Expand);161 setOperationAction(ISD::UREM, MVT::i32, Expand);162 }163 164 setOperationAction(ISD::SDIVREM, MVT::i32, Expand);165 setOperationAction(ISD::UDIVREM, MVT::i32, Expand);166 167 setOperationAction(ISD::SHL_PARTS, MVT::i32, Custom);168 setOperationAction(ISD::SRA_PARTS, MVT::i32, Custom);169 setOperationAction(ISD::SRL_PARTS, MVT::i32, Custom);170 171 setOperationAction(ISD::BSWAP, MVT::i32, Expand);172 setOperationAction(ISD::ROTL, MVT::i32, Expand);173 setOperationAction(ISD::ROTR, MVT::i32, Expand);174 setOperationAction(ISD::CTPOP, MVT::i32, Custom);175 setOperationAction(ISD::CTTZ, MVT::i32, Expand);176 setOperationAction(ISD::CTLZ, MVT::i32, Expand);177 setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand);178 setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand);179 180 setOperationAction({ISD::SMIN, ISD::SMAX, ISD::UMIN, ISD::UMAX}, MVT::i32,181 Subtarget.hasMINMAX() ? Legal : Expand);182 183 // Implement custom stack allocations184 setOperationAction(ISD::DYNAMIC_STACKALLOC, PtrVT, Custom);185 // Implement custom stack save and restore186 setOperationAction(ISD::STACKSAVE, MVT::Other, Custom);187 setOperationAction(ISD::STACKRESTORE, MVT::Other, Custom);188 189 // VASTART, VAARG and VACOPY need to deal with the Xtensa-specific varargs190 // structure, but VAEND is a no-op.191 setOperationAction(ISD::VASTART, MVT::Other, Custom);192 setOperationAction(ISD::VAARG, MVT::Other, Custom);193 setOperationAction(ISD::VACOPY, MVT::Other, Custom);194 setOperationAction(ISD::VAEND, MVT::Other, Expand);195 196 // Handle floating-point types.197 for (unsigned I = MVT::FIRST_FP_VALUETYPE; I <= MVT::LAST_FP_VALUETYPE; ++I) {198 MVT VT = MVT::SimpleValueType(I);199 if (isTypeLegal(VT)) {200 if (VT.getSizeInBits() == 32 && Subtarget.hasSingleFloat()) {201 setOperationAction(ISD::FABS, VT, Legal);202 setOperationAction(ISD::FADD, VT, Legal);203 setOperationAction(ISD::FSUB, VT, Legal);204 setOperationAction(ISD::FMA, VT, Legal);205 setOperationAction(ISD::FMUL, VT, Legal);206 setOperationAction(ISD::FNEG, VT, Legal);207 } else {208 setOperationAction(ISD::FABS, VT, Expand);209 setOperationAction(ISD::FADD, VT, Expand);210 setOperationAction(ISD::FSUB, VT, Expand);211 setOperationAction(ISD::FMA, VT, Expand);212 setOperationAction(ISD::FMUL, VT, Expand);213 setOperationAction(ISD::FNEG, VT, Expand);214 }215 216 // TODO: once implemented in InstrInfo uncomment217 setOperationAction(ISD::FSQRT, VT, Expand);218 setOperationAction(ISD::FSIN, VT, Expand);219 setOperationAction(ISD::FCOS, VT, Expand);220 setOperationAction(ISD::FREM, VT, Expand);221 setOperationAction(ISD::FDIV, VT, Expand);222 setOperationAction(ISD::FPOW, VT, Expand);223 setOperationAction(ISD::FSQRT, VT, Expand);224 setOperationAction(ISD::FCOPYSIGN, VT, Expand);225 }226 }227 228 // Handle floating-point types.229 if (Subtarget.hasSingleFloat()) {230 setOperationAction(ISD::BITCAST, MVT::i32, Legal);231 setOperationAction(ISD::BITCAST, MVT::f32, Legal);232 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Legal);233 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Legal);234 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Legal);235 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Legal);236 } else {237 setOperationAction(ISD::BITCAST, MVT::i32, Expand);238 setOperationAction(ISD::BITCAST, MVT::f32, Expand);239 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);240 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Expand);241 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);242 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Expand);243 }244 245 // Floating-point truncation and stores need to be done separately.246 setTruncStoreAction(MVT::f64, MVT::f32, Expand);247 248 if (Subtarget.hasS32C1I()) {249 setMaxAtomicSizeInBitsSupported(32);250 setMinCmpXchgSizeInBits(32);251 } else if (Subtarget.hasForcedAtomics()) {252 setMaxAtomicSizeInBitsSupported(32);253 } else {254 setMaxAtomicSizeInBitsSupported(0);255 }256 257 // Compute derived properties from the register classes258 computeRegisterProperties(STI.getRegisterInfo());259}260 261bool XtensaTargetLowering::isOffsetFoldingLegal(262 const GlobalAddressSDNode *GA) const {263 // The Xtensa target isn't yet aware of offsets.264 return false;265}266 267bool XtensaTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,268 bool ForCodeSize) const {269 return false;270}271 272//===----------------------------------------------------------------------===//273// Inline asm support274//===----------------------------------------------------------------------===//275TargetLowering::ConstraintType276XtensaTargetLowering::getConstraintType(StringRef Constraint) const {277 if (Constraint.size() == 1) {278 switch (Constraint[0]) {279 case 'r':280 return C_RegisterClass;281 default:282 break;283 }284 }285 return TargetLowering::getConstraintType(Constraint);286}287 288TargetLowering::ConstraintWeight289XtensaTargetLowering::getSingleConstraintMatchWeight(290 AsmOperandInfo &Info, const char *Constraint) const {291 ConstraintWeight Weight = CW_Invalid;292 Value *CallOperandVal = Info.CallOperandVal;293 // If we don't have a value, we can't do a match,294 // but allow it at the lowest weight.295 if (!CallOperandVal)296 return CW_Default;297 298 Type *Ty = CallOperandVal->getType();299 300 // Look at the constraint type.301 switch (*Constraint) {302 default:303 Weight = TargetLowering::getSingleConstraintMatchWeight(Info, Constraint);304 break;305 case 'r':306 if (Ty->isIntegerTy())307 Weight = CW_Register;308 break;309 }310 return Weight;311}312 313std::pair<unsigned, const TargetRegisterClass *>314XtensaTargetLowering::getRegForInlineAsmConstraint(315 const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {316 if (Constraint.size() == 1) {317 // GCC Constraint Letters318 switch (Constraint[0]) {319 default:320 break;321 case 'r': // General-purpose register322 return std::make_pair(0U, &Xtensa::ARRegClass);323 }324 }325 return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);326}327 328void XtensaTargetLowering::LowerAsmOperandForConstraint(329 SDValue Op, StringRef Constraint, std::vector<SDValue> &Ops,330 SelectionDAG &DAG) const {331 SDLoc DL(Op);332 333 // Only support length 1 constraints for now.334 if (Constraint.size() > 1)335 return;336 337 TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);338}339 340//===----------------------------------------------------------------------===//341// Calling conventions342//===----------------------------------------------------------------------===//343 344#include "XtensaGenCallingConv.inc"345 346static const MCPhysReg IntRegs[] = {Xtensa::A2, Xtensa::A3, Xtensa::A4,347 Xtensa::A5, Xtensa::A6, Xtensa::A7};348 349static bool CC_Xtensa_Custom(unsigned ValNo, MVT ValVT, MVT LocVT,350 CCValAssign::LocInfo LocInfo,351 ISD::ArgFlagsTy ArgFlags, Type *OrigTy,352 CCState &State) {353 if (ArgFlags.isByVal()) {354 Align ByValAlign = ArgFlags.getNonZeroByValAlign();355 unsigned ByValSize = ArgFlags.getByValSize();356 if (ByValSize < 4) {357 ByValSize = 4;358 }359 if (ByValAlign < Align(4)) {360 ByValAlign = Align(4);361 }362 unsigned Offset = State.AllocateStack(ByValSize, ByValAlign);363 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));364 // Mark all unused registers as allocated to avoid misuse365 // of such registers.366 while (State.AllocateReg(IntRegs))367 ;368 return false;369 }370 371 // Promote i8 and i16372 if (LocVT == MVT::i8 || LocVT == MVT::i16) {373 LocVT = MVT::i32;374 if (ArgFlags.isSExt())375 LocInfo = CCValAssign::SExt;376 else if (ArgFlags.isZExt())377 LocInfo = CCValAssign::ZExt;378 else379 LocInfo = CCValAssign::AExt;380 }381 382 unsigned Register;383 384 Align OrigAlign = ArgFlags.getNonZeroOrigAlign();385 bool needs64BitAlign = (ValVT == MVT::i32 && OrigAlign == Align(8));386 bool needs128BitAlign = (ValVT == MVT::i32 && OrigAlign == Align(16));387 388 if (ValVT == MVT::i32) {389 Register = State.AllocateReg(IntRegs);390 // If this is the first part of an i64 arg,391 // the allocated register must be either A2, A4 or A6.392 if (needs64BitAlign && (Register == Xtensa::A3 || Register == Xtensa::A5 ||393 Register == Xtensa::A7))394 Register = State.AllocateReg(IntRegs);395 // arguments with 16byte alignment must be passed in the first register or396 // passed via stack397 if (needs128BitAlign && (Register != Xtensa::A2))398 while ((Register = State.AllocateReg(IntRegs)))399 ;400 LocVT = MVT::i32;401 } else if (ValVT == MVT::f64) {402 // Allocate int register and shadow next int register.403 Register = State.AllocateReg(IntRegs);404 if (Register == Xtensa::A3 || Register == Xtensa::A5 ||405 Register == Xtensa::A7)406 Register = State.AllocateReg(IntRegs);407 State.AllocateReg(IntRegs);408 LocVT = MVT::i32;409 } else {410 report_fatal_error("Cannot handle this ValVT.");411 }412 413 if (!Register) {414 unsigned Offset = State.AllocateStack(ValVT.getStoreSize(), OrigAlign);415 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));416 } else {417 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Register, LocVT, LocInfo));418 }419 420 return false;421}422 423/// Return the register type for a given MVT424MVT XtensaTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,425 CallingConv::ID CC,426 EVT VT) const {427 if (VT.isFloatingPoint())428 return MVT::i32;429 430 return TargetLowering::getRegisterTypeForCallingConv(Context, CC, VT);431}432 433CCAssignFn *XtensaTargetLowering::CCAssignFnForCall(CallingConv::ID CC,434 bool IsVarArg) const {435 return CC_Xtensa_Custom;436}437 438SDValue XtensaTargetLowering::LowerFormalArguments(439 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,440 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,441 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {442 MachineFunction &MF = DAG.getMachineFunction();443 MachineFrameInfo &MFI = MF.getFrameInfo();444 XtensaMachineFunctionInfo *XtensaFI = MF.getInfo<XtensaMachineFunctionInfo>();445 446 // Used with vargs to acumulate store chains.447 std::vector<SDValue> OutChains;448 449 // Assign locations to all of the incoming arguments.450 SmallVector<CCValAssign, 16> ArgLocs;451 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,452 *DAG.getContext());453 454 CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, IsVarArg));455 456 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {457 CCValAssign &VA = ArgLocs[i];458 // Arguments stored on registers459 if (VA.isRegLoc()) {460 EVT RegVT = VA.getLocVT();461 462 if (RegVT != MVT::i32)463 report_fatal_error("RegVT not supported by FormalArguments Lowering");464 465 // Transform the arguments stored on466 // physical registers into virtual ones467 Register Reg = 0;468 MCRegister FrameReg = Subtarget.getRegisterInfo()->getFrameRegister(MF);469 470 // Argument passed in FrameReg in Windowed ABI we save in A8 (in471 // emitPrologue), so load argument from A8472 if (Subtarget.isWindowedABI() && (VA.getLocReg() == FrameReg)) {473 Reg = MF.addLiveIn(Xtensa::A8, &Xtensa::ARRegClass);474 XtensaFI->setSaveFrameRegister();475 } else {476 Reg = MF.addLiveIn(VA.getLocReg(), &Xtensa::ARRegClass);477 }478 479 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, RegVT);480 481 // If this is an 8 or 16-bit value, it has been passed promoted482 // to 32 bits. Insert an assert[sz]ext to capture this, then483 // truncate to the right size.484 if (VA.getLocInfo() != CCValAssign::Full) {485 unsigned Opcode = 0;486 if (VA.getLocInfo() == CCValAssign::SExt)487 Opcode = ISD::AssertSext;488 else if (VA.getLocInfo() == CCValAssign::ZExt)489 Opcode = ISD::AssertZext;490 if (Opcode)491 ArgValue = DAG.getNode(Opcode, DL, RegVT, ArgValue,492 DAG.getValueType(VA.getValVT()));493 ArgValue = DAG.getNode((VA.getValVT() == MVT::f32) ? ISD::BITCAST494 : ISD::TRUNCATE,495 DL, VA.getValVT(), ArgValue);496 }497 498 InVals.push_back(ArgValue);499 500 } else {501 assert(VA.isMemLoc());502 503 EVT ValVT = VA.getValVT();504 505 // The stack pointer offset is relative to the caller stack frame.506 int FI = MFI.CreateFixedObject(ValVT.getStoreSize(), VA.getLocMemOffset(),507 true);508 509 if (Ins[VA.getValNo()].Flags.isByVal()) {510 // Assume that in this case load operation is created511 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);512 InVals.push_back(FIN);513 } else {514 // Create load nodes to retrieve arguments from the stack515 SDValue FIN =516 DAG.getFrameIndex(FI, getFrameIndexTy(DAG.getDataLayout()));517 InVals.push_back(DAG.getLoad(518 ValVT, DL, Chain, FIN,519 MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI)));520 }521 }522 }523 524 if (IsVarArg) {525 unsigned Idx = CCInfo.getFirstUnallocated(IntRegs);526 unsigned ArgRegsNum = std::size(IntRegs);527 const TargetRegisterClass *RC = &Xtensa::ARRegClass;528 MachineFrameInfo &MFI = MF.getFrameInfo();529 MachineRegisterInfo &RegInfo = MF.getRegInfo();530 unsigned RegSize = 4;531 MVT RegTy = MVT::i32;532 MVT FITy = getFrameIndexTy(DAG.getDataLayout());533 534 XtensaFI->setVarArgsFirstGPR(Idx + 2); // 2 - number of a2 register535 536 XtensaFI->setVarArgsOnStackFrameIndex(537 MFI.CreateFixedObject(4, CCInfo.getStackSize(), true));538 539 // Offset of the first variable argument from stack pointer, and size of540 // the vararg save area. For now, the varargs save area is either zero or541 // large enough to hold a0-a7.542 int VaArgOffset, VarArgsSaveSize;543 544 // If all registers are allocated, then all varargs must be passed on the545 // stack and we don't need to save any argregs.546 if (ArgRegsNum == Idx) {547 VaArgOffset = CCInfo.getStackSize();548 VarArgsSaveSize = 0;549 } else {550 VarArgsSaveSize = RegSize * (ArgRegsNum - Idx);551 VaArgOffset = -VarArgsSaveSize;552 553 // Record the frame index of the first variable argument554 // which is a value necessary to VASTART.555 int FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);556 XtensaFI->setVarArgsInRegsFrameIndex(FI);557 558 // Copy the integer registers that may have been used for passing varargs559 // to the vararg save area.560 for (unsigned I = Idx; I < ArgRegsNum; ++I, VaArgOffset += RegSize) {561 const Register Reg = RegInfo.createVirtualRegister(RC);562 RegInfo.addLiveIn(IntRegs[I], Reg);563 564 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, RegTy);565 FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);566 SDValue PtrOff = DAG.getFrameIndex(FI, FITy);567 SDValue Store = DAG.getStore(Chain, DL, ArgValue, PtrOff,568 MachinePointerInfo::getFixedStack(MF, FI));569 OutChains.push_back(Store);570 }571 }572 }573 574 // All stores are grouped in one node to allow the matching between575 // the size of Ins and InVals. This only happens when on varg functions576 if (!OutChains.empty()) {577 OutChains.push_back(Chain);578 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);579 }580 581 return Chain;582}583 584SDValue585XtensaTargetLowering::LowerCall(CallLoweringInfo &CLI,586 SmallVectorImpl<SDValue> &InVals) const {587 SelectionDAG &DAG = CLI.DAG;588 SDLoc &DL = CLI.DL;589 SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs;590 SmallVector<SDValue, 32> &OutVals = CLI.OutVals;591 SmallVector<ISD::InputArg, 32> &Ins = CLI.Ins;592 SDValue Chain = CLI.Chain;593 SDValue Callee = CLI.Callee;594 bool &IsTailCall = CLI.IsTailCall;595 CallingConv::ID CallConv = CLI.CallConv;596 bool IsVarArg = CLI.IsVarArg;597 598 MachineFunction &MF = DAG.getMachineFunction();599 EVT PtrVT = getPointerTy(DAG.getDataLayout());600 const TargetFrameLowering *TFL = Subtarget.getFrameLowering();601 602 // TODO: Support tail call optimization.603 IsTailCall = false;604 605 // Analyze the operands of the call, assigning locations to each operand.606 SmallVector<CCValAssign, 16> ArgLocs;607 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());608 609 CCAssignFn *CC = CCAssignFnForCall(CallConv, IsVarArg);610 611 CCInfo.AnalyzeCallOperands(Outs, CC);612 613 // Get a count of how many bytes are to be pushed on the stack.614 unsigned NumBytes = CCInfo.getStackSize();615 616 Align StackAlignment = TFL->getStackAlign();617 unsigned NextStackOffset = alignTo(NumBytes, StackAlignment);618 619 Chain = DAG.getCALLSEQ_START(Chain, NextStackOffset, 0, DL);620 621 // Copy argument values to their designated locations.622 std::deque<std::pair<unsigned, SDValue>> RegsToPass;623 SmallVector<SDValue, 8> MemOpChains;624 SDValue StackPtr;625 for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) {626 CCValAssign &VA = ArgLocs[I];627 SDValue ArgValue = OutVals[I];628 ISD::ArgFlagsTy Flags = Outs[I].Flags;629 630 if (VA.isRegLoc())631 // Queue up the argument copies and emit them at the end.632 RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue));633 else if (Flags.isByVal()) {634 assert(VA.isMemLoc());635 assert(Flags.getByValSize() &&636 "ByVal args of size 0 should have been ignored by front-end.");637 assert(!IsTailCall &&638 "Do not tail-call optimize if there is a byval argument.");639 640 if (!StackPtr.getNode())641 StackPtr = DAG.getCopyFromReg(Chain, DL, Xtensa::SP, PtrVT);642 unsigned Offset = VA.getLocMemOffset();643 SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,644 DAG.getIntPtrConstant(Offset, DL));645 SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), DL, MVT::i32);646 SDValue Memcpy = DAG.getMemcpy(647 Chain, DL, Address, ArgValue, SizeNode, Flags.getNonZeroByValAlign(),648 /*isVolatile=*/false, /*AlwaysInline=*/false,649 /*CI=*/nullptr, std::nullopt, MachinePointerInfo(),650 MachinePointerInfo());651 MemOpChains.push_back(Memcpy);652 } else {653 assert(VA.isMemLoc() && "Argument not register or memory");654 655 // Work out the address of the stack slot. Unpromoted ints and656 // floats are passed as right-justified 8-byte values.657 if (!StackPtr.getNode())658 StackPtr = DAG.getCopyFromReg(Chain, DL, Xtensa::SP, PtrVT);659 unsigned Offset = VA.getLocMemOffset();660 SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,661 DAG.getIntPtrConstant(Offset, DL));662 663 // Emit the store.664 MemOpChains.push_back(665 DAG.getStore(Chain, DL, ArgValue, Address, MachinePointerInfo()));666 }667 }668 669 // Join the stores, which are independent of one another.670 if (!MemOpChains.empty())671 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);672 673 // Build a sequence of copy-to-reg nodes, chained and glued together.674 SDValue Glue;675 for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) {676 unsigned Reg = RegsToPass[I].first;677 if (Subtarget.isWindowedABI())678 Reg = toCallerWindow(Reg);679 Chain = DAG.getCopyToReg(Chain, DL, Reg, RegsToPass[I].second, Glue);680 Glue = Chain.getValue(1);681 }682 std::string name;683 unsigned char TF = 0;684 685 // Accept direct calls by converting symbolic call addresses to the686 // associated Target* opcodes.687 if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {688 name = E->getSymbol();689 TF = E->getTargetFlags();690 if (isPositionIndependent()) {691 report_fatal_error("PIC relocations is not supported");692 } else693 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, TF);694 } else if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {695 const GlobalValue *GV = G->getGlobal();696 name = GV->getName().str();697 }698 699 if ((!name.empty()) && isLongCall(name.c_str())) {700 // Create a constant pool entry for the callee address701 XtensaCP::XtensaCPModifier Modifier = XtensaCP::no_modifier;702 XtensaMachineFunctionInfo *XtensaFI =703 MF.getInfo<XtensaMachineFunctionInfo>();704 unsigned LabelId = XtensaFI->createCPLabelId();705 706 XtensaConstantPoolValue *CPV = XtensaConstantPoolSymbol::Create(707 *DAG.getContext(), name.c_str(), LabelId, false, Modifier);708 709 // Get the address of the callee into a register710 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4), 0, TF);711 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);712 Callee = DAG.getLoad(713 PtrVT, DL, DAG.getEntryNode(), CPWrap,714 MachinePointerInfo::getConstantPool(DAG.getMachineFunction()));715 }716 717 // The first call operand is the chain and the second is the target address.718 SmallVector<SDValue, 8> Ops;719 Ops.push_back(Chain);720 Ops.push_back(Callee);721 722 // Add a register mask operand representing the call-preserved registers.723 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();724 const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);725 assert(Mask && "Missing call preserved mask for calling convention");726 Ops.push_back(DAG.getRegisterMask(Mask));727 728 // Add argument registers to the end of the list so that they are729 // known live into the call.730 for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) {731 unsigned Reg = RegsToPass[I].first;732 if (Subtarget.isWindowedABI())733 Reg = toCallerWindow(Reg);734 Ops.push_back(DAG.getRegister(Reg, RegsToPass[I].second.getValueType()));735 }736 737 // Glue the call to the argument copies, if any.738 if (Glue.getNode())739 Ops.push_back(Glue);740 741 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);742 Chain = DAG.getNode(Subtarget.isWindowedABI() ? XtensaISD::CALLW8743 : XtensaISD::CALL,744 DL, NodeTys, Ops);745 Glue = Chain.getValue(1);746 747 // Mark the end of the call, which is glued to the call itself.748 Chain = DAG.getCALLSEQ_END(Chain, DAG.getConstant(NumBytes, DL, PtrVT, true),749 DAG.getConstant(0, DL, PtrVT, true), Glue, DL);750 Glue = Chain.getValue(1);751 752 // Assign locations to each value returned by this call.753 SmallVector<CCValAssign, 16> RetLocs;754 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext());755 RetCCInfo.AnalyzeCallResult(Ins, Subtarget.isWindowedABI() ? RetCCW8_Xtensa756 : RetCC_Xtensa);757 758 // Copy all of the result registers out of their specified physreg.759 for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) {760 CCValAssign &VA = RetLocs[I];761 762 // Copy the value out, gluing the copy to the end of the call sequence.763 unsigned Reg = VA.getLocReg();764 SDValue RetValue = DAG.getCopyFromReg(Chain, DL, Reg, VA.getLocVT(), Glue);765 Chain = RetValue.getValue(1);766 Glue = RetValue.getValue(2);767 768 InVals.push_back(RetValue);769 }770 return Chain;771}772 773bool XtensaTargetLowering::CanLowerReturn(774 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,775 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,776 const Type *RetTy) const {777 SmallVector<CCValAssign, 16> RVLocs;778 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);779 return CCInfo.CheckReturn(Outs, RetCC_Xtensa);780}781 782SDValue783XtensaTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,784 bool IsVarArg,785 const SmallVectorImpl<ISD::OutputArg> &Outs,786 const SmallVectorImpl<SDValue> &OutVals,787 const SDLoc &DL, SelectionDAG &DAG) const {788 MachineFunction &MF = DAG.getMachineFunction();789 790 // Assign locations to each returned value.791 SmallVector<CCValAssign, 16> RetLocs;792 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext());793 RetCCInfo.AnalyzeReturn(Outs, RetCC_Xtensa);794 795 SDValue Glue;796 // Quick exit for void returns797 if (RetLocs.empty())798 return DAG.getNode(Subtarget.isWindowedABI() ? XtensaISD::RETW799 : XtensaISD::RET,800 DL, MVT::Other, Chain);801 802 // Copy the result values into the output registers.803 SmallVector<SDValue, 4> RetOps;804 RetOps.push_back(Chain);805 for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) {806 CCValAssign &VA = RetLocs[I];807 SDValue RetValue = OutVals[I];808 809 // Make the return register live on exit.810 assert(VA.isRegLoc() && "Can only return in registers!");811 812 // Chain and glue the copies together.813 unsigned Register = VA.getLocReg();814 Chain = DAG.getCopyToReg(Chain, DL, Register, RetValue, Glue);815 Glue = Chain.getValue(1);816 RetOps.push_back(DAG.getRegister(Register, VA.getLocVT()));817 }818 819 // Update chain and glue.820 RetOps[0] = Chain;821 if (Glue.getNode())822 RetOps.push_back(Glue);823 824 return DAG.getNode(Subtarget.isWindowedABI() ? XtensaISD::RETW825 : XtensaISD::RET,826 DL, MVT::Other, RetOps);827}828 829static unsigned getBranchOpcode(ISD::CondCode Cond) {830 switch (Cond) {831 case ISD::SETEQ:832 return Xtensa::BEQ;833 case ISD::SETNE:834 return Xtensa::BNE;835 case ISD::SETLT:836 return Xtensa::BLT;837 case ISD::SETLE:838 return Xtensa::BGE;839 case ISD::SETGT:840 return Xtensa::BLT;841 case ISD::SETGE:842 return Xtensa::BGE;843 case ISD::SETULT:844 return Xtensa::BLTU;845 case ISD::SETULE:846 return Xtensa::BGEU;847 case ISD::SETUGT:848 return Xtensa::BLTU;849 case ISD::SETUGE:850 return Xtensa::BGEU;851 default:852 llvm_unreachable("Unknown branch kind");853 }854}855 856static std::pair<unsigned, unsigned> getFPBranchKind(ISD::CondCode Cond) {857 switch (Cond) {858 case ISD::SETUNE:859 return std::make_pair(Xtensa::BF, Xtensa::OEQ_S);860 case ISD::SETUO:861 return std::make_pair(Xtensa::BT, Xtensa::UN_S);862 case ISD::SETO:863 return std::make_pair(Xtensa::BF, Xtensa::UN_S);864 case ISD::SETUEQ:865 return std::make_pair(Xtensa::BT, Xtensa::UEQ_S);866 case ISD::SETULE:867 return std::make_pair(Xtensa::BT, Xtensa::ULE_S);868 case ISD::SETULT:869 return std::make_pair(Xtensa::BT, Xtensa::ULT_S);870 case ISD::SETEQ:871 case ISD::SETOEQ:872 return std::make_pair(Xtensa::BT, Xtensa::OEQ_S);873 case ISD::SETNE:874 return std::make_pair(Xtensa::BF, Xtensa::OEQ_S);875 case ISD::SETLE:876 case ISD::SETOLE:877 return std::make_pair(Xtensa::BT, Xtensa::OLE_S);878 case ISD::SETLT:879 case ISD::SETOLT:880 return std::make_pair(Xtensa::BT, Xtensa::OLT_S);881 case ISD::SETGE:882 return std::make_pair(Xtensa::BF, Xtensa::OLT_S);883 case ISD::SETGT:884 return std::make_pair(Xtensa::BF, Xtensa::OLE_S);885 case ISD::SETOGT:886 return std::make_pair(Xtensa::BF, Xtensa::ULE_S);887 case ISD::SETOGE:888 return std::make_pair(Xtensa::BF, Xtensa::ULT_S);889 case ISD::SETONE:890 return std::make_pair(Xtensa::BF, Xtensa::UEQ_S);891 case ISD::SETUGT:892 return std::make_pair(Xtensa::BF, Xtensa::OLE_S);893 case ISD::SETUGE:894 return std::make_pair(Xtensa::BF, Xtensa::OLT_S);895 default:896 llvm_unreachable("Invalid condition!");897 }898}899 900SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op,901 SelectionDAG &DAG) const {902 SDLoc DL(Op);903 EVT Ty = Op.getValueType();904 SDValue LHS = Op.getOperand(0);905 SDValue RHS = Op.getOperand(1);906 SDValue TrueValue = Op.getOperand(2);907 SDValue FalseValue = Op.getOperand(3);908 ISD::CondCode CC = cast<CondCodeSDNode>(Op->getOperand(4))->get();909 910 if (LHS.getValueType() == MVT::i32) {911 unsigned BrOpcode = getBranchOpcode(CC);912 SDValue TargetCC = DAG.getConstant(BrOpcode, DL, MVT::i32);913 914 SDValue Res = DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue,915 FalseValue, TargetCC, Op->getFlags());916 return Res;917 }918 assert(LHS.getValueType() == MVT::f32 &&919 "We expect MVT::f32 type of the LHS Operand in SELECT_CC");920 unsigned BrOpcode;921 unsigned CmpOpCode;922 std::tie(BrOpcode, CmpOpCode) = getFPBranchKind(CC);923 SDValue TargetCC = DAG.getConstant(CmpOpCode, DL, MVT::i32);924 SDValue TargetBC = DAG.getConstant(BrOpcode, DL, MVT::i32);925 return DAG.getNode(XtensaISD::SELECT_CC_FP, DL, Ty,926 {LHS, RHS, TrueValue, FalseValue, TargetCC, TargetBC},927 Op->getFlags());928}929 930SDValue XtensaTargetLowering::LowerRETURNADDR(SDValue Op,931 SelectionDAG &DAG) const {932 // This nodes represent llvm.returnaddress on the DAG.933 // It takes one operand, the index of the return address to return.934 // An index of zero corresponds to the current function's return address.935 // An index of one to the parent's return address, and so on.936 // Depths > 0 not supported yet!937 if (Op.getConstantOperandVal(0) != 0)938 return SDValue();939 940 MachineFunction &MF = DAG.getMachineFunction();941 MachineFrameInfo &MFI = MF.getFrameInfo();942 EVT VT = Op.getValueType();943 MFI.setReturnAddressIsTaken(true);944 945 // Return RA, which contains the return address. Mark it an implicit946 // live-in.947 Register RA = MF.addLiveIn(Xtensa::A0, getRegClassFor(MVT::i32));948 return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), RA, VT);949}950 951SDValue XtensaTargetLowering::LowerImmediate(SDValue Op,952 SelectionDAG &DAG) const {953 const ConstantSDNode *CN = cast<ConstantSDNode>(Op);954 SDLoc DL(CN);955 APInt APVal = CN->getAPIntValue();956 int64_t Value = APVal.getSExtValue();957 if (Op.getValueType() == MVT::i32) {958 // Check if use node maybe lowered to the MOVI instruction959 if (Value > -2048 && Value <= 2047)960 return Op;961 // Check if use node maybe lowered to the ADDMI instruction962 SDNode &OpNode = *Op.getNode();963 if ((OpNode.hasOneUse() && OpNode.user_begin()->getOpcode() == ISD::ADD) &&964 isShiftedInt<8, 8>(Value))965 return Op;966 Type *Ty = Type::getInt32Ty(*DAG.getContext());967 Constant *CV = ConstantInt::get(Ty, Value);968 SDValue CP = DAG.getConstantPool(CV, MVT::i32);969 SDValue Res =970 DAG.getLoad(MVT::i32, DL, DAG.getEntryNode(), CP, MachinePointerInfo());971 return Res;972 }973 return Op;974}975 976SDValue XtensaTargetLowering::LowerGlobalAddress(SDValue Op,977 SelectionDAG &DAG) const {978 const GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Op);979 SDLoc DL(Op);980 auto PtrVT = Op.getValueType();981 const GlobalValue *GV = G->getGlobal();982 983 SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, Align(4));984 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);985 SDValue Res = DAG.getLoad(986 PtrVT, DL, DAG.getEntryNode(), CPWrap,987 MachinePointerInfo::getConstantPool(DAG.getMachineFunction()));988 return Res;989}990 991SDValue XtensaTargetLowering::LowerGlobalTLSAddress(SDValue Op,992 SelectionDAG &DAG) const {993 const GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Op);994 SDLoc DL(Op);995 EVT PtrVT = Op.getValueType();996 const GlobalValue *GV = G->getGlobal();997 998 if (DAG.getTarget().useEmulatedTLS())999 return LowerToTLSEmulatedModel(G, DAG);1000 1001 TLSModel::Model model = getTargetMachine().getTLSModel(GV);1002 1003 if (!Subtarget.hasTHREADPTR()) {1004 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(1005 DAG.getMachineFunction().getFunction(), "only emulated TLS supported",1006 DL.getDebugLoc()));1007 return DAG.getPOISON(Op->getValueType(0));1008 }1009 1010 if (model == TLSModel::LocalExec || model == TLSModel::InitialExec) {1011 bool Priv = GV->isPrivateLinkage(GV->getLinkage());1012 MachineFunction &MF = DAG.getMachineFunction();1013 XtensaMachineFunctionInfo *XtensaFI =1014 MF.getInfo<XtensaMachineFunctionInfo>();1015 unsigned LabelId = XtensaFI->createCPLabelId();1016 1017 // Create a constant pool entry for the callee address1018 XtensaConstantPoolValue *CPV = XtensaConstantPoolSymbol::Create(1019 *DAG.getContext(), GV->getName().str().c_str(), LabelId, Priv,1020 XtensaCP::TPOFF);1021 1022 // Get the address of the callee into a register1023 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));1024 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);1025 SDValue Addr = DAG.getLoad(1026 PtrVT, DL, DAG.getEntryNode(), CPWrap,1027 MachinePointerInfo::getConstantPool(DAG.getMachineFunction()));1028 1029 SDValue TPRegister = DAG.getRegister(Xtensa::THREADPTR, MVT::i32);1030 SDValue ThreadPointer =1031 DAG.getNode(XtensaISD::RUR, DL, MVT::i32, TPRegister);1032 1033 return DAG.getNode(ISD::ADD, DL, PtrVT, ThreadPointer, Addr);1034 }1035 1036 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(1037 DAG.getMachineFunction().getFunction(),1038 "only local-exec and initial-exec TLS mode supported", DL.getDebugLoc()));1039 1040 return DAG.getPOISON(Op->getValueType(0));1041}1042 1043SDValue XtensaTargetLowering::LowerBlockAddress(SDValue Op,1044 SelectionDAG &DAG) const {1045 BlockAddressSDNode *Node = cast<BlockAddressSDNode>(Op);1046 SDLoc DL(Op);1047 const BlockAddress *BA = Node->getBlockAddress();1048 EVT PtrVT = Op.getValueType();1049 MachineFunction &MF = DAG.getMachineFunction();1050 XtensaMachineFunctionInfo *XtensaFI = MF.getInfo<XtensaMachineFunctionInfo>();1051 unsigned LabelId = XtensaFI->createCPLabelId();1052 1053 XtensaConstantPoolValue *CPV =1054 XtensaConstantPoolConstant::Create(BA, LabelId, XtensaCP::CPBlockAddress);1055 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));1056 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);1057 SDValue Res = DAG.getLoad(1058 PtrVT, DL, DAG.getEntryNode(), CPWrap,1059 MachinePointerInfo::getConstantPool(DAG.getMachineFunction()));1060 return Res;1061}1062 1063SDValue XtensaTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) const {1064 SDValue Chain = Op.getOperand(0);1065 SDValue Table = Op.getOperand(1);1066 SDValue Index = Op.getOperand(2);1067 SDLoc DL(Op);1068 JumpTableSDNode *JT = cast<JumpTableSDNode>(Table);1069 MachineFunction &MF = DAG.getMachineFunction();1070 const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();1071 SDValue TargetJT = DAG.getTargetJumpTable(JT->getIndex(), MVT::i32);1072 const DataLayout &TD = DAG.getDataLayout();1073 EVT PtrVT = Table.getValueType();1074 unsigned EntrySize = MJTI->getEntrySize(TD);1075 1076 assert((MJTI->getEntrySize(TD) == 4) && "Unsupported jump-table entry size");1077 1078 Index = DAG.getNode(1079 ISD::SHL, DL, Index.getValueType(), Index,1080 DAG.getConstant(Log2_32(EntrySize), DL, Index.getValueType()));1081 1082 SDValue Addr = DAG.getNode(ISD::ADD, DL, Index.getValueType(), Index, Table);1083 SDValue LD =1084 DAG.getLoad(PtrVT, DL, Chain, Addr,1085 MachinePointerInfo::getJumpTable(DAG.getMachineFunction()));1086 1087 return DAG.getNode(XtensaISD::BR_JT, DL, MVT::Other, LD.getValue(1), LD,1088 TargetJT);1089}1090 1091SDValue XtensaTargetLowering::LowerJumpTable(SDValue Op,1092 SelectionDAG &DAG) const {1093 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);1094 EVT PtrVT = Op.getValueType();1095 SDLoc DL(Op);1096 1097 // Create a constant pool entry for the jumptable address1098 XtensaConstantPoolValue *CPV =1099 XtensaConstantPoolJumpTable::Create(*DAG.getContext(), JT->getIndex());1100 1101 // Get the address of the jumptable into a register1102 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));1103 1104 SDValue Res = DAG.getLoad(1105 PtrVT, DL, DAG.getEntryNode(), getAddrPCRel(CPAddr, DAG),1106 MachinePointerInfo::getConstantPool(DAG.getMachineFunction()));1107 return Res;1108}1109 1110SDValue XtensaTargetLowering::getAddrPCRel(SDValue Op,1111 SelectionDAG &DAG) const {1112 SDLoc DL(Op);1113 EVT Ty = Op.getValueType();1114 return DAG.getNode(XtensaISD::PCREL_WRAPPER, DL, Ty, Op);1115}1116 1117SDValue XtensaTargetLowering::LowerConstantPool(SDValue Op,1118 SelectionDAG &DAG) const {1119 EVT PtrVT = Op.getValueType();1120 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);1121 SDValue Result;1122 1123 if (!CP->isMachineConstantPoolEntry()) {1124 Result = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, CP->getAlign(),1125 CP->getOffset());1126 } else {1127 report_fatal_error("This constantpool type is not supported yet");1128 }1129 1130 return getAddrPCRel(Result, DAG);1131}1132 1133SDValue XtensaTargetLowering::LowerSTACKSAVE(SDValue Op,1134 SelectionDAG &DAG) const {1135 return DAG.getCopyFromReg(Op.getOperand(0), SDLoc(Op), Xtensa::SP,1136 Op.getValueType());1137}1138 1139SDValue XtensaTargetLowering::LowerSTACKRESTORE(SDValue Op,1140 SelectionDAG &DAG) const {1141 SDValue Chain = Op.getOperand(0);1142 SDValue NewSP = Op.getOperand(1);1143 1144 if (Subtarget.isWindowedABI()) {1145 return DAG.getNode(XtensaISD::MOVSP, SDLoc(Op), MVT::Other, Chain, NewSP);1146 }1147 1148 return DAG.getCopyToReg(Chain, SDLoc(Op), Xtensa::SP, NewSP);1149}1150 1151SDValue XtensaTargetLowering::LowerFRAMEADDR(SDValue Op,1152 SelectionDAG &DAG) const {1153 // This nodes represent llvm.frameaddress on the DAG.1154 // It takes one operand, the index of the frame address to return.1155 // An index of zero corresponds to the current function's frame address.1156 // An index of one to the parent's frame address, and so on.1157 // Depths > 0 not supported yet!1158 if (Op.getConstantOperandVal(0) != 0)1159 return SDValue();1160 1161 MachineFunction &MF = DAG.getMachineFunction();1162 MachineFrameInfo &MFI = MF.getFrameInfo();1163 MFI.setFrameAddressIsTaken(true);1164 EVT VT = Op.getValueType();1165 SDLoc DL(Op);1166 1167 MCRegister FrameRegister = Subtarget.getRegisterInfo()->getFrameRegister(MF);1168 SDValue FrameAddr =1169 DAG.getCopyFromReg(DAG.getEntryNode(), DL, FrameRegister, VT);1170 return FrameAddr;1171}1172 1173SDValue XtensaTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,1174 SelectionDAG &DAG) const {1175 SDValue Chain = Op.getOperand(0); // Legalize the chain.1176 SDValue Size = Op.getOperand(1); // Legalize the size.1177 EVT VT = Size->getValueType(0);1178 SDLoc DL(Op);1179 1180 // Round up Size to 321181 SDValue SizeTmp =1182 DAG.getNode(ISD::ADD, DL, VT, Size, DAG.getConstant(31, DL, MVT::i32));1183 SDValue SizeRoundUp = DAG.getNode(ISD::AND, DL, VT, SizeTmp,1184 DAG.getSignedConstant(~31, DL, MVT::i32));1185 1186 MCRegister SPReg = Xtensa::SP;1187 SDValue SP = DAG.getCopyFromReg(Chain, DL, SPReg, VT);1188 SDValue NewSP = DAG.getNode(ISD::SUB, DL, VT, SP, SizeRoundUp); // Value1189 if (Subtarget.isWindowedABI()) {1190 Chain = DAG.getNode(XtensaISD::MOVSP, SDLoc(Op), MVT::Other, SP.getValue(1),1191 NewSP);1192 } else {1193 Chain = DAG.getCopyToReg(SP.getValue(1), DL, SPReg, NewSP); // Output chain1194 }1195 1196 SDValue NewVal = DAG.getCopyFromReg(Chain, DL, SPReg, MVT::i32);1197 Chain = NewVal.getValue(1);1198 1199 SDValue Ops[2] = {NewVal, Chain};1200 return DAG.getMergeValues(Ops, DL);1201}1202 1203SDValue XtensaTargetLowering::LowerVASTART(SDValue Op,1204 SelectionDAG &DAG) const {1205 MachineFunction &MF = DAG.getMachineFunction();1206 XtensaMachineFunctionInfo *XtensaFI = MF.getInfo<XtensaMachineFunctionInfo>();1207 SDValue Chain = Op.getOperand(0);1208 SDValue Addr = Op.getOperand(1);1209 EVT PtrVT = Addr.getValueType();1210 SDLoc DL(Op);1211 1212 // Struct va_list_tag1213 // int32 *va_stk - points to the arguments passed in memory1214 // int32 *va_reg - points to the registers with arguments saved in memory1215 // int32 va_ndx - offset from va_stk or va_reg pointers which points to the1216 // next variable argument1217 1218 SDValue VAIndex;1219 SDValue StackOffsetFI =1220 DAG.getFrameIndex(XtensaFI->getVarArgsOnStackFrameIndex(), PtrVT);1221 unsigned ArgWords = XtensaFI->getVarArgsFirstGPR() - 2;1222 1223 // If first variable argument passed in registers (maximum words in registers1224 // is 6) then set va_ndx to the position of this argument in registers area1225 // stored in memory (va_reg pointer). Otherwise va_ndx should point to the1226 // position of the first variable argument on stack (va_stk pointer).1227 if (ArgWords < 6) {1228 VAIndex = DAG.getConstant(ArgWords * 4, DL, MVT::i32);1229 } else {1230 VAIndex = DAG.getConstant(32, DL, MVT::i32);1231 }1232 1233 SDValue FrameIndex =1234 DAG.getFrameIndex(XtensaFI->getVarArgsInRegsFrameIndex(), PtrVT);1235 uint64_t FrameOffset = PtrVT.getStoreSize();1236 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();1237 1238 // Store pointer to arguments given on stack (va_stk)1239 SDValue StackPtr = DAG.getNode(ISD::SUB, DL, PtrVT, StackOffsetFI,1240 DAG.getConstant(32, DL, PtrVT));1241 1242 SDValue StoreStackPtr =1243 DAG.getStore(Chain, DL, StackPtr, Addr, MachinePointerInfo(SV));1244 1245 uint64_t NextOffset = FrameOffset;1246 SDValue NextPtr =1247 DAG.getObjectPtrOffset(DL, Addr, TypeSize::getFixed(NextOffset));1248 1249 // Store pointer to arguments given on registers (va_reg)1250 SDValue StoreRegPtr = DAG.getStore(StoreStackPtr, DL, FrameIndex, NextPtr,1251 MachinePointerInfo(SV, NextOffset));1252 NextOffset += FrameOffset;1253 NextPtr = DAG.getObjectPtrOffset(DL, Addr, TypeSize::getFixed(NextOffset));1254 1255 // Store third word : position in bytes of the first VA argument (va_ndx)1256 return DAG.getStore(StoreRegPtr, DL, VAIndex, NextPtr,1257 MachinePointerInfo(SV, NextOffset));1258}1259 1260SDValue XtensaTargetLowering::LowerVACOPY(SDValue Op, SelectionDAG &DAG) const {1261 // Size of the va_list_tag structure1262 constexpr unsigned VAListSize = 3 * 4;1263 SDValue Chain = Op.getOperand(0);1264 SDValue DstPtr = Op.getOperand(1);1265 SDValue SrcPtr = Op.getOperand(2);1266 const Value *DstSV = cast<SrcValueSDNode>(Op.getOperand(3))->getValue();1267 const Value *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();1268 SDLoc DL(Op);1269 1270 return DAG.getMemcpy(Chain, DL, DstPtr, SrcPtr,1271 DAG.getConstant(VAListSize, SDLoc(Op), MVT::i32),1272 Align(4), /*isVolatile*/ false, /*AlwaysInline*/ true,1273 /*CI=*/nullptr, std::nullopt, MachinePointerInfo(DstSV),1274 MachinePointerInfo(SrcSV));1275}1276 1277SDValue XtensaTargetLowering::LowerVAARG(SDValue Op, SelectionDAG &DAG) const {1278 SDNode *Node = Op.getNode();1279 EVT VT = Node->getValueType(0);1280 Type *Ty = VT.getTypeForEVT(*DAG.getContext());1281 EVT PtrVT = Op.getValueType();1282 SDValue InChain = Node->getOperand(0);1283 SDValue VAListPtr = Node->getOperand(1);1284 const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();1285 SDLoc DL(Node);1286 auto &TD = DAG.getDataLayout();1287 Align ArgAlignment = TD.getABITypeAlign(Ty);1288 unsigned ArgAlignInBytes = ArgAlignment.value();1289 unsigned ArgSizeInBytes = TD.getTypeAllocSize(Ty);1290 unsigned VASizeInBytes = llvm::alignTo(ArgSizeInBytes, 4);1291 1292 // va_stk1293 SDValue VAStack =1294 DAG.getLoad(MVT::i32, DL, InChain, VAListPtr, MachinePointerInfo());1295 InChain = VAStack.getValue(1);1296 1297 // va_reg1298 SDValue VARegPtr =1299 DAG.getObjectPtrOffset(DL, VAListPtr, TypeSize::getFixed(4));1300 SDValue VAReg =1301 DAG.getLoad(MVT::i32, DL, InChain, VARegPtr, MachinePointerInfo());1302 InChain = VAReg.getValue(1);1303 1304 // va_ndx1305 SDValue VarArgIndexPtr =1306 DAG.getObjectPtrOffset(DL, VARegPtr, TypeSize::getFixed(4));1307 SDValue VAIndex =1308 DAG.getLoad(MVT::i32, DL, InChain, VarArgIndexPtr, MachinePointerInfo());1309 InChain = VAIndex.getValue(1);1310 1311 SDValue OrigIndex = VAIndex;1312 1313 if (ArgAlignInBytes > 4) {1314 OrigIndex = DAG.getNode(ISD::ADD, DL, PtrVT, OrigIndex,1315 DAG.getConstant(ArgAlignInBytes - 1, DL, MVT::i32));1316 OrigIndex =1317 DAG.getNode(ISD::AND, DL, PtrVT, OrigIndex,1318 DAG.getSignedConstant(-ArgAlignInBytes, DL, MVT::i32));1319 }1320 1321 VAIndex = DAG.getNode(ISD::ADD, DL, PtrVT, OrigIndex,1322 DAG.getConstant(VASizeInBytes, DL, MVT::i32));1323 1324 SDValue CC = DAG.getSetCC(DL, MVT::i32, OrigIndex,1325 DAG.getConstant(6 * 4, DL, MVT::i32), ISD::SETLE);1326 1327 SDValue StkIndex =1328 DAG.getNode(ISD::ADD, DL, PtrVT, VAIndex,1329 DAG.getConstant(32 + VASizeInBytes, DL, MVT::i32));1330 1331 CC = DAG.getSetCC(DL, MVT::i32, VAIndex, DAG.getConstant(6 * 4, DL, MVT::i32),1332 ISD::SETLE);1333 1334 SDValue Array = DAG.getNode(ISD::SELECT, DL, MVT::i32, CC, VAReg, VAStack);1335 1336 VAIndex = DAG.getNode(ISD::SELECT, DL, MVT::i32, CC, VAIndex, StkIndex);1337 1338 CC = DAG.getSetCC(DL, MVT::i32, VAIndex, DAG.getConstant(6 * 4, DL, MVT::i32),1339 ISD::SETLE);1340 1341 SDValue VAIndexStore = DAG.getStore(InChain, DL, VAIndex, VarArgIndexPtr,1342 MachinePointerInfo(SV));1343 InChain = VAIndexStore;1344 1345 SDValue Addr = DAG.getNode(ISD::SUB, DL, PtrVT, VAIndex,1346 DAG.getConstant(VASizeInBytes, DL, MVT::i32));1347 1348 Addr = DAG.getNode(ISD::ADD, DL, PtrVT, Array, Addr);1349 1350 return DAG.getLoad(VT, DL, InChain, Addr, MachinePointerInfo());1351}1352 1353SDValue XtensaTargetLowering::LowerShiftLeftParts(SDValue Op,1354 SelectionDAG &DAG) const {1355 SDLoc DL(Op);1356 MVT VT = MVT::i32;1357 SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1);1358 SDValue Shamt = Op.getOperand(2);1359 1360 // if Shamt - register size < 0: // Shamt < register size1361 // Lo = Lo << Shamt1362 // Hi = (Hi << Shamt) | (Lo >>u (register size - Shamt))1363 // else:1364 // Lo = 01365 // Hi = Lo << (Shamt - register size)1366 1367 SDValue MinusRegisterSize = DAG.getSignedConstant(-32, DL, VT);1368 SDValue ShamtMinusRegisterSize =1369 DAG.getNode(ISD::ADD, DL, VT, Shamt, MinusRegisterSize);1370 1371 SDValue LoTrue = DAG.getNode(ISD::SHL, DL, VT, Lo, Shamt);1372 SDValue HiTrue = DAG.getNode(XtensaISD::SRCL, DL, VT, Hi, Lo, Shamt);1373 SDValue Zero = DAG.getConstant(0, DL, VT);1374 SDValue HiFalse = DAG.getNode(ISD::SHL, DL, VT, Lo, ShamtMinusRegisterSize);1375 1376 SDValue Cond = DAG.getSetCC(DL, VT, ShamtMinusRegisterSize, Zero, ISD::SETLT);1377 Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, LoTrue, Zero);1378 Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond, HiTrue, HiFalse);1379 1380 return DAG.getMergeValues({Lo, Hi}, DL);1381}1382 1383SDValue XtensaTargetLowering::LowerShiftRightParts(SDValue Op,1384 SelectionDAG &DAG,1385 bool IsSRA) const {1386 SDLoc DL(Op);1387 SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1);1388 SDValue Shamt = Op.getOperand(2);1389 MVT VT = MVT::i32;1390 1391 // SRA expansion:1392 // if Shamt - register size < 0: // Shamt < register size1393 // Lo = (Lo >>u Shamt) | (Hi << u (register size - Shamt))1394 // Hi = Hi >>s Shamt1395 // else:1396 // Lo = Hi >>s (Shamt - register size);1397 // Hi = Hi >>s (register size - 1)1398 //1399 // SRL expansion:1400 // if Shamt - register size < 0: // Shamt < register size1401 // Lo = (Lo >>u Shamt) | (Hi << u (register size - Shamt))1402 // Hi = Hi >>u Shamt1403 // else:1404 // Lo = Hi >>u (Shamt - register size);1405 // Hi = 0;1406 1407 unsigned ShiftRightOp = IsSRA ? ISD::SRA : ISD::SRL;1408 SDValue MinusRegisterSize = DAG.getSignedConstant(-32, DL, VT);1409 SDValue RegisterSizeMinus1 = DAG.getConstant(32 - 1, DL, VT);1410 SDValue ShamtMinusRegisterSize =1411 DAG.getNode(ISD::ADD, DL, VT, Shamt, MinusRegisterSize);1412 1413 SDValue LoTrue = DAG.getNode(XtensaISD::SRCR, DL, VT, Hi, Lo, Shamt);1414 SDValue HiTrue = DAG.getNode(ShiftRightOp, DL, VT, Hi, Shamt);1415 SDValue Zero = DAG.getConstant(0, DL, VT);1416 SDValue LoFalse =1417 DAG.getNode(ShiftRightOp, DL, VT, Hi, ShamtMinusRegisterSize);1418 SDValue HiFalse;1419 1420 if (IsSRA) {1421 HiFalse = DAG.getNode(ShiftRightOp, DL, VT, Hi, RegisterSizeMinus1);1422 } else {1423 HiFalse = Zero;1424 }1425 1426 SDValue Cond = DAG.getSetCC(DL, VT, ShamtMinusRegisterSize, Zero, ISD::SETLT);1427 Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, LoTrue, LoFalse);1428 Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond, HiTrue, HiFalse);1429 1430 return DAG.getMergeValues({Lo, Hi}, DL);1431}1432 1433SDValue XtensaTargetLowering::LowerCTPOP(SDValue Op, SelectionDAG &DAG) const {1434 auto &TLI = DAG.getTargetLoweringInfo();1435 return TLI.expandCTPOP(Op.getNode(), DAG);1436}1437 1438bool XtensaTargetLowering::decomposeMulByConstant(LLVMContext &Context, EVT VT,1439 SDValue C) const {1440 APInt Imm;1441 unsigned EltSizeInBits;1442 1443 if (ISD::isConstantSplatVector(C.getNode(), Imm)) {1444 EltSizeInBits = VT.getScalarSizeInBits();1445 } else if (VT.isScalarInteger()) {1446 EltSizeInBits = VT.getSizeInBits();1447 if (auto *ConstNode = dyn_cast<ConstantSDNode>(C.getNode()))1448 Imm = ConstNode->getAPIntValue();1449 else1450 return false;1451 } else {1452 return false;1453 }1454 1455 // Omit if data size exceeds.1456 if (EltSizeInBits > 32)1457 return false;1458 1459 // Convert MULT to LSL.1460 if (Imm.isPowerOf2() && Imm.isIntN(5))1461 return true;1462 1463 return false;1464}1465 1466SDValue XtensaTargetLowering::LowerOperation(SDValue Op,1467 SelectionDAG &DAG) const {1468 switch (Op.getOpcode()) {1469 case ISD::BR_JT:1470 return LowerBR_JT(Op, DAG);1471 case ISD::Constant:1472 return LowerImmediate(Op, DAG);1473 case ISD::RETURNADDR:1474 return LowerRETURNADDR(Op, DAG);1475 case ISD::GlobalAddress:1476 return LowerGlobalAddress(Op, DAG);1477 case ISD::GlobalTLSAddress:1478 return LowerGlobalTLSAddress(Op, DAG);1479 case ISD::BlockAddress:1480 return LowerBlockAddress(Op, DAG);1481 case ISD::JumpTable:1482 return LowerJumpTable(Op, DAG);1483 case ISD::CTPOP:1484 return LowerCTPOP(Op, DAG);1485 case ISD::ConstantPool:1486 return LowerConstantPool(Op, DAG);1487 case ISD::SELECT_CC:1488 return LowerSELECT_CC(Op, DAG);1489 case ISD::STACKSAVE:1490 return LowerSTACKSAVE(Op, DAG);1491 case ISD::STACKRESTORE:1492 return LowerSTACKRESTORE(Op, DAG);1493 case ISD::FRAMEADDR:1494 return LowerFRAMEADDR(Op, DAG);1495 case ISD::DYNAMIC_STACKALLOC:1496 return LowerDYNAMIC_STACKALLOC(Op, DAG);1497 case ISD::VASTART:1498 return LowerVASTART(Op, DAG);1499 case ISD::VAARG:1500 return LowerVAARG(Op, DAG);1501 case ISD::VACOPY:1502 return LowerVACOPY(Op, DAG);1503 case ISD::SHL_PARTS:1504 return LowerShiftLeftParts(Op, DAG);1505 case ISD::SRA_PARTS:1506 return LowerShiftRightParts(Op, DAG, true);1507 case ISD::SRL_PARTS:1508 return LowerShiftRightParts(Op, DAG, false);1509 default:1510 report_fatal_error("Unexpected node to lower");1511 }1512}1513 1514TargetLowering::AtomicExpansionKind1515XtensaTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {1516 return AtomicExpansionKind::CmpXChg;1517}1518 1519//===----------------------------------------------------------------------===//1520// Custom insertion1521//===----------------------------------------------------------------------===//1522 1523MachineBasicBlock *1524XtensaTargetLowering::emitSelectCC(MachineInstr &MI,1525 MachineBasicBlock *MBB) const {1526 const TargetInstrInfo &TII = *Subtarget.getInstrInfo();1527 DebugLoc DL = MI.getDebugLoc();1528 1529 MachineOperand &LHS = MI.getOperand(1);1530 MachineOperand &RHS = MI.getOperand(2);1531 MachineOperand &TrueValue = MI.getOperand(3);1532 MachineOperand &FalseValue = MI.getOperand(4);1533 1534 // To "insert" a SELECT_CC instruction, we actually have to insert1535 // CopyMBB and SinkMBB blocks and add branch to MBB. We build phi1536 // operation in SinkMBB like phi (TrueVakue,FalseValue), where TrueValue1537 // is passed from MMB and FalseValue is passed from CopyMBB.1538 // MBB1539 // | \1540 // | CopyMBB1541 // | /1542 // SinkMBB1543 // The incoming instruction knows the1544 // destination vreg to set, the condition code register to branch on, the1545 // true/false values to select between, and a branch opcode to use.1546 const BasicBlock *LLVM_BB = MBB->getBasicBlock();1547 MachineFunction::iterator It = ++MBB->getIterator();1548 1549 MachineFunction *F = MBB->getParent();1550 MachineBasicBlock *CopyMBB = F->CreateMachineBasicBlock(LLVM_BB);1551 MachineBasicBlock *SinkMBB = F->CreateMachineBasicBlock(LLVM_BB);1552 1553 F->insert(It, CopyMBB);1554 F->insert(It, SinkMBB);1555 1556 // Transfer the remainder of MBB and its successor edges to SinkMBB.1557 SinkMBB->splice(SinkMBB->begin(), MBB,1558 std::next(MachineBasicBlock::iterator(MI)), MBB->end());1559 SinkMBB->transferSuccessorsAndUpdatePHIs(MBB);1560 1561 MBB->addSuccessor(CopyMBB);1562 MBB->addSuccessor(SinkMBB);1563 1564 if (MI.getOpcode() == Xtensa::SELECT_CC_FP_FP ||1565 MI.getOpcode() == Xtensa::SELECT_CC_FP_INT) {1566 unsigned CmpKind = MI.getOperand(5).getImm();1567 unsigned BrKind = MI.getOperand(6).getImm();1568 MCPhysReg BReg = Xtensa::B0;1569 1570 BuildMI(MBB, DL, TII.get(CmpKind), BReg)1571 .addReg(LHS.getReg())1572 .addReg(RHS.getReg());1573 BuildMI(MBB, DL, TII.get(BrKind))1574 .addReg(BReg, RegState::Kill)1575 .addMBB(SinkMBB);1576 } else {1577 unsigned BrKind = MI.getOperand(5).getImm();1578 BuildMI(MBB, DL, TII.get(BrKind))1579 .addReg(LHS.getReg())1580 .addReg(RHS.getReg())1581 .addMBB(SinkMBB);1582 }1583 1584 CopyMBB->addSuccessor(SinkMBB);1585 1586 // SinkMBB:1587 // %Result = phi [ %FalseValue, CopyMBB ], [ %TrueValue, MBB ]1588 // ...1589 1590 BuildMI(*SinkMBB, SinkMBB->begin(), DL, TII.get(Xtensa::PHI),1591 MI.getOperand(0).getReg())1592 .addReg(FalseValue.getReg())1593 .addMBB(CopyMBB)1594 .addReg(TrueValue.getReg())1595 .addMBB(MBB);1596 1597 MI.eraseFromParent(); // The pseudo instruction is gone now.1598 return SinkMBB;1599}1600 1601MachineBasicBlock *XtensaTargetLowering::EmitInstrWithCustomInserter(1602 MachineInstr &MI, MachineBasicBlock *MBB) const {1603 DebugLoc DL = MI.getDebugLoc();1604 const XtensaInstrInfo &TII = *Subtarget.getInstrInfo();1605 1606 switch (MI.getOpcode()) {1607 case Xtensa::BRCC_FP: {1608 MachineOperand &Cond = MI.getOperand(0);1609 MachineOperand &LHS = MI.getOperand(1);1610 MachineOperand &RHS = MI.getOperand(2);1611 MachineBasicBlock *TargetBB = MI.getOperand(3).getMBB();1612 unsigned BrKind = 0;1613 unsigned CmpKind = 0;1614 ISD::CondCode CondCode = (ISD::CondCode)Cond.getImm();1615 MCPhysReg BReg = Xtensa::B0;1616 1617 std::tie(BrKind, CmpKind) = getFPBranchKind(CondCode);1618 BuildMI(*MBB, MI, DL, TII.get(CmpKind), BReg)1619 .addReg(LHS.getReg())1620 .addReg(RHS.getReg());1621 BuildMI(*MBB, MI, DL, TII.get(BrKind))1622 .addReg(BReg, RegState::Kill)1623 .addMBB(TargetBB);1624 1625 MI.eraseFromParent();1626 return MBB;1627 }1628 case Xtensa::SELECT_CC_FP_FP:1629 case Xtensa::SELECT_CC_FP_INT:1630 case Xtensa::SELECT_CC_INT_FP:1631 case Xtensa::SELECT:1632 return emitSelectCC(MI, MBB);1633 case Xtensa::S8I:1634 case Xtensa::S16I:1635 case Xtensa::S32I:1636 case Xtensa::S32I_N:1637 case Xtensa::SSI:1638 case Xtensa::SSIP:1639 case Xtensa::SSX:1640 case Xtensa::SSXP:1641 case Xtensa::L8UI:1642 case Xtensa::L16SI:1643 case Xtensa::L16UI:1644 case Xtensa::L32I:1645 case Xtensa::L32I_N:1646 case Xtensa::LSI:1647 case Xtensa::LSIP:1648 case Xtensa::LSX:1649 case Xtensa::LSXP: {1650 // Insert memory wait instruction "memw" before volatile load/store as it is1651 // implemented in gcc. If memoperands is empty then assume that it aslo1652 // maybe volatile load/store and insert "memw".1653 if (MI.memoperands_empty() || (*MI.memoperands_begin())->isVolatile()) {1654 BuildMI(*MBB, MI, DL, TII.get(Xtensa::MEMW));1655 }1656 return MBB;1657 }1658 case Xtensa::MOVSP_P: {1659 MachineOperand &NewSP = MI.getOperand(0);1660 1661 BuildMI(*MBB, MI, DL, TII.get(Xtensa::MOVSP), Xtensa::SP)1662 .addReg(NewSP.getReg());1663 MI.eraseFromParent();1664 1665 return MBB;1666 }1667 case Xtensa::ATOMIC_CMP_SWAP_32_P: {1668 MachineOperand &R = MI.getOperand(0);1669 MachineOperand &Addr = MI.getOperand(1);1670 MachineOperand &Cmp = MI.getOperand(2);1671 MachineOperand &Swap = MI.getOperand(3);1672 1673 BuildMI(*MBB, MI, DL, TII.get(Xtensa::WSR), Xtensa::SCOMPARE1)1674 .addReg(Cmp.getReg());1675 1676 BuildMI(*MBB, MI, DL, TII.get(Xtensa::S32C1I), R.getReg())1677 .addReg(Swap.getReg())1678 .addReg(Addr.getReg())1679 .addImm(0);1680 1681 MI.eraseFromParent();1682 return MBB;1683 }1684 default:1685 llvm_unreachable("Unexpected instr type to insert");1686 }1687}1688