LLVM 24.0.0git
MipsFastISel.cpp
Go to the documentation of this file.
1//===- MipsFastISel.cpp - Mips FastISel implementation --------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file defines the MIPS-specific support for the FastISel class.
11/// Some of the target-specific code is generated by tablegen in the file
12/// MipsGenFastISel.inc, which is #included here.
13///
14//===----------------------------------------------------------------------===//
15
18#include "MipsCCState.h"
19#include "MipsISelLowering.h"
20#include "MipsInstrInfo.h"
21#include "MipsMachineFunction.h"
22#include "MipsSubtarget.h"
23#include "llvm/ADT/APInt.h"
24#include "llvm/ADT/DenseMap.h"
40#include "llvm/IR/Attributes.h"
41#include "llvm/IR/CallingConv.h"
42#include "llvm/IR/Constant.h"
43#include "llvm/IR/Constants.h"
44#include "llvm/IR/DataLayout.h"
45#include "llvm/IR/Function.h"
47#include "llvm/IR/GlobalValue.h"
49#include "llvm/IR/InstrTypes.h"
50#include "llvm/IR/Instruction.h"
53#include "llvm/IR/Operator.h"
54#include "llvm/IR/Type.h"
55#include "llvm/IR/User.h"
56#include "llvm/IR/Value.h"
57#include "llvm/MC/MCContext.h"
58#include "llvm/MC/MCInstrDesc.h"
59#include "llvm/MC/MCSymbol.h"
62#include "llvm/Support/Debug.h"
66#include <algorithm>
67#include <array>
68#include <cassert>
69#include <cstdint>
70
71#define DEBUG_TYPE "mips-fastisel"
72
73using namespace llvm;
74
75namespace {
76
77class MipsFastISel final : public FastISel {
78
79 // All possible address modes.
80 class Address {
81 public:
82 enum BaseKind { RegBase, FrameIndexBase };
83
84 private:
85 BaseKind Kind = RegBase;
86 union {
87 unsigned Reg;
88 int FI;
89 } Base;
90
91 int64_t Offset = 0;
92
93 const GlobalValue *GV = nullptr;
94
95 public:
96 // Innocuous defaults for our address.
97 Address() { Base.Reg = 0; }
98
99 void setKind(BaseKind K) { Kind = K; }
100 BaseKind getKind() const { return Kind; }
101 bool isRegBase() const { return Kind == RegBase; }
102 bool isFIBase() const { return Kind == FrameIndexBase; }
103
104 void setReg(unsigned Reg) {
105 assert(isRegBase() && "Invalid base register access!");
106 Base.Reg = Reg;
107 }
108
109 unsigned getReg() const {
110 assert(isRegBase() && "Invalid base register access!");
111 return Base.Reg;
112 }
113
114 void setFI(unsigned FI) {
115 assert(isFIBase() && "Invalid base frame index access!");
116 Base.FI = FI;
117 }
118
119 unsigned getFI() const {
120 assert(isFIBase() && "Invalid base frame index access!");
121 return Base.FI;
122 }
123
124 void setOffset(int64_t Offset_) { Offset = Offset_; }
125 int64_t getOffset() const { return Offset; }
126 void setGlobalValue(const GlobalValue *G) { GV = G; }
127 const GlobalValue *getGlobalValue() { return GV; }
128 };
129
130 /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can
131 /// make the right decision when generating code for different targets.
132 const TargetMachine &TM;
133 const MipsSubtarget *Subtarget;
134 const TargetInstrInfo &TII;
135 const TargetLowering &TLI;
136 MipsFunctionInfo *MFI;
137
138 // Convenience variables to avoid some queries.
139 LLVMContext *Context;
140
141 bool fastLowerArguments() override;
142 bool fastLowerCall(CallLoweringInfo &CLI) override;
143 bool fastLowerIntrinsicCall(const IntrinsicInst *II) override;
144
145 bool UnsupportedFPMode; // To allow fast-isel to proceed and just not handle
146 // floating point but not reject doing fast-isel in other
147 // situations
148
149private:
150 // Selection routines.
151 bool selectLogicalOp(const Instruction *I);
152 bool selectLoad(const Instruction *I);
153 bool selectStore(const Instruction *I);
154 bool selectBranch(const Instruction *I);
155 bool selectSelect(const Instruction *I);
156 bool selectCmp(const Instruction *I);
157 bool selectFPExt(const Instruction *I);
158 bool selectFPTrunc(const Instruction *I);
159 bool selectFPToInt(const Instruction *I, bool IsSigned);
160 bool selectRet(const Instruction *I);
161 bool selectTrunc(const Instruction *I);
162 bool selectIntExt(const Instruction *I);
163 bool selectShift(const Instruction *I);
164 bool selectDivRem(const Instruction *I, unsigned ISDOpcode);
165
166 // Utility helper routines.
167 bool isTypeLegal(Type *Ty, MVT &VT);
168 bool isTypeSupported(Type *Ty, MVT &VT);
169 bool isLoadTypeLegal(Type *Ty, MVT &VT);
170 bool computeAddress(const Value *Obj, Address &Addr);
171 bool computeCallAddress(const Value *V, Address &Addr);
172 void simplifyAddress(Address &Addr);
173
174 // Emit helper routines.
175 bool emitCmp(unsigned DestReg, const CmpInst *CI);
176 bool emitLoad(MVT VT, unsigned &ResultReg, Address &Addr);
177 bool emitStore(MVT VT, unsigned SrcReg, Address &Addr);
178 unsigned emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, bool isZExt);
179 bool emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg,
180
181 bool IsZExt);
182 bool emitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg);
183
184 bool emitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg);
185 bool emitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT,
186 unsigned DestReg);
187 bool emitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT,
188 unsigned DestReg);
189
190 unsigned getRegEnsuringSimpleIntegerWidening(const Value *, bool IsUnsigned);
191
192 unsigned emitLogicalOp(unsigned ISDOpc, MVT RetVT, const Value *LHS,
193 const Value *RHS);
194
195 unsigned materializeFP(const ConstantFP *CFP, MVT VT);
196 unsigned materializeGV(const GlobalValue *GV, MVT VT);
197 unsigned materializeInt(const Constant *C, MVT VT);
198 unsigned materialize32BitInt(int64_t Imm, const TargetRegisterClass *RC);
199 unsigned materializeExternalCallSym(MCSymbol *Syn);
200
201 MachineInstrBuilder emitInst(unsigned Opc) {
202 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc));
203 }
204
205 MachineInstrBuilder emitInst(unsigned Opc, unsigned DstReg) {
206 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc),
207 DstReg);
208 }
209
210 MachineInstrBuilder emitInstStore(unsigned Opc, unsigned SrcReg,
211 unsigned MemReg, int64_t MemOffset) {
212 return emitInst(Opc).addReg(SrcReg).addReg(MemReg).addImm(MemOffset);
213 }
214
215 MachineInstrBuilder emitInstLoad(unsigned Opc, unsigned DstReg,
216 unsigned MemReg, int64_t MemOffset) {
217 return emitInst(Opc, DstReg).addReg(MemReg).addImm(MemOffset);
218 }
219
220 unsigned fastEmitInst_rr(unsigned MachineInstOpcode,
221 const TargetRegisterClass *RC,
222 unsigned Op0, unsigned Op1);
223
224 // for some reason, this default is not generated by tablegen
225 // so we explicitly generate it here.
226 unsigned fastEmitInst_riir(uint64_t inst, const TargetRegisterClass *RC,
227 unsigned Op0, uint64_t imm1, uint64_t imm2,
228 unsigned Op3) {
229 return 0;
230 }
231
232 // Call handling routines.
233private:
234 CCAssignFn *CCAssignFnForCall(CallingConv::ID CC) const;
235 bool processCallArgs(CallLoweringInfo &CLI, SmallVectorImpl<MVT> &ArgVTs,
236 unsigned &NumBytes);
237 bool finishCall(CallLoweringInfo &CLI, MVT RetVT, unsigned NumBytes);
238
239 const MipsABIInfo &getABI() const { return Subtarget->getABI(); }
240
241public:
242 // Backend specific FastISel code.
243 explicit MipsFastISel(FunctionLoweringInfo &funcInfo,
244 const TargetLibraryInfo *libInfo,
245 const LibcallLoweringInfo *libcallLowering)
246 : FastISel(funcInfo, libInfo, libcallLowering),
247 TM(funcInfo.MF->getTarget()),
248 Subtarget(&funcInfo.MF->getSubtarget<MipsSubtarget>()),
249 TII(*Subtarget->getInstrInfo()), TLI(*Subtarget->getTargetLowering()) {
250 MFI = funcInfo.MF->getInfo<MipsFunctionInfo>();
251 Context = &funcInfo.Fn->getContext();
252 UnsupportedFPMode = Subtarget->isFP64bit() || Subtarget->useSoftFloat();
253 }
254
255 Register fastMaterializeAlloca(const AllocaInst *AI) override;
256 Register fastMaterializeConstant(const Constant *C) override;
257 bool fastSelectInstruction(const Instruction *I) override;
258
259#include "MipsGenFastISel.inc"
260};
261
262} // end anonymous namespace
263
264[[maybe_unused]] static bool CC_Mips(unsigned ValNo, MVT ValVT, MVT LocVT,
265 CCValAssign::LocInfo LocInfo,
266 ISD::ArgFlagsTy ArgFlags, Type *OrigTy,
267 CCState &State);
268
269static bool CC_MipsO32_FP32(unsigned ValNo, MVT ValVT, MVT LocVT,
270 CCValAssign::LocInfo LocInfo,
271 ISD::ArgFlagsTy ArgFlags, Type *OrigTy,
272 CCState &State) {
273 llvm_unreachable("should not be called");
274}
275
276static bool CC_MipsO32_FP64(unsigned ValNo, MVT ValVT, MVT LocVT,
277 CCValAssign::LocInfo LocInfo,
278 ISD::ArgFlagsTy ArgFlags, Type *OrigTy,
279 CCState &State) {
280 llvm_unreachable("should not be called");
281}
282
283#define GET_CALLING_CONV_IMPL
284#include "MipsGenCallingConv.inc"
285
286CCAssignFn *MipsFastISel::CCAssignFnForCall(CallingConv::ID CC) const {
287 return CC_MipsO32;
288}
289
290unsigned MipsFastISel::emitLogicalOp(unsigned ISDOpc, MVT RetVT,
291 const Value *LHS, const Value *RHS) {
292 // Canonicalize immediates to the RHS first.
294 std::swap(LHS, RHS);
295
296 unsigned Opc;
297 switch (ISDOpc) {
298 case ISD::AND:
299 Opc = Mips::AND;
300 break;
301 case ISD::OR:
302 Opc = Mips::OR;
303 break;
304 case ISD::XOR:
305 Opc = Mips::XOR;
306 break;
307 default:
308 llvm_unreachable("unexpected opcode");
309 }
310
311 Register LHSReg = getRegForValue(LHS);
312 if (!LHSReg)
313 return 0;
314
315 unsigned RHSReg;
316 if (const auto *C = dyn_cast<ConstantInt>(RHS))
317 RHSReg = materializeInt(C, MVT::i32);
318 else
319 RHSReg = getRegForValue(RHS);
320 if (!RHSReg)
321 return 0;
322
323 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
324 if (!ResultReg)
325 return 0;
326
327 emitInst(Opc, ResultReg).addReg(LHSReg).addReg(RHSReg);
328 return ResultReg;
329}
330
331Register MipsFastISel::fastMaterializeAlloca(const AllocaInst *AI) {
332 assert(TLI.getValueType(DL, AI->getType(), true) == MVT::i32 &&
333 "Alloca should always return a pointer.");
334
335 auto SI = FuncInfo.StaticAllocaMap.find(AI);
336
337 if (SI != FuncInfo.StaticAllocaMap.end()) {
338 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
339 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Mips::LEA_ADDiu),
340 ResultReg)
341 .addFrameIndex(SI->second)
342 .addImm(0);
343 return ResultReg;
344 }
345
346 return Register();
347}
348
349unsigned MipsFastISel::materializeInt(const Constant *C, MVT VT) {
350 if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1)
351 return 0;
352 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
353 const ConstantInt *CI = cast<ConstantInt>(C);
354 return materialize32BitInt(CI->getZExtValue(), RC);
355}
356
357unsigned MipsFastISel::materialize32BitInt(int64_t Imm,
358 const TargetRegisterClass *RC) {
359 Register ResultReg = createResultReg(RC);
360
361 if (isInt<16>(Imm)) {
362 unsigned Opc = Mips::ADDiu;
363 emitInst(Opc, ResultReg).addReg(Mips::ZERO).addImm(Imm);
364 return ResultReg;
365 } else if (isUInt<16>(Imm)) {
366 emitInst(Mips::ORi, ResultReg).addReg(Mips::ZERO).addImm(Imm);
367 return ResultReg;
368 }
369 unsigned Lo = Imm & 0xFFFF;
370 unsigned Hi = (Imm >> 16) & 0xFFFF;
371 if (Lo) {
372 // Both Lo and Hi have nonzero bits.
373 Register TmpReg = createResultReg(RC);
374 emitInst(Mips::LUi, TmpReg).addImm(Hi);
375 emitInst(Mips::ORi, ResultReg).addReg(TmpReg).addImm(Lo);
376 } else {
377 emitInst(Mips::LUi, ResultReg).addImm(Hi);
378 }
379 return ResultReg;
380}
381
382unsigned MipsFastISel::materializeFP(const ConstantFP *CFP, MVT VT) {
383 if (UnsupportedFPMode)
384 return 0;
385 int64_t Imm = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
386 if (VT == MVT::f32) {
387 const TargetRegisterClass *RC = &Mips::FGR32RegClass;
388 Register DestReg = createResultReg(RC);
389 unsigned TempReg = materialize32BitInt(Imm, &Mips::GPR32RegClass);
390 emitInst(Mips::MTC1, DestReg).addReg(TempReg);
391 return DestReg;
392 } else if (VT == MVT::f64) {
393 const TargetRegisterClass *RC = &Mips::AFGR64RegClass;
394 Register DestReg = createResultReg(RC);
395 unsigned TempReg1 = materialize32BitInt(Imm >> 32, &Mips::GPR32RegClass);
396 unsigned TempReg2 =
397 materialize32BitInt(Imm & 0xFFFFFFFF, &Mips::GPR32RegClass);
398 emitInst(Mips::BuildPairF64, DestReg).addReg(TempReg2).addReg(TempReg1);
399 return DestReg;
400 }
401 return 0;
402}
403
404unsigned MipsFastISel::materializeGV(const GlobalValue *GV, MVT VT) {
405 // For now 32-bit only.
406 if (VT != MVT::i32)
407 return 0;
408 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
409 Register DestReg = createResultReg(RC);
410 const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
411 bool IsThreadLocal = GVar && GVar->isThreadLocal();
412 // TLS not supported at this time.
413 if (IsThreadLocal)
414 return 0;
415 emitInst(Mips::LW, DestReg)
416 .addReg(MFI->getGlobalBaseReg(*MF))
417 .addGlobalAddress(GV, 0, MipsII::MO_GOT);
418 if (GV->hasLocalLinkage()) {
419 Register TempReg = createResultReg(RC);
420 emitInst(Mips::ADDiu, TempReg)
421 .addReg(DestReg)
422 .addGlobalAddress(GV, 0, MipsII::MO_ABS_LO);
423 DestReg = TempReg;
424 }
425 return DestReg;
426}
427
428unsigned MipsFastISel::materializeExternalCallSym(MCSymbol *Sym) {
429 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
430 Register DestReg = createResultReg(RC);
431 emitInst(Mips::LW, DestReg)
432 .addReg(MFI->getGlobalBaseReg(*MF))
433 .addSym(Sym, MipsII::MO_GOT);
434 return DestReg;
435}
436
437// Materialize a constant into a register, and return the register
438// number (or zero if we failed to handle it).
439Register MipsFastISel::fastMaterializeConstant(const Constant *C) {
440 EVT CEVT = TLI.getValueType(DL, C->getType(), true);
441
442 // Only handle simple types.
443 if (!CEVT.isSimple())
444 return Register();
445 MVT VT = CEVT.getSimpleVT();
446
447 if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
448 return (UnsupportedFPMode) ? 0 : materializeFP(CFP, VT);
449 else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
450 return materializeGV(GV, VT);
451 else if (isa<ConstantInt>(C))
452 return materializeInt(C, VT);
453
454 return Register();
455}
456
457bool MipsFastISel::computeAddress(const Value *Obj, Address &Addr) {
458 const User *U = nullptr;
459 unsigned Opcode = Instruction::UserOp1;
460 if (const Instruction *I = dyn_cast<Instruction>(Obj)) {
461 // Don't walk into other basic blocks unless the object is an alloca from
462 // another block, otherwise it may not have a virtual register assigned.
463 if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(Obj)) ||
464 FuncInfo.getMBB(I->getParent()) == FuncInfo.MBB) {
465 Opcode = I->getOpcode();
466 U = I;
467 }
468 } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(Obj)) {
469 Opcode = C->getOpcode();
470 U = C;
471 }
472 switch (Opcode) {
473 default:
474 break;
475 case Instruction::BitCast:
476 // Look through bitcasts.
477 return computeAddress(U->getOperand(0), Addr);
478 case Instruction::GetElementPtr: {
479 Address SavedAddr = Addr;
480 int64_t TmpOffset = Addr.getOffset();
481 // Iterate through the GEP folding the constants into offsets where
482 // we can.
484 for (User::const_op_iterator i = U->op_begin() + 1, e = U->op_end(); i != e;
485 ++i, ++GTI) {
486 const Value *Op = *i;
487 if (StructType *STy = GTI.getStructTypeOrNull()) {
488 const StructLayout *SL = DL.getStructLayout(STy);
489 unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();
490 TmpOffset += SL->getElementOffset(Idx);
491 } else {
493 while (true) {
494 if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
495 // Constant-offset addressing.
496 TmpOffset += CI->getSExtValue() * S;
497 break;
498 }
499 if (canFoldAddIntoGEP(U, Op)) {
500 // A compatible add with a constant operand. Fold the constant.
501 ConstantInt *CI =
502 cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1));
503 TmpOffset += CI->getSExtValue() * S;
504 // Iterate on the other operand.
505 Op = cast<AddOperator>(Op)->getOperand(0);
506 continue;
507 }
508 // Unsupported
509 goto unsupported_gep;
510 }
511 }
512 }
513 // Try to grab the base operand now.
514 Addr.setOffset(TmpOffset);
515 if (computeAddress(U->getOperand(0), Addr))
516 return true;
517 // We failed, restore everything and try the other options.
518 Addr = SavedAddr;
519 unsupported_gep:
520 break;
521 }
522 case Instruction::Alloca: {
523 const AllocaInst *AI = cast<AllocaInst>(Obj);
524 auto SI = FuncInfo.StaticAllocaMap.find(AI);
525 if (SI != FuncInfo.StaticAllocaMap.end()) {
526 Addr.setKind(Address::FrameIndexBase);
527 Addr.setFI(SI->second);
528 return true;
529 }
530 break;
531 }
532 }
533 Addr.setReg(getRegForValue(Obj));
534 return Addr.getReg() != 0;
535}
536
537bool MipsFastISel::computeCallAddress(const Value *V, Address &Addr) {
538 const User *U = nullptr;
539 unsigned Opcode = Instruction::UserOp1;
540
541 if (const auto *I = dyn_cast<Instruction>(V)) {
542 // Check if the value is defined in the same basic block. This information
543 // is crucial to know whether or not folding an operand is valid.
544 if (I->getParent() == FuncInfo.MBB->getBasicBlock()) {
545 Opcode = I->getOpcode();
546 U = I;
547 }
548 } else if (const auto *C = dyn_cast<ConstantExpr>(V)) {
549 Opcode = C->getOpcode();
550 U = C;
551 }
552
553 switch (Opcode) {
554 default:
555 break;
556 case Instruction::BitCast:
557 // Look past bitcasts if its operand is in the same BB.
558 return computeCallAddress(U->getOperand(0), Addr);
559 break;
560 case Instruction::IntToPtr:
561 // Look past no-op inttoptrs if its operand is in the same BB.
562 if (TLI.getValueType(DL, U->getOperand(0)->getType()) ==
563 TLI.getPointerTy(DL))
564 return computeCallAddress(U->getOperand(0), Addr);
565 break;
566 case Instruction::PtrToInt:
567 // Look past no-op ptrtoints if its operand is in the same BB.
568 if (TLI.getValueType(DL, U->getType()) == TLI.getPointerTy(DL))
569 return computeCallAddress(U->getOperand(0), Addr);
570 break;
571 }
572
573 if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
574 Addr.setGlobalValue(GV);
575 return true;
576 }
577
578 // If all else fails, try to materialize the value in a register.
579 if (!Addr.getGlobalValue()) {
580 Addr.setReg(getRegForValue(V));
581 return Addr.getReg() != 0;
582 }
583
584 return false;
585}
586
587bool MipsFastISel::isTypeLegal(Type *Ty, MVT &VT) {
588 EVT evt = TLI.getValueType(DL, Ty, true);
589 // Only handle simple types.
590 if (evt == MVT::Other || !evt.isSimple())
591 return false;
592 VT = evt.getSimpleVT();
593
594 // Handle all legal types, i.e. a register that will directly hold this
595 // value.
596 return TLI.isTypeLegal(VT);
597}
598
599bool MipsFastISel::isTypeSupported(Type *Ty, MVT &VT) {
600 if (Ty->isVectorTy())
601 return false;
602
603 if (isTypeLegal(Ty, VT))
604 return true;
605
606 // If this is a type than can be sign or zero-extended to a basic operation
607 // go ahead and accept it now.
608 if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)
609 return true;
610
611 return false;
612}
613
614bool MipsFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) {
615 if (isTypeLegal(Ty, VT))
616 return true;
617 // We will extend this in a later patch:
618 // If this is a type than can be sign or zero-extended to a basic operation
619 // go ahead and accept it now.
620 if (VT == MVT::i8 || VT == MVT::i16)
621 return true;
622 return false;
623}
624
625// Because of how EmitCmp is called with fast-isel, you can
626// end up with redundant "andi" instructions after the sequences emitted below.
627// We should try and solve this issue in the future.
628//
629bool MipsFastISel::emitCmp(unsigned ResultReg, const CmpInst *CI) {
630 const Value *Left = CI->getOperand(0), *Right = CI->getOperand(1);
631 bool IsUnsigned = CI->isUnsigned();
632 unsigned LeftReg = getRegEnsuringSimpleIntegerWidening(Left, IsUnsigned);
633 if (LeftReg == 0)
634 return false;
635 unsigned RightReg = getRegEnsuringSimpleIntegerWidening(Right, IsUnsigned);
636 if (RightReg == 0)
637 return false;
639
640 switch (P) {
641 default:
642 return false;
643 case CmpInst::ICMP_EQ: {
644 Register TempReg = createResultReg(&Mips::GPR32RegClass);
645 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
646 emitInst(Mips::SLTiu, ResultReg).addReg(TempReg).addImm(1);
647 break;
648 }
649 case CmpInst::ICMP_NE: {
650 Register TempReg = createResultReg(&Mips::GPR32RegClass);
651 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
652 emitInst(Mips::SLTu, ResultReg).addReg(Mips::ZERO).addReg(TempReg);
653 break;
654 }
656 emitInst(Mips::SLTu, ResultReg).addReg(RightReg).addReg(LeftReg);
657 break;
659 emitInst(Mips::SLTu, ResultReg).addReg(LeftReg).addReg(RightReg);
660 break;
661 case CmpInst::ICMP_UGE: {
662 Register TempReg = createResultReg(&Mips::GPR32RegClass);
663 emitInst(Mips::SLTu, TempReg).addReg(LeftReg).addReg(RightReg);
664 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
665 break;
666 }
667 case CmpInst::ICMP_ULE: {
668 Register TempReg = createResultReg(&Mips::GPR32RegClass);
669 emitInst(Mips::SLTu, TempReg).addReg(RightReg).addReg(LeftReg);
670 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
671 break;
672 }
674 emitInst(Mips::SLT, ResultReg).addReg(RightReg).addReg(LeftReg);
675 break;
677 emitInst(Mips::SLT, ResultReg).addReg(LeftReg).addReg(RightReg);
678 break;
679 case CmpInst::ICMP_SGE: {
680 Register TempReg = createResultReg(&Mips::GPR32RegClass);
681 emitInst(Mips::SLT, TempReg).addReg(LeftReg).addReg(RightReg);
682 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
683 break;
684 }
685 case CmpInst::ICMP_SLE: {
686 Register TempReg = createResultReg(&Mips::GPR32RegClass);
687 emitInst(Mips::SLT, TempReg).addReg(RightReg).addReg(LeftReg);
688 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
689 break;
690 }
696 case CmpInst::FCMP_OGE: {
697 if (UnsupportedFPMode)
698 return false;
699 bool IsFloat = Left->getType()->isFloatTy();
700 bool IsDouble = Left->getType()->isDoubleTy();
701 if (!IsFloat && !IsDouble)
702 return false;
703 unsigned Opc, CondMovOpc;
704 switch (P) {
706 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
707 CondMovOpc = Mips::MOVT_I;
708 break;
710 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
711 CondMovOpc = Mips::MOVF_I;
712 break;
714 Opc = IsFloat ? Mips::C_OLT_S : Mips::C_OLT_D32;
715 CondMovOpc = Mips::MOVT_I;
716 break;
718 Opc = IsFloat ? Mips::C_OLE_S : Mips::C_OLE_D32;
719 CondMovOpc = Mips::MOVT_I;
720 break;
722 Opc = IsFloat ? Mips::C_ULE_S : Mips::C_ULE_D32;
723 CondMovOpc = Mips::MOVF_I;
724 break;
726 Opc = IsFloat ? Mips::C_ULT_S : Mips::C_ULT_D32;
727 CondMovOpc = Mips::MOVF_I;
728 break;
729 default:
730 llvm_unreachable("Only switching of a subset of CCs.");
731 }
732 Register RegWithZero = createResultReg(&Mips::GPR32RegClass);
733 Register RegWithOne = createResultReg(&Mips::GPR32RegClass);
734 emitInst(Mips::ADDiu, RegWithZero).addReg(Mips::ZERO).addImm(0);
735 emitInst(Mips::ADDiu, RegWithOne).addReg(Mips::ZERO).addImm(1);
736 emitInst(Opc).addReg(Mips::FCC0, RegState::Define).addReg(LeftReg)
737 .addReg(RightReg);
738 emitInst(CondMovOpc, ResultReg)
739 .addReg(RegWithOne)
740 .addReg(Mips::FCC0)
741 .addReg(RegWithZero);
742 break;
743 }
744 }
745 return true;
746}
747
748bool MipsFastISel::emitLoad(MVT VT, unsigned &ResultReg, Address &Addr) {
749 //
750 // more cases will be handled here in following patches.
751 //
752 unsigned Opc;
753 switch (VT.SimpleTy) {
754 case MVT::i32:
755 ResultReg = createResultReg(&Mips::GPR32RegClass);
756 Opc = Mips::LW;
757 break;
758 case MVT::i16:
759 ResultReg = createResultReg(&Mips::GPR32RegClass);
760 Opc = Mips::LHu;
761 break;
762 case MVT::i8:
763 ResultReg = createResultReg(&Mips::GPR32RegClass);
764 Opc = Mips::LBu;
765 break;
766 case MVT::f32:
767 if (UnsupportedFPMode)
768 return false;
769 ResultReg = createResultReg(&Mips::FGR32RegClass);
770 Opc = Mips::LWC1;
771 break;
772 case MVT::f64:
773 if (UnsupportedFPMode)
774 return false;
775 ResultReg = createResultReg(&Mips::AFGR64RegClass);
776 Opc = Mips::LDC1;
777 break;
778 default:
779 return false;
780 }
781 if (Addr.isRegBase()) {
782 simplifyAddress(Addr);
783 emitInstLoad(Opc, ResultReg, Addr.getReg(), Addr.getOffset());
784 return true;
785 }
786 if (Addr.isFIBase()) {
787 unsigned FI = Addr.getFI();
788 int64_t Offset = Addr.getOffset();
789 MachineFrameInfo &MFI = MF->getFrameInfo();
790 MachineMemOperand *MMO = MF->getMachineMemOperand(
792 MFI.getObjectSize(FI), Align(4));
793 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ResultReg)
794 .addFrameIndex(FI)
795 .addImm(Offset)
796 .addMemOperand(MMO);
797 return true;
798 }
799 return false;
800}
801
802bool MipsFastISel::emitStore(MVT VT, unsigned SrcReg, Address &Addr) {
803 //
804 // more cases will be handled here in following patches.
805 //
806 unsigned Opc;
807 switch (VT.SimpleTy) {
808 case MVT::i8:
809 Opc = Mips::SB;
810 break;
811 case MVT::i16:
812 Opc = Mips::SH;
813 break;
814 case MVT::i32:
815 Opc = Mips::SW;
816 break;
817 case MVT::f32:
818 if (UnsupportedFPMode)
819 return false;
820 Opc = Mips::SWC1;
821 break;
822 case MVT::f64:
823 if (UnsupportedFPMode)
824 return false;
825 Opc = Mips::SDC1;
826 break;
827 default:
828 return false;
829 }
830 if (Addr.isRegBase()) {
831 simplifyAddress(Addr);
832 emitInstStore(Opc, SrcReg, Addr.getReg(), Addr.getOffset());
833 return true;
834 }
835 if (Addr.isFIBase()) {
836 unsigned FI = Addr.getFI();
837 int64_t Offset = Addr.getOffset();
838 MachineFrameInfo &MFI = MF->getFrameInfo();
839 MachineMemOperand *MMO = MF->getMachineMemOperand(
841 MFI.getObjectSize(FI), Align(4));
842 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc))
843 .addReg(SrcReg)
844 .addFrameIndex(FI)
845 .addImm(Offset)
846 .addMemOperand(MMO);
847 return true;
848 }
849 return false;
850}
851
852bool MipsFastISel::selectLogicalOp(const Instruction *I) {
853 MVT VT;
854 if (!isTypeSupported(I->getType(), VT))
855 return false;
856
857 unsigned ResultReg;
858 switch (I->getOpcode()) {
859 default:
860 llvm_unreachable("Unexpected instruction.");
861 case Instruction::And:
862 ResultReg = emitLogicalOp(ISD::AND, VT, I->getOperand(0), I->getOperand(1));
863 break;
864 case Instruction::Or:
865 ResultReg = emitLogicalOp(ISD::OR, VT, I->getOperand(0), I->getOperand(1));
866 break;
867 case Instruction::Xor:
868 ResultReg = emitLogicalOp(ISD::XOR, VT, I->getOperand(0), I->getOperand(1));
869 break;
870 }
871
872 if (!ResultReg)
873 return false;
874
875 updateValueMap(I, ResultReg);
876 return true;
877}
878
879bool MipsFastISel::selectLoad(const Instruction *I) {
880 const LoadInst *LI = cast<LoadInst>(I);
881
882 // Atomic loads need special handling.
883 if (LI->isAtomic())
884 return false;
885
886 // Verify we have a legal type before going any further.
887 MVT VT;
888 if (!isLoadTypeLegal(LI->getType(), VT))
889 return false;
890
891 // Underaligned loads need special handling.
892 if (LI->getAlign() < VT.getFixedSizeInBits() / 8 &&
893 !Subtarget->systemSupportsUnalignedAccess())
894 return false;
895
896 // See if we can handle this address.
897 Address Addr;
898 if (!computeAddress(LI->getOperand(0), Addr))
899 return false;
900
901 unsigned ResultReg;
902 if (!emitLoad(VT, ResultReg, Addr))
903 return false;
904 updateValueMap(LI, ResultReg);
905 return true;
906}
907
908bool MipsFastISel::selectStore(const Instruction *I) {
909 const StoreInst *SI = cast<StoreInst>(I);
910
911 Value *Op0 = SI->getOperand(0);
912 unsigned SrcReg = 0;
913
914 // Atomic stores need special handling.
915 if (SI->isAtomic())
916 return false;
917
918 // Verify we have a legal type before going any further.
919 MVT VT;
920 if (!isLoadTypeLegal(SI->getOperand(0)->getType(), VT))
921 return false;
922
923 // Underaligned stores need special handling.
924 if (SI->getAlign() < VT.getFixedSizeInBits() / 8 &&
925 !Subtarget->systemSupportsUnalignedAccess())
926 return false;
927
928 // Get the value to be stored into a register.
929 SrcReg = getRegForValue(Op0);
930 if (SrcReg == 0)
931 return false;
932
933 // See if we can handle this address.
934 Address Addr;
935 if (!computeAddress(SI->getOperand(1), Addr))
936 return false;
937
938 if (!emitStore(VT, SrcReg, Addr))
939 return false;
940 return true;
941}
942
943// This can cause a redundant sltiu to be generated.
944// FIXME: try and eliminate this in a future patch.
945bool MipsFastISel::selectBranch(const Instruction *I) {
946 const CondBrInst *BI = cast<CondBrInst>(I);
947 MachineBasicBlock *BrBB = FuncInfo.MBB;
948 //
949 // TBB is the basic block for the case where the comparison is true.
950 // FBB is the basic block for the case where the comparison is false.
951 // if (cond) goto TBB
952 // goto FBB
953 // TBB:
954 //
955 MachineBasicBlock *TBB = FuncInfo.getMBB(BI->getSuccessor(0));
956 MachineBasicBlock *FBB = FuncInfo.getMBB(BI->getSuccessor(1));
957
958 // Fold the common case of a conditional branch with a comparison
959 // in the same block.
960 unsigned ZExtCondReg = 0;
961 if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) {
962 if (CI->hasOneUse() && CI->getParent() == I->getParent()) {
963 ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
964 if (!emitCmp(ZExtCondReg, CI))
965 return false;
966 }
967 }
968
969 // For the general case, we need to mask with 1.
970 if (ZExtCondReg == 0) {
971 Register CondReg = getRegForValue(BI->getCondition());
972 if (CondReg == 0)
973 return false;
974
975 ZExtCondReg = emitIntExt(MVT::i1, CondReg, MVT::i32, true);
976 if (ZExtCondReg == 0)
977 return false;
978 }
979
980 BuildMI(*BrBB, FuncInfo.InsertPt, MIMD, TII.get(Mips::BGTZ))
981 .addReg(ZExtCondReg)
982 .addMBB(TBB)
983 .setOperandDead(2); // implicit-def $at
984 finishCondBranch(BI->getParent(), TBB, FBB);
985 return true;
986}
987
988bool MipsFastISel::selectCmp(const Instruction *I) {
989 const CmpInst *CI = cast<CmpInst>(I);
990 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
991 if (!emitCmp(ResultReg, CI))
992 return false;
993 updateValueMap(I, ResultReg);
994 return true;
995}
996
997// Attempt to fast-select a floating-point extend instruction.
998bool MipsFastISel::selectFPExt(const Instruction *I) {
999 if (UnsupportedFPMode)
1000 return false;
1001 Value *Src = I->getOperand(0);
1002 EVT SrcVT = TLI.getValueType(DL, Src->getType(), true);
1003 EVT DestVT = TLI.getValueType(DL, I->getType(), true);
1004
1005 if (SrcVT != MVT::f32 || DestVT != MVT::f64)
1006 return false;
1007
1008 Register SrcReg =
1009 getRegForValue(Src); // this must be a 32bit floating point register class
1010 // maybe we should handle this differently
1011 if (!SrcReg)
1012 return false;
1013
1014 Register DestReg = createResultReg(&Mips::AFGR64RegClass);
1015 emitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg);
1016 updateValueMap(I, DestReg);
1017 return true;
1018}
1019
1020bool MipsFastISel::selectSelect(const Instruction *I) {
1021 assert(isa<SelectInst>(I) && "Expected a select instruction.");
1022
1023 LLVM_DEBUG(dbgs() << "selectSelect\n");
1024
1025 MVT VT;
1026 if (!isTypeSupported(I->getType(), VT) || UnsupportedFPMode) {
1027 LLVM_DEBUG(
1028 dbgs() << ".. .. gave up (!isTypeSupported || UnsupportedFPMode)\n");
1029 return false;
1030 }
1031
1032 unsigned CondMovOpc;
1033 const TargetRegisterClass *RC;
1034
1035 if (VT.isInteger() && !VT.isVector() && VT.getSizeInBits() <= 32) {
1036 CondMovOpc = Mips::MOVN_I_I;
1037 RC = &Mips::GPR32RegClass;
1038 } else if (VT == MVT::f32) {
1039 CondMovOpc = Mips::MOVN_I_S;
1040 RC = &Mips::FGR32RegClass;
1041 } else if (VT == MVT::f64) {
1042 CondMovOpc = Mips::MOVN_I_D32;
1043 RC = &Mips::AFGR64RegClass;
1044 } else
1045 return false;
1046
1047 const SelectInst *SI = cast<SelectInst>(I);
1048 const Value *Cond = SI->getCondition();
1049 Register Src1Reg = getRegForValue(SI->getTrueValue());
1050 Register Src2Reg = getRegForValue(SI->getFalseValue());
1051 Register CondReg = getRegForValue(Cond);
1052
1053 if (!Src1Reg || !Src2Reg || !CondReg)
1054 return false;
1055
1056 Register ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
1057 if (!ZExtCondReg)
1058 return false;
1059
1060 if (!emitIntExt(MVT::i1, CondReg, MVT::i32, ZExtCondReg, true))
1061 return false;
1062
1063 Register ResultReg = createResultReg(RC);
1064 Register TempReg = createResultReg(RC);
1065
1066 if (!ResultReg || !TempReg)
1067 return false;
1068
1069 emitInst(TargetOpcode::COPY, TempReg).addReg(Src2Reg);
1070 emitInst(CondMovOpc, ResultReg)
1071 .addReg(Src1Reg).addReg(ZExtCondReg).addReg(TempReg);
1072 updateValueMap(I, ResultReg);
1073 return true;
1074}
1075
1076// Attempt to fast-select a floating-point truncate instruction.
1077bool MipsFastISel::selectFPTrunc(const Instruction *I) {
1078 if (UnsupportedFPMode)
1079 return false;
1080 Value *Src = I->getOperand(0);
1081 EVT SrcVT = TLI.getValueType(DL, Src->getType(), true);
1082 EVT DestVT = TLI.getValueType(DL, I->getType(), true);
1083
1084 if (SrcVT != MVT::f64 || DestVT != MVT::f32)
1085 return false;
1086
1087 Register SrcReg = getRegForValue(Src);
1088 if (!SrcReg)
1089 return false;
1090
1091 Register DestReg = createResultReg(&Mips::FGR32RegClass);
1092 if (!DestReg)
1093 return false;
1094
1095 emitInst(Mips::CVT_S_D32, DestReg).addReg(SrcReg);
1096 updateValueMap(I, DestReg);
1097 return true;
1098}
1099
1100// Attempt to fast-select a floating-point-to-integer conversion.
1101bool MipsFastISel::selectFPToInt(const Instruction *I, bool IsSigned) {
1102 if (UnsupportedFPMode)
1103 return false;
1104 MVT DstVT, SrcVT;
1105 if (!IsSigned)
1106 return false; // We don't handle this case yet. There is no native
1107 // instruction for this but it can be synthesized.
1108 Type *DstTy = I->getType();
1109 if (!isTypeLegal(DstTy, DstVT))
1110 return false;
1111
1112 if (DstVT != MVT::i32)
1113 return false;
1114
1115 Value *Src = I->getOperand(0);
1116 Type *SrcTy = Src->getType();
1117 if (!isTypeLegal(SrcTy, SrcVT))
1118 return false;
1119
1120 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
1121 return false;
1122
1123 Register SrcReg = getRegForValue(Src);
1124 if (SrcReg == 0)
1125 return false;
1126
1127 // Determine the opcode for the conversion, which takes place
1128 // entirely within FPRs.
1129 Register DestReg = createResultReg(&Mips::GPR32RegClass);
1130 Register TempReg = createResultReg(&Mips::FGR32RegClass);
1131 unsigned Opc = (SrcVT == MVT::f32) ? Mips::TRUNC_W_S : Mips::TRUNC_W_D32;
1132
1133 // Generate the convert.
1134 emitInst(Opc, TempReg).addReg(SrcReg);
1135 emitInst(Mips::MFC1, DestReg).addReg(TempReg);
1136
1137 updateValueMap(I, DestReg);
1138 return true;
1139}
1140
1141bool MipsFastISel::processCallArgs(CallLoweringInfo &CLI,
1142 SmallVectorImpl<MVT> &OutVTs,
1143 unsigned &NumBytes) {
1144 CallingConv::ID CC = CLI.CallConv;
1147 for (const ArgListEntry &Arg : CLI.Args)
1148 ArgTys.push_back(Arg.Val->getType());
1149 CCState CCInfo(CC, false, *FuncInfo.MF, ArgLocs, *Context);
1150 CCInfo.AnalyzeCallOperands(OutVTs, CLI.OutFlags, ArgTys,
1151 CCAssignFnForCall(CC));
1152 // Get a count of how many bytes are to be pushed on the stack.
1153 NumBytes = CCInfo.getStackSize();
1154 // This is the minimum argument area used for A0-A3.
1155 if (NumBytes < 16)
1156 NumBytes = 16;
1157
1158 emitInst(Mips::ADJCALLSTACKDOWN).addImm(16).addImm(0);
1159 // Process the args.
1160 MVT firstMVT;
1161 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
1162 CCValAssign &VA = ArgLocs[i];
1163 const Value *ArgVal = CLI.OutVals[VA.getValNo()];
1164 MVT ArgVT = OutVTs[VA.getValNo()];
1165
1166 if (i == 0) {
1167 firstMVT = ArgVT;
1168 if (ArgVT == MVT::f32) {
1169 VA.convertToReg(Mips::F12);
1170 } else if (ArgVT == MVT::f64) {
1171 if (Subtarget->isFP64bit())
1172 VA.convertToReg(Mips::D6_64);
1173 else
1174 VA.convertToReg(Mips::D6);
1175 }
1176 } else if (i == 1) {
1177 if ((firstMVT == MVT::f32) || (firstMVT == MVT::f64)) {
1178 if (ArgVT == MVT::f32) {
1179 VA.convertToReg(Mips::F14);
1180 } else if (ArgVT == MVT::f64) {
1181 if (Subtarget->isFP64bit())
1182 VA.convertToReg(Mips::D7_64);
1183 else
1184 VA.convertToReg(Mips::D7);
1185 }
1186 }
1187 }
1188 if (((ArgVT == MVT::i32) || (ArgVT == MVT::f32) || (ArgVT == MVT::i16) ||
1189 (ArgVT == MVT::i8)) &&
1190 VA.isMemLoc()) {
1191 switch (VA.getLocMemOffset()) {
1192 case 0:
1193 VA.convertToReg(getABI().getArgReg(0, false));
1194 break;
1195 case 4:
1196 VA.convertToReg(getABI().getArgReg(1, false));
1197 break;
1198 case 8:
1199 VA.convertToReg(getABI().getArgReg(2, false));
1200 break;
1201 case 12:
1202 VA.convertToReg(getABI().getArgReg(3, false));
1203 break;
1204 default:
1205 break;
1206 }
1207 }
1208 Register ArgReg = getRegForValue(ArgVal);
1209 if (!ArgReg)
1210 return false;
1211
1212 // Handle arg promotion: SExt, ZExt, AExt.
1213 switch (VA.getLocInfo()) {
1214 case CCValAssign::Full:
1215 break;
1216 case CCValAssign::AExt:
1217 case CCValAssign::SExt: {
1218 MVT DestVT = VA.getLocVT();
1219 MVT SrcVT = ArgVT;
1220 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT, /*isZExt=*/false);
1221 if (!ArgReg)
1222 return false;
1223 break;
1224 }
1225 case CCValAssign::ZExt: {
1226 MVT DestVT = VA.getLocVT();
1227 MVT SrcVT = ArgVT;
1228 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT, /*isZExt=*/true);
1229 if (!ArgReg)
1230 return false;
1231 break;
1232 }
1233 default:
1234 llvm_unreachable("Unknown arg promotion!");
1235 }
1236
1237 // Now copy/store arg to correct locations.
1238 if (VA.isRegLoc() && !VA.needsCustom()) {
1239 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1240 TII.get(TargetOpcode::COPY), VA.getLocReg()).addReg(ArgReg);
1241 CLI.OutRegs.push_back(VA.getLocReg());
1242 } else if (VA.needsCustom()) {
1243 llvm_unreachable("Mips does not use custom args.");
1244 return false;
1245 } else {
1246 //
1247 // FIXME: This path will currently return false. It was copied
1248 // from the AArch64 port and should be essentially fine for Mips too.
1249 // The work to finish up this path will be done in a follow-on patch.
1250 //
1251 assert(VA.isMemLoc() && "Assuming store on stack.");
1252 // Don't emit stores for undef values.
1253 if (isa<UndefValue>(ArgVal))
1254 continue;
1255
1256 // Need to store on the stack.
1257 // FIXME: This alignment is incorrect but this path is disabled
1258 // for now (will return false). We need to determine the right alignment
1259 // based on the normal alignment for the underlying machine type.
1260 //
1261 unsigned ArgSize = alignTo(ArgVT.getSizeInBits(), 4);
1262
1263 unsigned BEAlign = 0;
1264 if (ArgSize < 8 && !Subtarget->isLittle())
1265 BEAlign = 8 - ArgSize;
1266
1267 Address Addr;
1268 Addr.setKind(Address::RegBase);
1269 Addr.setReg(Mips::SP);
1270 Addr.setOffset(VA.getLocMemOffset() + BEAlign);
1271
1272 Align Alignment = DL.getABITypeAlign(ArgVal->getType());
1273 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
1274 MachinePointerInfo::getStack(*FuncInfo.MF, Addr.getOffset()),
1275 MachineMemOperand::MOStore, ArgVT.getStoreSize(), Alignment);
1276 (void)(MMO);
1277 // if (!emitStore(ArgVT, ArgReg, Addr, MMO))
1278 return false; // can't store on the stack yet.
1279 }
1280 }
1281
1282 return true;
1283}
1284
1285bool MipsFastISel::finishCall(CallLoweringInfo &CLI, MVT RetVT,
1286 unsigned NumBytes) {
1287 CallingConv::ID CC = CLI.CallConv;
1288 emitInst(Mips::ADJCALLSTACKUP).addImm(16).addImm(0);
1289 if (RetVT != MVT::isVoid) {
1291 MipsCCState CCInfo(CC, false, *FuncInfo.MF, RVLocs, *Context);
1292
1293 CCInfo.AnalyzeCallResult(CLI.Ins, RetCC_Mips);
1294
1295 // Only handle a single return value.
1296 if (RVLocs.size() != 1)
1297 return false;
1298 // Copy all of the result registers out of their specified physreg.
1299 MVT CopyVT = RVLocs[0].getValVT();
1300 // Special handling for extended integers.
1301 if (RetVT == MVT::i1 || RetVT == MVT::i8 || RetVT == MVT::i16)
1302 CopyVT = MVT::i32;
1303
1304 Register ResultReg = createResultReg(TLI.getRegClassFor(CopyVT));
1305 if (!ResultReg)
1306 return false;
1307 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1308 TII.get(TargetOpcode::COPY),
1309 ResultReg).addReg(RVLocs[0].getLocReg());
1310 CLI.InRegs.push_back(RVLocs[0].getLocReg());
1311
1312 CLI.ResultReg = ResultReg;
1313 CLI.NumResultRegs = 1;
1314 }
1315 return true;
1316}
1317
1318bool MipsFastISel::fastLowerArguments() {
1319 LLVM_DEBUG(dbgs() << "fastLowerArguments\n");
1320
1321 if (!FuncInfo.CanLowerReturn) {
1322 LLVM_DEBUG(dbgs() << ".. gave up (!CanLowerReturn)\n");
1323 return false;
1324 }
1325
1326 const Function *F = FuncInfo.Fn;
1327 if (F->isVarArg()) {
1328 LLVM_DEBUG(dbgs() << ".. gave up (varargs)\n");
1329 return false;
1330 }
1331
1332 CallingConv::ID CC = F->getCallingConv();
1333 if (CC != CallingConv::C) {
1334 LLVM_DEBUG(dbgs() << ".. gave up (calling convention is not C)\n");
1335 return false;
1336 }
1337
1338 ArrayRef<MCPhysReg> GPR32ArgRegs = getABI().getArgRegs(false);
1339 std::array<MCPhysReg, 2> FGR32ArgRegs = {{Mips::F12, Mips::F14}};
1340 std::array<MCPhysReg, 2> AFGR64ArgRegs = {{Mips::D6, Mips::D7}};
1341 auto NextGPR32 = GPR32ArgRegs.begin();
1342 auto NextFGR32 = FGR32ArgRegs.begin();
1343 auto NextAFGR64 = AFGR64ArgRegs.begin();
1344
1345 struct AllocatedReg {
1346 const TargetRegisterClass *RC;
1347 unsigned Reg;
1348 AllocatedReg(const TargetRegisterClass *RC, unsigned Reg)
1349 : RC(RC), Reg(Reg) {}
1350 };
1351
1352 // Only handle simple cases. i.e. All arguments are directly mapped to
1353 // registers of the appropriate type.
1355 for (const auto &FormalArg : F->args()) {
1356 if (FormalArg.hasAttribute(Attribute::InReg) ||
1357 FormalArg.hasAttribute(Attribute::StructRet) ||
1358 FormalArg.hasAttribute(Attribute::ByVal)) {
1359 LLVM_DEBUG(dbgs() << ".. gave up (inreg, structret, byval)\n");
1360 return false;
1361 }
1362
1363 Type *ArgTy = FormalArg.getType();
1364 if (ArgTy->isStructTy() || ArgTy->isArrayTy() || ArgTy->isVectorTy()) {
1365 LLVM_DEBUG(dbgs() << ".. gave up (struct, array, or vector)\n");
1366 return false;
1367 }
1368
1369 EVT ArgVT = TLI.getValueType(DL, ArgTy);
1370 LLVM_DEBUG(dbgs() << ".. " << FormalArg.getArgNo() << ": "
1371 << ArgVT << "\n");
1372 if (!ArgVT.isSimple()) {
1373 LLVM_DEBUG(dbgs() << ".. .. gave up (not a simple type)\n");
1374 return false;
1375 }
1376
1377 switch (ArgVT.getSimpleVT().SimpleTy) {
1378 case MVT::i1:
1379 case MVT::i8:
1380 case MVT::i16:
1381 if (!FormalArg.hasAttribute(Attribute::SExt) &&
1382 !FormalArg.hasAttribute(Attribute::ZExt)) {
1383 // It must be any extend, this shouldn't happen for clang-generated IR
1384 // so just fall back on SelectionDAG.
1385 LLVM_DEBUG(dbgs() << ".. .. gave up (i8/i16 arg is not extended)\n");
1386 return false;
1387 }
1388
1389 if (NextGPR32 == GPR32ArgRegs.end()) {
1390 LLVM_DEBUG(dbgs() << ".. .. gave up (ran out of GPR32 arguments)\n");
1391 return false;
1392 }
1393
1394 LLVM_DEBUG(dbgs() << ".. .. GPR32(" << *NextGPR32 << ")\n");
1395 Allocation.emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1396
1397 // Allocating any GPR32 prohibits further use of floating point arguments.
1398 NextFGR32 = FGR32ArgRegs.end();
1399 NextAFGR64 = AFGR64ArgRegs.end();
1400 break;
1401
1402 case MVT::i32:
1403 if (FormalArg.hasAttribute(Attribute::ZExt)) {
1404 // The O32 ABI does not permit a zero-extended i32.
1405 LLVM_DEBUG(dbgs() << ".. .. gave up (i32 arg is zero extended)\n");
1406 return false;
1407 }
1408
1409 if (NextGPR32 == GPR32ArgRegs.end()) {
1410 LLVM_DEBUG(dbgs() << ".. .. gave up (ran out of GPR32 arguments)\n");
1411 return false;
1412 }
1413
1414 LLVM_DEBUG(dbgs() << ".. .. GPR32(" << *NextGPR32 << ")\n");
1415 Allocation.emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1416
1417 // Allocating any GPR32 prohibits further use of floating point arguments.
1418 NextFGR32 = FGR32ArgRegs.end();
1419 NextAFGR64 = AFGR64ArgRegs.end();
1420 break;
1421
1422 case MVT::f32:
1423 if (UnsupportedFPMode) {
1424 LLVM_DEBUG(dbgs() << ".. .. gave up (UnsupportedFPMode)\n");
1425 return false;
1426 }
1427 if (NextFGR32 == FGR32ArgRegs.end()) {
1428 LLVM_DEBUG(dbgs() << ".. .. gave up (ran out of FGR32 arguments)\n");
1429 return false;
1430 }
1431 LLVM_DEBUG(dbgs() << ".. .. FGR32(" << *NextFGR32 << ")\n");
1432 Allocation.emplace_back(&Mips::FGR32RegClass, *NextFGR32++);
1433 // Allocating an FGR32 also allocates the super-register AFGR64, and
1434 // ABI rules require us to skip the corresponding GPR32.
1435 if (NextGPR32 != GPR32ArgRegs.end())
1436 NextGPR32++;
1437 if (NextAFGR64 != AFGR64ArgRegs.end())
1438 NextAFGR64++;
1439 break;
1440
1441 case MVT::f64:
1442 if (UnsupportedFPMode) {
1443 LLVM_DEBUG(dbgs() << ".. .. gave up (UnsupportedFPMode)\n");
1444 return false;
1445 }
1446 if (NextAFGR64 == AFGR64ArgRegs.end()) {
1447 LLVM_DEBUG(dbgs() << ".. .. gave up (ran out of AFGR64 arguments)\n");
1448 return false;
1449 }
1450 LLVM_DEBUG(dbgs() << ".. .. AFGR64(" << *NextAFGR64 << ")\n");
1451 Allocation.emplace_back(&Mips::AFGR64RegClass, *NextAFGR64++);
1452 // Allocating an FGR32 also allocates the super-register AFGR64, and
1453 // ABI rules require us to skip the corresponding GPR32 pair.
1454 if (NextGPR32 != GPR32ArgRegs.end())
1455 NextGPR32++;
1456 if (NextGPR32 != GPR32ArgRegs.end())
1457 NextGPR32++;
1458 if (NextFGR32 != FGR32ArgRegs.end())
1459 NextFGR32++;
1460 break;
1461
1462 default:
1463 LLVM_DEBUG(dbgs() << ".. .. gave up (unknown type)\n");
1464 return false;
1465 }
1466 }
1467
1468 for (const auto &FormalArg : F->args()) {
1469 unsigned ArgNo = FormalArg.getArgNo();
1470 unsigned SrcReg = Allocation[ArgNo].Reg;
1471 Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, Allocation[ArgNo].RC);
1472 // FIXME: Unfortunately it's necessary to emit a copy from the livein copy.
1473 // Without this, EmitLiveInCopies may eliminate the livein if its only
1474 // use is a bitcast (which isn't turned into an instruction).
1475 Register ResultReg = createResultReg(Allocation[ArgNo].RC);
1476 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY),
1477 ResultReg)
1478 .addReg(DstReg);
1479 updateValueMap(&FormalArg, ResultReg);
1480 }
1481
1482 // Calculate the size of the incoming arguments area.
1483 // We currently reject all the cases where this would be non-zero.
1484 unsigned IncomingArgSizeInBytes = 0;
1485
1486 // Account for the reserved argument area on ABI's that have one (O32).
1487 // It seems strange to do this on the caller side but it's necessary in
1488 // SelectionDAG's implementation.
1489 IncomingArgSizeInBytes = std::max(getABI().GetCalleeAllocdArgSizeInBytes(CC),
1490 IncomingArgSizeInBytes);
1491
1492 MF->getInfo<MipsFunctionInfo>()->setFormalArgInfo(IncomingArgSizeInBytes,
1493 false);
1494
1495 return true;
1496}
1497
1498bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1499 CallingConv::ID CC = CLI.CallConv;
1500 bool IsTailCall = CLI.IsTailCall;
1501 bool IsVarArg = CLI.IsVarArg;
1502 const Value *Callee = CLI.Callee;
1503 MCSymbol *Symbol = CLI.Symbol;
1504
1505 // Do not handle FastCC.
1506 if (CC == CallingConv::Fast)
1507 return false;
1508
1509 // Allow SelectionDAG isel to handle tail calls.
1510 if (IsTailCall)
1511 return false;
1512
1513 // Let SDISel handle vararg functions.
1514 if (IsVarArg)
1515 return false;
1516
1517 // FIXME: Only handle *simple* calls for now.
1518 MVT RetVT;
1519 if (CLI.RetTy->isVoidTy())
1520 RetVT = MVT::isVoid;
1521 else if (!isTypeSupported(CLI.RetTy, RetVT))
1522 return false;
1523
1524 for (auto Flag : CLI.OutFlags)
1525 if (Flag.isInReg() || Flag.isSRet() || Flag.isNest() || Flag.isByVal())
1526 return false;
1527
1528 // Set up the argument vectors.
1529 SmallVector<MVT, 16> OutVTs;
1530 OutVTs.reserve(CLI.OutVals.size());
1531
1532 for (auto *Val : CLI.OutVals) {
1533 MVT VT;
1534 if (!isTypeLegal(Val->getType(), VT) &&
1535 !(VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16))
1536 return false;
1537
1538 // We don't handle vector parameters yet.
1539 if (VT.isVector() || VT.getSizeInBits() > 64)
1540 return false;
1541
1542 OutVTs.push_back(VT);
1543 }
1544
1545 Address Addr;
1546 if (!computeCallAddress(Callee, Addr))
1547 return false;
1548
1549 // Handle the arguments now that we've gotten them.
1550 unsigned NumBytes;
1551 if (!processCallArgs(CLI, OutVTs, NumBytes))
1552 return false;
1553
1554 if (!Addr.getGlobalValue())
1555 return false;
1556
1557 // Issue the call.
1558 unsigned DestAddress;
1559 if (Symbol)
1560 DestAddress = materializeExternalCallSym(Symbol);
1561 else
1562 DestAddress = materializeGV(Addr.getGlobalValue(), MVT::i32);
1563 emitInst(TargetOpcode::COPY, getABI().getTempReg(9, false))
1564 .addReg(DestAddress);
1565 MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1566 TII.get(Mips::JALR), Mips::RA)
1567 .addReg(getABI().getTempReg(9, false));
1568
1569 // Add implicit physical register uses to the call.
1570 for (auto Reg : CLI.OutRegs)
1571 MIB.addReg(Reg, RegState::Implicit);
1572
1573 // Add a register mask with the call-preserved registers.
1574 // Proper defs for return values will be added by setPhysRegsDeadExcept().
1575 MIB.addRegMask(TRI.getCallPreservedMask(*FuncInfo.MF, CC));
1576
1577 CLI.Call = MIB;
1578
1579 if (Subtarget->getMCCLOpts().jalr_reloc && !Subtarget->inMips16Mode()) {
1580 // Attach callee address to the instruction, let asm printer emit
1581 // .reloc R_MIPS_JALR.
1582 if (Symbol)
1583 MIB.addSym(Symbol, MipsII::MO_JALR);
1584 else
1585 MIB.addSym(TM.getSymbol(Addr.getGlobalValue()), MipsII::MO_JALR);
1586 }
1587
1588 // Finish off the call including any return values.
1589 return finishCall(CLI, RetVT, NumBytes);
1590}
1591
1592bool MipsFastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) {
1593 switch (II->getIntrinsicID()) {
1594 default:
1595 return false;
1596 case Intrinsic::bswap: {
1597 Type *RetTy = II->getCalledFunction()->getReturnType();
1598
1599 MVT VT;
1600 if (!isTypeSupported(RetTy, VT))
1601 return false;
1602
1603 Register SrcReg = getRegForValue(II->getOperand(0));
1604 if (SrcReg == 0)
1605 return false;
1606 Register DestReg = createResultReg(&Mips::GPR32RegClass);
1607 if (DestReg == 0)
1608 return false;
1609 if (VT == MVT::i16) {
1610 if (Subtarget->hasMips32r2()) {
1611 emitInst(Mips::WSBH, DestReg).addReg(SrcReg);
1612 updateValueMap(II, DestReg);
1613 return true;
1614 } else {
1615 unsigned TempReg[3];
1616 for (unsigned &R : TempReg) {
1617 R = createResultReg(&Mips::GPR32RegClass);
1618 if (R == 0)
1619 return false;
1620 }
1621 emitInst(Mips::SLL, TempReg[0]).addReg(SrcReg).addImm(8);
1622 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(8);
1623 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[1]).addImm(0xFF);
1624 emitInst(Mips::OR, DestReg).addReg(TempReg[0]).addReg(TempReg[2]);
1625 updateValueMap(II, DestReg);
1626 return true;
1627 }
1628 } else if (VT == MVT::i32) {
1629 if (Subtarget->hasMips32r2()) {
1630 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1631 emitInst(Mips::WSBH, TempReg).addReg(SrcReg);
1632 emitInst(Mips::ROTR, DestReg).addReg(TempReg).addImm(16);
1633 updateValueMap(II, DestReg);
1634 return true;
1635 } else {
1636 unsigned TempReg[8];
1637 for (unsigned &R : TempReg) {
1638 R = createResultReg(&Mips::GPR32RegClass);
1639 if (R == 0)
1640 return false;
1641 }
1642
1643 emitInst(Mips::SRL, TempReg[0]).addReg(SrcReg).addImm(8);
1644 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(24);
1645 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[0]).addImm(0xFF00);
1646 emitInst(Mips::OR, TempReg[3]).addReg(TempReg[1]).addReg(TempReg[2]);
1647
1648 emitInst(Mips::ANDi, TempReg[4]).addReg(SrcReg).addImm(0xFF00);
1649 emitInst(Mips::SLL, TempReg[5]).addReg(TempReg[4]).addImm(8);
1650
1651 emitInst(Mips::SLL, TempReg[6]).addReg(SrcReg).addImm(24);
1652 emitInst(Mips::OR, TempReg[7]).addReg(TempReg[3]).addReg(TempReg[5]);
1653 emitInst(Mips::OR, DestReg).addReg(TempReg[6]).addReg(TempReg[7]);
1654 updateValueMap(II, DestReg);
1655 return true;
1656 }
1657 }
1658 return false;
1659 }
1660 case Intrinsic::memcpy:
1661 case Intrinsic::memmove: {
1662 const auto *MTI = cast<MemTransferInst>(II);
1663 // Don't handle volatile.
1664 if (MTI->isVolatile())
1665 return false;
1666 if (!MTI->getLength()->getType()->isIntegerTy(32))
1667 return false;
1668 const char *IntrMemName = isa<MemCpyInst>(II) ? "memcpy" : "memmove";
1669 return lowerCallTo(II, IntrMemName, II->arg_size() - 1);
1670 }
1671 case Intrinsic::memset: {
1672 const MemSetInst *MSI = cast<MemSetInst>(II);
1673 // Don't handle volatile.
1674 if (MSI->isVolatile())
1675 return false;
1676 if (!MSI->getLength()->getType()->isIntegerTy(32))
1677 return false;
1678 return lowerCallTo(II, "memset", II->arg_size() - 1);
1679 }
1680 }
1681 return false;
1682}
1683
1684bool MipsFastISel::selectRet(const Instruction *I) {
1685 const Function &F = *I->getParent()->getParent();
1686 const ReturnInst *Ret = cast<ReturnInst>(I);
1687
1688 LLVM_DEBUG(dbgs() << "selectRet\n");
1689
1690 if (!FuncInfo.CanLowerReturn)
1691 return false;
1692
1693 // Build a list of return value registers.
1694 SmallVector<unsigned, 4> RetRegs;
1695
1696 if (Ret->getNumOperands() > 0) {
1697 CallingConv::ID CC = F.getCallingConv();
1698
1699 // Do not handle FastCC.
1700 if (CC == CallingConv::Fast)
1701 return false;
1702
1704 GetReturnInfo(CC, F.getReturnType(), F.getAttributes(), Outs, TLI, DL);
1705
1706 // Analyze operands of the call, assigning locations to each operand.
1708 MipsCCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, ValLocs,
1709 I->getContext());
1710 CCAssignFn *RetCC = RetCC_Mips;
1711 CCInfo.AnalyzeReturn(Outs, RetCC);
1712
1713 // Only handle a single return value for now.
1714 if (ValLocs.size() != 1)
1715 return false;
1716
1717 CCValAssign &VA = ValLocs[0];
1718 const Value *RV = Ret->getOperand(0);
1719
1720 // Don't bother handling odd stuff for now.
1721 if ((VA.getLocInfo() != CCValAssign::Full) &&
1722 (VA.getLocInfo() != CCValAssign::BCvt))
1723 return false;
1724
1725 // Only handle register returns for now.
1726 if (!VA.isRegLoc())
1727 return false;
1728
1729 Register Reg = getRegForValue(RV);
1730 if (Reg == 0)
1731 return false;
1732
1733 unsigned SrcReg = Reg + VA.getValNo();
1734 Register DestReg = VA.getLocReg();
1735 // Avoid a cross-class copy. This is very unlikely.
1736 if (!MRI.getRegClass(SrcReg)->contains(DestReg))
1737 return false;
1738
1739 EVT RVEVT = TLI.getValueType(DL, RV->getType());
1740 if (!RVEVT.isSimple())
1741 return false;
1742
1743 if (RVEVT.isVector())
1744 return false;
1745
1746 MVT RVVT = RVEVT.getSimpleVT();
1747 if (RVVT == MVT::f128)
1748 return false;
1749
1750 // Do not handle FGR64 returns for now.
1751 if (RVVT == MVT::f64 && UnsupportedFPMode) {
1752 LLVM_DEBUG(dbgs() << ".. .. gave up (UnsupportedFPMode\n");
1753 return false;
1754 }
1755
1756 MVT DestVT = VA.getValVT();
1757 // Special handling for extended integers.
1758 if (RVVT != DestVT) {
1759 if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)
1760 return false;
1761
1762 if (Outs[0].Flags.isZExt() || Outs[0].Flags.isSExt()) {
1763 bool IsZExt = Outs[0].Flags.isZExt();
1764 SrcReg = emitIntExt(RVVT, SrcReg, DestVT, IsZExt);
1765 if (SrcReg == 0)
1766 return false;
1767 }
1768 }
1769
1770 // Make the copy.
1771 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1772 TII.get(TargetOpcode::COPY), DestReg).addReg(SrcReg);
1773
1774 // Add register to return instruction.
1775 RetRegs.push_back(VA.getLocReg());
1776 }
1777 MachineInstrBuilder MIB = emitInst(Mips::RetRA);
1778 for (unsigned Reg : RetRegs)
1779 MIB.addReg(Reg, RegState::Implicit);
1780 return true;
1781}
1782
1783bool MipsFastISel::selectTrunc(const Instruction *I) {
1784 // The high bits for a type smaller than the register size are assumed to be
1785 // undefined.
1786 Value *Op = I->getOperand(0);
1787
1788 EVT SrcVT, DestVT;
1789 SrcVT = TLI.getValueType(DL, Op->getType(), true);
1790 DestVT = TLI.getValueType(DL, I->getType(), true);
1791
1792 if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)
1793 return false;
1794 if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)
1795 return false;
1796
1797 Register SrcReg = getRegForValue(Op);
1798 if (!SrcReg)
1799 return false;
1800
1801 // Because the high bits are undefined, a truncate doesn't generate
1802 // any code.
1803 updateValueMap(I, SrcReg);
1804 return true;
1805}
1806
1807bool MipsFastISel::selectIntExt(const Instruction *I) {
1808 Type *DestTy = I->getType();
1809 Value *Src = I->getOperand(0);
1810 Type *SrcTy = Src->getType();
1811
1812 bool isZExt = isa<ZExtInst>(I);
1813 Register SrcReg = getRegForValue(Src);
1814 if (!SrcReg)
1815 return false;
1816
1817 EVT SrcEVT, DestEVT;
1818 SrcEVT = TLI.getValueType(DL, SrcTy, true);
1819 DestEVT = TLI.getValueType(DL, DestTy, true);
1820 if (!SrcEVT.isSimple())
1821 return false;
1822 if (!DestEVT.isSimple())
1823 return false;
1824
1825 MVT SrcVT = SrcEVT.getSimpleVT();
1826 MVT DestVT = DestEVT.getSimpleVT();
1827 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1828
1829 if (!emitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt))
1830 return false;
1831 updateValueMap(I, ResultReg);
1832 return true;
1833}
1834
1835bool MipsFastISel::emitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT,
1836 unsigned DestReg) {
1837 unsigned ShiftAmt;
1838 switch (SrcVT.SimpleTy) {
1839 default:
1840 return false;
1841 case MVT::i8:
1842 ShiftAmt = 24;
1843 break;
1844 case MVT::i16:
1845 ShiftAmt = 16;
1846 break;
1847 }
1848 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1849 emitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt);
1850 emitInst(Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt);
1851 return true;
1852}
1853
1854bool MipsFastISel::emitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT,
1855 unsigned DestReg) {
1856 switch (SrcVT.SimpleTy) {
1857 default:
1858 return false;
1859 case MVT::i8:
1860 emitInst(Mips::SEB, DestReg).addReg(SrcReg);
1861 break;
1862 case MVT::i16:
1863 emitInst(Mips::SEH, DestReg).addReg(SrcReg);
1864 break;
1865 }
1866 return true;
1867}
1868
1869bool MipsFastISel::emitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
1870 unsigned DestReg) {
1871 if ((DestVT != MVT::i32) && (DestVT != MVT::i16))
1872 return false;
1873 if (Subtarget->hasMips32r2())
1874 return emitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg);
1875 return emitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg);
1876}
1877
1878bool MipsFastISel::emitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
1879 unsigned DestReg) {
1880 int64_t Imm;
1881
1882 switch (SrcVT.SimpleTy) {
1883 default:
1884 return false;
1885 case MVT::i1:
1886 Imm = 1;
1887 break;
1888 case MVT::i8:
1889 Imm = 0xff;
1890 break;
1891 case MVT::i16:
1892 Imm = 0xffff;
1893 break;
1894 }
1895
1896 emitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(Imm);
1897 return true;
1898}
1899
1900bool MipsFastISel::emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
1901 unsigned DestReg, bool IsZExt) {
1902 // FastISel does not have plumbing to deal with extensions where the SrcVT or
1903 // DestVT are odd things, so test to make sure that they are both types we can
1904 // handle (i1/i8/i16/i32 for SrcVT and i8/i16/i32/i64 for DestVT), otherwise
1905 // bail out to SelectionDAG.
1906 if (((DestVT != MVT::i8) && (DestVT != MVT::i16) && (DestVT != MVT::i32)) ||
1907 ((SrcVT != MVT::i1) && (SrcVT != MVT::i8) && (SrcVT != MVT::i16)))
1908 return false;
1909 if (IsZExt)
1910 return emitIntZExt(SrcVT, SrcReg, DestVT, DestReg);
1911 return emitIntSExt(SrcVT, SrcReg, DestVT, DestReg);
1912}
1913
1914unsigned MipsFastISel::emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
1915 bool isZExt) {
1916 unsigned DestReg = createResultReg(&Mips::GPR32RegClass);
1917 bool Success = emitIntExt(SrcVT, SrcReg, DestVT, DestReg, isZExt);
1918 return Success ? DestReg : 0;
1919}
1920
1921bool MipsFastISel::selectDivRem(const Instruction *I, unsigned ISDOpcode) {
1922 EVT DestEVT = TLI.getValueType(DL, I->getType(), true);
1923 if (!DestEVT.isSimple())
1924 return false;
1925
1926 MVT DestVT = DestEVT.getSimpleVT();
1927 if (DestVT != MVT::i32)
1928 return false;
1929
1930 unsigned DivOpc;
1931 switch (ISDOpcode) {
1932 default:
1933 return false;
1934 case ISD::SDIV:
1935 case ISD::SREM:
1936 DivOpc = Mips::SDIV;
1937 break;
1938 case ISD::UDIV:
1939 case ISD::UREM:
1940 DivOpc = Mips::UDIV;
1941 break;
1942 }
1943
1944 Register Src0Reg = getRegForValue(I->getOperand(0));
1945 Register Src1Reg = getRegForValue(I->getOperand(1));
1946 if (!Src0Reg || !Src1Reg)
1947 return false;
1948
1949 emitInst(DivOpc).addReg(Src0Reg).addReg(Src1Reg);
1950 if (!Subtarget->getMCCLOpts().mno_check_zero_division &&
1951 (!isa<ConstantInt>(I->getOperand(1)) ||
1952 dyn_cast<ConstantInt>(I->getOperand(1))->isZero())) {
1953 emitInst(Mips::TEQ).addReg(Src1Reg).addReg(Mips::ZERO).addImm(7);
1954 }
1955
1956 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1957 if (!ResultReg)
1958 return false;
1959
1960 unsigned MFOpc = (ISDOpcode == ISD::SREM || ISDOpcode == ISD::UREM)
1961 ? Mips::MFHI
1962 : Mips::MFLO;
1963 emitInst(MFOpc, ResultReg);
1964
1965 updateValueMap(I, ResultReg);
1966 return true;
1967}
1968
1969bool MipsFastISel::selectShift(const Instruction *I) {
1970 MVT RetVT;
1971
1972 if (!isTypeSupported(I->getType(), RetVT))
1973 return false;
1974
1975 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1976 if (!ResultReg)
1977 return false;
1978
1979 unsigned Opcode = I->getOpcode();
1980 const Value *Op0 = I->getOperand(0);
1981 Register Op0Reg = getRegForValue(Op0);
1982 if (!Op0Reg)
1983 return false;
1984
1985 // If AShr or LShr, then we need to make sure the operand0 is sign extended.
1986 if (Opcode == Instruction::AShr || Opcode == Instruction::LShr) {
1987 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1988 if (!TempReg)
1989 return false;
1990
1991 MVT Op0MVT = TLI.getValueType(DL, Op0->getType(), true).getSimpleVT();
1992 bool IsZExt = Opcode == Instruction::LShr;
1993 if (!emitIntExt(Op0MVT, Op0Reg, MVT::i32, TempReg, IsZExt))
1994 return false;
1995
1996 Op0Reg = TempReg;
1997 }
1998
1999 if (const auto *C = dyn_cast<ConstantInt>(I->getOperand(1))) {
2000 uint64_t ShiftVal = C->getZExtValue();
2001
2002 switch (Opcode) {
2003 default:
2004 llvm_unreachable("Unexpected instruction.");
2005 case Instruction::Shl:
2006 Opcode = Mips::SLL;
2007 break;
2008 case Instruction::AShr:
2009 Opcode = Mips::SRA;
2010 break;
2011 case Instruction::LShr:
2012 Opcode = Mips::SRL;
2013 break;
2014 }
2015
2016 emitInst(Opcode, ResultReg).addReg(Op0Reg).addImm(ShiftVal);
2017 updateValueMap(I, ResultReg);
2018 return true;
2019 }
2020
2021 Register Op1Reg = getRegForValue(I->getOperand(1));
2022 if (!Op1Reg)
2023 return false;
2024
2025 switch (Opcode) {
2026 default:
2027 llvm_unreachable("Unexpected instruction.");
2028 case Instruction::Shl:
2029 Opcode = Mips::SLLV;
2030 break;
2031 case Instruction::AShr:
2032 Opcode = Mips::SRAV;
2033 break;
2034 case Instruction::LShr:
2035 Opcode = Mips::SRLV;
2036 break;
2037 }
2038
2039 emitInst(Opcode, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
2040 updateValueMap(I, ResultReg);
2041 return true;
2042}
2043
2044bool MipsFastISel::fastSelectInstruction(const Instruction *I) {
2045 switch (I->getOpcode()) {
2046 default:
2047 break;
2048 case Instruction::Load:
2049 return selectLoad(I);
2050 case Instruction::Store:
2051 return selectStore(I);
2052 case Instruction::SDiv:
2053 if (!selectBinaryOp(I, ISD::SDIV))
2054 return selectDivRem(I, ISD::SDIV);
2055 return true;
2056 case Instruction::UDiv:
2057 if (!selectBinaryOp(I, ISD::UDIV))
2058 return selectDivRem(I, ISD::UDIV);
2059 return true;
2060 case Instruction::SRem:
2061 if (!selectBinaryOp(I, ISD::SREM))
2062 return selectDivRem(I, ISD::SREM);
2063 return true;
2064 case Instruction::URem:
2065 if (!selectBinaryOp(I, ISD::UREM))
2066 return selectDivRem(I, ISD::UREM);
2067 return true;
2068 case Instruction::Shl:
2069 case Instruction::LShr:
2070 case Instruction::AShr:
2071 return selectShift(I);
2072 case Instruction::And:
2073 case Instruction::Or:
2074 case Instruction::Xor:
2075 return selectLogicalOp(I);
2076 case Instruction::CondBr:
2077 return selectBranch(I);
2078 case Instruction::Ret:
2079 return selectRet(I);
2080 case Instruction::Trunc:
2081 return selectTrunc(I);
2082 case Instruction::ZExt:
2083 case Instruction::SExt:
2084 return selectIntExt(I);
2085 case Instruction::FPTrunc:
2086 return selectFPTrunc(I);
2087 case Instruction::FPExt:
2088 return selectFPExt(I);
2089 case Instruction::FPToSI:
2090 return selectFPToInt(I, /*isSigned*/ true);
2091 case Instruction::FPToUI:
2092 return selectFPToInt(I, /*isSigned*/ false);
2093 case Instruction::ICmp:
2094 case Instruction::FCmp:
2095 return selectCmp(I);
2096 case Instruction::Select:
2097 return selectSelect(I);
2098 }
2099 return false;
2100}
2101
2102unsigned MipsFastISel::getRegEnsuringSimpleIntegerWidening(const Value *V,
2103 bool IsUnsigned) {
2104 Register VReg = getRegForValue(V);
2105 if (VReg == 0)
2106 return 0;
2107 MVT VMVT = TLI.getValueType(DL, V->getType(), true).getSimpleVT();
2108
2109 if (VMVT == MVT::i1)
2110 return 0;
2111
2112 if ((VMVT == MVT::i8) || (VMVT == MVT::i16)) {
2113 Register TempReg = createResultReg(&Mips::GPR32RegClass);
2114 if (!emitIntExt(VMVT, VReg, MVT::i32, TempReg, IsUnsigned))
2115 return 0;
2116 VReg = TempReg;
2117 }
2118 return VReg;
2119}
2120
2121void MipsFastISel::simplifyAddress(Address &Addr) {
2122 if (!isInt<16>(Addr.getOffset())) {
2123 unsigned TempReg =
2124 materialize32BitInt(Addr.getOffset(), &Mips::GPR32RegClass);
2125 Register DestReg = createResultReg(&Mips::GPR32RegClass);
2126 emitInst(Mips::ADDu, DestReg).addReg(TempReg).addReg(Addr.getReg());
2127 Addr.setReg(DestReg);
2128 Addr.setOffset(0);
2129 }
2130}
2131
2132unsigned MipsFastISel::fastEmitInst_rr(unsigned MachineInstOpcode,
2133 const TargetRegisterClass *RC,
2134 unsigned Op0, unsigned Op1) {
2135 // We treat the MUL instruction in a special way because it clobbers
2136 // the HI0 & LO0 registers. The TableGen definition of this instruction can
2137 // mark these registers only as implicitly defined. As a result, the
2138 // register allocator runs out of registers when this instruction is
2139 // followed by another instruction that defines the same registers too.
2140 // We can fix this by explicitly marking those registers as dead.
2141 if (MachineInstOpcode == Mips::MUL) {
2142 Register ResultReg = createResultReg(RC);
2143 const MCInstrDesc &II = TII.get(MachineInstOpcode);
2144 Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs());
2145 Op1 = constrainOperandRegClass(II, Op1, II.getNumDefs() + 1);
2146 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)
2147 .addReg(Op0)
2148 .addReg(Op1)
2149 .setOperandDead(3) // implicit-def $hi0
2150 .setOperandDead(4); // implicit-def $lo0
2151 return ResultReg;
2152 }
2153
2154 return FastISel::fastEmitInst_rr(MachineInstOpcode, RC, Op0, Op1);
2155}
2156
2157namespace llvm {
2158
2160 const TargetLibraryInfo *libInfo,
2161 const LibcallLoweringInfo *libcallLowering) {
2162 return new MipsFastISel(funcInfo, libInfo, libcallLowering);
2163}
2164
2165} // end namespace llvm
#define Success
static unsigned selectBinaryOp(unsigned GenericOpc, unsigned RegBankID, unsigned OpSize)
Select the AArch64 opcode for the basic binary operation GenericOpc, appropriate for the register ban...
static void emitLoad(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator Pos, const TargetInstrInfo &TII, unsigned Reg1, unsigned Reg2, int Offset, bool IsPostDec)
Emit a load-pair instruction for frame-destroy.
static void emitStore(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator Pos, const TargetInstrInfo &TII, unsigned Reg1, unsigned Reg2, int Offset, bool IsPreDec)
Emit a store-pair instruction for frame-setup.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned Imm
unsigned uint64_t
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This file defines the FastISel class.
const HexagonInstrInfo * TII
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool CC_Mips(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static bool CC_MipsO32_FP64(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static bool CC_MipsO32_FP32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State, ArrayRef< MCPhysReg > F64Regs)
uint64_t IntrinsicInst * II
#define P(N)
if(PassOpts->AAPipeline)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
static SDValue emitCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
This file describes how to lower LLVM code to machine code.
Value * RHS
Value * LHS
APInt bitcastToAPInt() const
Definition APFloat.h:1475
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1560
an instruction to allocate memory on the stack
PointerType * getType() const
Overload to return most specific pointer type.
iterator end() const
Definition ArrayRef.h:130
iterator begin() const
Definition ArrayRef.h:129
CCState - This class holds information needed while lowering arguments and return values.
void convertToReg(MCRegister Reg)
Register getLocReg() const
LocInfo getLocInfo() const
bool needsCustom() const
int64_t getLocMemOffset() const
unsigned getValNo() const
This class is the base class for the comparison instructions.
Definition InstrTypes.h:728
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
Definition InstrTypes.h:743
@ ICMP_SLT
signed less than
Definition InstrTypes.h:769
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:770
@ FCMP_OLT
0 1 0 0 True if ordered and less than
Definition InstrTypes.h:746
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
Definition InstrTypes.h:744
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
Definition InstrTypes.h:745
@ ICMP_UGE
unsigned greater or equal
Definition InstrTypes.h:764
@ ICMP_UGT
unsigned greater than
Definition InstrTypes.h:763
@ ICMP_SGT
signed greater than
Definition InstrTypes.h:767
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:765
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
Definition InstrTypes.h:747
@ ICMP_NE
not equal
Definition InstrTypes.h:762
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:768
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
Definition InstrTypes.h:756
@ ICMP_ULE
unsigned less or equal
Definition InstrTypes.h:766
Predicate getPredicate() const
Return the predicate for this instruction.
Definition InstrTypes.h:828
bool isUnsigned() const
Definition InstrTypes.h:999
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
ConstantFP - Floating Point Values [float, double].
Definition Constants.h:420
const APFloat & getValueAPF() const
Definition Constants.h:463
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
Definition Constants.h:174
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Definition Constants.h:168
This is an important base class in LLVM.
Definition Constant.h:43
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
Definition FastISel.h:67
Register fastEmitInst_rr(unsigned MachineInstOpcode, const TargetRegisterClass *RC, Register Op0, Register Op1)
Emit a MachineInstr with two register operands and a result register in the given register class.
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:356
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
bool hasLocalLinkage() const
LLVM_ABI bool isAtomic() const LLVM_READONLY
Return true if this instruction has an AtomicOrdering of unordered or higher.
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
Tracks which library functions to use for a particular subtarget or function.
Align getAlign() const
Return the alignment of the access that is being performed.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
Machine Value Type.
SimpleValueType SimpleTy
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & setOperandDead(unsigned OpIdx) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Value * getLength() const
bool isVolatile() const
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
Register getGlobalBaseReg(MachineFunction &MF)
bool isFP64bit() const
bool useSoftFloat() const
const MipsInstrInfo * getInstrInfo() const override
bool inMips16Mode() const
bool systemSupportsUnalignedAccess() const
Does the system support unaligned memory access.
bool hasMips32r2() const
const MipsTargetLowering * getTargetLowering() const override
const MipsABIInfo & getABI() const
const MipsMCOptions & getMCCLOpts() const
Wrapper class representing virtual and physical registers.
Definition Register.h:20
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void push_back(const T &Elt)
TypeSize getElementOffset(unsigned Idx) const
Definition DataLayout.h:774
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
MCSymbol * getSymbol(const GlobalValue *GV) const
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:283
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
const Use * const_op_iterator
Definition User.h:255
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:441
TypeSize getSequentialElementStride(const DataLayout &DL) const
const ParentTy * getParent() const
Definition ilist_node.h:34
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:749
Flag
These should be considered private to the implementation of the MCInstrDesc class.
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo, const LibcallLoweringInfo *libcallLowering)
WebAssemblyABI getABI(StringRef Name)
Parse an ABI name into the corresponding enum.
@ User
could "use" a pointer
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
LLVM_ABI Register constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const TargetRegisterClass &RegClass, MachineOperand &RegMO)
Constrain the Register operand OpIdx, so that it is now constrained to the TargetRegisterClass passed...
Definition Utils.cpp:60
LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:149
generic_gep_type_iterator<> gep_type_iterator
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
gep_type_iterator gep_type_begin(const User *GEP)
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition ValueTypes.h:145
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:339
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:176
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.