#include "MipsISelLowering.h"
#include "MCTargetDesc/MipsBaseInfo.h"
#include "MCTargetDesc/MipsInstPrinter.h"
#include "MCTargetDesc/MipsMCTargetDesc.h"
#include "MipsCCState.h"
#include "MipsInstrInfo.h"
#include "MipsMachineFunction.h"
#include "MipsRegisterInfo.h"
#include "MipsSubtarget.h"
#include "MipsTargetMachine.h"
#include "MipsTargetObjectFile.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/FunctionLoweringInfo.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RuntimeLibcallUtil.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGenTypes/MachineValueType.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstdint>
#include <deque>
#include <iterator>
#include <utility>
#include <vector>
usingnamespacellvm;
#define DEBUG_TYPE …
STATISTIC(NumTailCalls, "Number of tail calls");
static cl::opt<bool>
NoZeroDivCheck("mno-check-zero-division", cl::Hidden,
cl::desc("MIPS: Don't trap on integer division by zero."),
cl::init(false));
extern cl::opt<bool> EmitJalrReloc;
static const MCPhysReg Mips64DPRegs[8] = …;
MVT MipsTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,
CallingConv::ID CC,
EVT VT) const { … }
unsigned MipsTargetLowering::getNumRegistersForCallingConv(LLVMContext &Context,
CallingConv::ID CC,
EVT VT) const { … }
unsigned MipsTargetLowering::getVectorTypeBreakdownForCallingConv(
LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT,
unsigned &NumIntermediates, MVT &RegisterVT) const { … }
SDValue MipsTargetLowering::getGlobalReg(SelectionDAG &DAG, EVT Ty) const { … }
SDValue MipsTargetLowering::getTargetNode(GlobalAddressSDNode *N, EVT Ty,
SelectionDAG &DAG,
unsigned Flag) const { … }
SDValue MipsTargetLowering::getTargetNode(ExternalSymbolSDNode *N, EVT Ty,
SelectionDAG &DAG,
unsigned Flag) const { … }
SDValue MipsTargetLowering::getTargetNode(BlockAddressSDNode *N, EVT Ty,
SelectionDAG &DAG,
unsigned Flag) const { … }
SDValue MipsTargetLowering::getTargetNode(JumpTableSDNode *N, EVT Ty,
SelectionDAG &DAG,
unsigned Flag) const { … }
SDValue MipsTargetLowering::getTargetNode(ConstantPoolSDNode *N, EVT Ty,
SelectionDAG &DAG,
unsigned Flag) const { … }
const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { … }
MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
const MipsSubtarget &STI)
: … { … }
const MipsTargetLowering *
MipsTargetLowering::create(const MipsTargetMachine &TM,
const MipsSubtarget &STI) { … }
FastISel *
MipsTargetLowering::createFastISel(FunctionLoweringInfo &funcInfo,
const TargetLibraryInfo *libInfo) const { … }
EVT MipsTargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &,
EVT VT) const { … }
static SDValue performDivRemCombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const MipsSubtarget &Subtarget) { … }
static Mips::CondCode condCodeToFCC(ISD::CondCode CC) { … }
static bool invertFPCondCodeUser(Mips::CondCode CC) { … }
static SDValue createFPCmp(SelectionDAG &DAG, const SDValue &Op) { … }
static SDValue createCMovFP(SelectionDAG &DAG, SDValue Cond, SDValue True,
SDValue False, const SDLoc &DL) { … }
static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const MipsSubtarget &Subtarget) { … }
static SDValue performCMovFPCombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const MipsSubtarget &Subtarget) { … }
static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const MipsSubtarget &Subtarget) { … }
static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const MipsSubtarget &Subtarget) { … }
static SDValue performMADD_MSUBCombine(SDNode *ROOTNode, SelectionDAG &CurDAG,
const MipsSubtarget &Subtarget) { … }
static SDValue performSUBCombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const MipsSubtarget &Subtarget) { … }
static SDValue performADDCombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const MipsSubtarget &Subtarget) { … }
static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const MipsSubtarget &Subtarget) { … }
SDValue MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
const { … }
bool MipsTargetLowering::isCheapToSpeculateCttz(Type *Ty) const { … }
bool MipsTargetLowering::isCheapToSpeculateCtlz(Type *Ty) const { … }
bool MipsTargetLowering::hasBitTest(SDValue X, SDValue Y) const { … }
bool MipsTargetLowering::shouldFoldConstantShiftPairToMask(
const SDNode *N, CombineLevel Level) const { … }
void
MipsTargetLowering::ReplaceNodeResults(SDNode *N,
SmallVectorImpl<SDValue> &Results,
SelectionDAG &DAG) const { … }
SDValue MipsTargetLowering::
LowerOperation(SDValue Op, SelectionDAG &DAG) const
{ … }
static unsigned
addLiveIn(MachineFunction &MF, unsigned PReg, const TargetRegisterClass *RC)
{ … }
static MachineBasicBlock *insertDivByZeroTrap(MachineInstr &MI,
MachineBasicBlock &MBB,
const TargetInstrInfo &TII,
bool Is64Bit, bool IsMicroMips) { … }
MachineBasicBlock *
MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
MachineBasicBlock *BB) const { … }
MachineBasicBlock *
MipsTargetLowering::emitAtomicBinary(MachineInstr &MI,
MachineBasicBlock *BB) const { … }
MachineBasicBlock *MipsTargetLowering::emitSignExtendToI32InReg(
MachineInstr &MI, MachineBasicBlock *BB, unsigned Size, unsigned DstReg,
unsigned SrcReg) const { … }
MachineBasicBlock *MipsTargetLowering::emitAtomicBinaryPartword(
MachineInstr &MI, MachineBasicBlock *BB, unsigned Size) const { … }
MachineBasicBlock *
MipsTargetLowering::emitAtomicCmpSwap(MachineInstr &MI,
MachineBasicBlock *BB) const { … }
MachineBasicBlock *MipsTargetLowering::emitAtomicCmpSwapPartword(
MachineInstr &MI, MachineBasicBlock *BB, unsigned Size) const { … }
SDValue MipsTargetLowering::lowerBRCOND(SDValue Op, SelectionDAG &DAG) const { … }
SDValue MipsTargetLowering::
lowerSELECT(SDValue Op, SelectionDAG &DAG) const
{ … }
SDValue MipsTargetLowering::lowerSETCC(SDValue Op, SelectionDAG &DAG) const { … }
SDValue MipsTargetLowering::lowerGlobalAddress(SDValue Op,
SelectionDAG &DAG) const { … }
SDValue MipsTargetLowering::lowerBlockAddress(SDValue Op,
SelectionDAG &DAG) const { … }
SDValue MipsTargetLowering::
lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const
{ … }
SDValue MipsTargetLowering::
lowerJumpTable(SDValue Op, SelectionDAG &DAG) const
{ … }
SDValue MipsTargetLowering::
lowerConstantPool(SDValue Op, SelectionDAG &DAG) const
{ … }
SDValue MipsTargetLowering::lowerVASTART(SDValue Op, SelectionDAG &DAG) const { … }
SDValue MipsTargetLowering::lowerVAARG(SDValue Op, SelectionDAG &DAG) const { … }
static SDValue lowerFCOPYSIGN32(SDValue Op, SelectionDAG &DAG,
bool HasExtractInsert) { … }
static SDValue lowerFCOPYSIGN64(SDValue Op, SelectionDAG &DAG,
bool HasExtractInsert) { … }
SDValue
MipsTargetLowering::lowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const { … }
SDValue MipsTargetLowering::lowerFABS32(SDValue Op, SelectionDAG &DAG,
bool HasExtractInsert) const { … }
SDValue MipsTargetLowering::lowerFABS64(SDValue Op, SelectionDAG &DAG,
bool HasExtractInsert) const { … }
SDValue MipsTargetLowering::lowerFABS(SDValue Op, SelectionDAG &DAG) const { … }
SDValue MipsTargetLowering::lowerFCANONICALIZE(SDValue Op,
SelectionDAG &DAG) const { … }
SDValue MipsTargetLowering::
lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { … }
SDValue MipsTargetLowering::lowerRETURNADDR(SDValue Op,
SelectionDAG &DAG) const { … }
SDValue MipsTargetLowering::lowerEH_RETURN(SDValue Op, SelectionDAG &DAG)
const { … }
SDValue MipsTargetLowering::lowerATOMIC_FENCE(SDValue Op,
SelectionDAG &DAG) const { … }
SDValue MipsTargetLowering::lowerShiftLeftParts(SDValue Op,
SelectionDAG &DAG) const { … }
SDValue MipsTargetLowering::lowerShiftRightParts(SDValue Op, SelectionDAG &DAG,
bool IsSRA) const { … }
static SDValue createLoadLR(unsigned Opc, SelectionDAG &DAG, LoadSDNode *LD,
SDValue Chain, SDValue Src, unsigned Offset) { … }
SDValue MipsTargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const { … }
static SDValue createStoreLR(unsigned Opc, SelectionDAG &DAG, StoreSDNode *SD,
SDValue Chain, unsigned Offset) { … }
static SDValue lowerUnalignedIntStore(StoreSDNode *SD, SelectionDAG &DAG,
bool IsLittle) { … }
static SDValue lowerFP_TO_SINT_STORE(StoreSDNode *SD, SelectionDAG &DAG,
bool SingleFloat) { … }
SDValue MipsTargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const { … }
SDValue MipsTargetLowering::lowerEH_DWARF_CFA(SDValue Op,
SelectionDAG &DAG) const { … }
SDValue MipsTargetLowering::lowerFP_TO_SINT(SDValue Op,
SelectionDAG &DAG) const { … }
static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT,
CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
CCState &State, ArrayRef<MCPhysReg> F64Regs) { … }
static bool CC_MipsO32_FP32(unsigned ValNo, MVT ValVT,
MVT LocVT, CCValAssign::LocInfo LocInfo,
ISD::ArgFlagsTy ArgFlags, CCState &State) { … }
static bool CC_MipsO32_FP64(unsigned ValNo, MVT ValVT,
MVT LocVT, CCValAssign::LocInfo LocInfo,
ISD::ArgFlagsTy ArgFlags, CCState &State) { … }
static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT,
CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
CCState &State) LLVM_ATTRIBUTE_UNUSED;
#include "MipsGenCallingConv.inc"
CCAssignFn *MipsTargetLowering::CCAssignFnForCall() const{ … }
CCAssignFn *MipsTargetLowering::CCAssignFnForReturn() const{ … }
SDValue MipsTargetLowering::passArgOnStack(SDValue StackPtr, unsigned Offset,
SDValue Chain, SDValue Arg,
const SDLoc &DL, bool IsTailCall,
SelectionDAG &DAG) const { … }
void MipsTargetLowering::
getOpndList(SmallVectorImpl<SDValue> &Ops,
std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
SDValue Chain) const { … }
void MipsTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI,
SDNode *Node) const { … }
SDValue
MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const { … }
SDValue MipsTargetLowering::LowerCallResult(
SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool IsVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
TargetLowering::CallLoweringInfo &CLI) const { … }
static SDValue UnpackFromArgumentSlot(SDValue Val, const CCValAssign &VA,
EVT ArgVT, const SDLoc &DL,
SelectionDAG &DAG) { … }
SDValue MipsTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { … }
bool
MipsTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
MachineFunction &MF, bool IsVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
LLVMContext &Context) const { … }
bool MipsTargetLowering::shouldSignExtendTypeInLibCall(EVT Type,
bool IsSigned) const { … }
SDValue
MipsTargetLowering::LowerInterruptReturn(SmallVectorImpl<SDValue> &RetOps,
const SDLoc &DL,
SelectionDAG &DAG) const { … }
SDValue
MipsTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
bool IsVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &DL, SelectionDAG &DAG) const { … }
MipsTargetLowering::ConstraintType
MipsTargetLowering::getConstraintType(StringRef Constraint) const { … }
TargetLowering::ConstraintWeight
MipsTargetLowering::getSingleConstraintMatchWeight(
AsmOperandInfo &info, const char *constraint) const { … }
static std::pair<bool, bool> parsePhysicalReg(StringRef C, StringRef &Prefix,
unsigned long long &Reg) { … }
EVT MipsTargetLowering::getTypeForExtReturn(LLVMContext &Context, EVT VT,
ISD::NodeType) const { … }
std::pair<unsigned, const TargetRegisterClass *> MipsTargetLowering::
parseRegForInlineAsmConstraint(StringRef C, MVT VT) const { … }
std::pair<unsigned, const TargetRegisterClass *>
MipsTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
StringRef Constraint,
MVT VT) const { … }
void MipsTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
StringRef Constraint,
std::vector<SDValue> &Ops,
SelectionDAG &DAG) const { … }
bool MipsTargetLowering::isLegalAddressingMode(const DataLayout &DL,
const AddrMode &AM, Type *Ty,
unsigned AS,
Instruction *I) const { … }
bool
MipsTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const { … }
EVT MipsTargetLowering::getOptimalMemOpType(
const MemOp &Op, const AttributeList &FuncAttributes) const { … }
bool MipsTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
bool ForCodeSize) const { … }
unsigned MipsTargetLowering::getJumpTableEncoding() const { … }
bool MipsTargetLowering::useSoftFloat() const { … }
void MipsTargetLowering::copyByValRegs(
SDValue Chain, const SDLoc &DL, std::vector<SDValue> &OutChains,
SelectionDAG &DAG, const ISD::ArgFlagsTy &Flags,
SmallVectorImpl<SDValue> &InVals, const Argument *FuncArg,
unsigned FirstReg, unsigned LastReg, const CCValAssign &VA,
MipsCCState &State) const { … }
void MipsTargetLowering::passByValArg(
SDValue Chain, const SDLoc &DL,
std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
SmallVectorImpl<SDValue> &MemOpChains, SDValue StackPtr,
MachineFrameInfo &MFI, SelectionDAG &DAG, SDValue Arg, unsigned FirstReg,
unsigned LastReg, const ISD::ArgFlagsTy &Flags, bool isLittle,
const CCValAssign &VA) const { … }
void MipsTargetLowering::writeVarArgRegs(std::vector<SDValue> &OutChains,
SDValue Chain, const SDLoc &DL,
SelectionDAG &DAG,
CCState &State) const { … }
void MipsTargetLowering::HandleByVal(CCState *State, unsigned &Size,
Align Alignment) const { … }
MachineBasicBlock *MipsTargetLowering::emitPseudoSELECT(MachineInstr &MI,
MachineBasicBlock *BB,
bool isFPCmp,
unsigned Opc) const { … }
MachineBasicBlock *
MipsTargetLowering::emitPseudoD_SELECT(MachineInstr &MI,
MachineBasicBlock *BB) const { … }
Register
MipsTargetLowering::getRegisterByName(const char *RegName, LLT VT,
const MachineFunction &MF) const { … }
MachineBasicBlock *MipsTargetLowering::emitLDR_W(MachineInstr &MI,
MachineBasicBlock *BB) const { … }
MachineBasicBlock *MipsTargetLowering::emitLDR_D(MachineInstr &MI,
MachineBasicBlock *BB) const { … }
MachineBasicBlock *MipsTargetLowering::emitSTR_W(MachineInstr &MI,
MachineBasicBlock *BB) const { … }
MachineBasicBlock *MipsTargetLowering::emitSTR_D(MachineInstr &MI,
MachineBasicBlock *BB) const { … }