blob: bd3d08527b7bdf15991c179d2a6cd08781e451b5 [file] [log] [blame]
Reed Kotler720c5ca2014-04-17 22:15:34 +00001//===-- MipsastISel.cpp - Mips FastISel implementation
2//---------------------===//
3
4#include "llvm/CodeGen/FunctionLoweringInfo.h"
5#include "llvm/CodeGen/FastISel.h"
Reed Kotler67077b32014-04-29 17:57:50 +00006#include "llvm/CodeGen/MachineInstrBuilder.h"
Reed Kotlerbab3f232014-05-01 20:39:21 +00007#include "llvm/IR/GlobalAlias.h"
8#include "llvm/IR/GlobalVariable.h"
Reed Kotler67077b32014-04-29 17:57:50 +00009#include "llvm/Target/TargetInstrInfo.h"
Reed Kotler720c5ca2014-04-17 22:15:34 +000010#include "llvm/Target/TargetLibraryInfo.h"
Reed Kotlerbab3f232014-05-01 20:39:21 +000011#include "MipsRegisterInfo.h"
Reed Kotler720c5ca2014-04-17 22:15:34 +000012#include "MipsISelLowering.h"
Reed Kotler67077b32014-04-29 17:57:50 +000013#include "MipsMachineFunction.h"
14#include "MipsSubtarget.h"
Reed Kotler9fe25f32014-06-08 02:08:43 +000015#include "MipsTargetMachine.h"
Reed Kotler720c5ca2014-04-17 22:15:34 +000016
17using namespace llvm;
18
19namespace {
20
Reed Kotlerbab3f232014-05-01 20:39:21 +000021// All possible address modes.
22typedef struct Address {
23 enum { RegBase, FrameIndexBase } BaseType;
24
25 union {
26 unsigned Reg;
27 int FI;
28 } Base;
29
30 int64_t Offset;
31
32 // Innocuous defaults for our address.
33 Address() : BaseType(RegBase), Offset(0) { Base.Reg = 0; }
34} Address;
35
Reed Kotler720c5ca2014-04-17 22:15:34 +000036class MipsFastISel final : public FastISel {
37
Reed Kotler67077b32014-04-29 17:57:50 +000038 /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can
39 /// make the right decision when generating code for different targets.
Reed Kotler67077b32014-04-29 17:57:50 +000040 Module &M;
41 const TargetMachine &TM;
42 const TargetInstrInfo &TII;
43 const TargetLowering &TLI;
Eric Christopher22405e42014-07-10 17:26:51 +000044 const MipsSubtarget *Subtarget;
Reed Kotler67077b32014-04-29 17:57:50 +000045 MipsFunctionInfo *MFI;
46
47 // Convenience variables to avoid some queries.
48 LLVMContext *Context;
49
50 bool TargetSupported;
51
Reed Kotler720c5ca2014-04-17 22:15:34 +000052public:
53 explicit MipsFastISel(FunctionLoweringInfo &funcInfo,
54 const TargetLibraryInfo *libInfo)
Reed Kotler67077b32014-04-29 17:57:50 +000055 : FastISel(funcInfo, libInfo),
56 M(const_cast<Module &>(*funcInfo.Fn->getParent())),
Eric Christopherd9134482014-08-04 21:25:23 +000057 TM(funcInfo.MF->getTarget()),
58 TII(*TM.getSubtargetImpl()->getInstrInfo()),
59 TLI(*TM.getSubtargetImpl()->getTargetLowering()),
Eric Christopher22405e42014-07-10 17:26:51 +000060 Subtarget(&TM.getSubtarget<MipsSubtarget>()) {
Reed Kotler67077b32014-04-29 17:57:50 +000061 MFI = funcInfo.MF->getInfo<MipsFunctionInfo>();
62 Context = &funcInfo.Fn->getContext();
Eric Christopher22405e42014-07-10 17:26:51 +000063 TargetSupported = ((Subtarget->getRelocationModel() == Reloc::PIC_) &&
Reed Kotler32be74b2014-09-15 20:30:25 +000064 ((Subtarget->hasMips32r2() || Subtarget->hasMips32()) &&
65 (Subtarget->isABI_O32())));
Reed Kotler67077b32014-04-29 17:57:50 +000066 }
67
Juergen Ributzka5b8bb4d2014-09-03 20:56:52 +000068 bool fastSelectInstruction(const Instruction *I) override;
69 unsigned fastMaterializeConstant(const Constant *C) override;
Reed Kotler67077b32014-04-29 17:57:50 +000070
Reed Kotlerbab3f232014-05-01 20:39:21 +000071 bool ComputeAddress(const Value *Obj, Address &Addr);
72
73private:
Reed Kotler9fe3bfd2014-06-16 22:05:47 +000074 bool EmitLoad(MVT VT, unsigned &ResultReg, Address &Addr,
75 unsigned Alignment = 0);
Reed Kotlerbab3f232014-05-01 20:39:21 +000076 bool EmitStore(MVT VT, unsigned SrcReg, Address &Addr,
77 unsigned Alignment = 0);
Reed Kotler9fe3bfd2014-06-16 22:05:47 +000078 bool SelectLoad(const Instruction *I);
Reed Kotler67077b32014-04-29 17:57:50 +000079 bool SelectRet(const Instruction *I);
Reed Kotlerbab3f232014-05-01 20:39:21 +000080 bool SelectStore(const Instruction *I);
Reed Kotler3ebdcc92014-09-30 16:30:13 +000081 bool SelectIntExt(const Instruction *I);
82 bool SelectTrunc(const Instruction *I);
83 bool SelectFPExt(const Instruction *I);
Reed Kotlerbab3f232014-05-01 20:39:21 +000084
85 bool isTypeLegal(Type *Ty, MVT &VT);
86 bool isLoadTypeLegal(Type *Ty, MVT &VT);
87
88 unsigned MaterializeFP(const ConstantFP *CFP, MVT VT);
89 unsigned MaterializeGV(const GlobalValue *GV, MVT VT);
90 unsigned MaterializeInt(const Constant *C, MVT VT);
Reed Kotler6280d972014-05-15 21:54:15 +000091 unsigned Materialize32BitInt(int64_t Imm, const TargetRegisterClass *RC);
Reed Kotler9fe25f32014-06-08 02:08:43 +000092
Reed Kotler3ebdcc92014-09-30 16:30:13 +000093 bool EmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg,
94 bool IsZExt);
95
96 bool EmitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg);
97
98 bool EmitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg);
99 bool EmitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT,
100 unsigned DestReg);
101 bool EmitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT,
102 unsigned DestReg);
Reed Kotler9fe25f32014-06-08 02:08:43 +0000103 // for some reason, this default is not generated by tablegen
Reed Kotlerfb77bc92014-06-08 03:04:42 +0000104 // so we explicitly generate it here.
Reed Kotler9fe25f32014-06-08 02:08:43 +0000105 //
Juergen Ributzka88e32512014-09-03 20:56:59 +0000106 unsigned fastEmitInst_riir(uint64_t inst, const TargetRegisterClass *RC,
Reed Kotler9fe25f32014-06-08 02:08:43 +0000107 unsigned Op0, bool Op0IsKill, uint64_t imm1,
108 uint64_t imm2, unsigned Op3, bool Op3IsKill) {
109 return 0;
110 }
111
Reed Kotlerfb77bc92014-06-08 03:04:42 +0000112 MachineInstrBuilder EmitInst(unsigned Opc) {
113 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc));
114 }
115
116 MachineInstrBuilder EmitInst(unsigned Opc, unsigned DstReg) {
117 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc),
118 DstReg);
119 }
120
121 MachineInstrBuilder EmitInstStore(unsigned Opc, unsigned SrcReg,
122 unsigned MemReg, int64_t MemOffset) {
123 return EmitInst(Opc).addReg(SrcReg).addReg(MemReg).addImm(MemOffset);
124 }
125
Reed Kotler9fe3bfd2014-06-16 22:05:47 +0000126 MachineInstrBuilder EmitInstLoad(unsigned Opc, unsigned DstReg,
Reed Kotler87048a42014-08-07 22:09:01 +0000127 unsigned MemReg, int64_t MemOffset) {
Reed Kotler9fe3bfd2014-06-16 22:05:47 +0000128 return EmitInst(Opc, DstReg).addReg(MemReg).addImm(MemOffset);
129 }
130
Reed Kotler9fe25f32014-06-08 02:08:43 +0000131#include "MipsGenFastISel.inc"
Reed Kotler720c5ca2014-04-17 22:15:34 +0000132};
Reed Kotler67077b32014-04-29 17:57:50 +0000133
Reed Kotlerbab3f232014-05-01 20:39:21 +0000134bool MipsFastISel::isTypeLegal(Type *Ty, MVT &VT) {
135 EVT evt = TLI.getValueType(Ty, true);
136 // Only handle simple types.
137 if (evt == MVT::Other || !evt.isSimple())
138 return false;
139 VT = evt.getSimpleVT();
140
141 // Handle all legal types, i.e. a register that will directly hold this
142 // value.
143 return TLI.isTypeLegal(VT);
144}
145
146bool MipsFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) {
147 if (isTypeLegal(Ty, VT))
148 return true;
149 // We will extend this in a later patch:
150 // If this is a type than can be sign or zero-extended to a basic operation
151 // go ahead and accept it now.
Reed Kotler9fe3bfd2014-06-16 22:05:47 +0000152 if (VT == MVT::i8 || VT == MVT::i16)
153 return true;
Reed Kotlerbab3f232014-05-01 20:39:21 +0000154 return false;
155}
156
157bool MipsFastISel::ComputeAddress(const Value *Obj, Address &Addr) {
158 // This construct looks a big awkward but it is how other ports handle this
159 // and as this function is more fully completed, these cases which
160 // return false will have additional code in them.
161 //
162 if (isa<Instruction>(Obj))
163 return false;
164 else if (isa<ConstantExpr>(Obj))
165 return false;
166 Addr.Base.Reg = getRegForValue(Obj);
167 return Addr.Base.Reg != 0;
168}
169
Reed Kotler9fe3bfd2014-06-16 22:05:47 +0000170bool MipsFastISel::EmitLoad(MVT VT, unsigned &ResultReg, Address &Addr,
171 unsigned Alignment) {
172 //
173 // more cases will be handled here in following patches.
174 //
175 unsigned Opc;
176 switch (VT.SimpleTy) {
177 case MVT::i32: {
178 ResultReg = createResultReg(&Mips::GPR32RegClass);
179 Opc = Mips::LW;
180 break;
181 }
182 case MVT::i16: {
183 ResultReg = createResultReg(&Mips::GPR32RegClass);
184 Opc = Mips::LHu;
185 break;
186 }
187 case MVT::i8: {
188 ResultReg = createResultReg(&Mips::GPR32RegClass);
189 Opc = Mips::LBu;
190 break;
191 }
192 case MVT::f32: {
193 ResultReg = createResultReg(&Mips::FGR32RegClass);
194 Opc = Mips::LWC1;
195 break;
196 }
197 case MVT::f64: {
198 ResultReg = createResultReg(&Mips::AFGR64RegClass);
199 Opc = Mips::LDC1;
200 break;
201 }
202 default:
203 return false;
204 }
205 EmitInstLoad(Opc, ResultReg, Addr.Base.Reg, Addr.Offset);
206 return true;
207}
208
Reed Kotlerbab3f232014-05-01 20:39:21 +0000209// Materialize a constant into a register, and return the register
210// number (or zero if we failed to handle it).
Juergen Ributzka5b8bb4d2014-09-03 20:56:52 +0000211unsigned MipsFastISel::fastMaterializeConstant(const Constant *C) {
Reed Kotlerbab3f232014-05-01 20:39:21 +0000212 EVT CEVT = TLI.getValueType(C->getType(), true);
213
214 // Only handle simple types.
215 if (!CEVT.isSimple())
216 return 0;
217 MVT VT = CEVT.getSimpleVT();
218
219 if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
220 return MaterializeFP(CFP, VT);
221 else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
222 return MaterializeGV(GV, VT);
223 else if (isa<ConstantInt>(C))
224 return MaterializeInt(C, VT);
225
226 return 0;
227}
228
229bool MipsFastISel::EmitStore(MVT VT, unsigned SrcReg, Address &Addr,
230 unsigned Alignment) {
231 //
232 // more cases will be handled here in following patches.
233 //
Reed Kotler9fe3bfd2014-06-16 22:05:47 +0000234 unsigned Opc;
235 switch (VT.SimpleTy) {
236 case MVT::i8:
237 Opc = Mips::SB;
238 break;
239 case MVT::i16:
240 Opc = Mips::SH;
241 break;
242 case MVT::i32:
243 Opc = Mips::SW;
244 break;
245 case MVT::f32:
246 Opc = Mips::SWC1;
247 break;
248 case MVT::f64:
249 Opc = Mips::SDC1;
250 break;
251 default:
Reed Kotlerbab3f232014-05-01 20:39:21 +0000252 return false;
Reed Kotler9fe3bfd2014-06-16 22:05:47 +0000253 }
254 EmitInstStore(Opc, SrcReg, Addr.Base.Reg, Addr.Offset);
255 return true;
256}
257
Reed Kotler3ebdcc92014-09-30 16:30:13 +0000258bool MipsFastISel::EmitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT,
259 unsigned DestReg) {
260 unsigned ShiftAmt;
261 switch (SrcVT.SimpleTy) {
262 default:
263 return false;
264 case MVT::i8:
265 ShiftAmt = 24;
266 break;
267 case MVT::i16:
268 ShiftAmt = 16;
269 break;
270 }
271 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
272 EmitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt);
273 EmitInst(Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt);
274 return true;
275}
276
277bool MipsFastISel::EmitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT,
278 unsigned DestReg) {
279 switch (SrcVT.SimpleTy) {
280 default:
281 return false;
282 case MVT::i8:
283 EmitInst(Mips::SEB, DestReg).addReg(SrcReg);
284 break;
285 case MVT::i16:
286 EmitInst(Mips::SEH, DestReg).addReg(SrcReg);
287 break;
288 }
289 return true;
290}
291
292bool MipsFastISel::EmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
293 unsigned DestReg, bool IsZExt) {
294 if (IsZExt)
295 return EmitIntZExt(SrcVT, SrcReg, DestVT, DestReg);
296 return EmitIntSExt(SrcVT, SrcReg, DestVT, DestReg);
297}
298
299bool MipsFastISel::EmitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
300 unsigned DestReg) {
301 if ((DestVT != MVT::i32) && (DestVT != MVT::i16))
302 return false;
303 if (Subtarget->hasMips32r2())
304 return EmitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg);
305 return EmitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg);
306}
307
308bool MipsFastISel::EmitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
309 unsigned DestReg) {
310 switch (SrcVT.SimpleTy) {
311 default:
312 return false;
313 case MVT::i1:
314 EmitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(1);
315 break;
316 case MVT::i8:
317 EmitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(0xff);
318 break;
319 case MVT::i16:
320 EmitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(0xffff);
321 break;
322 }
323 return true;
324}
325
Reed Kotler9fe3bfd2014-06-16 22:05:47 +0000326bool MipsFastISel::SelectLoad(const Instruction *I) {
327 // Atomic loads need special handling.
328 if (cast<LoadInst>(I)->isAtomic())
329 return false;
330
331 // Verify we have a legal type before going any further.
332 MVT VT;
333 if (!isLoadTypeLegal(I->getType(), VT))
334 return false;
335
336 // See if we can handle this address.
337 Address Addr;
338 if (!ComputeAddress(I->getOperand(0), Addr))
339 return false;
340
341 unsigned ResultReg;
342 if (!EmitLoad(VT, ResultReg, Addr, cast<LoadInst>(I)->getAlignment()))
343 return false;
Juergen Ributzka5b8bb4d2014-09-03 20:56:52 +0000344 updateValueMap(I, ResultReg);
Reed Kotlerbab3f232014-05-01 20:39:21 +0000345 return true;
346}
347
348bool MipsFastISel::SelectStore(const Instruction *I) {
349 Value *Op0 = I->getOperand(0);
350 unsigned SrcReg = 0;
351
352 // Atomic stores need special handling.
353 if (cast<StoreInst>(I)->isAtomic())
354 return false;
355
356 // Verify we have a legal type before going any further.
357 MVT VT;
358 if (!isLoadTypeLegal(I->getOperand(0)->getType(), VT))
359 return false;
360
361 // Get the value to be stored into a register.
362 SrcReg = getRegForValue(Op0);
363 if (SrcReg == 0)
364 return false;
365
366 // See if we can handle this address.
367 Address Addr;
368 if (!ComputeAddress(I->getOperand(1), Addr))
369 return false;
370
371 if (!EmitStore(VT, SrcReg, Addr, cast<StoreInst>(I)->getAlignment()))
372 return false;
373 return true;
374}
375
Reed Kotler67077b32014-04-29 17:57:50 +0000376bool MipsFastISel::SelectRet(const Instruction *I) {
377 const ReturnInst *Ret = cast<ReturnInst>(I);
378
379 if (!FuncInfo.CanLowerReturn)
380 return false;
381 if (Ret->getNumOperands() > 0) {
382 return false;
383 }
Reed Kotlerfb77bc92014-06-08 03:04:42 +0000384 EmitInst(Mips::RetRA);
Reed Kotler67077b32014-04-29 17:57:50 +0000385 return true;
386}
387
Reed Kotler3ebdcc92014-09-30 16:30:13 +0000388// Attempt to fast-select a floating-point extend instruction.
389bool MipsFastISel::SelectFPExt(const Instruction *I) {
390 Value *Src = I->getOperand(0);
391 EVT SrcVT = TLI.getValueType(Src->getType(), true);
392 EVT DestVT = TLI.getValueType(I->getType(), true);
393
394 if (SrcVT != MVT::f32 || DestVT != MVT::f64)
395 return false;
396
397 unsigned SrcReg =
398 getRegForValue(Src); // his must be a 32 bit floating point register class
399 // maybe we should handle this differently
400 if (!SrcReg)
401 return false;
402
403 unsigned DestReg = createResultReg(&Mips::AFGR64RegClass);
404 EmitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg);
405 updateValueMap(I, DestReg);
406 return true;
407}
408
409bool MipsFastISel::SelectIntExt(const Instruction *I) {
410 Type *DestTy = I->getType();
411 Value *Src = I->getOperand(0);
412 Type *SrcTy = Src->getType();
413
414 bool isZExt = isa<ZExtInst>(I);
415 unsigned SrcReg = getRegForValue(Src);
416 if (!SrcReg)
417 return false;
418
419 EVT SrcEVT, DestEVT;
420 SrcEVT = TLI.getValueType(SrcTy, true);
421 DestEVT = TLI.getValueType(DestTy, true);
422 if (!SrcEVT.isSimple())
423 return false;
424 if (!DestEVT.isSimple())
425 return false;
426
427 MVT SrcVT = SrcEVT.getSimpleVT();
428 MVT DestVT = DestEVT.getSimpleVT();
429 unsigned ResultReg = createResultReg(&Mips::GPR32RegClass);
430
431 if (!EmitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt))
432 return false;
433 updateValueMap(I, ResultReg);
434 return true;
435}
436
437bool MipsFastISel::SelectTrunc(const Instruction *I) {
438 // The high bits for a type smaller than the register size are assumed to be
439 // undefined.
440 Value *Op = I->getOperand(0);
441
442 EVT SrcVT, DestVT;
443 SrcVT = TLI.getValueType(Op->getType(), true);
444 DestVT = TLI.getValueType(I->getType(), true);
445
446 if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)
447 return false;
448 if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)
449 return false;
450
451 unsigned SrcReg = getRegForValue(Op);
452 if (!SrcReg)
453 return false;
454
455 // Because the high bits are undefined, a truncate doesn't generate
456 // any code.
457 updateValueMap(I, SrcReg);
458 return true;
459}
460
Juergen Ributzka5b8bb4d2014-09-03 20:56:52 +0000461bool MipsFastISel::fastSelectInstruction(const Instruction *I) {
Reed Kotler67077b32014-04-29 17:57:50 +0000462 if (!TargetSupported)
463 return false;
464 switch (I->getOpcode()) {
465 default:
466 break;
Reed Kotler9fe3bfd2014-06-16 22:05:47 +0000467 case Instruction::Load:
468 return SelectLoad(I);
Reed Kotlerbab3f232014-05-01 20:39:21 +0000469 case Instruction::Store:
470 return SelectStore(I);
Reed Kotler67077b32014-04-29 17:57:50 +0000471 case Instruction::Ret:
472 return SelectRet(I);
Reed Kotler3ebdcc92014-09-30 16:30:13 +0000473 case Instruction::Trunc:
474 return SelectTrunc(I);
475 case Instruction::ZExt:
476 case Instruction::SExt:
477 return SelectIntExt(I);
478 case Instruction::FPExt:
479 return SelectFPExt(I);
Reed Kotler67077b32014-04-29 17:57:50 +0000480 }
481 return false;
482}
Reed Kotler720c5ca2014-04-17 22:15:34 +0000483
Reed Kotlerbab3f232014-05-01 20:39:21 +0000484unsigned MipsFastISel::MaterializeFP(const ConstantFP *CFP, MVT VT) {
Reed Kotler063d4fb2014-06-10 16:45:44 +0000485 int64_t Imm = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
486 if (VT == MVT::f32) {
487 const TargetRegisterClass *RC = &Mips::FGR32RegClass;
488 unsigned DestReg = createResultReg(RC);
489 unsigned TempReg = Materialize32BitInt(Imm, &Mips::GPR32RegClass);
490 EmitInst(Mips::MTC1, DestReg).addReg(TempReg);
491 return DestReg;
492 } else if (VT == MVT::f64) {
493 const TargetRegisterClass *RC = &Mips::AFGR64RegClass;
494 unsigned DestReg = createResultReg(RC);
495 unsigned TempReg1 = Materialize32BitInt(Imm >> 32, &Mips::GPR32RegClass);
496 unsigned TempReg2 =
497 Materialize32BitInt(Imm & 0xFFFFFFFF, &Mips::GPR32RegClass);
498 EmitInst(Mips::BuildPairF64, DestReg).addReg(TempReg2).addReg(TempReg1);
499 return DestReg;
500 }
Reed Kotlerbab3f232014-05-01 20:39:21 +0000501 return 0;
502}
503
504unsigned MipsFastISel::MaterializeGV(const GlobalValue *GV, MVT VT) {
505 // For now 32-bit only.
506 if (VT != MVT::i32)
507 return 0;
508 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
509 unsigned DestReg = createResultReg(RC);
510 const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
511 bool IsThreadLocal = GVar && GVar->isThreadLocal();
512 // TLS not supported at this time.
513 if (IsThreadLocal)
514 return 0;
Reed Kotler3ebdcc92014-09-30 16:30:13 +0000515 EmitInst(Mips::LW, DestReg)
516 .addReg(MFI->getGlobalBaseReg())
517 .addGlobalAddress(GV, 0, MipsII::MO_GOT);
Reed Kotler87048a42014-08-07 22:09:01 +0000518 if ((GV->hasInternalLinkage() ||
519 (GV->hasLocalLinkage() && !isa<Function>(GV)))) {
520 unsigned TempReg = createResultReg(RC);
Reed Kotler3ebdcc92014-09-30 16:30:13 +0000521 EmitInst(Mips::ADDiu, TempReg)
522 .addReg(DestReg)
523 .addGlobalAddress(GV, 0, MipsII::MO_ABS_LO);
Reed Kotler87048a42014-08-07 22:09:01 +0000524 DestReg = TempReg;
525 }
Reed Kotlerbab3f232014-05-01 20:39:21 +0000526 return DestReg;
527}
Reed Kotler87048a42014-08-07 22:09:01 +0000528
Reed Kotlerbab3f232014-05-01 20:39:21 +0000529unsigned MipsFastISel::MaterializeInt(const Constant *C, MVT VT) {
Reed Kotler6280d972014-05-15 21:54:15 +0000530 if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1)
Reed Kotlerbab3f232014-05-01 20:39:21 +0000531 return 0;
532 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
Reed Kotlerbab3f232014-05-01 20:39:21 +0000533 const ConstantInt *CI = cast<ConstantInt>(C);
Reed Kotler6280d972014-05-15 21:54:15 +0000534 int64_t Imm;
Reed Kotler87048a42014-08-07 22:09:01 +0000535 if ((VT != MVT::i1) && CI->isNegative())
Reed Kotler6280d972014-05-15 21:54:15 +0000536 Imm = CI->getSExtValue();
537 else
538 Imm = CI->getZExtValue();
539 return Materialize32BitInt(Imm, RC);
540}
541
542unsigned MipsFastISel::Materialize32BitInt(int64_t Imm,
543 const TargetRegisterClass *RC) {
544 unsigned ResultReg = createResultReg(RC);
545
546 if (isInt<16>(Imm)) {
Reed Kotlerbab3f232014-05-01 20:39:21 +0000547 unsigned Opc = Mips::ADDiu;
Reed Kotlerfb77bc92014-06-08 03:04:42 +0000548 EmitInst(Opc, ResultReg).addReg(Mips::ZERO).addImm(Imm);
Reed Kotler6280d972014-05-15 21:54:15 +0000549 return ResultReg;
550 } else if (isUInt<16>(Imm)) {
Reed Kotlerfb77bc92014-06-08 03:04:42 +0000551 EmitInst(Mips::ORi, ResultReg).addReg(Mips::ZERO).addImm(Imm);
Reed Kotler6280d972014-05-15 21:54:15 +0000552 return ResultReg;
Reed Kotlerbab3f232014-05-01 20:39:21 +0000553 }
Reed Kotler6280d972014-05-15 21:54:15 +0000554 unsigned Lo = Imm & 0xFFFF;
555 unsigned Hi = (Imm >> 16) & 0xFFFF;
556 if (Lo) {
557 // Both Lo and Hi have nonzero bits.
558 unsigned TmpReg = createResultReg(RC);
Reed Kotlerfb77bc92014-06-08 03:04:42 +0000559 EmitInst(Mips::LUi, TmpReg).addImm(Hi);
560 EmitInst(Mips::ORi, ResultReg).addReg(TmpReg).addImm(Lo);
Reed Kotler6280d972014-05-15 21:54:15 +0000561 } else {
Reed Kotlerfb77bc92014-06-08 03:04:42 +0000562 EmitInst(Mips::LUi, ResultReg).addImm(Hi);
Reed Kotler6280d972014-05-15 21:54:15 +0000563 }
564 return ResultReg;
Reed Kotlerbab3f232014-05-01 20:39:21 +0000565}
Reed Kotler3ebdcc92014-09-30 16:30:13 +0000566}
Reed Kotlerbab3f232014-05-01 20:39:21 +0000567
Reed Kotler720c5ca2014-04-17 22:15:34 +0000568namespace llvm {
569FastISel *Mips::createFastISel(FunctionLoweringInfo &funcInfo,
570 const TargetLibraryInfo *libInfo) {
571 return new MipsFastISel(funcInfo, libInfo);
572}
573}