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