27 #define DEBUG_TYPE "mips-lower"
30 "mips16-dont-expand-cond-pseudo",
32 cl::desc(
"Don't expand conditional move related "
33 "pseudos for Mips 16"),
37 struct Mips16Libcall {
41 bool operator<(
const Mips16Libcall &RHS)
const {
42 return std::strcmp(
Name, RHS.Name) < 0;
46 struct Mips16IntrinsicHelperType{
50 bool operator<(
const Mips16IntrinsicHelperType &RHS)
const {
51 return std::strcmp(
Name, RHS.Name) < 0;
53 bool operator==(
const Mips16IntrinsicHelperType &RHS)
const {
54 return std::strcmp(
Name, RHS.Name) == 0;
98 {
"__fixunsdfsi",
"__mips16_call_stub_2" },
99 {
"ceil",
"__mips16_call_stub_df_2"},
100 {
"ceilf",
"__mips16_call_stub_sf_1"},
101 {
"copysign",
"__mips16_call_stub_df_10"},
102 {
"copysignf",
"__mips16_call_stub_sf_5"},
103 {
"cos",
"__mips16_call_stub_df_2"},
104 {
"cosf",
"__mips16_call_stub_sf_1"},
105 {
"exp2",
"__mips16_call_stub_df_2"},
106 {
"exp2f",
"__mips16_call_stub_sf_1"},
107 {
"floor",
"__mips16_call_stub_df_2"},
108 {
"floorf",
"__mips16_call_stub_sf_1"},
109 {
"log2",
"__mips16_call_stub_df_2"},
110 {
"log2f",
"__mips16_call_stub_sf_1"},
111 {
"nearbyint",
"__mips16_call_stub_df_2"},
112 {
"nearbyintf",
"__mips16_call_stub_sf_1"},
113 {
"rint",
"__mips16_call_stub_df_2"},
114 {
"rintf",
"__mips16_call_stub_sf_1"},
115 {
"sin",
"__mips16_call_stub_df_2"},
116 {
"sinf",
"__mips16_call_stub_sf_1"},
117 {
"sqrt",
"__mips16_call_stub_df_2"},
118 {
"sqrtf",
"__mips16_call_stub_sf_1"},
119 {
"trunc",
"__mips16_call_stub_df_2"},
120 {
"truncf",
"__mips16_call_stub_sf_1"},
131 setMips16HardFloatLibCalls();
176 return emitSel16(Mips::BeqzRxImm16, MI, BB);
178 return emitSel16(Mips::BnezRxImm16, MI, BB);
179 case Mips::SelTBteqZCmpi:
180 return emitSeliT16(Mips::Bteqz16, Mips::CmpiRxImmX16, MI, BB);
181 case Mips::SelTBteqZSlti:
182 return emitSeliT16(Mips::Bteqz16, Mips::SltiRxImmX16, MI, BB);
183 case Mips::SelTBteqZSltiu:
184 return emitSeliT16(Mips::Bteqz16, Mips::SltiuRxImmX16, MI, BB);
185 case Mips::SelTBtneZCmpi:
186 return emitSeliT16(Mips::Btnez16, Mips::CmpiRxImmX16, MI, BB);
187 case Mips::SelTBtneZSlti:
188 return emitSeliT16(Mips::Btnez16, Mips::SltiRxImmX16, MI, BB);
189 case Mips::SelTBtneZSltiu:
190 return emitSeliT16(Mips::Btnez16, Mips::SltiuRxImmX16, MI, BB);
191 case Mips::SelTBteqZCmp:
192 return emitSelT16(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB);
193 case Mips::SelTBteqZSlt:
194 return emitSelT16(Mips::Bteqz16, Mips::SltRxRy16, MI, BB);
195 case Mips::SelTBteqZSltu:
196 return emitSelT16(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB);
197 case Mips::SelTBtneZCmp:
198 return emitSelT16(Mips::Btnez16, Mips::CmpRxRy16, MI, BB);
199 case Mips::SelTBtneZSlt:
200 return emitSelT16(Mips::Btnez16, Mips::SltRxRy16, MI, BB);
201 case Mips::SelTBtneZSltu:
202 return emitSelT16(Mips::Btnez16, Mips::SltuRxRy16, MI, BB);
203 case Mips::BteqzT8CmpX16:
204 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB);
205 case Mips::BteqzT8SltX16:
206 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltRxRy16, MI, BB);
207 case Mips::BteqzT8SltuX16:
210 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB);
211 case Mips::BtnezT8CmpX16:
212 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::CmpRxRy16, MI, BB);
213 case Mips::BtnezT8SltX16:
214 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltRxRy16, MI, BB);
215 case Mips::BtnezT8SltuX16:
218 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltuRxRy16, MI, BB);
219 case Mips::BteqzT8CmpiX16:
return emitFEXT_T8I8I16_ins(
220 Mips::Bteqz16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16,
false, MI, BB);
221 case Mips::BteqzT8SltiX16:
return emitFEXT_T8I8I16_ins(
222 Mips::Bteqz16, Mips::SltiRxImm16, Mips::SltiRxImmX16,
true, MI, BB);
223 case Mips::BteqzT8SltiuX16:
return emitFEXT_T8I8I16_ins(
224 Mips::Bteqz16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16,
false, MI, BB);
225 case Mips::BtnezT8CmpiX16:
return emitFEXT_T8I8I16_ins(
226 Mips::Btnez16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16,
false, MI, BB);
227 case Mips::BtnezT8SltiX16:
return emitFEXT_T8I8I16_ins(
228 Mips::Btnez16, Mips::SltiRxImm16, Mips::SltiRxImmX16,
true, MI, BB);
229 case Mips::BtnezT8SltiuX16:
return emitFEXT_T8I8I16_ins(
230 Mips::Btnez16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16,
false, MI, BB);
232 case Mips::SltCCRxRy16:
233 return emitFEXT_CCRX16_ins(Mips::SltRxRy16, MI, BB);
235 case Mips::SltiCCRxImmX16:
236 return emitFEXT_CCRXI16_ins
237 (Mips::SltiRxImm16, Mips::SltiRxImmX16, MI, BB);
238 case Mips::SltiuCCRxImmX16:
239 return emitFEXT_CCRXI16_ins
240 (Mips::SltiuRxImm16, Mips::SltiuRxImmX16, MI, BB);
241 case Mips::SltuCCRxRy16:
242 return emitFEXT_CCRX16_ins
243 (Mips::SltuRxRy16, MI, BB);
247 bool Mips16TargetLowering::isEligibleForTailCallOptimization(
248 const CCState &CCInfo,
unsigned NextStackOffset,
254 void Mips16TargetLowering::setMips16HardFloatLibCalls() {
257 "Array not sorted!");
297 unsigned int Mips16TargetLowering::getMips16HelperFunctionStubNumber
298 (ArgListTy &Args)
const {
299 unsigned int resultNum = 0;
300 if (Args.size() >= 1) {
301 Type *t = Args[0].Ty;
310 if (Args.size() >=2) {
311 Type *t = Args[1].Ty;
347 #define P_ "__mips16_call_stub_"
348 #define MAX_STUB_NUMBER 10
349 #define T1 P "1", P "2", 0, 0, P "5", P "6", 0, 0, P "9", P "10"
374 const char* Mips16TargetLowering::
375 getMips16HelperFunction
376 (
Type* RetTy, ArgListTy &Args,
bool &needHelper)
const {
377 const unsigned int stubNum = getMips16HelperFunctionStubNumber(Args);
379 const unsigned int maxStubNum = 10;
380 assert(stubNum <= maxStubNum);
381 const bool validStubNum[maxStubNum+1] =
382 {
true,
true,
true,
false,
false,
true,
true,
false,
false,
true,
true};
383 assert(validStubNum[stubNum]);
389 else if (RetTy ->isDoubleTy()) {
422 void Mips16TargetLowering::
424 std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
425 bool IsPICCall,
bool GlobalOrExternal,
bool InternalLinkage,
426 bool IsCallReloc, CallLoweringInfo &CLI,
SDValue Callee,
431 const char* Mips16HelperFunction =
nullptr;
432 bool NeedMips16Helper =
false;
440 bool LookupHelper =
true;
446 LookupHelper =
false;
448 const char *
Symbol = S->getSymbol();
449 Mips16IntrinsicHelperType IntrinsicFind = {
Symbol,
"" };
452 if (!IsPICCall && (Signature && (FuncInfo->
StubsNeeded.find(Symbol) ==
472 const Mips16IntrinsicHelperType *Helper =
476 *Helper == IntrinsicFind) {
477 Mips16HelperFunction = Helper->Helper;
478 NeedMips16Helper =
true;
479 LookupHelper =
false;
484 dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {
486 G->getGlobal()->getName().data() };
490 LookupHelper =
false;
493 Mips16HelperFunction =
494 getMips16HelperFunction(CLI.RetTy, CLI.getArgs(), NeedMips16Helper);
501 if (IsPICCall || !GlobalOrExternal) {
502 unsigned V0Reg = Mips::V0;
503 if (NeedMips16Helper) {
504 RegsToPass.push_front(std::make_pair(V0Reg, Callee));
512 RegsToPass.push_front(std::make_pair((
unsigned)Mips::T9, Callee));
518 InternalLinkage, IsCallReloc, CLI, Callee,
584 Mips16TargetLowering::emitSelT16(
unsigned Opc1,
unsigned Opc2,
MachineInstr *MI,
622 BuildMI(BB, DL, TII->
get(Opc1)).addMBB(sinkMBB);
648 Mips16TargetLowering::emitSeliT16(
unsigned Opc1,
unsigned Opc2,
687 BuildMI(BB, DL, TII->
get(Opc1)).addMBB(sinkMBB);
713 Mips16TargetLowering::emitFEXT_T8I816_ins(
unsigned BtOpc,
unsigned CmpOpc,
730 unsigned BtOpc,
unsigned CmpiOpc,
unsigned CmpiXOpc,
bool ImmSigned,
754 (
unsigned shortOp,
unsigned longOp, int64_t Imm) {
764 Mips16TargetLowering::emitFEXT_CCRX16_ins(
unsigned SltOpc,
MachineInstr *MI,
781 Mips16TargetLowering::emitFEXT_CCRXI16_ins(
unsigned SltiOpc,
unsigned SltiXOpc,
792 TII->
get(SltOpc)).addReg(regX).
addImm(Imm);
bool isUInt< 8 >(uint64_t x)
void push_back(const T &Elt)
const MachineFunction * getParent() const
getParent - 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)
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
isDoubleTy - Return true if this is 'double', a 64-bit IEEE fp type.
const_iterator begin(StringRef path)
Get begin iterator over path.
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *fromMBB)
transferSuccessorsAndUpdatePHIs - Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor blocks which refer to fromMBB to refer to this.
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)
const HexagonInstrInfo * TII
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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
addImm - 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...
SDValue getAddrGlobal(NodeTy *N, SDLoc DL, EVT Ty, SelectionDAG &DAG, unsigned Flag, SDValue Chain, const MachinePointerInfo &PtrInfo) const
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
const DataLayout & getDataLayout() const
const BasicBlock * getBasicBlock() const
getBasicBlock - 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.
LLVM_CONSTEXPR size_t array_lengthof(T(&)[N])
Find the length of an array.
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
FuncSignature const * findFuncSignature(const char *name)
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
getContainedType - 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
isFloatTy - 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...
bool useSoftFloat() const
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
unsigned getNumContainedTypes() const
getNumContainedTypes - 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.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[]
CCState - This class holds information needed while lowering arguments and return values...
const MipsRegisterInfo * getRegisterInfo() const override
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Byte Swap and Counting operators.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
bool isStructTy() const
isStructTy - 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 '...
MachinePointerInfo callPtrInfo(StringRef Name)
Create a MachinePointerInfo that has a MipsCallEntr object representing a GOT entry for an external f...
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
std::map< const char *, const llvm::Mips16HardFloatInfo::FuncSignature * > StubsNeeded
Fast - This calling convention attempts to make calls as fast as possible (e.g.
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...
bool isInt< 16 >(int64_t x)
unsigned getReg() const
getReg - Returns the register number.
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 isUInt< 16 >(uint64_t x)
BasicBlockListType::iterator iterator
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
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
addReg - Add a new virtual register operand...
void addSuccessor(MachineBasicBlock *succ, uint32_t weight=0)
addSuccessor - Add succ as a successor of this MachineBasicBlock.