25 #define DEBUG_TYPE "mips-lower"
28 "mips16-dont-expand-cond-pseudo",
30 cl::desc(
"Don't expand conditional move related "
31 "pseudos for Mips 16"),
35 struct Mips16Libcall {
39 bool operator<(
const Mips16Libcall &RHS)
const {
44 struct Mips16IntrinsicHelperType{
48 bool operator<(
const Mips16IntrinsicHelperType &RHS)
const {
51 bool operator==(
const Mips16IntrinsicHelperType &RHS)
const {
96 {
"__fixunsdfsi",
"__mips16_call_stub_2" },
97 {
"ceil",
"__mips16_call_stub_df_2"},
98 {
"ceilf",
"__mips16_call_stub_sf_1"},
99 {
"copysign",
"__mips16_call_stub_df_10"},
100 {
"copysignf",
"__mips16_call_stub_sf_5"},
101 {
"cos",
"__mips16_call_stub_df_2"},
102 {
"cosf",
"__mips16_call_stub_sf_1"},
103 {
"exp2",
"__mips16_call_stub_df_2"},
104 {
"exp2f",
"__mips16_call_stub_sf_1"},
105 {
"floor",
"__mips16_call_stub_df_2"},
106 {
"floorf",
"__mips16_call_stub_sf_1"},
107 {
"log2",
"__mips16_call_stub_df_2"},
108 {
"log2f",
"__mips16_call_stub_sf_1"},
109 {
"nearbyint",
"__mips16_call_stub_df_2"},
110 {
"nearbyintf",
"__mips16_call_stub_sf_1"},
111 {
"rint",
"__mips16_call_stub_df_2"},
112 {
"rintf",
"__mips16_call_stub_sf_1"},
113 {
"sin",
"__mips16_call_stub_df_2"},
114 {
"sinf",
"__mips16_call_stub_sf_1"},
115 {
"sqrt",
"__mips16_call_stub_df_2"},
116 {
"sqrtf",
"__mips16_call_stub_sf_1"},
117 {
"trunc",
"__mips16_call_stub_df_2"},
118 {
"truncf",
"__mips16_call_stub_sf_1"},
129 setMips16HardFloatLibCalls();
174 return emitSel16(Mips::BeqzRxImm16, MI, BB);
176 return emitSel16(Mips::BnezRxImm16, MI, BB);
177 case Mips::SelTBteqZCmpi:
178 return emitSeliT16(Mips::Bteqz16, Mips::CmpiRxImmX16, MI, BB);
179 case Mips::SelTBteqZSlti:
180 return emitSeliT16(Mips::Bteqz16, Mips::SltiRxImmX16, MI, BB);
181 case Mips::SelTBteqZSltiu:
182 return emitSeliT16(Mips::Bteqz16, Mips::SltiuRxImmX16, MI, BB);
183 case Mips::SelTBtneZCmpi:
184 return emitSeliT16(Mips::Btnez16, Mips::CmpiRxImmX16, MI, BB);
185 case Mips::SelTBtneZSlti:
186 return emitSeliT16(Mips::Btnez16, Mips::SltiRxImmX16, MI, BB);
187 case Mips::SelTBtneZSltiu:
188 return emitSeliT16(Mips::Btnez16, Mips::SltiuRxImmX16, MI, BB);
189 case Mips::SelTBteqZCmp:
190 return emitSelT16(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB);
191 case Mips::SelTBteqZSlt:
192 return emitSelT16(Mips::Bteqz16, Mips::SltRxRy16, MI, BB);
193 case Mips::SelTBteqZSltu:
194 return emitSelT16(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB);
195 case Mips::SelTBtneZCmp:
196 return emitSelT16(Mips::Btnez16, Mips::CmpRxRy16, MI, BB);
197 case Mips::SelTBtneZSlt:
198 return emitSelT16(Mips::Btnez16, Mips::SltRxRy16, MI, BB);
199 case Mips::SelTBtneZSltu:
200 return emitSelT16(Mips::Btnez16, Mips::SltuRxRy16, MI, BB);
201 case Mips::BteqzT8CmpX16:
202 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB);
203 case Mips::BteqzT8SltX16:
204 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltRxRy16, MI, BB);
205 case Mips::BteqzT8SltuX16:
208 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB);
209 case Mips::BtnezT8CmpX16:
210 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::CmpRxRy16, MI, BB);
211 case Mips::BtnezT8SltX16:
212 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltRxRy16, MI, BB);
213 case Mips::BtnezT8SltuX16:
216 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltuRxRy16, MI, BB);
217 case Mips::BteqzT8CmpiX16:
return emitFEXT_T8I8I16_ins(
218 Mips::Bteqz16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16,
false, MI, BB);
219 case Mips::BteqzT8SltiX16:
return emitFEXT_T8I8I16_ins(
220 Mips::Bteqz16, Mips::SltiRxImm16, Mips::SltiRxImmX16,
true, MI, BB);
221 case Mips::BteqzT8SltiuX16:
return emitFEXT_T8I8I16_ins(
222 Mips::Bteqz16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16,
false, MI, BB);
223 case Mips::BtnezT8CmpiX16:
return emitFEXT_T8I8I16_ins(
224 Mips::Btnez16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16,
false, MI, BB);
225 case Mips::BtnezT8SltiX16:
return emitFEXT_T8I8I16_ins(
226 Mips::Btnez16, Mips::SltiRxImm16, Mips::SltiRxImmX16,
true, MI, BB);
227 case Mips::BtnezT8SltiuX16:
return emitFEXT_T8I8I16_ins(
228 Mips::Btnez16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16,
false, MI, BB);
230 case Mips::SltCCRxRy16:
231 return emitFEXT_CCRX16_ins(Mips::SltRxRy16, MI, BB);
233 case Mips::SltiCCRxImmX16:
234 return emitFEXT_CCRXI16_ins
235 (Mips::SltiRxImm16, Mips::SltiRxImmX16, MI, BB);
236 case Mips::SltiuCCRxImmX16:
237 return emitFEXT_CCRXI16_ins
238 (Mips::SltiuRxImm16, Mips::SltiuRxImmX16, MI, BB);
239 case Mips::SltuCCRxRy16:
240 return emitFEXT_CCRX16_ins
241 (Mips::SltuRxRy16, MI, BB);
245 bool Mips16TargetLowering::isEligibleForTailCallOptimization(
246 const CCState &CCInfo,
unsigned NextStackOffset,
252 void Mips16TargetLowering::setMips16HardFloatLibCalls() {
255 "Array not sorted!");
295 unsigned int Mips16TargetLowering::getMips16HelperFunctionStubNumber
296 (ArgListTy &
Args)
const {
297 unsigned int resultNum = 0;
298 if (Args.size() >= 1) {
299 Type *
t = Args[0].Ty;
308 if (Args.size() >=2) {
309 Type *t = Args[1].Ty;
345 #define P_ "__mips16_call_stub_"
346 #define MAX_STUB_NUMBER 10
347 #define T1 P "1", P "2", 0, 0, P "5", P "6", 0, 0, P "9", P "10"
372 const char* Mips16TargetLowering::
373 getMips16HelperFunction
374 (
Type* RetTy, ArgListTy &Args,
bool &needHelper)
const {
375 const unsigned int stubNum = getMips16HelperFunctionStubNumber(Args);
377 const unsigned int maxStubNum = 10;
378 assert(stubNum <= maxStubNum);
379 const bool validStubNum[maxStubNum+1] =
380 {
true,
true,
true,
false,
false,
true,
true,
false,
false,
true,
true};
381 assert(validStubNum[stubNum]);
387 else if (RetTy ->isDoubleTy()) {
420 void Mips16TargetLowering::
422 std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
423 bool IsPICCall,
bool GlobalOrExternal,
bool InternalLinkage,
424 bool IsCallReloc, CallLoweringInfo &CLI,
SDValue Callee,
429 const char* Mips16HelperFunction =
nullptr;
430 bool NeedMips16Helper =
false;
438 bool LookupHelper =
true;
444 LookupHelper =
false;
446 const char *
Symbol = S->getSymbol();
447 Mips16IntrinsicHelperType IntrinsicFind = {
Symbol,
"" };
450 if (!IsPICCall && (Signature && (FuncInfo->
StubsNeeded.find(Symbol) ==
470 const Mips16IntrinsicHelperType *Helper =
474 *Helper == IntrinsicFind) {
475 Mips16HelperFunction = Helper->Helper;
476 NeedMips16Helper =
true;
477 LookupHelper =
false;
482 dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {
484 G->getGlobal()->getName().data() };
488 LookupHelper =
false;
491 Mips16HelperFunction =
492 getMips16HelperFunction(CLI.RetTy, CLI.getArgs(), NeedMips16Helper);
499 if (IsPICCall || !GlobalOrExternal) {
500 unsigned V0Reg = Mips::V0;
501 if (NeedMips16Helper) {
502 RegsToPass.push_front(std::make_pair(V0Reg, Callee));
510 RegsToPass.push_front(std::make_pair((
unsigned)Mips::T9, Callee));
516 InternalLinkage, IsCallReloc, CLI, Callee,
584 Mips16TargetLowering::emitSelT16(
unsigned Opc1,
unsigned Opc2,
MachineInstr &MI,
622 BuildMI(BB, DL, TII->
get(Opc1)).addMBB(sinkMBB);
649 Mips16TargetLowering::emitSeliT16(
unsigned Opc1,
unsigned Opc2,
688 BuildMI(BB, DL, TII->
get(Opc1)).addMBB(sinkMBB);
715 Mips16TargetLowering::emitFEXT_T8I816_ins(
unsigned BtOpc,
unsigned CmpOpc,
733 unsigned BtOpc,
unsigned CmpiOpc,
unsigned CmpiXOpc,
bool ImmSigned,
756 (
unsigned shortOp,
unsigned longOp, int64_t Imm) {
766 Mips16TargetLowering::emitFEXT_CCRX16_ins(
unsigned SltOpc,
MachineInstr &MI,
784 Mips16TargetLowering::emitFEXT_CCRXI16_ins(
unsigned SltiOpc,
unsigned SltiXOpc,
void push_back(const T &Elt)
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const_iterator end(StringRef path)
Get end iterator over path.
const char * getSymbol() const
static char const * vMips16Helper[MAX_STUB_NUMBER+1]
const MipsSubtarget & Subtarget
MachineBasicBlock * getMBB() const
const MipsTargetLowering * createMips16TargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
Create MipsTargetLowering objects.
Mips16TargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit...
static char const * scMips16Helper[MAX_STUB_NUMBER+1]
const MipsInstrInfo * getInstrInfo() const override
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
const_iterator begin(StringRef path)
Get begin iterator over path.
constexpr bool isInt< 16 >(int64_t x)
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with strcmp
static unsigned Mips16WhichOp8uOr16simm(unsigned shortOp, unsigned longOp, int64_t Imm)
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
SDValue getExternalSymbol(const char *Sym, EVT VT)
MachinePointerInfo callPtrInfo(const char *ES)
Create a MachinePointerInfo that has an ExternalSymbolPseudoSourceValue object representing a GOT ent...
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
const HexagonInstrInfo * TII
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
MachineFunction & getMachineFunction() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amt) For double-word atomic operations: ValLo, ValHi, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amtLo, amtHi) ValLo, ValHi, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amtLo, amtHi) These correspond to the atomicrmw instruction.
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
static char const * dfMips16Helper[MAX_STUB_NUMBER+1]
bool inMips16HardFloat() const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
static char const * dcMips16Helper[MAX_STUB_NUMBER+1]
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
const DataLayout & getDataLayout() const
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
static const Mips16Libcall HardFloatLibCalls[]
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
TargetInstrInfo - Interface to description of machine instruction set.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
initializer< Ty > init(const Ty &Val)
FuncSignature const * findFuncSignature(const char *name)
constexpr bool isUInt< 8 >(uint64_t x)
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type...
Type * getContainedType(unsigned i) const
This method is used to implement the type iterator (defined at the end of the file).
static const SubtargetFeatureKV * Find(StringRef S, ArrayRef< SubtargetFeatureKV > A)
Find KV in array using binary search.
const MachineOperand & getOperand(unsigned i) const
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
self_iterator getIterator()
bool useSoftFloat() const
unsigned getNumContainedTypes() const
Return the number of types in the derived type.
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo...
EVT - Extended Value Type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[]
MO_GOT - Represents the offset into the global offset table at which the address the relocation entry...
Iterator for intrusive lists based on ilist_node.
CCState - This class holds information needed while lowering arguments and return values...
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MipsRegisterInfo * getRegisterInfo() const override
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getAddrGlobal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, unsigned Flag, SDValue Chain, const MachinePointerInfo &PtrInfo) const
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
Byte Swap and Counting operators.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
bool isStructTy() const
True if this is an instance of StructType.
static cl::opt< bool > DontExpandCondPseudos16("mips16-dont-expand-cond-pseudo", cl::init(false), cl::desc("Don't expand conditional move related ""pseudos for Mips 16"), cl::Hidden)
Representation of each machine instruction.
static char const * sfMips16Helper[MAX_STUB_NUMBER+1]
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
std::map< const char *, const llvm::Mips16HardFloatInfo::FuncSignature * > StubsNeeded
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
virtual void 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
This function fills Ops, which is the list of operands that will later be used when a function call n...
constexpr bool isUInt< 16 >(uint64_t x)
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void insert(iterator MBBI, MachineBasicBlock *MBB)
bool operator<(int64_t V1, const APSInt &V2)
MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
bool operator==(uint64_t V1, const APInt &V2)
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, unsigned Align, bool *Fast) const override
Determine if the target supports unaligned memory accesses.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Fast - This calling convention attempts to make calls as fast as possible (e.g.