13 #define DEBUG_TYPE "mips-lower"
25 "mips16-dont-expand-cond-pseudo",
27 cl::desc(
"Dont expand conditional move related "
28 "pseudos for Mips 16"),
32 struct Mips16Libcall {
36 bool operator<(
const Mips16Libcall &RHS)
const {
41 struct Mips16IntrinsicHelperType{
45 bool operator<(
const Mips16IntrinsicHelperType &RHS)
const {
48 bool operator==(
const Mips16IntrinsicHelperType &RHS)
const {
93 {
"__fixunsdfsi",
"__mips16_call_stub_2" },
94 {
"ceil",
"__mips16_call_stub_df_2"},
95 {
"ceilf",
"__mips16_call_stub_sf_1"},
96 {
"copysign",
"__mips16_call_stub_df_10"},
97 {
"copysignf",
"__mips16_call_stub_sf_5"},
98 {
"cos",
"__mips16_call_stub_df_2"},
99 {
"cosf",
"__mips16_call_stub_sf_1"},
100 {
"exp2",
"__mips16_call_stub_df_2"},
101 {
"exp2f",
"__mips16_call_stub_sf_1"},
102 {
"floor",
"__mips16_call_stub_df_2"},
103 {
"floorf",
"__mips16_call_stub_sf_1"},
104 {
"log2",
"__mips16_call_stub_df_2"},
105 {
"log2f",
"__mips16_call_stub_sf_1"},
106 {
"nearbyint",
"__mips16_call_stub_df_2"},
107 {
"nearbyintf",
"__mips16_call_stub_sf_1"},
108 {
"rint",
"__mips16_call_stub_df_2"},
109 {
"rintf",
"__mips16_call_stub_sf_1"},
110 {
"sin",
"__mips16_call_stub_df_2"},
111 {
"sinf",
"__mips16_call_stub_sf_1"},
112 {
"sqrt",
"__mips16_call_stub_df_2"},
113 {
"sqrtf",
"__mips16_call_stub_sf_1"},
114 {
"trunc",
"__mips16_call_stub_df_2"},
115 {
"truncf",
"__mips16_call_stub_sf_1"},
132 setMips16HardFloatLibCalls();
173 return emitSel16(Mips::BeqzRxImm16, MI, BB);
175 return emitSel16(Mips::BnezRxImm16, MI, BB);
176 case Mips::SelTBteqZCmpi:
177 return emitSeliT16(Mips::Bteqz16, Mips::CmpiRxImmX16, MI, BB);
178 case Mips::SelTBteqZSlti:
179 return emitSeliT16(Mips::Bteqz16, Mips::SltiRxImmX16, MI, BB);
180 case Mips::SelTBteqZSltiu:
181 return emitSeliT16(Mips::Bteqz16, Mips::SltiuRxImmX16, MI, BB);
182 case Mips::SelTBtneZCmpi:
183 return emitSeliT16(Mips::Btnez16, Mips::CmpiRxImmX16, MI, BB);
184 case Mips::SelTBtneZSlti:
185 return emitSeliT16(Mips::Btnez16, Mips::SltiRxImmX16, MI, BB);
186 case Mips::SelTBtneZSltiu:
187 return emitSeliT16(Mips::Btnez16, Mips::SltiuRxImmX16, MI, BB);
188 case Mips::SelTBteqZCmp:
189 return emitSelT16(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB);
190 case Mips::SelTBteqZSlt:
191 return emitSelT16(Mips::Bteqz16, Mips::SltRxRy16, MI, BB);
192 case Mips::SelTBteqZSltu:
193 return emitSelT16(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB);
194 case Mips::SelTBtneZCmp:
195 return emitSelT16(Mips::Btnez16, Mips::CmpRxRy16, MI, BB);
196 case Mips::SelTBtneZSlt:
197 return emitSelT16(Mips::Btnez16, Mips::SltRxRy16, MI, BB);
198 case Mips::SelTBtneZSltu:
199 return emitSelT16(Mips::Btnez16, Mips::SltuRxRy16, MI, BB);
200 case Mips::BteqzT8CmpX16:
201 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB);
202 case Mips::BteqzT8SltX16:
203 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltRxRy16, MI, BB);
204 case Mips::BteqzT8SltuX16:
207 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB);
208 case Mips::BtnezT8CmpX16:
209 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::CmpRxRy16, MI, BB);
210 case Mips::BtnezT8SltX16:
211 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltRxRy16, MI, BB);
212 case Mips::BtnezT8SltuX16:
215 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltuRxRy16, MI, BB);
216 case Mips::BteqzT8CmpiX16:
return emitFEXT_T8I8I16_ins(
217 Mips::Bteqz16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16,
false, MI, BB);
218 case Mips::BteqzT8SltiX16:
return emitFEXT_T8I8I16_ins(
219 Mips::Bteqz16, Mips::SltiRxImm16, Mips::SltiRxImmX16,
true, MI, BB);
220 case Mips::BteqzT8SltiuX16:
return emitFEXT_T8I8I16_ins(
221 Mips::Bteqz16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16,
false, MI, BB);
222 case Mips::BtnezT8CmpiX16:
return emitFEXT_T8I8I16_ins(
223 Mips::Btnez16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16,
false, MI, BB);
224 case Mips::BtnezT8SltiX16:
return emitFEXT_T8I8I16_ins(
225 Mips::Btnez16, Mips::SltiRxImm16, Mips::SltiRxImmX16,
true, MI, BB);
226 case Mips::BtnezT8SltiuX16:
return emitFEXT_T8I8I16_ins(
227 Mips::Btnez16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16,
false, MI, BB);
229 case Mips::SltCCRxRy16:
230 return emitFEXT_CCRX16_ins(Mips::SltRxRy16, MI, BB);
232 case Mips::SltiCCRxImmX16:
233 return emitFEXT_CCRXI16_ins
234 (Mips::SltiRxImm16, Mips::SltiRxImmX16, MI, BB);
235 case Mips::SltiuCCRxImmX16:
236 return emitFEXT_CCRXI16_ins
237 (Mips::SltiuRxImm16, Mips::SltiuRxImmX16, MI, BB);
238 case Mips::SltuCCRxRy16:
239 return emitFEXT_CCRX16_ins
240 (Mips::SltuRxRy16, MI, BB);
244 bool Mips16TargetLowering::
245 isEligibleForTailCallOptimization(
const MipsCC &MipsCCInfo,
246 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;
346 #define P_ "__mips16_call_stub_"
347 #define MAX_STUB_NUMBER 10
348 #define T1 P "1", P "2", 0, 0, P "5", P "6", 0, 0, P "9", P "10"
373 const char* Mips16TargetLowering::
374 getMips16HelperFunction
375 (
Type* RetTy, ArgListTy &Args,
bool &needHelper)
const {
376 const unsigned int stubNum = getMips16HelperFunctionStubNumber(Args);
378 const unsigned int maxStubNum = 10;
379 assert(stubNum <= maxStubNum);
380 const bool validStubNum[maxStubNum+1] =
381 {
true,
true,
true,
false,
false,
true,
true,
false,
false,
true,
true};
382 assert(validStubNum[stubNum]);
388 else if (RetTy ->isDoubleTy()) {
421 void Mips16TargetLowering::
423 std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
424 bool IsPICCall,
bool GlobalOrExternal,
bool InternalLinkage,
429 const char* Mips16HelperFunction = 0;
430 bool NeedMips16Helper =
false;
439 bool LookupHelper =
true;
445 LookupHelper =
false;
447 Mips16IntrinsicHelperType IntrinsicFind = {S->getSymbol(),
""};
455 Mips16HelperFunction = h->Helper;
456 NeedMips16Helper =
true;
457 LookupHelper =
false;
462 dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {
464 G->getGlobal()->getName().data() };
468 LookupHelper =
false;
470 if (LookupHelper) Mips16HelperFunction =
471 getMips16HelperFunction(CLI.RetTy, CLI.Args, NeedMips16Helper);
479 if (IsPICCall || !GlobalOrExternal) {
480 unsigned V0Reg = Mips::V0;
481 if (NeedMips16Helper) {
482 RegsToPass.push_front(std::make_pair(V0Reg, Callee));
489 RegsToPass.push_front(std::make_pair((
unsigned)Mips::T9, Callee));
495 InternalLinkage, CLI, Callee, Chain);
561 (
unsigned Opc1,
unsigned Opc2,
600 BuildMI(BB, DL, TII->
get(Opc1)).addMBB(sinkMBB);
626 (
unsigned Opc1,
unsigned Opc2,
665 BuildMI(BB, DL, TII->
get(Opc1)).addMBB(sinkMBB);
691 *Mips16TargetLowering::emitFEXT_T8I816_ins(
unsigned BtOpc,
unsigned CmpOpc,
708 unsigned BtOpc,
unsigned CmpiOpc,
unsigned CmpiXOpc,
bool ImmSigned,
732 (
unsigned shortOp,
unsigned longOp, int64_t Imm) {
751 TII->
get(SltOpc)).addReg(regX).
addReg(regY);
759 unsigned SltiOpc,
unsigned SltiXOpc,
769 TII->
get(SltOpc)).addReg(regX).
addImm(Imm);
bool isUInt< 8 >(uint64_t x)
int strcmp(const char *s1, const char *s2);
void push_back(const T &Elt)
const MachineFunction * getParent() const
T * array_endof(T(&x)[N])
SDValue getAddrGlobal(NodeTy *N, EVT Ty, SelectionDAG &DAG, unsigned Flag, SDValue Chain, const MachinePointerInfo &PtrInfo) const
const char * getSymbol() const
virtual void getOpndList(SmallVectorImpl< SDValue > &Ops, std::deque< std::pair< unsigned, SDValue > > &RegsToPass, bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const
static char const * vMips16Helper[MAX_STUB_NUMBER+1]
MachineBasicBlock * getMBB() const
static const SubtargetFeatureKV * Find(StringRef S, const SubtargetFeatureKV *A, size_t L)
Find KV in array using binary search.
const TargetMachine & getTargetMachine() const
virtual MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const
static char const * scMips16Helper[MAX_STUB_NUMBER+1]
void operator<(const Optional< T > &X, const Optional< U > &Y)
Poison comparison between two Optional objects. Clients needs to explicitly compare the underlying va...
bool isDoubleTy() const
isDoubleTy - Return true if this is 'double', a 64-bit IEEE fp type.
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *fromMBB)
static unsigned Mips16WhichOp8uOr16simm(unsigned shortOp, unsigned longOp, int64_t Imm)
SDValue getExternalSymbol(const char *Sym, EVT VT)
virtual MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const
const HexagonInstrInfo * TII
#define llvm_unreachable(msg)
EVT getValueType(unsigned ResNo) const
MachineFunction & getMachineFunction() const
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
virtual MVT getPointerTy(uint32_t=0) const
static char const * dfMips16Helper[MAX_STUB_NUMBER+1]
bool inMips16HardFloat() const
const MachineInstrBuilder & addImm(int64_t Val) const
static char const * dcMips16Helper[MAX_STUB_NUMBER+1]
size_t array_lengthof(T(&)[N])
Find the length of an array.
const BasicBlock * getBasicBlock() const
static const Mips16Libcall HardFloatLibCalls[]
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=0)
LLVM Basic Block Representation.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Type * getContainedType(unsigned i) const
const MachineOperand & getOperand(unsigned i) const
bool isFloatTy() const
isFloatTy - Return true if this is 'float', a 32-bit IEEE fp type.
ItTy next(ItTy it, Dist n)
const MipsSubtarget * Subtarget
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
unsigned getNumContainedTypes() const
const MCInstrDesc & get(unsigned Opcode) const
static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[]
virtual const TargetInstrInfo * getInstrInfo() const
Byte Swap and Counting operators.
static cl::opt< bool > DontExpandCondPseudos16("mips16-dont-expand-cond-pseudo", cl::init(false), cl::desc("Dont expand conditional move related ""pseudos for Mips 16"), cl::Hidden)
void clearRegisterClasses()
Remove all register classes.
void computeRegisterProperties()
static char const * sfMips16Helper[MAX_STUB_NUMBER+1]
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
bool isInt< 16 >(int64_t x)
MachinePointerInfo callPtrInfo(const StringRef &Name)
Create a MachinePointerInfo that has a MipsCallEntr object representing a GOT entry for an external f...
unsigned getReg() const
getReg - Returns the register number.
void insert(iterator MBBI, MachineBasicBlock *MBB)
bool isUInt< 16 >(uint64_t x)
BasicBlockListType::iterator iterator
const MipsTargetLowering * createMips16TargetLowering(MipsTargetMachine &TM)
Create MipsTargetLowering objects.
bool operator==(uint64_t V1, const APInt &V2)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
void addSuccessor(MachineBasicBlock *succ, uint32_t weight=0)
DebugLoc getDebugLoc() const
virtual bool allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const
Determine if the target supports unaligned memory accesses.
Mips16TargetLowering(MipsTargetMachine &TM)