1*9880d681SAndroid Build Coastguard Worker //===-- Mips16ISelLowering.h - Mips16 DAG Lowering Interface ----*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // Subclass of MipsTargetLowering specialized for mips16.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker #include "Mips16ISelLowering.h"
14*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/MipsBaseInfo.h"
15*9880d681SAndroid Build Coastguard Worker #include "Mips16HardFloatInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "MipsMachineFunction.h"
17*9880d681SAndroid Build Coastguard Worker #include "MipsRegisterInfo.h"
18*9880d681SAndroid Build Coastguard Worker #include "MipsTargetMachine.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Worker using namespace llvm;
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "mips-lower"
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> DontExpandCondPseudos16(
28*9880d681SAndroid Build Coastguard Worker "mips16-dont-expand-cond-pseudo",
29*9880d681SAndroid Build Coastguard Worker cl::init(false),
30*9880d681SAndroid Build Coastguard Worker cl::desc("Don't expand conditional move related "
31*9880d681SAndroid Build Coastguard Worker "pseudos for Mips 16"),
32*9880d681SAndroid Build Coastguard Worker cl::Hidden);
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker namespace {
35*9880d681SAndroid Build Coastguard Worker struct Mips16Libcall {
36*9880d681SAndroid Build Coastguard Worker RTLIB::Libcall Libcall;
37*9880d681SAndroid Build Coastguard Worker const char *Name;
38*9880d681SAndroid Build Coastguard Worker
operator <__anon707a79fa0111::Mips16Libcall39*9880d681SAndroid Build Coastguard Worker bool operator<(const Mips16Libcall &RHS) const {
40*9880d681SAndroid Build Coastguard Worker return std::strcmp(Name, RHS.Name) < 0;
41*9880d681SAndroid Build Coastguard Worker }
42*9880d681SAndroid Build Coastguard Worker };
43*9880d681SAndroid Build Coastguard Worker
44*9880d681SAndroid Build Coastguard Worker struct Mips16IntrinsicHelperType{
45*9880d681SAndroid Build Coastguard Worker const char* Name;
46*9880d681SAndroid Build Coastguard Worker const char* Helper;
47*9880d681SAndroid Build Coastguard Worker
operator <__anon707a79fa0111::Mips16IntrinsicHelperType48*9880d681SAndroid Build Coastguard Worker bool operator<(const Mips16IntrinsicHelperType &RHS) const {
49*9880d681SAndroid Build Coastguard Worker return std::strcmp(Name, RHS.Name) < 0;
50*9880d681SAndroid Build Coastguard Worker }
operator ==__anon707a79fa0111::Mips16IntrinsicHelperType51*9880d681SAndroid Build Coastguard Worker bool operator==(const Mips16IntrinsicHelperType &RHS) const {
52*9880d681SAndroid Build Coastguard Worker return std::strcmp(Name, RHS.Name) == 0;
53*9880d681SAndroid Build Coastguard Worker }
54*9880d681SAndroid Build Coastguard Worker };
55*9880d681SAndroid Build Coastguard Worker }
56*9880d681SAndroid Build Coastguard Worker
57*9880d681SAndroid Build Coastguard Worker // Libcalls for which no helper is generated. Sorted by name for binary search.
58*9880d681SAndroid Build Coastguard Worker static const Mips16Libcall HardFloatLibCalls[] = {
59*9880d681SAndroid Build Coastguard Worker { RTLIB::ADD_F64, "__mips16_adddf3" },
60*9880d681SAndroid Build Coastguard Worker { RTLIB::ADD_F32, "__mips16_addsf3" },
61*9880d681SAndroid Build Coastguard Worker { RTLIB::DIV_F64, "__mips16_divdf3" },
62*9880d681SAndroid Build Coastguard Worker { RTLIB::DIV_F32, "__mips16_divsf3" },
63*9880d681SAndroid Build Coastguard Worker { RTLIB::OEQ_F64, "__mips16_eqdf2" },
64*9880d681SAndroid Build Coastguard Worker { RTLIB::OEQ_F32, "__mips16_eqsf2" },
65*9880d681SAndroid Build Coastguard Worker { RTLIB::FPEXT_F32_F64, "__mips16_extendsfdf2" },
66*9880d681SAndroid Build Coastguard Worker { RTLIB::FPTOSINT_F64_I32, "__mips16_fix_truncdfsi" },
67*9880d681SAndroid Build Coastguard Worker { RTLIB::FPTOSINT_F32_I32, "__mips16_fix_truncsfsi" },
68*9880d681SAndroid Build Coastguard Worker { RTLIB::SINTTOFP_I32_F64, "__mips16_floatsidf" },
69*9880d681SAndroid Build Coastguard Worker { RTLIB::SINTTOFP_I32_F32, "__mips16_floatsisf" },
70*9880d681SAndroid Build Coastguard Worker { RTLIB::UINTTOFP_I32_F64, "__mips16_floatunsidf" },
71*9880d681SAndroid Build Coastguard Worker { RTLIB::UINTTOFP_I32_F32, "__mips16_floatunsisf" },
72*9880d681SAndroid Build Coastguard Worker { RTLIB::OGE_F64, "__mips16_gedf2" },
73*9880d681SAndroid Build Coastguard Worker { RTLIB::OGE_F32, "__mips16_gesf2" },
74*9880d681SAndroid Build Coastguard Worker { RTLIB::OGT_F64, "__mips16_gtdf2" },
75*9880d681SAndroid Build Coastguard Worker { RTLIB::OGT_F32, "__mips16_gtsf2" },
76*9880d681SAndroid Build Coastguard Worker { RTLIB::OLE_F64, "__mips16_ledf2" },
77*9880d681SAndroid Build Coastguard Worker { RTLIB::OLE_F32, "__mips16_lesf2" },
78*9880d681SAndroid Build Coastguard Worker { RTLIB::OLT_F64, "__mips16_ltdf2" },
79*9880d681SAndroid Build Coastguard Worker { RTLIB::OLT_F32, "__mips16_ltsf2" },
80*9880d681SAndroid Build Coastguard Worker { RTLIB::MUL_F64, "__mips16_muldf3" },
81*9880d681SAndroid Build Coastguard Worker { RTLIB::MUL_F32, "__mips16_mulsf3" },
82*9880d681SAndroid Build Coastguard Worker { RTLIB::UNE_F64, "__mips16_nedf2" },
83*9880d681SAndroid Build Coastguard Worker { RTLIB::UNE_F32, "__mips16_nesf2" },
84*9880d681SAndroid Build Coastguard Worker { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_dc" }, // No associated libcall.
85*9880d681SAndroid Build Coastguard Worker { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_df" }, // No associated libcall.
86*9880d681SAndroid Build Coastguard Worker { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_sc" }, // No associated libcall.
87*9880d681SAndroid Build Coastguard Worker { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_sf" }, // No associated libcall.
88*9880d681SAndroid Build Coastguard Worker { RTLIB::SUB_F64, "__mips16_subdf3" },
89*9880d681SAndroid Build Coastguard Worker { RTLIB::SUB_F32, "__mips16_subsf3" },
90*9880d681SAndroid Build Coastguard Worker { RTLIB::FPROUND_F64_F32, "__mips16_truncdfsf2" },
91*9880d681SAndroid Build Coastguard Worker { RTLIB::UO_F64, "__mips16_unorddf2" },
92*9880d681SAndroid Build Coastguard Worker { RTLIB::UO_F32, "__mips16_unordsf2" }
93*9880d681SAndroid Build Coastguard Worker };
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Worker static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[] = {
96*9880d681SAndroid Build Coastguard Worker {"__fixunsdfsi", "__mips16_call_stub_2" },
97*9880d681SAndroid Build Coastguard Worker {"ceil", "__mips16_call_stub_df_2"},
98*9880d681SAndroid Build Coastguard Worker {"ceilf", "__mips16_call_stub_sf_1"},
99*9880d681SAndroid Build Coastguard Worker {"copysign", "__mips16_call_stub_df_10"},
100*9880d681SAndroid Build Coastguard Worker {"copysignf", "__mips16_call_stub_sf_5"},
101*9880d681SAndroid Build Coastguard Worker {"cos", "__mips16_call_stub_df_2"},
102*9880d681SAndroid Build Coastguard Worker {"cosf", "__mips16_call_stub_sf_1"},
103*9880d681SAndroid Build Coastguard Worker {"exp2", "__mips16_call_stub_df_2"},
104*9880d681SAndroid Build Coastguard Worker {"exp2f", "__mips16_call_stub_sf_1"},
105*9880d681SAndroid Build Coastguard Worker {"floor", "__mips16_call_stub_df_2"},
106*9880d681SAndroid Build Coastguard Worker {"floorf", "__mips16_call_stub_sf_1"},
107*9880d681SAndroid Build Coastguard Worker {"log2", "__mips16_call_stub_df_2"},
108*9880d681SAndroid Build Coastguard Worker {"log2f", "__mips16_call_stub_sf_1"},
109*9880d681SAndroid Build Coastguard Worker {"nearbyint", "__mips16_call_stub_df_2"},
110*9880d681SAndroid Build Coastguard Worker {"nearbyintf", "__mips16_call_stub_sf_1"},
111*9880d681SAndroid Build Coastguard Worker {"rint", "__mips16_call_stub_df_2"},
112*9880d681SAndroid Build Coastguard Worker {"rintf", "__mips16_call_stub_sf_1"},
113*9880d681SAndroid Build Coastguard Worker {"sin", "__mips16_call_stub_df_2"},
114*9880d681SAndroid Build Coastguard Worker {"sinf", "__mips16_call_stub_sf_1"},
115*9880d681SAndroid Build Coastguard Worker {"sqrt", "__mips16_call_stub_df_2"},
116*9880d681SAndroid Build Coastguard Worker {"sqrtf", "__mips16_call_stub_sf_1"},
117*9880d681SAndroid Build Coastguard Worker {"trunc", "__mips16_call_stub_df_2"},
118*9880d681SAndroid Build Coastguard Worker {"truncf", "__mips16_call_stub_sf_1"},
119*9880d681SAndroid Build Coastguard Worker };
120*9880d681SAndroid Build Coastguard Worker
Mips16TargetLowering(const MipsTargetMachine & TM,const MipsSubtarget & STI)121*9880d681SAndroid Build Coastguard Worker Mips16TargetLowering::Mips16TargetLowering(const MipsTargetMachine &TM,
122*9880d681SAndroid Build Coastguard Worker const MipsSubtarget &STI)
123*9880d681SAndroid Build Coastguard Worker : MipsTargetLowering(TM, STI) {
124*9880d681SAndroid Build Coastguard Worker
125*9880d681SAndroid Build Coastguard Worker // Set up the register classes
126*9880d681SAndroid Build Coastguard Worker addRegisterClass(MVT::i32, &Mips::CPU16RegsRegClass);
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Worker if (!Subtarget.useSoftFloat())
129*9880d681SAndroid Build Coastguard Worker setMips16HardFloatLibCalls();
130*9880d681SAndroid Build Coastguard Worker
131*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Expand);
132*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32, Expand);
133*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::ATOMIC_SWAP, MVT::i32, Expand);
134*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i32, Expand);
135*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::ATOMIC_LOAD_SUB, MVT::i32, Expand);
136*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::ATOMIC_LOAD_AND, MVT::i32, Expand);
137*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::ATOMIC_LOAD_OR, MVT::i32, Expand);
138*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i32, Expand);
139*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::ATOMIC_LOAD_NAND, MVT::i32, Expand);
140*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::ATOMIC_LOAD_MIN, MVT::i32, Expand);
141*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::ATOMIC_LOAD_MAX, MVT::i32, Expand);
142*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::ATOMIC_LOAD_UMIN, MVT::i32, Expand);
143*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::ATOMIC_LOAD_UMAX, MVT::i32, Expand);
144*9880d681SAndroid Build Coastguard Worker
145*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::ROTR, MVT::i32, Expand);
146*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::ROTR, MVT::i64, Expand);
147*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::BSWAP, MVT::i32, Expand);
148*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::BSWAP, MVT::i64, Expand);
149*9880d681SAndroid Build Coastguard Worker
150*9880d681SAndroid Build Coastguard Worker computeRegisterProperties(STI.getRegisterInfo());
151*9880d681SAndroid Build Coastguard Worker }
152*9880d681SAndroid Build Coastguard Worker
153*9880d681SAndroid Build Coastguard Worker const MipsTargetLowering *
createMips16TargetLowering(const MipsTargetMachine & TM,const MipsSubtarget & STI)154*9880d681SAndroid Build Coastguard Worker llvm::createMips16TargetLowering(const MipsTargetMachine &TM,
155*9880d681SAndroid Build Coastguard Worker const MipsSubtarget &STI) {
156*9880d681SAndroid Build Coastguard Worker return new Mips16TargetLowering(TM, STI);
157*9880d681SAndroid Build Coastguard Worker }
158*9880d681SAndroid Build Coastguard Worker
159*9880d681SAndroid Build Coastguard Worker bool
allowsMisalignedMemoryAccesses(EVT VT,unsigned,unsigned,bool * Fast) const160*9880d681SAndroid Build Coastguard Worker Mips16TargetLowering::allowsMisalignedMemoryAccesses(EVT VT,
161*9880d681SAndroid Build Coastguard Worker unsigned,
162*9880d681SAndroid Build Coastguard Worker unsigned,
163*9880d681SAndroid Build Coastguard Worker bool *Fast) const {
164*9880d681SAndroid Build Coastguard Worker return false;
165*9880d681SAndroid Build Coastguard Worker }
166*9880d681SAndroid Build Coastguard Worker
167*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *
EmitInstrWithCustomInserter(MachineInstr & MI,MachineBasicBlock * BB) const168*9880d681SAndroid Build Coastguard Worker Mips16TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
169*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *BB) const {
170*9880d681SAndroid Build Coastguard Worker switch (MI.getOpcode()) {
171*9880d681SAndroid Build Coastguard Worker default:
172*9880d681SAndroid Build Coastguard Worker return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB);
173*9880d681SAndroid Build Coastguard Worker case Mips::SelBeqZ:
174*9880d681SAndroid Build Coastguard Worker return emitSel16(Mips::BeqzRxImm16, MI, BB);
175*9880d681SAndroid Build Coastguard Worker case Mips::SelBneZ:
176*9880d681SAndroid Build Coastguard Worker return emitSel16(Mips::BnezRxImm16, MI, BB);
177*9880d681SAndroid Build Coastguard Worker case Mips::SelTBteqZCmpi:
178*9880d681SAndroid Build Coastguard Worker return emitSeliT16(Mips::Bteqz16, Mips::CmpiRxImmX16, MI, BB);
179*9880d681SAndroid Build Coastguard Worker case Mips::SelTBteqZSlti:
180*9880d681SAndroid Build Coastguard Worker return emitSeliT16(Mips::Bteqz16, Mips::SltiRxImmX16, MI, BB);
181*9880d681SAndroid Build Coastguard Worker case Mips::SelTBteqZSltiu:
182*9880d681SAndroid Build Coastguard Worker return emitSeliT16(Mips::Bteqz16, Mips::SltiuRxImmX16, MI, BB);
183*9880d681SAndroid Build Coastguard Worker case Mips::SelTBtneZCmpi:
184*9880d681SAndroid Build Coastguard Worker return emitSeliT16(Mips::Btnez16, Mips::CmpiRxImmX16, MI, BB);
185*9880d681SAndroid Build Coastguard Worker case Mips::SelTBtneZSlti:
186*9880d681SAndroid Build Coastguard Worker return emitSeliT16(Mips::Btnez16, Mips::SltiRxImmX16, MI, BB);
187*9880d681SAndroid Build Coastguard Worker case Mips::SelTBtneZSltiu:
188*9880d681SAndroid Build Coastguard Worker return emitSeliT16(Mips::Btnez16, Mips::SltiuRxImmX16, MI, BB);
189*9880d681SAndroid Build Coastguard Worker case Mips::SelTBteqZCmp:
190*9880d681SAndroid Build Coastguard Worker return emitSelT16(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB);
191*9880d681SAndroid Build Coastguard Worker case Mips::SelTBteqZSlt:
192*9880d681SAndroid Build Coastguard Worker return emitSelT16(Mips::Bteqz16, Mips::SltRxRy16, MI, BB);
193*9880d681SAndroid Build Coastguard Worker case Mips::SelTBteqZSltu:
194*9880d681SAndroid Build Coastguard Worker return emitSelT16(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB);
195*9880d681SAndroid Build Coastguard Worker case Mips::SelTBtneZCmp:
196*9880d681SAndroid Build Coastguard Worker return emitSelT16(Mips::Btnez16, Mips::CmpRxRy16, MI, BB);
197*9880d681SAndroid Build Coastguard Worker case Mips::SelTBtneZSlt:
198*9880d681SAndroid Build Coastguard Worker return emitSelT16(Mips::Btnez16, Mips::SltRxRy16, MI, BB);
199*9880d681SAndroid Build Coastguard Worker case Mips::SelTBtneZSltu:
200*9880d681SAndroid Build Coastguard Worker return emitSelT16(Mips::Btnez16, Mips::SltuRxRy16, MI, BB);
201*9880d681SAndroid Build Coastguard Worker case Mips::BteqzT8CmpX16:
202*9880d681SAndroid Build Coastguard Worker return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB);
203*9880d681SAndroid Build Coastguard Worker case Mips::BteqzT8SltX16:
204*9880d681SAndroid Build Coastguard Worker return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltRxRy16, MI, BB);
205*9880d681SAndroid Build Coastguard Worker case Mips::BteqzT8SltuX16:
206*9880d681SAndroid Build Coastguard Worker // TBD: figure out a way to get this or remove the instruction
207*9880d681SAndroid Build Coastguard Worker // altogether.
208*9880d681SAndroid Build Coastguard Worker return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB);
209*9880d681SAndroid Build Coastguard Worker case Mips::BtnezT8CmpX16:
210*9880d681SAndroid Build Coastguard Worker return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::CmpRxRy16, MI, BB);
211*9880d681SAndroid Build Coastguard Worker case Mips::BtnezT8SltX16:
212*9880d681SAndroid Build Coastguard Worker return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltRxRy16, MI, BB);
213*9880d681SAndroid Build Coastguard Worker case Mips::BtnezT8SltuX16:
214*9880d681SAndroid Build Coastguard Worker // TBD: figure out a way to get this or remove the instruction
215*9880d681SAndroid Build Coastguard Worker // altogether.
216*9880d681SAndroid Build Coastguard Worker return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltuRxRy16, MI, BB);
217*9880d681SAndroid Build Coastguard Worker case Mips::BteqzT8CmpiX16: return emitFEXT_T8I8I16_ins(
218*9880d681SAndroid Build Coastguard Worker Mips::Bteqz16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16, false, MI, BB);
219*9880d681SAndroid Build Coastguard Worker case Mips::BteqzT8SltiX16: return emitFEXT_T8I8I16_ins(
220*9880d681SAndroid Build Coastguard Worker Mips::Bteqz16, Mips::SltiRxImm16, Mips::SltiRxImmX16, true, MI, BB);
221*9880d681SAndroid Build Coastguard Worker case Mips::BteqzT8SltiuX16: return emitFEXT_T8I8I16_ins(
222*9880d681SAndroid Build Coastguard Worker Mips::Bteqz16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16, false, MI, BB);
223*9880d681SAndroid Build Coastguard Worker case Mips::BtnezT8CmpiX16: return emitFEXT_T8I8I16_ins(
224*9880d681SAndroid Build Coastguard Worker Mips::Btnez16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16, false, MI, BB);
225*9880d681SAndroid Build Coastguard Worker case Mips::BtnezT8SltiX16: return emitFEXT_T8I8I16_ins(
226*9880d681SAndroid Build Coastguard Worker Mips::Btnez16, Mips::SltiRxImm16, Mips::SltiRxImmX16, true, MI, BB);
227*9880d681SAndroid Build Coastguard Worker case Mips::BtnezT8SltiuX16: return emitFEXT_T8I8I16_ins(
228*9880d681SAndroid Build Coastguard Worker Mips::Btnez16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16, false, MI, BB);
229*9880d681SAndroid Build Coastguard Worker break;
230*9880d681SAndroid Build Coastguard Worker case Mips::SltCCRxRy16:
231*9880d681SAndroid Build Coastguard Worker return emitFEXT_CCRX16_ins(Mips::SltRxRy16, MI, BB);
232*9880d681SAndroid Build Coastguard Worker break;
233*9880d681SAndroid Build Coastguard Worker case Mips::SltiCCRxImmX16:
234*9880d681SAndroid Build Coastguard Worker return emitFEXT_CCRXI16_ins
235*9880d681SAndroid Build Coastguard Worker (Mips::SltiRxImm16, Mips::SltiRxImmX16, MI, BB);
236*9880d681SAndroid Build Coastguard Worker case Mips::SltiuCCRxImmX16:
237*9880d681SAndroid Build Coastguard Worker return emitFEXT_CCRXI16_ins
238*9880d681SAndroid Build Coastguard Worker (Mips::SltiuRxImm16, Mips::SltiuRxImmX16, MI, BB);
239*9880d681SAndroid Build Coastguard Worker case Mips::SltuCCRxRy16:
240*9880d681SAndroid Build Coastguard Worker return emitFEXT_CCRX16_ins
241*9880d681SAndroid Build Coastguard Worker (Mips::SltuRxRy16, MI, BB);
242*9880d681SAndroid Build Coastguard Worker }
243*9880d681SAndroid Build Coastguard Worker }
244*9880d681SAndroid Build Coastguard Worker
isEligibleForTailCallOptimization(const CCState & CCInfo,unsigned NextStackOffset,const MipsFunctionInfo & FI) const245*9880d681SAndroid Build Coastguard Worker bool Mips16TargetLowering::isEligibleForTailCallOptimization(
246*9880d681SAndroid Build Coastguard Worker const CCState &CCInfo, unsigned NextStackOffset,
247*9880d681SAndroid Build Coastguard Worker const MipsFunctionInfo &FI) const {
248*9880d681SAndroid Build Coastguard Worker // No tail call optimization for mips16.
249*9880d681SAndroid Build Coastguard Worker return false;
250*9880d681SAndroid Build Coastguard Worker }
251*9880d681SAndroid Build Coastguard Worker
setMips16HardFloatLibCalls()252*9880d681SAndroid Build Coastguard Worker void Mips16TargetLowering::setMips16HardFloatLibCalls() {
253*9880d681SAndroid Build Coastguard Worker for (unsigned I = 0; I != array_lengthof(HardFloatLibCalls); ++I) {
254*9880d681SAndroid Build Coastguard Worker assert((I == 0 || HardFloatLibCalls[I - 1] < HardFloatLibCalls[I]) &&
255*9880d681SAndroid Build Coastguard Worker "Array not sorted!");
256*9880d681SAndroid Build Coastguard Worker if (HardFloatLibCalls[I].Libcall != RTLIB::UNKNOWN_LIBCALL)
257*9880d681SAndroid Build Coastguard Worker setLibcallName(HardFloatLibCalls[I].Libcall, HardFloatLibCalls[I].Name);
258*9880d681SAndroid Build Coastguard Worker }
259*9880d681SAndroid Build Coastguard Worker
260*9880d681SAndroid Build Coastguard Worker setLibcallName(RTLIB::O_F64, "__mips16_unorddf2");
261*9880d681SAndroid Build Coastguard Worker setLibcallName(RTLIB::O_F32, "__mips16_unordsf2");
262*9880d681SAndroid Build Coastguard Worker }
263*9880d681SAndroid Build Coastguard Worker
264*9880d681SAndroid Build Coastguard Worker //
265*9880d681SAndroid Build Coastguard Worker // The Mips16 hard float is a crazy quilt inherited from gcc. I have a much
266*9880d681SAndroid Build Coastguard Worker // cleaner way to do all of this but it will have to wait until the traditional
267*9880d681SAndroid Build Coastguard Worker // gcc mechanism is completed.
268*9880d681SAndroid Build Coastguard Worker //
269*9880d681SAndroid Build Coastguard Worker // For Pic, in order for Mips16 code to call Mips32 code which according the abi
270*9880d681SAndroid Build Coastguard Worker // have either arguments or returned values placed in floating point registers,
271*9880d681SAndroid Build Coastguard Worker // we use a set of helper functions. (This includes functions which return type
272*9880d681SAndroid Build Coastguard Worker // complex which on Mips are returned in a pair of floating point registers).
273*9880d681SAndroid Build Coastguard Worker //
274*9880d681SAndroid Build Coastguard Worker // This is an encoding that we inherited from gcc.
275*9880d681SAndroid Build Coastguard Worker // In Mips traditional O32, N32 ABI, floating point numbers are passed in
276*9880d681SAndroid Build Coastguard Worker // floating point argument registers 1,2 only when the first and optionally
277*9880d681SAndroid Build Coastguard Worker // the second arguments are float (sf) or double (df).
278*9880d681SAndroid Build Coastguard Worker // For Mips16 we are only concerned with the situations where floating point
279*9880d681SAndroid Build Coastguard Worker // arguments are being passed in floating point registers by the ABI, because
280*9880d681SAndroid Build Coastguard Worker // Mips16 mode code cannot execute floating point instructions to load those
281*9880d681SAndroid Build Coastguard Worker // values and hence helper functions are needed.
282*9880d681SAndroid Build Coastguard Worker // The possibilities are (), (sf), (sf, sf), (sf, df), (df), (df, sf), (df, df)
283*9880d681SAndroid Build Coastguard Worker // the helper function suffixs for these are:
284*9880d681SAndroid Build Coastguard Worker // 0, 1, 5, 9, 2, 6, 10
285*9880d681SAndroid Build Coastguard Worker // this suffix can then be calculated as follows:
286*9880d681SAndroid Build Coastguard Worker // for a given argument Arg:
287*9880d681SAndroid Build Coastguard Worker // Arg1x, Arg2x = 1 : Arg is sf
288*9880d681SAndroid Build Coastguard Worker // 2 : Arg is df
289*9880d681SAndroid Build Coastguard Worker // 0: Arg is neither sf or df
290*9880d681SAndroid Build Coastguard Worker // So this stub is the string for number Arg1x + Arg2x*4.
291*9880d681SAndroid Build Coastguard Worker // However not all numbers between 0 and 10 are possible, we check anyway and
292*9880d681SAndroid Build Coastguard Worker // assert if the impossible exists.
293*9880d681SAndroid Build Coastguard Worker //
294*9880d681SAndroid Build Coastguard Worker
getMips16HelperFunctionStubNumber(ArgListTy & Args) const295*9880d681SAndroid Build Coastguard Worker unsigned int Mips16TargetLowering::getMips16HelperFunctionStubNumber
296*9880d681SAndroid Build Coastguard Worker (ArgListTy &Args) const {
297*9880d681SAndroid Build Coastguard Worker unsigned int resultNum = 0;
298*9880d681SAndroid Build Coastguard Worker if (Args.size() >= 1) {
299*9880d681SAndroid Build Coastguard Worker Type *t = Args[0].Ty;
300*9880d681SAndroid Build Coastguard Worker if (t->isFloatTy()) {
301*9880d681SAndroid Build Coastguard Worker resultNum = 1;
302*9880d681SAndroid Build Coastguard Worker }
303*9880d681SAndroid Build Coastguard Worker else if (t->isDoubleTy()) {
304*9880d681SAndroid Build Coastguard Worker resultNum = 2;
305*9880d681SAndroid Build Coastguard Worker }
306*9880d681SAndroid Build Coastguard Worker }
307*9880d681SAndroid Build Coastguard Worker if (resultNum) {
308*9880d681SAndroid Build Coastguard Worker if (Args.size() >=2) {
309*9880d681SAndroid Build Coastguard Worker Type *t = Args[1].Ty;
310*9880d681SAndroid Build Coastguard Worker if (t->isFloatTy()) {
311*9880d681SAndroid Build Coastguard Worker resultNum += 4;
312*9880d681SAndroid Build Coastguard Worker }
313*9880d681SAndroid Build Coastguard Worker else if (t->isDoubleTy()) {
314*9880d681SAndroid Build Coastguard Worker resultNum += 8;
315*9880d681SAndroid Build Coastguard Worker }
316*9880d681SAndroid Build Coastguard Worker }
317*9880d681SAndroid Build Coastguard Worker }
318*9880d681SAndroid Build Coastguard Worker return resultNum;
319*9880d681SAndroid Build Coastguard Worker }
320*9880d681SAndroid Build Coastguard Worker
321*9880d681SAndroid Build Coastguard Worker //
322*9880d681SAndroid Build Coastguard Worker // Prefixes are attached to stub numbers depending on the return type.
323*9880d681SAndroid Build Coastguard Worker // return type: float sf_
324*9880d681SAndroid Build Coastguard Worker // double df_
325*9880d681SAndroid Build Coastguard Worker // single complex sc_
326*9880d681SAndroid Build Coastguard Worker // double complext dc_
327*9880d681SAndroid Build Coastguard Worker // others NO PREFIX
328*9880d681SAndroid Build Coastguard Worker //
329*9880d681SAndroid Build Coastguard Worker //
330*9880d681SAndroid Build Coastguard Worker // The full name of a helper function is__mips16_call_stub +
331*9880d681SAndroid Build Coastguard Worker // return type dependent prefix + stub number
332*9880d681SAndroid Build Coastguard Worker //
333*9880d681SAndroid Build Coastguard Worker // FIXME: This is something that probably should be in a different source file
334*9880d681SAndroid Build Coastguard Worker // and perhaps done differently but my main purpose is to not waste runtime
335*9880d681SAndroid Build Coastguard Worker // on something that we can enumerate in the source. Another possibility is
336*9880d681SAndroid Build Coastguard Worker // to have a python script to generate these mapping tables. This will do
337*9880d681SAndroid Build Coastguard Worker // for now. There are a whole series of helper function mapping arrays, one
338*9880d681SAndroid Build Coastguard Worker // for each return type class as outlined above. There there are 11 possible
339*9880d681SAndroid Build Coastguard Worker // entries. Ones with 0 are ones which should never be selected.
340*9880d681SAndroid Build Coastguard Worker //
341*9880d681SAndroid Build Coastguard Worker // All the arrays are similar except for ones which return neither
342*9880d681SAndroid Build Coastguard Worker // sf, df, sc, dc, in which we only care about ones which have sf or df as a
343*9880d681SAndroid Build Coastguard Worker // first parameter.
344*9880d681SAndroid Build Coastguard Worker //
345*9880d681SAndroid Build Coastguard Worker #define P_ "__mips16_call_stub_"
346*9880d681SAndroid Build Coastguard Worker #define MAX_STUB_NUMBER 10
347*9880d681SAndroid Build Coastguard Worker #define T1 P "1", P "2", 0, 0, P "5", P "6", 0, 0, P "9", P "10"
348*9880d681SAndroid Build Coastguard Worker #define T P "0" , T1
349*9880d681SAndroid Build Coastguard Worker #define P P_
350*9880d681SAndroid Build Coastguard Worker static char const * vMips16Helper[MAX_STUB_NUMBER+1] =
351*9880d681SAndroid Build Coastguard Worker {nullptr, T1 };
352*9880d681SAndroid Build Coastguard Worker #undef P
353*9880d681SAndroid Build Coastguard Worker #define P P_ "sf_"
354*9880d681SAndroid Build Coastguard Worker static char const * sfMips16Helper[MAX_STUB_NUMBER+1] =
355*9880d681SAndroid Build Coastguard Worker { T };
356*9880d681SAndroid Build Coastguard Worker #undef P
357*9880d681SAndroid Build Coastguard Worker #define P P_ "df_"
358*9880d681SAndroid Build Coastguard Worker static char const * dfMips16Helper[MAX_STUB_NUMBER+1] =
359*9880d681SAndroid Build Coastguard Worker { T };
360*9880d681SAndroid Build Coastguard Worker #undef P
361*9880d681SAndroid Build Coastguard Worker #define P P_ "sc_"
362*9880d681SAndroid Build Coastguard Worker static char const * scMips16Helper[MAX_STUB_NUMBER+1] =
363*9880d681SAndroid Build Coastguard Worker { T };
364*9880d681SAndroid Build Coastguard Worker #undef P
365*9880d681SAndroid Build Coastguard Worker #define P P_ "dc_"
366*9880d681SAndroid Build Coastguard Worker static char const * dcMips16Helper[MAX_STUB_NUMBER+1] =
367*9880d681SAndroid Build Coastguard Worker { T };
368*9880d681SAndroid Build Coastguard Worker #undef P
369*9880d681SAndroid Build Coastguard Worker #undef P_
370*9880d681SAndroid Build Coastguard Worker
371*9880d681SAndroid Build Coastguard Worker
372*9880d681SAndroid Build Coastguard Worker const char* Mips16TargetLowering::
getMips16HelperFunction(Type * RetTy,ArgListTy & Args,bool & needHelper) const373*9880d681SAndroid Build Coastguard Worker getMips16HelperFunction
374*9880d681SAndroid Build Coastguard Worker (Type* RetTy, ArgListTy &Args, bool &needHelper) const {
375*9880d681SAndroid Build Coastguard Worker const unsigned int stubNum = getMips16HelperFunctionStubNumber(Args);
376*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
377*9880d681SAndroid Build Coastguard Worker const unsigned int maxStubNum = 10;
378*9880d681SAndroid Build Coastguard Worker assert(stubNum <= maxStubNum);
379*9880d681SAndroid Build Coastguard Worker const bool validStubNum[maxStubNum+1] =
380*9880d681SAndroid Build Coastguard Worker {true, true, true, false, false, true, true, false, false, true, true};
381*9880d681SAndroid Build Coastguard Worker assert(validStubNum[stubNum]);
382*9880d681SAndroid Build Coastguard Worker #endif
383*9880d681SAndroid Build Coastguard Worker const char *result;
384*9880d681SAndroid Build Coastguard Worker if (RetTy->isFloatTy()) {
385*9880d681SAndroid Build Coastguard Worker result = sfMips16Helper[stubNum];
386*9880d681SAndroid Build Coastguard Worker }
387*9880d681SAndroid Build Coastguard Worker else if (RetTy ->isDoubleTy()) {
388*9880d681SAndroid Build Coastguard Worker result = dfMips16Helper[stubNum];
389*9880d681SAndroid Build Coastguard Worker }
390*9880d681SAndroid Build Coastguard Worker else if (RetTy->isStructTy()) {
391*9880d681SAndroid Build Coastguard Worker // check if it's complex
392*9880d681SAndroid Build Coastguard Worker if (RetTy->getNumContainedTypes() == 2) {
393*9880d681SAndroid Build Coastguard Worker if ((RetTy->getContainedType(0)->isFloatTy()) &&
394*9880d681SAndroid Build Coastguard Worker (RetTy->getContainedType(1)->isFloatTy())) {
395*9880d681SAndroid Build Coastguard Worker result = scMips16Helper[stubNum];
396*9880d681SAndroid Build Coastguard Worker }
397*9880d681SAndroid Build Coastguard Worker else if ((RetTy->getContainedType(0)->isDoubleTy()) &&
398*9880d681SAndroid Build Coastguard Worker (RetTy->getContainedType(1)->isDoubleTy())) {
399*9880d681SAndroid Build Coastguard Worker result = dcMips16Helper[stubNum];
400*9880d681SAndroid Build Coastguard Worker }
401*9880d681SAndroid Build Coastguard Worker else {
402*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Uncovered condition");
403*9880d681SAndroid Build Coastguard Worker }
404*9880d681SAndroid Build Coastguard Worker }
405*9880d681SAndroid Build Coastguard Worker else {
406*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Uncovered condition");
407*9880d681SAndroid Build Coastguard Worker }
408*9880d681SAndroid Build Coastguard Worker }
409*9880d681SAndroid Build Coastguard Worker else {
410*9880d681SAndroid Build Coastguard Worker if (stubNum == 0) {
411*9880d681SAndroid Build Coastguard Worker needHelper = false;
412*9880d681SAndroid Build Coastguard Worker return "";
413*9880d681SAndroid Build Coastguard Worker }
414*9880d681SAndroid Build Coastguard Worker result = vMips16Helper[stubNum];
415*9880d681SAndroid Build Coastguard Worker }
416*9880d681SAndroid Build Coastguard Worker needHelper = true;
417*9880d681SAndroid Build Coastguard Worker return result;
418*9880d681SAndroid Build Coastguard Worker }
419*9880d681SAndroid Build Coastguard Worker
420*9880d681SAndroid Build Coastguard Worker void Mips16TargetLowering::
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) const421*9880d681SAndroid Build Coastguard Worker getOpndList(SmallVectorImpl<SDValue> &Ops,
422*9880d681SAndroid Build Coastguard Worker std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
423*9880d681SAndroid Build Coastguard Worker bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
424*9880d681SAndroid Build Coastguard Worker bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
425*9880d681SAndroid Build Coastguard Worker SDValue Chain) const {
426*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG = CLI.DAG;
427*9880d681SAndroid Build Coastguard Worker MachineFunction &MF = DAG.getMachineFunction();
428*9880d681SAndroid Build Coastguard Worker MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
429*9880d681SAndroid Build Coastguard Worker const char* Mips16HelperFunction = nullptr;
430*9880d681SAndroid Build Coastguard Worker bool NeedMips16Helper = false;
431*9880d681SAndroid Build Coastguard Worker
432*9880d681SAndroid Build Coastguard Worker if (Subtarget.inMips16HardFloat()) {
433*9880d681SAndroid Build Coastguard Worker //
434*9880d681SAndroid Build Coastguard Worker // currently we don't have symbols tagged with the mips16 or mips32
435*9880d681SAndroid Build Coastguard Worker // qualifier so we will assume that we don't know what kind it is.
436*9880d681SAndroid Build Coastguard Worker // and generate the helper
437*9880d681SAndroid Build Coastguard Worker //
438*9880d681SAndroid Build Coastguard Worker bool LookupHelper = true;
439*9880d681SAndroid Build Coastguard Worker if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(CLI.Callee)) {
440*9880d681SAndroid Build Coastguard Worker Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL, S->getSymbol() };
441*9880d681SAndroid Build Coastguard Worker
442*9880d681SAndroid Build Coastguard Worker if (std::binary_search(std::begin(HardFloatLibCalls),
443*9880d681SAndroid Build Coastguard Worker std::end(HardFloatLibCalls), Find))
444*9880d681SAndroid Build Coastguard Worker LookupHelper = false;
445*9880d681SAndroid Build Coastguard Worker else {
446*9880d681SAndroid Build Coastguard Worker const char *Symbol = S->getSymbol();
447*9880d681SAndroid Build Coastguard Worker Mips16IntrinsicHelperType IntrinsicFind = { Symbol, "" };
448*9880d681SAndroid Build Coastguard Worker const Mips16HardFloatInfo::FuncSignature *Signature =
449*9880d681SAndroid Build Coastguard Worker Mips16HardFloatInfo::findFuncSignature(Symbol);
450*9880d681SAndroid Build Coastguard Worker if (!IsPICCall && (Signature && (FuncInfo->StubsNeeded.find(Symbol) ==
451*9880d681SAndroid Build Coastguard Worker FuncInfo->StubsNeeded.end()))) {
452*9880d681SAndroid Build Coastguard Worker FuncInfo->StubsNeeded[Symbol] = Signature;
453*9880d681SAndroid Build Coastguard Worker //
454*9880d681SAndroid Build Coastguard Worker // S2 is normally saved if the stub is for a function which
455*9880d681SAndroid Build Coastguard Worker // returns a float or double value and is not otherwise. This is
456*9880d681SAndroid Build Coastguard Worker // because more work is required after the function the stub
457*9880d681SAndroid Build Coastguard Worker // is calling completes, and so the stub cannot directly return
458*9880d681SAndroid Build Coastguard Worker // and the stub has no stack space to store the return address so
459*9880d681SAndroid Build Coastguard Worker // S2 is used for that purpose.
460*9880d681SAndroid Build Coastguard Worker // In order to take advantage of not saving S2, we need to also
461*9880d681SAndroid Build Coastguard Worker // optimize the call in the stub and this requires some further
462*9880d681SAndroid Build Coastguard Worker // functionality in MipsAsmPrinter which we don't have yet.
463*9880d681SAndroid Build Coastguard Worker // So for now we always save S2. The optimization will be done
464*9880d681SAndroid Build Coastguard Worker // in a follow-on patch.
465*9880d681SAndroid Build Coastguard Worker //
466*9880d681SAndroid Build Coastguard Worker if (1 || (Signature->RetSig != Mips16HardFloatInfo::NoFPRet))
467*9880d681SAndroid Build Coastguard Worker FuncInfo->setSaveS2();
468*9880d681SAndroid Build Coastguard Worker }
469*9880d681SAndroid Build Coastguard Worker // one more look at list of intrinsics
470*9880d681SAndroid Build Coastguard Worker const Mips16IntrinsicHelperType *Helper =
471*9880d681SAndroid Build Coastguard Worker std::lower_bound(std::begin(Mips16IntrinsicHelper),
472*9880d681SAndroid Build Coastguard Worker std::end(Mips16IntrinsicHelper), IntrinsicFind);
473*9880d681SAndroid Build Coastguard Worker if (Helper != std::end(Mips16IntrinsicHelper) &&
474*9880d681SAndroid Build Coastguard Worker *Helper == IntrinsicFind) {
475*9880d681SAndroid Build Coastguard Worker Mips16HelperFunction = Helper->Helper;
476*9880d681SAndroid Build Coastguard Worker NeedMips16Helper = true;
477*9880d681SAndroid Build Coastguard Worker LookupHelper = false;
478*9880d681SAndroid Build Coastguard Worker }
479*9880d681SAndroid Build Coastguard Worker
480*9880d681SAndroid Build Coastguard Worker }
481*9880d681SAndroid Build Coastguard Worker } else if (GlobalAddressSDNode *G =
482*9880d681SAndroid Build Coastguard Worker dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {
483*9880d681SAndroid Build Coastguard Worker Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL,
484*9880d681SAndroid Build Coastguard Worker G->getGlobal()->getName().data() };
485*9880d681SAndroid Build Coastguard Worker
486*9880d681SAndroid Build Coastguard Worker if (std::binary_search(std::begin(HardFloatLibCalls),
487*9880d681SAndroid Build Coastguard Worker std::end(HardFloatLibCalls), Find))
488*9880d681SAndroid Build Coastguard Worker LookupHelper = false;
489*9880d681SAndroid Build Coastguard Worker }
490*9880d681SAndroid Build Coastguard Worker if (LookupHelper)
491*9880d681SAndroid Build Coastguard Worker Mips16HelperFunction =
492*9880d681SAndroid Build Coastguard Worker getMips16HelperFunction(CLI.RetTy, CLI.getArgs(), NeedMips16Helper);
493*9880d681SAndroid Build Coastguard Worker }
494*9880d681SAndroid Build Coastguard Worker
495*9880d681SAndroid Build Coastguard Worker SDValue JumpTarget = Callee;
496*9880d681SAndroid Build Coastguard Worker
497*9880d681SAndroid Build Coastguard Worker // T9 should contain the address of the callee function if
498*9880d681SAndroid Build Coastguard Worker // -relocation-model=pic or it is an indirect call.
499*9880d681SAndroid Build Coastguard Worker if (IsPICCall || !GlobalOrExternal) {
500*9880d681SAndroid Build Coastguard Worker unsigned V0Reg = Mips::V0;
501*9880d681SAndroid Build Coastguard Worker if (NeedMips16Helper) {
502*9880d681SAndroid Build Coastguard Worker RegsToPass.push_front(std::make_pair(V0Reg, Callee));
503*9880d681SAndroid Build Coastguard Worker JumpTarget = DAG.getExternalSymbol(Mips16HelperFunction,
504*9880d681SAndroid Build Coastguard Worker getPointerTy(DAG.getDataLayout()));
505*9880d681SAndroid Build Coastguard Worker ExternalSymbolSDNode *S = cast<ExternalSymbolSDNode>(JumpTarget);
506*9880d681SAndroid Build Coastguard Worker JumpTarget = getAddrGlobal(S, CLI.DL, JumpTarget.getValueType(), DAG,
507*9880d681SAndroid Build Coastguard Worker MipsII::MO_GOT, Chain,
508*9880d681SAndroid Build Coastguard Worker FuncInfo->callPtrInfo(S->getSymbol()));
509*9880d681SAndroid Build Coastguard Worker } else
510*9880d681SAndroid Build Coastguard Worker RegsToPass.push_front(std::make_pair((unsigned)Mips::T9, Callee));
511*9880d681SAndroid Build Coastguard Worker }
512*9880d681SAndroid Build Coastguard Worker
513*9880d681SAndroid Build Coastguard Worker Ops.push_back(JumpTarget);
514*9880d681SAndroid Build Coastguard Worker
515*9880d681SAndroid Build Coastguard Worker MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
516*9880d681SAndroid Build Coastguard Worker InternalLinkage, IsCallReloc, CLI, Callee,
517*9880d681SAndroid Build Coastguard Worker Chain);
518*9880d681SAndroid Build Coastguard Worker }
519*9880d681SAndroid Build Coastguard Worker
520*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *
emitSel16(unsigned Opc,MachineInstr & MI,MachineBasicBlock * BB) const521*9880d681SAndroid Build Coastguard Worker Mips16TargetLowering::emitSel16(unsigned Opc, MachineInstr &MI,
522*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *BB) const {
523*9880d681SAndroid Build Coastguard Worker if (DontExpandCondPseudos16)
524*9880d681SAndroid Build Coastguard Worker return BB;
525*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo *TII = Subtarget.getInstrInfo();
526*9880d681SAndroid Build Coastguard Worker DebugLoc DL = MI.getDebugLoc();
527*9880d681SAndroid Build Coastguard Worker // To "insert" a SELECT_CC instruction, we actually have to insert the
528*9880d681SAndroid Build Coastguard Worker // diamond control-flow pattern. The incoming instruction knows the
529*9880d681SAndroid Build Coastguard Worker // destination vreg to set, the condition code register to branch on, the
530*9880d681SAndroid Build Coastguard Worker // true/false values to select between, and a branch opcode to use.
531*9880d681SAndroid Build Coastguard Worker const BasicBlock *LLVM_BB = BB->getBasicBlock();
532*9880d681SAndroid Build Coastguard Worker MachineFunction::iterator It = ++BB->getIterator();
533*9880d681SAndroid Build Coastguard Worker
534*9880d681SAndroid Build Coastguard Worker // thisMBB:
535*9880d681SAndroid Build Coastguard Worker // ...
536*9880d681SAndroid Build Coastguard Worker // TrueVal = ...
537*9880d681SAndroid Build Coastguard Worker // setcc r1, r2, r3
538*9880d681SAndroid Build Coastguard Worker // bNE r1, r0, copy1MBB
539*9880d681SAndroid Build Coastguard Worker // fallthrough --> copy0MBB
540*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *thisMBB = BB;
541*9880d681SAndroid Build Coastguard Worker MachineFunction *F = BB->getParent();
542*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
543*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
544*9880d681SAndroid Build Coastguard Worker F->insert(It, copy0MBB);
545*9880d681SAndroid Build Coastguard Worker F->insert(It, sinkMBB);
546*9880d681SAndroid Build Coastguard Worker
547*9880d681SAndroid Build Coastguard Worker // Transfer the remainder of BB and its successor edges to sinkMBB.
548*9880d681SAndroid Build Coastguard Worker sinkMBB->splice(sinkMBB->begin(), BB,
549*9880d681SAndroid Build Coastguard Worker std::next(MachineBasicBlock::iterator(MI)), BB->end());
550*9880d681SAndroid Build Coastguard Worker sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
551*9880d681SAndroid Build Coastguard Worker
552*9880d681SAndroid Build Coastguard Worker // Next, add the true and fallthrough blocks as its successors.
553*9880d681SAndroid Build Coastguard Worker BB->addSuccessor(copy0MBB);
554*9880d681SAndroid Build Coastguard Worker BB->addSuccessor(sinkMBB);
555*9880d681SAndroid Build Coastguard Worker
556*9880d681SAndroid Build Coastguard Worker BuildMI(BB, DL, TII->get(Opc))
557*9880d681SAndroid Build Coastguard Worker .addReg(MI.getOperand(3).getReg())
558*9880d681SAndroid Build Coastguard Worker .addMBB(sinkMBB);
559*9880d681SAndroid Build Coastguard Worker
560*9880d681SAndroid Build Coastguard Worker // copy0MBB:
561*9880d681SAndroid Build Coastguard Worker // %FalseValue = ...
562*9880d681SAndroid Build Coastguard Worker // # fallthrough to sinkMBB
563*9880d681SAndroid Build Coastguard Worker BB = copy0MBB;
564*9880d681SAndroid Build Coastguard Worker
565*9880d681SAndroid Build Coastguard Worker // Update machine-CFG edges
566*9880d681SAndroid Build Coastguard Worker BB->addSuccessor(sinkMBB);
567*9880d681SAndroid Build Coastguard Worker
568*9880d681SAndroid Build Coastguard Worker // sinkMBB:
569*9880d681SAndroid Build Coastguard Worker // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
570*9880d681SAndroid Build Coastguard Worker // ...
571*9880d681SAndroid Build Coastguard Worker BB = sinkMBB;
572*9880d681SAndroid Build Coastguard Worker
573*9880d681SAndroid Build Coastguard Worker BuildMI(*BB, BB->begin(), DL, TII->get(Mips::PHI), MI.getOperand(0).getReg())
574*9880d681SAndroid Build Coastguard Worker .addReg(MI.getOperand(1).getReg())
575*9880d681SAndroid Build Coastguard Worker .addMBB(thisMBB)
576*9880d681SAndroid Build Coastguard Worker .addReg(MI.getOperand(2).getReg())
577*9880d681SAndroid Build Coastguard Worker .addMBB(copy0MBB);
578*9880d681SAndroid Build Coastguard Worker
579*9880d681SAndroid Build Coastguard Worker MI.eraseFromParent(); // The pseudo instruction is gone now.
580*9880d681SAndroid Build Coastguard Worker return BB;
581*9880d681SAndroid Build Coastguard Worker }
582*9880d681SAndroid Build Coastguard Worker
583*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *
emitSelT16(unsigned Opc1,unsigned Opc2,MachineInstr & MI,MachineBasicBlock * BB) const584*9880d681SAndroid Build Coastguard Worker Mips16TargetLowering::emitSelT16(unsigned Opc1, unsigned Opc2, MachineInstr &MI,
585*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *BB) const {
586*9880d681SAndroid Build Coastguard Worker if (DontExpandCondPseudos16)
587*9880d681SAndroid Build Coastguard Worker return BB;
588*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo *TII = Subtarget.getInstrInfo();
589*9880d681SAndroid Build Coastguard Worker DebugLoc DL = MI.getDebugLoc();
590*9880d681SAndroid Build Coastguard Worker // To "insert" a SELECT_CC instruction, we actually have to insert the
591*9880d681SAndroid Build Coastguard Worker // diamond control-flow pattern. The incoming instruction knows the
592*9880d681SAndroid Build Coastguard Worker // destination vreg to set, the condition code register to branch on, the
593*9880d681SAndroid Build Coastguard Worker // true/false values to select between, and a branch opcode to use.
594*9880d681SAndroid Build Coastguard Worker const BasicBlock *LLVM_BB = BB->getBasicBlock();
595*9880d681SAndroid Build Coastguard Worker MachineFunction::iterator It = ++BB->getIterator();
596*9880d681SAndroid Build Coastguard Worker
597*9880d681SAndroid Build Coastguard Worker // thisMBB:
598*9880d681SAndroid Build Coastguard Worker // ...
599*9880d681SAndroid Build Coastguard Worker // TrueVal = ...
600*9880d681SAndroid Build Coastguard Worker // setcc r1, r2, r3
601*9880d681SAndroid Build Coastguard Worker // bNE r1, r0, copy1MBB
602*9880d681SAndroid Build Coastguard Worker // fallthrough --> copy0MBB
603*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *thisMBB = BB;
604*9880d681SAndroid Build Coastguard Worker MachineFunction *F = BB->getParent();
605*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
606*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
607*9880d681SAndroid Build Coastguard Worker F->insert(It, copy0MBB);
608*9880d681SAndroid Build Coastguard Worker F->insert(It, sinkMBB);
609*9880d681SAndroid Build Coastguard Worker
610*9880d681SAndroid Build Coastguard Worker // Transfer the remainder of BB and its successor edges to sinkMBB.
611*9880d681SAndroid Build Coastguard Worker sinkMBB->splice(sinkMBB->begin(), BB,
612*9880d681SAndroid Build Coastguard Worker std::next(MachineBasicBlock::iterator(MI)), BB->end());
613*9880d681SAndroid Build Coastguard Worker sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
614*9880d681SAndroid Build Coastguard Worker
615*9880d681SAndroid Build Coastguard Worker // Next, add the true and fallthrough blocks as its successors.
616*9880d681SAndroid Build Coastguard Worker BB->addSuccessor(copy0MBB);
617*9880d681SAndroid Build Coastguard Worker BB->addSuccessor(sinkMBB);
618*9880d681SAndroid Build Coastguard Worker
619*9880d681SAndroid Build Coastguard Worker BuildMI(BB, DL, TII->get(Opc2))
620*9880d681SAndroid Build Coastguard Worker .addReg(MI.getOperand(3).getReg())
621*9880d681SAndroid Build Coastguard Worker .addReg(MI.getOperand(4).getReg());
622*9880d681SAndroid Build Coastguard Worker BuildMI(BB, DL, TII->get(Opc1)).addMBB(sinkMBB);
623*9880d681SAndroid Build Coastguard Worker
624*9880d681SAndroid Build Coastguard Worker // copy0MBB:
625*9880d681SAndroid Build Coastguard Worker // %FalseValue = ...
626*9880d681SAndroid Build Coastguard Worker // # fallthrough to sinkMBB
627*9880d681SAndroid Build Coastguard Worker BB = copy0MBB;
628*9880d681SAndroid Build Coastguard Worker
629*9880d681SAndroid Build Coastguard Worker // Update machine-CFG edges
630*9880d681SAndroid Build Coastguard Worker BB->addSuccessor(sinkMBB);
631*9880d681SAndroid Build Coastguard Worker
632*9880d681SAndroid Build Coastguard Worker // sinkMBB:
633*9880d681SAndroid Build Coastguard Worker // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
634*9880d681SAndroid Build Coastguard Worker // ...
635*9880d681SAndroid Build Coastguard Worker BB = sinkMBB;
636*9880d681SAndroid Build Coastguard Worker
637*9880d681SAndroid Build Coastguard Worker BuildMI(*BB, BB->begin(), DL, TII->get(Mips::PHI), MI.getOperand(0).getReg())
638*9880d681SAndroid Build Coastguard Worker .addReg(MI.getOperand(1).getReg())
639*9880d681SAndroid Build Coastguard Worker .addMBB(thisMBB)
640*9880d681SAndroid Build Coastguard Worker .addReg(MI.getOperand(2).getReg())
641*9880d681SAndroid Build Coastguard Worker .addMBB(copy0MBB);
642*9880d681SAndroid Build Coastguard Worker
643*9880d681SAndroid Build Coastguard Worker MI.eraseFromParent(); // The pseudo instruction is gone now.
644*9880d681SAndroid Build Coastguard Worker return BB;
645*9880d681SAndroid Build Coastguard Worker
646*9880d681SAndroid Build Coastguard Worker }
647*9880d681SAndroid Build Coastguard Worker
648*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *
emitSeliT16(unsigned Opc1,unsigned Opc2,MachineInstr & MI,MachineBasicBlock * BB) const649*9880d681SAndroid Build Coastguard Worker Mips16TargetLowering::emitSeliT16(unsigned Opc1, unsigned Opc2,
650*9880d681SAndroid Build Coastguard Worker MachineInstr &MI,
651*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *BB) const {
652*9880d681SAndroid Build Coastguard Worker if (DontExpandCondPseudos16)
653*9880d681SAndroid Build Coastguard Worker return BB;
654*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo *TII = Subtarget.getInstrInfo();
655*9880d681SAndroid Build Coastguard Worker DebugLoc DL = MI.getDebugLoc();
656*9880d681SAndroid Build Coastguard Worker // To "insert" a SELECT_CC instruction, we actually have to insert the
657*9880d681SAndroid Build Coastguard Worker // diamond control-flow pattern. The incoming instruction knows the
658*9880d681SAndroid Build Coastguard Worker // destination vreg to set, the condition code register to branch on, the
659*9880d681SAndroid Build Coastguard Worker // true/false values to select between, and a branch opcode to use.
660*9880d681SAndroid Build Coastguard Worker const BasicBlock *LLVM_BB = BB->getBasicBlock();
661*9880d681SAndroid Build Coastguard Worker MachineFunction::iterator It = ++BB->getIterator();
662*9880d681SAndroid Build Coastguard Worker
663*9880d681SAndroid Build Coastguard Worker // thisMBB:
664*9880d681SAndroid Build Coastguard Worker // ...
665*9880d681SAndroid Build Coastguard Worker // TrueVal = ...
666*9880d681SAndroid Build Coastguard Worker // setcc r1, r2, r3
667*9880d681SAndroid Build Coastguard Worker // bNE r1, r0, copy1MBB
668*9880d681SAndroid Build Coastguard Worker // fallthrough --> copy0MBB
669*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *thisMBB = BB;
670*9880d681SAndroid Build Coastguard Worker MachineFunction *F = BB->getParent();
671*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
672*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
673*9880d681SAndroid Build Coastguard Worker F->insert(It, copy0MBB);
674*9880d681SAndroid Build Coastguard Worker F->insert(It, sinkMBB);
675*9880d681SAndroid Build Coastguard Worker
676*9880d681SAndroid Build Coastguard Worker // Transfer the remainder of BB and its successor edges to sinkMBB.
677*9880d681SAndroid Build Coastguard Worker sinkMBB->splice(sinkMBB->begin(), BB,
678*9880d681SAndroid Build Coastguard Worker std::next(MachineBasicBlock::iterator(MI)), BB->end());
679*9880d681SAndroid Build Coastguard Worker sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
680*9880d681SAndroid Build Coastguard Worker
681*9880d681SAndroid Build Coastguard Worker // Next, add the true and fallthrough blocks as its successors.
682*9880d681SAndroid Build Coastguard Worker BB->addSuccessor(copy0MBB);
683*9880d681SAndroid Build Coastguard Worker BB->addSuccessor(sinkMBB);
684*9880d681SAndroid Build Coastguard Worker
685*9880d681SAndroid Build Coastguard Worker BuildMI(BB, DL, TII->get(Opc2))
686*9880d681SAndroid Build Coastguard Worker .addReg(MI.getOperand(3).getReg())
687*9880d681SAndroid Build Coastguard Worker .addImm(MI.getOperand(4).getImm());
688*9880d681SAndroid Build Coastguard Worker BuildMI(BB, DL, TII->get(Opc1)).addMBB(sinkMBB);
689*9880d681SAndroid Build Coastguard Worker
690*9880d681SAndroid Build Coastguard Worker // copy0MBB:
691*9880d681SAndroid Build Coastguard Worker // %FalseValue = ...
692*9880d681SAndroid Build Coastguard Worker // # fallthrough to sinkMBB
693*9880d681SAndroid Build Coastguard Worker BB = copy0MBB;
694*9880d681SAndroid Build Coastguard Worker
695*9880d681SAndroid Build Coastguard Worker // Update machine-CFG edges
696*9880d681SAndroid Build Coastguard Worker BB->addSuccessor(sinkMBB);
697*9880d681SAndroid Build Coastguard Worker
698*9880d681SAndroid Build Coastguard Worker // sinkMBB:
699*9880d681SAndroid Build Coastguard Worker // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
700*9880d681SAndroid Build Coastguard Worker // ...
701*9880d681SAndroid Build Coastguard Worker BB = sinkMBB;
702*9880d681SAndroid Build Coastguard Worker
703*9880d681SAndroid Build Coastguard Worker BuildMI(*BB, BB->begin(), DL, TII->get(Mips::PHI), MI.getOperand(0).getReg())
704*9880d681SAndroid Build Coastguard Worker .addReg(MI.getOperand(1).getReg())
705*9880d681SAndroid Build Coastguard Worker .addMBB(thisMBB)
706*9880d681SAndroid Build Coastguard Worker .addReg(MI.getOperand(2).getReg())
707*9880d681SAndroid Build Coastguard Worker .addMBB(copy0MBB);
708*9880d681SAndroid Build Coastguard Worker
709*9880d681SAndroid Build Coastguard Worker MI.eraseFromParent(); // The pseudo instruction is gone now.
710*9880d681SAndroid Build Coastguard Worker return BB;
711*9880d681SAndroid Build Coastguard Worker
712*9880d681SAndroid Build Coastguard Worker }
713*9880d681SAndroid Build Coastguard Worker
714*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *
emitFEXT_T8I816_ins(unsigned BtOpc,unsigned CmpOpc,MachineInstr & MI,MachineBasicBlock * BB) const715*9880d681SAndroid Build Coastguard Worker Mips16TargetLowering::emitFEXT_T8I816_ins(unsigned BtOpc, unsigned CmpOpc,
716*9880d681SAndroid Build Coastguard Worker MachineInstr &MI,
717*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *BB) const {
718*9880d681SAndroid Build Coastguard Worker if (DontExpandCondPseudos16)
719*9880d681SAndroid Build Coastguard Worker return BB;
720*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo *TII = Subtarget.getInstrInfo();
721*9880d681SAndroid Build Coastguard Worker unsigned regX = MI.getOperand(0).getReg();
722*9880d681SAndroid Build Coastguard Worker unsigned regY = MI.getOperand(1).getReg();
723*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *target = MI.getOperand(2).getMBB();
724*9880d681SAndroid Build Coastguard Worker BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(CmpOpc))
725*9880d681SAndroid Build Coastguard Worker .addReg(regX)
726*9880d681SAndroid Build Coastguard Worker .addReg(regY);
727*9880d681SAndroid Build Coastguard Worker BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(BtOpc)).addMBB(target);
728*9880d681SAndroid Build Coastguard Worker MI.eraseFromParent(); // The pseudo instruction is gone now.
729*9880d681SAndroid Build Coastguard Worker return BB;
730*9880d681SAndroid Build Coastguard Worker }
731*9880d681SAndroid Build Coastguard Worker
emitFEXT_T8I8I16_ins(unsigned BtOpc,unsigned CmpiOpc,unsigned CmpiXOpc,bool ImmSigned,MachineInstr & MI,MachineBasicBlock * BB) const732*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Mips16TargetLowering::emitFEXT_T8I8I16_ins(
733*9880d681SAndroid Build Coastguard Worker unsigned BtOpc, unsigned CmpiOpc, unsigned CmpiXOpc, bool ImmSigned,
734*9880d681SAndroid Build Coastguard Worker MachineInstr &MI, MachineBasicBlock *BB) const {
735*9880d681SAndroid Build Coastguard Worker if (DontExpandCondPseudos16)
736*9880d681SAndroid Build Coastguard Worker return BB;
737*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo *TII = Subtarget.getInstrInfo();
738*9880d681SAndroid Build Coastguard Worker unsigned regX = MI.getOperand(0).getReg();
739*9880d681SAndroid Build Coastguard Worker int64_t imm = MI.getOperand(1).getImm();
740*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *target = MI.getOperand(2).getMBB();
741*9880d681SAndroid Build Coastguard Worker unsigned CmpOpc;
742*9880d681SAndroid Build Coastguard Worker if (isUInt<8>(imm))
743*9880d681SAndroid Build Coastguard Worker CmpOpc = CmpiOpc;
744*9880d681SAndroid Build Coastguard Worker else if ((!ImmSigned && isUInt<16>(imm)) ||
745*9880d681SAndroid Build Coastguard Worker (ImmSigned && isInt<16>(imm)))
746*9880d681SAndroid Build Coastguard Worker CmpOpc = CmpiXOpc;
747*9880d681SAndroid Build Coastguard Worker else
748*9880d681SAndroid Build Coastguard Worker llvm_unreachable("immediate field not usable");
749*9880d681SAndroid Build Coastguard Worker BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(CmpOpc)).addReg(regX).addImm(imm);
750*9880d681SAndroid Build Coastguard Worker BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(BtOpc)).addMBB(target);
751*9880d681SAndroid Build Coastguard Worker MI.eraseFromParent(); // The pseudo instruction is gone now.
752*9880d681SAndroid Build Coastguard Worker return BB;
753*9880d681SAndroid Build Coastguard Worker }
754*9880d681SAndroid Build Coastguard Worker
Mips16WhichOp8uOr16simm(unsigned shortOp,unsigned longOp,int64_t Imm)755*9880d681SAndroid Build Coastguard Worker static unsigned Mips16WhichOp8uOr16simm
756*9880d681SAndroid Build Coastguard Worker (unsigned shortOp, unsigned longOp, int64_t Imm) {
757*9880d681SAndroid Build Coastguard Worker if (isUInt<8>(Imm))
758*9880d681SAndroid Build Coastguard Worker return shortOp;
759*9880d681SAndroid Build Coastguard Worker else if (isInt<16>(Imm))
760*9880d681SAndroid Build Coastguard Worker return longOp;
761*9880d681SAndroid Build Coastguard Worker else
762*9880d681SAndroid Build Coastguard Worker llvm_unreachable("immediate field not usable");
763*9880d681SAndroid Build Coastguard Worker }
764*9880d681SAndroid Build Coastguard Worker
765*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *
emitFEXT_CCRX16_ins(unsigned SltOpc,MachineInstr & MI,MachineBasicBlock * BB) const766*9880d681SAndroid Build Coastguard Worker Mips16TargetLowering::emitFEXT_CCRX16_ins(unsigned SltOpc, MachineInstr &MI,
767*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *BB) const {
768*9880d681SAndroid Build Coastguard Worker if (DontExpandCondPseudos16)
769*9880d681SAndroid Build Coastguard Worker return BB;
770*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo *TII = Subtarget.getInstrInfo();
771*9880d681SAndroid Build Coastguard Worker unsigned CC = MI.getOperand(0).getReg();
772*9880d681SAndroid Build Coastguard Worker unsigned regX = MI.getOperand(1).getReg();
773*9880d681SAndroid Build Coastguard Worker unsigned regY = MI.getOperand(2).getReg();
774*9880d681SAndroid Build Coastguard Worker BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(SltOpc))
775*9880d681SAndroid Build Coastguard Worker .addReg(regX)
776*9880d681SAndroid Build Coastguard Worker .addReg(regY);
777*9880d681SAndroid Build Coastguard Worker BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(Mips::MoveR3216), CC)
778*9880d681SAndroid Build Coastguard Worker .addReg(Mips::T8);
779*9880d681SAndroid Build Coastguard Worker MI.eraseFromParent(); // The pseudo instruction is gone now.
780*9880d681SAndroid Build Coastguard Worker return BB;
781*9880d681SAndroid Build Coastguard Worker }
782*9880d681SAndroid Build Coastguard Worker
783*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *
emitFEXT_CCRXI16_ins(unsigned SltiOpc,unsigned SltiXOpc,MachineInstr & MI,MachineBasicBlock * BB) const784*9880d681SAndroid Build Coastguard Worker Mips16TargetLowering::emitFEXT_CCRXI16_ins(unsigned SltiOpc, unsigned SltiXOpc,
785*9880d681SAndroid Build Coastguard Worker MachineInstr &MI,
786*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *BB) const {
787*9880d681SAndroid Build Coastguard Worker if (DontExpandCondPseudos16)
788*9880d681SAndroid Build Coastguard Worker return BB;
789*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo *TII = Subtarget.getInstrInfo();
790*9880d681SAndroid Build Coastguard Worker unsigned CC = MI.getOperand(0).getReg();
791*9880d681SAndroid Build Coastguard Worker unsigned regX = MI.getOperand(1).getReg();
792*9880d681SAndroid Build Coastguard Worker int64_t Imm = MI.getOperand(2).getImm();
793*9880d681SAndroid Build Coastguard Worker unsigned SltOpc = Mips16WhichOp8uOr16simm(SltiOpc, SltiXOpc, Imm);
794*9880d681SAndroid Build Coastguard Worker BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(SltOpc)).addReg(regX).addImm(Imm);
795*9880d681SAndroid Build Coastguard Worker BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(Mips::MoveR3216), CC)
796*9880d681SAndroid Build Coastguard Worker .addReg(Mips::T8);
797*9880d681SAndroid Build Coastguard Worker MI.eraseFromParent(); // The pseudo instruction is gone now.
798*9880d681SAndroid Build Coastguard Worker return BB;
799*9880d681SAndroid Build Coastguard Worker
800*9880d681SAndroid Build Coastguard Worker }
801