LLVM: lib/Target/Mips/MipsFastISel.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
67#include
68#include
69#include
70#include
71
72#define DEBUG_TYPE "mips-fastisel"
73
74using namespace llvm;
75
77
78namespace {
79
80class MipsFastISel final : public FastISel {
81
82
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;
93
95
97
98 public:
99
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!");
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_; }
129 void setGlobalValue(const GlobalValue *G) { GV = G; }
130 const GlobalValue *getGlobalValue() { return GV; }
131 };
132
133
134
140
141
143
144 bool fastLowerArguments() override;
145 bool fastLowerCall(CallLoweringInfo &CLI) override;
146 bool fastLowerIntrinsicCall(const IntrinsicInst *II) override;
147
148 bool UnsupportedFPMode;
149
150
151
152private:
153
162 bool selectFPToInt(const Instruction *I, bool IsSigned);
167 bool selectDivRem(const Instruction *I, unsigned ISDOpcode);
168
169
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
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,
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
205 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc));
206 }
207
209 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc),
210 DstReg);
211 }
212
214 unsigned MemReg, int64_t MemOffset) {
216 }
217
219 unsigned MemReg, int64_t MemOffset) {
220 return emitInst(Opc, DstReg).addReg(MemReg).addImm(MemOffset);
221 }
222
223 unsigned fastEmitInst_rr(unsigned MachineInstOpcode,
225 unsigned Op0, unsigned Op1);
226
227
228
231 unsigned Op3) {
232 return 0;
233 }
234
235
236private:
239 unsigned &NumBytes);
240 bool finishCall(CallLoweringInfo &CLI, MVT RetVT, unsigned NumBytes);
241
244 }
245
246public:
247
256 }
257
260 bool fastSelectInstruction(const Instruction *I) override;
261
262#include "MipsGenFastISel.inc"
263};
264
265}
266
267[[maybe_unused]] static bool CC_Mips(unsigned ValNo, MVT ValVT, MVT LocVT,
271
278
285
286#include "MipsGenCallingConv.inc"
287
290}
291
292unsigned MipsFastISel::emitLogicalOp(unsigned ISDOpc, MVT RetVT,
294
297
298 unsigned Opc;
299 switch (ISDOpc) {
301 Opc = Mips::AND;
302 break;
304 Opc = Mips::OR;
305 break;
307 Opc = Mips::XOR;
308 break;
309 default:
311 }
312
314 if (!LHSReg)
315 return 0;
316
317 unsigned RHSReg;
319 RHSReg = materializeInt(C, MVT::i32);
320 else
321 RHSReg = getRegForValue(RHS);
322 if (!RHSReg)
323 return 0;
324
325 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
326 if (!ResultReg)
327 return 0;
328
329 emitInst(Opc, ResultReg).addReg(LHSReg).addReg(RHSReg);
330 return ResultReg;
331}
332
333Register MipsFastISel::fastMaterializeAlloca(const AllocaInst *AI) {
335 "Alloca should always return a pointer.");
336
337 DenseMap<const AllocaInst *, int>::iterator SI =
338 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)
346 return ResultReg;
347 }
348
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;
357 return materialize32BitInt(CI->getZExtValue(), RC);
358}
359
360unsigned MipsFastISel::materialize32BitInt(int64_t Imm,
361 const TargetRegisterClass *RC) {
362 Register ResultReg = createResultReg(RC);
363
365 unsigned Opc = Mips::ADDiu;
366 emitInst(Opc, ResultReg).addReg(Mips::ZERO).addImm(Imm);
367 return ResultReg;
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
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;
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
409 if (VT != MVT::i32)
410 return 0;
411 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
412 Register DestReg = createResultReg(RC);
414 bool IsThreadLocal = GVar && GVar->isThreadLocal();
415
416 if (IsThreadLocal)
417 return 0;
418 emitInst(Mips::LW, DestReg)
423 Register TempReg = createResultReg(RC);
424 emitInst(Mips::ADDiu, TempReg)
425 .addReg(DestReg)
427 DestReg = TempReg;
428 }
429 return DestReg;
430}
431
432unsigned MipsFastISel::materializeExternalCallSym(MCSymbol *Sym) {
433 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
434 Register DestReg = createResultReg(RC);
435 emitInst(Mips::LW, DestReg)
438 return DestReg;
439}
440
441
442
443Register MipsFastISel::fastMaterializeConstant(const Constant *C) {
445
446
450
452 return (UnsupportedFPMode) ? 0 : materializeFP(CFP, VT);
454 return materializeGV(GV, VT);
456 return materializeInt(C, VT);
457
459}
460
461bool MipsFastISel::computeAddress(const Value *Obj, Address &Addr) {
463 unsigned Opcode = Instruction::UserOp1;
465
466
467 if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(Obj)) ||
468 FuncInfo.getMBB(I->getParent()) == FuncInfo.MBB) {
469 Opcode = I->getOpcode();
471 }
473 Opcode = C->getOpcode();
475 }
476 switch (Opcode) {
477 default:
478 break;
479 case Instruction::BitCast:
480
481 return computeAddress(U->getOperand(0), Addr);
482 case Instruction::GetElementPtr: {
483 Address SavedAddr = Addr;
484 int64_t TmpOffset = Addr.getOffset();
485
486
489 ++i, ++GTI) {
492 const StructLayout *SL = DL.getStructLayout(STy);
495 } else {
497 while (true) {
499
500 TmpOffset += CI->getSExtValue() * S;
501 break;
502 }
503 if (canFoldAddIntoGEP(U, Op)) {
504
505 ConstantInt *CI =
508
510 continue;
511 }
512
513 goto unsupported_gep;
514 }
515 }
516 }
517
518 Addr.setOffset(TmpOffset);
519 if (computeAddress(U->getOperand(0), Addr))
520 return true;
521
522 Addr = SavedAddr;
523 unsupported_gep:
524 break;
525 }
526 case Instruction::Alloca: {
528 DenseMap<const AllocaInst *, int>::iterator SI =
529 FuncInfo.StaticAllocaMap.find(AI);
530 if (SI != FuncInfo.StaticAllocaMap.end()) {
531 Addr.setKind(Address::FrameIndexBase);
532 Addr.setFI(SI->second);
533 return true;
534 }
535 break;
536 }
537 }
538 Addr.setReg(getRegForValue(Obj));
539 return Addr.getReg() != 0;
540}
541
542bool MipsFastISel::computeCallAddress(const Value *V, Address &Addr) {
544 unsigned Opcode = Instruction::UserOp1;
545
547
548
549 if (I->getParent() == FuncInfo.MBB->getBasicBlock()) {
550 Opcode = I->getOpcode();
552 }
554 Opcode = C->getOpcode();
556 }
557
558 switch (Opcode) {
559 default:
560 break;
561 case Instruction::BitCast:
562
563 return computeCallAddress(U->getOperand(0), Addr);
564 break;
565 case Instruction::IntToPtr:
566
569 return computeCallAddress(U->getOperand(0), Addr);
570 break;
571 case Instruction::PtrToInt:
572
574 return computeCallAddress(U->getOperand(0), Addr);
575 break;
576 }
577
579 Addr.setGlobalValue(GV);
580 return true;
581 }
582
583
584 if (!Addr.getGlobalValue()) {
585 Addr.setReg(getRegForValue(V));
586 return Addr.getReg() != 0;
587 }
588
589 return false;
590}
591
592bool MipsFastISel::isTypeLegal(Type *Ty, MVT &VT) {
594
595 if (evt == MVT::Other || !evt.isSimple())
596 return false;
598
599
600
602}
603
604bool MipsFastISel::isTypeSupported(Type *Ty, MVT &VT) {
606 return false;
607
608 if (isTypeLegal(Ty, VT))
609 return true;
610
611
612
613 if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)
614 return true;
615
616 return false;
617}
618
619bool MipsFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) {
620 if (isTypeLegal(Ty, VT))
621 return true;
622
623
624
625 if (VT == MVT::i8 || VT == MVT::i16)
626 return true;
627 return false;
628}
629
630
631
632
633
634bool MipsFastISel::emitCmp(unsigned ResultReg, const CmpInst *CI) {
637 unsigned LeftReg = getRegEnsuringSimpleIntegerWidening(Left, IsUnsigned);
638 if (LeftReg == 0)
639 return false;
640 unsigned RightReg = getRegEnsuringSimpleIntegerWidening(Right, IsUnsigned);
641 if (RightReg == 0)
642 return false;
644
645 switch (P) {
646 default:
647 return false;
649 Register TempReg = createResultReg(&Mips::GPR32RegClass);
650 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
651 emitInst(Mips::SLTiu, ResultReg).addReg(TempReg).addImm(1);
652 break;
653 }
655 Register TempReg = createResultReg(&Mips::GPR32RegClass);
656 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
657 emitInst(Mips::SLTu, ResultReg).addReg(Mips::ZERO).addReg(TempReg);
658 break;
659 }
661 emitInst(Mips::SLTu, ResultReg).addReg(RightReg).addReg(LeftReg);
662 break;
664 emitInst(Mips::SLTu, ResultReg).addReg(LeftReg).addReg(RightReg);
665 break;
667 Register TempReg = createResultReg(&Mips::GPR32RegClass);
668 emitInst(Mips::SLTu, TempReg).addReg(LeftReg).addReg(RightReg);
669 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
670 break;
671 }
673 Register TempReg = createResultReg(&Mips::GPR32RegClass);
674 emitInst(Mips::SLTu, TempReg).addReg(RightReg).addReg(LeftReg);
675 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
676 break;
677 }
679 emitInst(Mips::SLT, ResultReg).addReg(RightReg).addReg(LeftReg);
680 break;
682 emitInst(Mips::SLT, ResultReg).addReg(LeftReg).addReg(RightReg);
683 break;
685 Register TempReg = createResultReg(&Mips::GPR32RegClass);
686 emitInst(Mips::SLT, TempReg).addReg(LeftReg).addReg(RightReg);
687 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
688 break;
689 }
691 Register TempReg = createResultReg(&Mips::GPR32RegClass);
692 emitInst(Mips::SLT, TempReg).addReg(RightReg).addReg(LeftReg);
693 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
694 break;
695 }
702 if (UnsupportedFPMode)
703 return false;
704 bool IsFloat = Left->getType()->isFloatTy();
705 bool IsDouble = Left->getType()->isDoubleTy();
706 if (!IsFloat && !IsDouble)
707 return false;
708 unsigned Opc, CondMovOpc;
709 switch (P) {
711 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
712 CondMovOpc = Mips::MOVT_I;
713 break;
715 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
716 CondMovOpc = Mips::MOVF_I;
717 break;
719 Opc = IsFloat ? Mips::C_OLT_S : Mips::C_OLT_D32;
720 CondMovOpc = Mips::MOVT_I;
721 break;
723 Opc = IsFloat ? Mips::C_OLE_S : Mips::C_OLE_D32;
724 CondMovOpc = Mips::MOVT_I;
725 break;
727 Opc = IsFloat ? Mips::C_ULE_S : Mips::C_ULE_D32;
728 CondMovOpc = Mips::MOVF_I;
729 break;
731 Opc = IsFloat ? Mips::C_ULT_S : Mips::C_ULT_D32;
732 CondMovOpc = Mips::MOVF_I;
733 break;
734 default:
736 }
737 Register RegWithZero = createResultReg(&Mips::GPR32RegClass);
738 Register RegWithOne = createResultReg(&Mips::GPR32RegClass);
739 emitInst(Mips::ADDiu, RegWithZero).addReg(Mips::ZERO).addImm(0);
740 emitInst(Mips::ADDiu, RegWithOne).addReg(Mips::ZERO).addImm(1);
742 .addReg(RightReg);
743 emitInst(CondMovOpc, ResultReg)
744 .addReg(RegWithOne)
745 .addReg(Mips::FCC0)
746 .addReg(RegWithZero);
747 break;
748 }
749 }
750 return true;
751}
752
753bool MipsFastISel::emitLoad(MVT VT, unsigned &ResultReg, Address &Addr) {
754
755
756
757 unsigned Opc;
759 case MVT::i32:
760 ResultReg = createResultReg(&Mips::GPR32RegClass);
761 Opc = Mips::LW;
762 break;
763 case MVT::i16:
764 ResultReg = createResultReg(&Mips::GPR32RegClass);
765 Opc = Mips::LHu;
766 break;
767 case MVT::i8:
768 ResultReg = createResultReg(&Mips::GPR32RegClass);
769 Opc = Mips::LBu;
770 break;
771 case MVT::f32:
772 if (UnsupportedFPMode)
773 return false;
774 ResultReg = createResultReg(&Mips::FGR32RegClass);
775 Opc = Mips::LWC1;
776 break;
777 case MVT::f64:
778 if (UnsupportedFPMode)
779 return false;
780 ResultReg = createResultReg(&Mips::AFGR64RegClass);
781 Opc = Mips::LDC1;
782 break;
783 default:
784 return false;
785 }
786 if (Addr.isRegBase()) {
787 simplifyAddress(Addr);
788 emitInstLoad(Opc, ResultReg, Addr.getReg(), Addr.getOffset());
789 return true;
790 }
791 if (Addr.isFIBase()) {
792 unsigned FI = Addr.getFI();
793 int64_t Offset = Addr.getOffset();
794 MachineFrameInfo &MFI = MF->getFrameInfo();
795 MachineMemOperand *MMO = MF->getMachineMemOperand(
798 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ResultReg)
802 return true;
803 }
804 return false;
805}
806
807bool MipsFastISel::emitStore(MVT VT, unsigned SrcReg, Address &Addr) {
808
809
810
811 unsigned Opc;
813 case MVT::i8:
814 Opc = Mips::SB;
815 break;
816 case MVT::i16:
817 Opc = Mips::SH;
818 break;
819 case MVT::i32:
820 Opc = Mips::SW;
821 break;
822 case MVT::f32:
823 if (UnsupportedFPMode)
824 return false;
825 Opc = Mips::SWC1;
826 break;
827 case MVT::f64:
828 if (UnsupportedFPMode)
829 return false;
830 Opc = Mips::SDC1;
831 break;
832 default:
833 return false;
834 }
835 if (Addr.isRegBase()) {
836 simplifyAddress(Addr);
837 emitInstStore(Opc, SrcReg, Addr.getReg(), Addr.getOffset());
838 return true;
839 }
840 if (Addr.isFIBase()) {
841 unsigned FI = Addr.getFI();
842 int64_t Offset = Addr.getOffset();
843 MachineFrameInfo &MFI = MF->getFrameInfo();
844 MachineMemOperand *MMO = MF->getMachineMemOperand(
847 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc))
852 return true;
853 }
854 return false;
855}
856
857bool MipsFastISel::selectLogicalOp(const Instruction *I) {
858 MVT VT;
859 if (!isTypeSupported(I->getType(), VT))
860 return false;
861
862 unsigned ResultReg;
863 switch (I->getOpcode()) {
864 default:
866 case Instruction::And:
867 ResultReg = emitLogicalOp(ISD::AND, VT, I->getOperand(0), I->getOperand(1));
868 break;
869 case Instruction::Or:
870 ResultReg = emitLogicalOp(ISD::OR, VT, I->getOperand(0), I->getOperand(1));
871 break;
872 case Instruction::Xor:
873 ResultReg = emitLogicalOp(ISD::XOR, VT, I->getOperand(0), I->getOperand(1));
874 break;
875 }
876
877 if (!ResultReg)
878 return false;
879
880 updateValueMap(I, ResultReg);
881 return true;
882}
883
884bool MipsFastISel::selectLoad(const Instruction *I) {
886
887
889 return false;
890
891
892 MVT VT;
893 if (!isLoadTypeLegal(LI->getType(), VT))
894 return false;
895
896
899 return false;
900
901
903 if (!computeAddress(LI->getOperand(0), Addr))
904 return false;
905
906 unsigned ResultReg;
907 if ((VT, ResultReg, Addr))
908 return false;
909 updateValueMap(LI, ResultReg);
910 return true;
911}
912
913bool MipsFastISel::selectStore(const Instruction *I) {
915
916 Value *Op0 = SI->getOperand(0);
917 unsigned SrcReg = 0;
918
919
920 if (SI->isAtomic())
921 return false;
922
923
924 MVT VT;
925 if (!isLoadTypeLegal(SI->getOperand(0)->getType(), VT))
926 return false;
927
928
931 return false;
932
933
934 SrcReg = getRegForValue(Op0);
935 if (SrcReg == 0)
936 return false;
937
938
940 if (!computeAddress(SI->getOperand(1), Addr))
941 return false;
942
943 if ((VT, SrcReg, Addr))
944 return false;
945 return true;
946}
947
948
949
950bool MipsFastISel::selectBranch(const Instruction *I) {
952 MachineBasicBlock *BrBB = FuncInfo.MBB;
953
954
955
956
957
958
959
960 MachineBasicBlock *TBB = FuncInfo.getMBB(BI->getSuccessor(0));
961 MachineBasicBlock *FBB = FuncInfo.getMBB(BI->getSuccessor(1));
962
963
964
965 unsigned ZExtCondReg = 0;
968 ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
969 if ((ZExtCondReg, CI))
970 return false;
971 }
972 }
973
974
975 if (ZExtCondReg == 0) {
977 if (CondReg == 0)
978 return false;
979
980 ZExtCondReg = emitIntExt(MVT::i1, CondReg, MVT::i32, true);
981 if (ZExtCondReg == 0)
982 return false;
983 }
984
985 BuildMI(*BrBB, FuncInfo.InsertPt, MIMD, TII.get(Mips::BGTZ))
989 return true;
990}
991
992bool MipsFastISel::selectCmp(const Instruction *I) {
994 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
995 if ((ResultReg, CI))
996 return false;
997 updateValueMap(I, ResultReg);
998 return true;
999}
1000
1001
1002bool MipsFastISel::selectFPExt(const Instruction *I) {
1003 if (UnsupportedFPMode)
1004 return false;
1005 Value *Src = I->getOperand(0);
1006 EVT SrcVT = TLI.getValueType(DL, Src->getType(), true);
1008
1009 if (SrcVT != MVT::f32 || DestVT != MVT::f64)
1010 return false;
1011
1013 getRegForValue(Src);
1014
1015 if (!SrcReg)
1016 return false;
1017
1018 Register DestReg = createResultReg(&Mips::AFGR64RegClass);
1019 emitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg);
1020 updateValueMap(I, DestReg);
1021 return true;
1022}
1023
1024bool MipsFastISel::selectSelect(const Instruction *I) {
1026
1028
1029 MVT VT;
1030 if (!isTypeSupported(I->getType(), VT) || UnsupportedFPMode) {
1032 dbgs() << ".. .. gave up (!isTypeSupported || UnsupportedFPMode)\n");
1033 return false;
1034 }
1035
1036 unsigned CondMovOpc;
1037 const TargetRegisterClass *RC;
1038
1040 CondMovOpc = Mips::MOVN_I_I;
1041 RC = &Mips::GPR32RegClass;
1042 } else if (VT == MVT::f32) {
1043 CondMovOpc = Mips::MOVN_I_S;
1044 RC = &Mips::FGR32RegClass;
1045 } else if (VT == MVT::f64) {
1046 CondMovOpc = Mips::MOVN_I_D32;
1047 RC = &Mips::AFGR64RegClass;
1048 } else
1049 return false;
1050
1053 Register Src1Reg = getRegForValue(SI->getTrueValue());
1054 Register Src2Reg = getRegForValue(SI->getFalseValue());
1056
1057 if (!Src1Reg || !Src2Reg || !CondReg)
1058 return false;
1059
1060 Register ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
1061 if (!ZExtCondReg)
1062 return false;
1063
1064 if (!emitIntExt(MVT::i1, CondReg, MVT::i32, ZExtCondReg, true))
1065 return false;
1066
1067 Register ResultReg = createResultReg(RC);
1068 Register TempReg = createResultReg(RC);
1069
1070 if (!ResultReg || !TempReg)
1071 return false;
1072
1073 emitInst(TargetOpcode::COPY, TempReg).addReg(Src2Reg);
1074 emitInst(CondMovOpc, ResultReg)
1075 .addReg(Src1Reg).addReg(ZExtCondReg).addReg(TempReg);
1076 updateValueMap(I, ResultReg);
1077 return true;
1078}
1079
1080
1081bool MipsFastISel::selectFPTrunc(const Instruction *I) {
1082 if (UnsupportedFPMode)
1083 return false;
1084 Value *Src = I->getOperand(0);
1085 EVT SrcVT = TLI.getValueType(DL, Src->getType(), true);
1087
1088 if (SrcVT != MVT::f64 || DestVT != MVT::f32)
1089 return false;
1090
1091 Register SrcReg = getRegForValue(Src);
1092 if (!SrcReg)
1093 return false;
1094
1095 Register DestReg = createResultReg(&Mips::FGR32RegClass);
1096 if (!DestReg)
1097 return false;
1098
1099 emitInst(Mips::CVT_S_D32, DestReg).addReg(SrcReg);
1100 updateValueMap(I, DestReg);
1101 return true;
1102}
1103
1104
1105bool MipsFastISel::selectFPToInt(const Instruction *I, bool IsSigned) {
1106 if (UnsupportedFPMode)
1107 return false;
1108 MVT DstVT, SrcVT;
1109 if (!IsSigned)
1110 return false;
1111
1112 Type *DstTy = I->getType();
1113 if (!isTypeLegal(DstTy, DstVT))
1114 return false;
1115
1116 if (DstVT != MVT::i32)
1117 return false;
1118
1119 Value *Src = I->getOperand(0);
1120 Type *SrcTy = Src->getType();
1121 if (!isTypeLegal(SrcTy, SrcVT))
1122 return false;
1123
1124 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
1125 return false;
1126
1127 Register SrcReg = getRegForValue(Src);
1128 if (SrcReg == 0)
1129 return false;
1130
1131
1132
1133 Register DestReg = createResultReg(&Mips::GPR32RegClass);
1134 Register TempReg = createResultReg(&Mips::FGR32RegClass);
1135 unsigned Opc = (SrcVT == MVT::f32) ? Mips::TRUNC_W_S : Mips::TRUNC_W_D32;
1136
1137
1138 emitInst(Opc, TempReg).addReg(SrcReg);
1139 emitInst(Mips::MFC1, DestReg).addReg(TempReg);
1140
1141 updateValueMap(I, DestReg);
1142 return true;
1143}
1144
1145bool MipsFastISel::processCallArgs(CallLoweringInfo &CLI,
1146 SmallVectorImpl &OutVTs,
1147 unsigned &NumBytes) {
1148 CallingConv::ID CC = CLI.CallConv;
1151 for (const ArgListEntry &Arg : CLI.Args)
1152 ArgTys.push_back(Arg.Val->getType());
1153 CCState CCInfo(CC, false, *FuncInfo.MF, ArgLocs, *Context);
1154 CCInfo.AnalyzeCallOperands(OutVTs, CLI.OutFlags, ArgTys,
1155 CCAssignFnForCall(CC));
1156
1157 NumBytes = CCInfo.getStackSize();
1158
1159 if (NumBytes < 16)
1160 NumBytes = 16;
1161
1162 emitInst(Mips::ADJCALLSTACKDOWN).addImm(16).addImm(0);
1163
1164 MVT firstMVT;
1165 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
1166 CCValAssign &VA = ArgLocs[i];
1167 const Value *ArgVal = CLI.OutVals[VA.getValNo()];
1168 MVT ArgVT = OutVTs[VA.getValNo()];
1169
1170 if (i == 0) {
1171 firstMVT = ArgVT;
1172 if (ArgVT == MVT::f32) {
1174 } else if (ArgVT == MVT::f64) {
1177 else
1179 }
1180 } else if (i == 1) {
1181 if ((firstMVT == MVT::f32) || (firstMVT == MVT::f64)) {
1182 if (ArgVT == MVT::f32) {
1184 } else if (ArgVT == MVT::f64) {
1187 else
1189 }
1190 }
1191 }
1192 if (((ArgVT == MVT::i32) || (ArgVT == MVT::f32) || (ArgVT == MVT::i16) ||
1193 (ArgVT == MVT::i8)) &&
1196 case 0:
1198 break;
1199 case 4:
1201 break;
1202 case 8:
1204 break;
1205 case 12:
1207 break;
1208 default:
1209 break;
1210 }
1211 }
1212 Register ArgReg = getRegForValue(ArgVal);
1213 if (!ArgReg)
1214 return false;
1215
1216
1219 break;
1223 MVT SrcVT = ArgVT;
1224 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT, false);
1225 if (!ArgReg)
1226 return false;
1227 break;
1228 }
1231 MVT SrcVT = ArgVT;
1232 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT, true);
1233 if (!ArgReg)
1234 return false;
1235 break;
1236 }
1237 default:
1239 }
1240
1241
1243 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1245 CLI.OutRegs.push_back(VA.getLocReg());
1248 return false;
1249 } else {
1250
1251
1252
1253
1254
1255 assert(VA.isMemLoc() && "Assuming store on stack.");
1256
1258 continue;
1259
1260
1261
1262
1263
1264
1266
1267 unsigned BEAlign = 0;
1268 if (ArgSize < 8 && !Subtarget->isLittle())
1269 BEAlign = 8 - ArgSize;
1270
1272 Addr.setKind(Address::RegBase);
1273 Addr.setReg(Mips::SP);
1275
1276 Align Alignment = DL.getABITypeAlign(ArgVal->getType());
1277 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
1280 (void)(MMO);
1281
1282 return false;
1283 }
1284 }
1285
1286 return true;
1287}
1288
1289bool MipsFastISel::finishCall(CallLoweringInfo &CLI, MVT RetVT,
1290 unsigned NumBytes) {
1291 CallingConv::ID CC = CLI.CallConv;
1292 emitInst(Mips::ADJCALLSTACKUP).addImm(16).addImm(0);
1293 if (RetVT != MVT::isVoid) {
1295 MipsCCState CCInfo(CC, false, *FuncInfo.MF, RVLocs, *Context);
1296
1297 CCInfo.AnalyzeCallResult(CLI.Ins, RetCC_Mips);
1298
1299
1300 if (RVLocs.size() != 1)
1301 return false;
1302
1303 MVT CopyVT = RVLocs[0].getValVT();
1304
1305 if (RetVT == MVT::i1 || RetVT == MVT::i8 || RetVT == MVT::i16)
1306 CopyVT = MVT::i32;
1307
1309 if (!ResultReg)
1310 return false;
1311 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1312 TII.get(TargetOpcode::COPY),
1313 ResultReg).addReg(RVLocs[0].getLocReg());
1314 CLI.InRegs.push_back(RVLocs[0].getLocReg());
1315
1316 CLI.ResultReg = ResultReg;
1317 CLI.NumResultRegs = 1;
1318 }
1319 return true;
1320}
1321
1322bool MipsFastISel::fastLowerArguments() {
1324
1325 if (!FuncInfo.CanLowerReturn) {
1326 LLVM_DEBUG(dbgs() << ".. gave up (!CanLowerReturn)\n");
1327 return false;
1328 }
1329
1330 const Function *F = FuncInfo.Fn;
1331 if (F->isVarArg()) {
1333 return false;
1334 }
1335
1336 CallingConv::ID CC = F->getCallingConv();
1337 if (CC != CallingConv::C) {
1338 LLVM_DEBUG(dbgs() << ".. gave up (calling convention is not C)\n");
1339 return false;
1340 }
1341
1342 std::array<MCPhysReg, 4> GPR32ArgRegs = {{Mips::A0, Mips::A1, Mips::A2,
1343 Mips::A3}};
1344 std::array<MCPhysReg, 2> FGR32ArgRegs = {{Mips::F12, Mips::F14}};
1345 std::array<MCPhysReg, 2> AFGR64ArgRegs = {{Mips::D6, Mips::D7}};
1346 auto NextGPR32 = GPR32ArgRegs.begin();
1347 auto NextFGR32 = FGR32ArgRegs.begin();
1348 auto NextAFGR64 = AFGR64ArgRegs.begin();
1349
1350 struct AllocatedReg {
1351 const TargetRegisterClass *RC;
1352 unsigned Reg;
1353 AllocatedReg(const TargetRegisterClass *RC, unsigned Reg)
1355 };
1356
1357
1358
1360 for (const auto &FormalArg : F->args()) {
1361 if (FormalArg.hasAttribute(Attribute::InReg) ||
1362 FormalArg.hasAttribute(Attribute::StructRet) ||
1363 FormalArg.hasAttribute(Attribute::ByVal)) {
1364 LLVM_DEBUG(dbgs() << ".. gave up (inreg, structret, byval)\n");
1365 return false;
1366 }
1367
1368 Type *ArgTy = FormalArg.getType();
1369 if (ArgTy->isStructTy() || ArgTy->isArrayTy() || ArgTy->isVectorTy()) {
1370 LLVM_DEBUG(dbgs() << ".. gave up (struct, array, or vector)\n");
1371 return false;
1372 }
1373
1375 LLVM_DEBUG(dbgs() << ".. " << FormalArg.getArgNo() << ": "
1376 << ArgVT << "\n");
1377 if (!ArgVT.isSimple()) {
1378 LLVM_DEBUG(dbgs() << ".. .. gave up (not a simple type)\n");
1379 return false;
1380 }
1381
1382 switch (ArgVT.getSimpleVT().SimpleTy) {
1383 case MVT::i1:
1384 case MVT::i8:
1385 case MVT::i16:
1386 if (!FormalArg.hasAttribute(Attribute::SExt) &&
1387 !FormalArg.hasAttribute(Attribute::ZExt)) {
1388
1389
1390 LLVM_DEBUG(dbgs() << ".. .. gave up (i8/i16 arg is not extended)\n");
1391 return false;
1392 }
1393
1394 if (NextGPR32 == GPR32ArgRegs.end()) {
1395 LLVM_DEBUG(dbgs() << ".. .. gave up (ran out of GPR32 arguments)\n");
1396 return false;
1397 }
1398
1399 LLVM_DEBUG(dbgs() << ".. .. GPR32(" << *NextGPR32 << ")\n");
1400 Allocation.emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1401
1402
1403 NextFGR32 = FGR32ArgRegs.end();
1404 NextAFGR64 = AFGR64ArgRegs.end();
1405 break;
1406
1407 case MVT::i32:
1408 if (FormalArg.hasAttribute(Attribute::ZExt)) {
1409
1410 LLVM_DEBUG(dbgs() << ".. .. gave up (i32 arg is zero extended)\n");
1411 return false;
1412 }
1413
1414 if (NextGPR32 == GPR32ArgRegs.end()) {
1415 LLVM_DEBUG(dbgs() << ".. .. gave up (ran out of GPR32 arguments)\n");
1416 return false;
1417 }
1418
1419 LLVM_DEBUG(dbgs() << ".. .. GPR32(" << *NextGPR32 << ")\n");
1420 Allocation.emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1421
1422
1423 NextFGR32 = FGR32ArgRegs.end();
1424 NextAFGR64 = AFGR64ArgRegs.end();
1425 break;
1426
1427 case MVT::f32:
1428 if (UnsupportedFPMode) {
1429 LLVM_DEBUG(dbgs() << ".. .. gave up (UnsupportedFPMode)\n");
1430 return false;
1431 }
1432 if (NextFGR32 == FGR32ArgRegs.end()) {
1433 LLVM_DEBUG(dbgs() << ".. .. gave up (ran out of FGR32 arguments)\n");
1434 return false;
1435 }
1436 LLVM_DEBUG(dbgs() << ".. .. FGR32(" << *NextFGR32 << ")\n");
1437 Allocation.emplace_back(&Mips::FGR32RegClass, *NextFGR32++);
1438
1439
1440 if (NextGPR32 != GPR32ArgRegs.end())
1441 NextGPR32++;
1442 if (NextAFGR64 != AFGR64ArgRegs.end())
1443 NextAFGR64++;
1444 break;
1445
1446 case MVT::f64:
1447 if (UnsupportedFPMode) {
1448 LLVM_DEBUG(dbgs() << ".. .. gave up (UnsupportedFPMode)\n");
1449 return false;
1450 }
1451 if (NextAFGR64 == AFGR64ArgRegs.end()) {
1452 LLVM_DEBUG(dbgs() << ".. .. gave up (ran out of AFGR64 arguments)\n");
1453 return false;
1454 }
1455 LLVM_DEBUG(dbgs() << ".. .. AFGR64(" << *NextAFGR64 << ")\n");
1456 Allocation.emplace_back(&Mips::AFGR64RegClass, *NextAFGR64++);
1457
1458
1459 if (NextGPR32 != GPR32ArgRegs.end())
1460 NextGPR32++;
1461 if (NextGPR32 != GPR32ArgRegs.end())
1462 NextGPR32++;
1463 if (NextFGR32 != FGR32ArgRegs.end())
1464 NextFGR32++;
1465 break;
1466
1467 default:
1468 LLVM_DEBUG(dbgs() << ".. .. gave up (unknown type)\n");
1469 return false;
1470 }
1471 }
1472
1473 for (const auto &FormalArg : F->args()) {
1474 unsigned ArgNo = FormalArg.getArgNo();
1475 unsigned SrcReg = Allocation[ArgNo].Reg;
1476 Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, Allocation[ArgNo].RC);
1477
1478
1479
1480 Register ResultReg = createResultReg(Allocation[ArgNo].RC);
1481 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1482 TII.get(TargetOpcode::COPY), ResultReg)
1483 .addReg(DstReg, getKillRegState(true));
1484 updateValueMap(&FormalArg, ResultReg);
1485 }
1486
1487
1488
1489 unsigned IncomingArgSizeInBytes = 0;
1490
1491
1492
1493
1494 IncomingArgSizeInBytes = std::min(getABI().GetCalleeAllocdArgSizeInBytes(CC),
1495 IncomingArgSizeInBytes);
1496
1497 MF->getInfo()->setFormalArgInfo(IncomingArgSizeInBytes,
1498 false);
1499
1500 return true;
1501}
1502
1503bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1504 CallingConv::ID CC = CLI.CallConv;
1505 bool IsTailCall = CLI.IsTailCall;
1506 bool IsVarArg = CLI.IsVarArg;
1509
1510
1511 if (CC == CallingConv::Fast)
1512 return false;
1513
1514
1515 if (IsTailCall)
1516 return false;
1517
1518
1519 if (IsVarArg)
1520 return false;
1521
1522
1523 MVT RetVT;
1524 if (CLI.RetTy->isVoidTy())
1525 RetVT = MVT::isVoid;
1526 else if (!isTypeSupported(CLI.RetTy, RetVT))
1527 return false;
1528
1529 for (auto Flag : CLI.OutFlags)
1530 if (Flag.isInReg() || Flag.isSRet() || Flag.isNest() || Flag.isByVal())
1531 return false;
1532
1533
1535 OutVTs.reserve(CLI.OutVals.size());
1536
1537 for (auto *Val : CLI.OutVals) {
1538 MVT VT;
1539 if (!isTypeLegal(Val->getType(), VT) &&
1540 !(VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16))
1541 return false;
1542
1543
1545 return false;
1546
1548 }
1549
1551 if (!computeCallAddress(Callee, Addr))
1552 return false;
1553
1554
1555 unsigned NumBytes;
1556 if (!processCallArgs(CLI, OutVTs, NumBytes))
1557 return false;
1558
1559 if (!Addr.getGlobalValue())
1560 return false;
1561
1562
1563 unsigned DestAddress;
1564 if (Symbol)
1565 DestAddress = materializeExternalCallSym(Symbol);
1566 else
1567 DestAddress = materializeGV(Addr.getGlobalValue(), MVT::i32);
1568 emitInst(TargetOpcode::COPY, Mips::T9).addReg(DestAddress);
1569 MachineInstrBuilder MIB =
1570 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Mips::JALR),
1571 Mips::RA).addReg(Mips::T9);
1572
1573
1574 for (auto Reg : CLI.OutRegs)
1576
1577
1578
1579 MIB.addRegMask(TRI.getCallPreservedMask(*FuncInfo.MF, CC));
1580
1581 CLI.Call = MIB;
1582
1584
1585
1586 if (Symbol)
1588 else
1589 MIB.addSym(FuncInfo.MF->getContext().getOrCreateSymbol(
1591 }
1592
1593
1594 return finishCall(CLI, RetVT, NumBytes);
1595}
1596
1597bool MipsFastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) {
1598 switch (II->getIntrinsicID()) {
1599 default:
1600 return false;
1601 case Intrinsic::bswap: {
1602 Type *RetTy = II->getCalledFunction()->getReturnType();
1603
1604 MVT VT;
1605 if (!isTypeSupported(RetTy, VT))
1606 return false;
1607
1608 Register SrcReg = getRegForValue(II->getOperand(0));
1609 if (SrcReg == 0)
1610 return false;
1611 Register DestReg = createResultReg(&Mips::GPR32RegClass);
1612 if (DestReg == 0)
1613 return false;
1614 if (VT == MVT::i16) {
1616 emitInst(Mips::WSBH, DestReg).addReg(SrcReg);
1617 updateValueMap(II, DestReg);
1618 return true;
1619 } else {
1620 unsigned TempReg[3];
1621 for (unsigned &R : TempReg) {
1622 R = createResultReg(&Mips::GPR32RegClass);
1623 if (R == 0)
1624 return false;
1625 }
1626 emitInst(Mips::SLL, TempReg[0]).addReg(SrcReg).addImm(8);
1627 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(8);
1628 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[1]).addImm(0xFF);
1629 emitInst(Mips::OR, DestReg).addReg(TempReg[0]).addReg(TempReg[2]);
1630 updateValueMap(II, DestReg);
1631 return true;
1632 }
1633 } else if (VT == MVT::i32) {
1635 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1636 emitInst(Mips::WSBH, TempReg).addReg(SrcReg);
1637 emitInst(Mips::ROTR, DestReg).addReg(TempReg).addImm(16);
1638 updateValueMap(II, DestReg);
1639 return true;
1640 } else {
1641 unsigned TempReg[8];
1642 for (unsigned &R : TempReg) {
1643 R = createResultReg(&Mips::GPR32RegClass);
1644 if (R == 0)
1645 return false;
1646 }
1647
1648 emitInst(Mips::SRL, TempReg[0]).addReg(SrcReg).addImm(8);
1649 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(24);
1650 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[0]).addImm(0xFF00);
1651 emitInst(Mips::OR, TempReg[3]).addReg(TempReg[1]).addReg(TempReg[2]);
1652
1653 emitInst(Mips::ANDi, TempReg[4]).addReg(SrcReg).addImm(0xFF00);
1654 emitInst(Mips::SLL, TempReg[5]).addReg(TempReg[4]).addImm(8);
1655
1656 emitInst(Mips::SLL, TempReg[6]).addReg(SrcReg).addImm(24);
1657 emitInst(Mips::OR, TempReg[7]).addReg(TempReg[3]).addReg(TempReg[5]);
1658 emitInst(Mips::OR, DestReg).addReg(TempReg[6]).addReg(TempReg[7]);
1659 updateValueMap(II, DestReg);
1660 return true;
1661 }
1662 }
1663 return false;
1664 }
1665 case Intrinsic::memcpy:
1666 case Intrinsic::memmove: {
1668
1669 if (MTI->isVolatile())
1670 return false;
1671 if (!MTI->getLength()->getType()->isIntegerTy(32))
1672 return false;
1673 const char *IntrMemName = isa(II) ? "memcpy" : "memmove";
1674 return lowerCallTo(II, IntrMemName, II->arg_size() - 1);
1675 }
1676 case Intrinsic::memset: {
1678
1680 return false;
1682 return false;
1683 return lowerCallTo(II, "memset", II->arg_size() - 1);
1684 }
1685 }
1686 return false;
1687}
1688
1689bool MipsFastISel::selectRet(const Instruction *I) {
1690 const Function &F = *I->getParent()->getParent();
1692
1694
1695 if (!FuncInfo.CanLowerReturn)
1696 return false;
1697
1698
1699 SmallVector<unsigned, 4> RetRegs;
1700
1702 CallingConv::ID CC = F.getCallingConv();
1703
1704
1705 if (CC == CallingConv::Fast)
1706 return false;
1707
1709 GetReturnInfo(CC, F.getReturnType(), F.getAttributes(), Outs, TLI, DL);
1710
1711
1713 MipsCCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, ValLocs,
1714 I->getContext());
1716 CCInfo.AnalyzeReturn(Outs, RetCC);
1717
1718
1719 if (ValLocs.size() != 1)
1720 return false;
1721
1722 CCValAssign &VA = ValLocs[0];
1724
1725
1728 return false;
1729
1730
1732 return false;
1733
1735 if (Reg == 0)
1736 return false;
1737
1740
1741 if (.getRegClass(SrcReg)->contains(DestReg))
1742 return false;
1743
1746 return false;
1747
1749 return false;
1750
1752 if (RVVT == MVT::f128)
1753 return false;
1754
1755
1756 if (RVVT == MVT::f64 && UnsupportedFPMode) {
1757 LLVM_DEBUG(dbgs() << ".. .. gave up (UnsupportedFPMode\n");
1758 return false;
1759 }
1760
1762
1763 if (RVVT != DestVT) {
1764 if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)
1765 return false;
1766
1767 if (Outs[0].Flags.isZExt() || Outs[0].Flags.isSExt()) {
1768 bool IsZExt = Outs[0].Flags.isZExt();
1769 SrcReg = emitIntExt(RVVT, SrcReg, DestVT, IsZExt);
1770 if (SrcReg == 0)
1771 return false;
1772 }
1773 }
1774
1775
1776 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1777 TII.get(TargetOpcode::COPY), DestReg).addReg(SrcReg);
1778
1779
1781 }
1782 MachineInstrBuilder MIB = emitInst(Mips::RetRA);
1783 for (unsigned Reg : RetRegs)
1785 return true;
1786}
1787
1788bool MipsFastISel::selectTrunc(const Instruction *I) {
1789
1790
1791 Value *Op = I->getOperand(0);
1792
1793 EVT SrcVT, DestVT;
1796
1797 if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)
1798 return false;
1799 if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)
1800 return false;
1801
1802 Register SrcReg = getRegForValue(Op);
1803 if (!SrcReg)
1804 return false;
1805
1806
1807
1808 updateValueMap(I, SrcReg);
1809 return true;
1810}
1811
1812bool MipsFastISel::selectIntExt(const Instruction *I) {
1813 Type *DestTy = I->getType();
1814 Value *Src = I->getOperand(0);
1815 Type *SrcTy = Src->getType();
1816
1818 Register SrcReg = getRegForValue(Src);
1819 if (!SrcReg)
1820 return false;
1821
1822 EVT SrcEVT, DestEVT;
1826 return false;
1828 return false;
1829
1832 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1833
1834 if (!emitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt))
1835 return false;
1836 updateValueMap(I, ResultReg);
1837 return true;
1838}
1839
1840bool MipsFastISel::emitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT,
1841 unsigned DestReg) {
1842 unsigned ShiftAmt;
1844 default:
1845 return false;
1846 case MVT::i8:
1847 ShiftAmt = 24;
1848 break;
1849 case MVT::i16:
1850 ShiftAmt = 16;
1851 break;
1852 }
1853 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1854 emitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt);
1855 emitInst(Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt);
1856 return true;
1857}
1858
1859bool MipsFastISel::emitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT,
1860 unsigned DestReg) {
1862 default:
1863 return false;
1864 case MVT::i8:
1865 emitInst(Mips::SEB, DestReg).addReg(SrcReg);
1866 break;
1867 case MVT::i16:
1868 emitInst(Mips::SEH, DestReg).addReg(SrcReg);
1869 break;
1870 }
1871 return true;
1872}
1873
1874bool MipsFastISel::emitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
1875 unsigned DestReg) {
1876 if ((DestVT != MVT::i32) && (DestVT != MVT::i16))
1877 return false;
1879 return emitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg);
1880 return emitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg);
1881}
1882
1883bool MipsFastISel::emitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
1884 unsigned DestReg) {
1885 int64_t Imm;
1886
1888 default:
1889 return false;
1890 case MVT::i1:
1891 Imm = 1;
1892 break;
1893 case MVT::i8:
1894 Imm = 0xff;
1895 break;
1896 case MVT::i16:
1897 Imm = 0xffff;
1898 break;
1899 }
1900
1901 emitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(Imm);
1902 return true;
1903}
1904
1905bool MipsFastISel::emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
1906 unsigned DestReg, bool IsZExt) {
1907
1908
1909
1910
1911 if (((DestVT != MVT::i8) && (DestVT != MVT::i16) && (DestVT != MVT::i32)) ||
1912 ((SrcVT != MVT::i1) && (SrcVT != MVT::i8) && (SrcVT != MVT::i16)))
1913 return false;
1914 if (IsZExt)
1915 return emitIntZExt(SrcVT, SrcReg, DestVT, DestReg);
1916 return emitIntSExt(SrcVT, SrcReg, DestVT, DestReg);
1917}
1918
1919unsigned MipsFastISel::emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
1920 bool isZExt) {
1921 unsigned DestReg = createResultReg(&Mips::GPR32RegClass);
1922 bool Success = emitIntExt(SrcVT, SrcReg, DestVT, DestReg, isZExt);
1923 return Success ? DestReg : 0;
1924}
1925
1926bool MipsFastISel::selectDivRem(const Instruction *I, unsigned ISDOpcode) {
1929 return false;
1930
1932 if (DestVT != MVT::i32)
1933 return false;
1934
1935 unsigned DivOpc;
1936 switch (ISDOpcode) {
1937 default:
1938 return false;
1941 DivOpc = Mips::SDIV;
1942 break;
1945 DivOpc = Mips::UDIV;
1946 break;
1947 }
1948
1949 Register Src0Reg = getRegForValue(I->getOperand(0));
1950 Register Src1Reg = getRegForValue(I->getOperand(1));
1951 if (!Src0Reg || !Src1Reg)
1952 return false;
1953
1954 emitInst(DivOpc).addReg(Src0Reg).addReg(Src1Reg);
1957 emitInst(Mips::TEQ).addReg(Src1Reg).addReg(Mips::ZERO).addImm(7);
1958 }
1959
1960 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1961 if (!ResultReg)
1962 return false;
1963
1965 ? Mips::MFHI
1966 : Mips::MFLO;
1967 emitInst(MFOpc, ResultReg);
1968
1969 updateValueMap(I, ResultReg);
1970 return true;
1971}
1972
1973bool MipsFastISel::selectShift(const Instruction *I) {
1974 MVT RetVT;
1975
1976 if (!isTypeSupported(I->getType(), RetVT))
1977 return false;
1978
1979 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1980 if (!ResultReg)
1981 return false;
1982
1983 unsigned Opcode = I->getOpcode();
1984 const Value *Op0 = I->getOperand(0);
1985 Register Op0Reg = getRegForValue(Op0);
1986 if (!Op0Reg)
1987 return false;
1988
1989
1990 if (Opcode == Instruction::AShr || Opcode == Instruction::LShr) {
1991 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1992 if (!TempReg)
1993 return false;
1994
1996 bool IsZExt = Opcode == Instruction::LShr;
1997 if (!emitIntExt(Op0MVT, Op0Reg, MVT::i32, TempReg, IsZExt))
1998 return false;
1999
2000 Op0Reg = TempReg;
2001 }
2002
2004 uint64_t ShiftVal = C->getZExtValue();
2005
2006 switch (Opcode) {
2007 default:
2009 case Instruction::Shl:
2010 Opcode = Mips::SLL;
2011 break;
2012 case Instruction::AShr:
2013 Opcode = Mips::SRA;
2014 break;
2015 case Instruction::LShr:
2016 Opcode = Mips::SRL;
2017 break;
2018 }
2019
2020 emitInst(Opcode, ResultReg).addReg(Op0Reg).addImm(ShiftVal);
2021 updateValueMap(I, ResultReg);
2022 return true;
2023 }
2024
2025 Register Op1Reg = getRegForValue(I->getOperand(1));
2026 if (!Op1Reg)
2027 return false;
2028
2029 switch (Opcode) {
2030 default:
2032 case Instruction::Shl:
2033 Opcode = Mips::SLLV;
2034 break;
2035 case Instruction::AShr:
2036 Opcode = Mips::SRAV;
2037 break;
2038 case Instruction::LShr:
2039 Opcode = Mips::SRLV;
2040 break;
2041 }
2042
2043 emitInst(Opcode, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
2044 updateValueMap(I, ResultReg);
2045 return true;
2046}
2047
2048bool MipsFastISel::fastSelectInstruction(const Instruction *I) {
2049 switch (I->getOpcode()) {
2050 default:
2051 break;
2052 case Instruction::Load:
2053 return selectLoad(I);
2054 case Instruction::Store:
2055 return selectStore(I);
2056 case Instruction::SDiv:
2059 return true;
2060 case Instruction::UDiv:
2063 return true;
2064 case Instruction::SRem:
2067 return true;
2068 case Instruction::URem:
2071 return true;
2072 case Instruction::Shl:
2073 case Instruction::LShr:
2074 case Instruction::AShr:
2075 return selectShift(I);
2076 case Instruction::And:
2077 case Instruction::Or:
2078 case Instruction::Xor:
2079 return selectLogicalOp(I);
2080 case Instruction::Br:
2081 return selectBranch(I);
2082 case Instruction::Ret:
2083 return selectRet(I);
2084 case Instruction::Trunc:
2085 return selectTrunc(I);
2086 case Instruction::ZExt:
2087 case Instruction::SExt:
2088 return selectIntExt(I);
2089 case Instruction::FPTrunc:
2090 return selectFPTrunc(I);
2091 case Instruction::FPExt:
2092 return selectFPExt(I);
2093 case Instruction::FPToSI:
2094 return selectFPToInt(I, true);
2095 case Instruction::FPToUI:
2096 return selectFPToInt(I, false);
2097 case Instruction::ICmp:
2098 case Instruction::FCmp:
2099 return selectCmp(I);
2100 case Instruction::Select:
2101 return selectSelect(I);
2102 }
2103 return false;
2104}
2105
2106unsigned MipsFastISel::getRegEnsuringSimpleIntegerWidening(const Value *V,
2107 bool IsUnsigned) {
2108 Register VReg = getRegForValue(V);
2109 if (VReg == 0)
2110 return 0;
2112
2113 if (VMVT == MVT::i1)
2114 return 0;
2115
2116 if ((VMVT == MVT::i8) || (VMVT == MVT::i16)) {
2117 Register TempReg = createResultReg(&Mips::GPR32RegClass);
2118 if (!emitIntExt(VMVT, VReg, MVT::i32, TempReg, IsUnsigned))
2119 return 0;
2120 VReg = TempReg;
2121 }
2122 return VReg;
2123}
2124
2125void MipsFastISel::simplifyAddress(Address &Addr) {
2126 if ((Addr.getOffset())) {
2127 unsigned TempReg =
2128 materialize32BitInt(Addr.getOffset(), &Mips::GPR32RegClass);
2129 Register DestReg = createResultReg(&Mips::GPR32RegClass);
2130 emitInst(Mips::ADDu, DestReg).addReg(TempReg).addReg(Addr.getReg());
2131 Addr.setReg(DestReg);
2132 Addr.setOffset(0);
2133 }
2134}
2135
2136unsigned MipsFastISel::fastEmitInst_rr(unsigned MachineInstOpcode,
2137 const TargetRegisterClass *RC,
2138 unsigned Op0, unsigned Op1) {
2139
2140
2141
2142
2143
2144
2145 if (MachineInstOpcode == Mips::MUL) {
2146 Register ResultReg = createResultReg(RC);
2147 const MCInstrDesc &II = TII.get(MachineInstOpcode);
2150 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)
2155 return ResultReg;
2156 }
2157
2159}
2160
2161namespace llvm {
2162
2165 return new MipsFastISel(funcInfo, libInfo);
2166}
2167
2168}
unsigned const MachineRegisterInfo * MRI
static unsigned selectBinaryOp(unsigned GenericOpc, unsigned RegBankID, unsigned OpSize)
Select the AArch64 opcode for the basic binary operation GenericOpc (such as G_OR or G_SDIV),...
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!")
const TargetInstrInfo & TII
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...
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.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
cl::opt< bool > EmitJalrReloc
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)
Definition MipsFastISel.cpp:279
static bool CC_MipsO32_FP32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
Definition MipsFastISel.cpp:272
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
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallVector class.
static SDValue emitCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
This file describes how to lower LLVM code to machine code.
APInt bitcastToAPInt() const
uint64_t getZExtValue() const
Get zero extended value.
an instruction to allocate memory on the stack
PointerType * getType() const
Overload to return most specific pointer type.
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() const
CCState - This class holds information needed while lowering arguments and return values.
void convertToReg(MCRegister Reg)
Register getLocReg() const
LocInfo getLocInfo() const
int64_t getLocMemOffset() const
unsigned getValNo() const
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_ULE
unsigned less or equal
Predicate getPredicate() const
Return the predicate for this instruction.
ConstantFP - Floating Point Values [float, double].
const APFloat & getValueAPF() const
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
This is an important base class in LLVM.
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
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.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
bool hasLocalLinkage() const
bool hasInternalLinkage() 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.
Align getAlign() const
Return the alignment of the access that is being performed.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
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 & 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 & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
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
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
Register getGlobalBaseReg(MachineFunction &MF)
bool useSoftFloat() const
const MipsInstrInfo * getInstrInfo() const override
bool inMips16Mode() const
bool systemSupportsUnalignedAccess() const
Does the system support unaligned memory access.
const MipsTargetLowering * getTargetLowering() const override
Wrapper class representing virtual and physical registers.
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
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.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isIntegerTy() const
True if this is an instance of IntegerType.
const Use * const_op_iterator
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
StructType * getStructTypeOrNull() const
TypeSize getSequentialElementStride(const DataLayout &DL) const
const ParentTy * getParent() const
#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.
@ C
The default llvm calling convention, compatible with C.
@ AND
Bitwise operators - logical and, logical or, logical xor.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo)
Definition MipsFastISel.cpp:2163
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
@ User
could "use" a pointer
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
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...
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.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
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.
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.
generic_gep_type_iterator<> gep_type_iterator
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
gep_type_iterator gep_type_begin(const User *GEP)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool isVector() const
Return true if this is a vector value type.
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.