LLVM: lib/Target/PowerPC/PPCFastISel.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55using namespace llvm;
56
57#define DEBUG_TYPE "ppcfastisel"
58
59namespace {
60
61struct Address {
62 enum {
63 RegBase,
64 FrameIndexBase
66
67 union {
68 unsigned Reg;
69 int FI;
71
73
74
78 }
79};
80
81class PPCFastISel final : public FastISel {
82
89
90 public:
98
99
100 private:
101 bool fastSelectInstruction(const Instruction *I) override;
104 bool tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,
105 const LoadInst *LI) override;
106 bool fastLowerArguments() override;
108 Register fastEmitInst_ri(unsigned MachineInstOpcode,
111 Register fastEmitInst_r(unsigned MachineInstOpcode,
113 Register fastEmitInst_rr(unsigned MachineInstOpcode,
116
117 bool fastLowerCall(CallLoweringInfo &CLI) override;
118
119
120 private:
127 bool SelectIToFP(const Instruction *I, bool IsSigned);
128 bool SelectFPToI(const Instruction *I, bool IsSigned);
129 bool SelectBinaryIntOp(const Instruction *I, unsigned ISDOpcode);
133
134
135 private:
136 bool isTypeLegal(Type *Ty, MVT &VT);
137 bool isLoadTypeLegal(Type *Ty, MVT &VT);
138 bool isValueAvailable(const Value *V) const;
140 return RC->getID() == PPC::VSFRCRegClassID;
141 }
143 return RC->getID() == PPC::VSSRCRegClassID;
144 }
146 unsigned Flag = 0, unsigned SubReg = 0) {
147 Register TmpReg = createResultReg(ToRC);
149 TII.get(TargetOpcode::COPY), TmpReg).addReg(SrcReg, Flag, SubReg);
150 return TmpReg;
151 }
152 bool PPCEmitCmp(const Value *Src1Value, const Value *Src2Value, bool isZExt,
154 bool PPCEmitLoad(MVT VT, Register &ResultReg, Address &Addr,
156 unsigned FP64LoadOpc = PPC::LFD);
157 bool PPCEmitStore(MVT VT, Register SrcReg, Address &Addr);
158 bool PPCComputeAddress(const Value *Obj, Address &Addr);
159 void PPCSimplifyAddress(Address &Addr, bool &UseOffset, Register &IndexReg);
161 bool IsZExt);
165 bool UseSExt = true);
169 bool IsSigned);
171
172
173 private:
179 unsigned &NumBytes, bool IsVarArg);
180 bool finishCall(MVT RetVT, CallLoweringInfo &CLI, unsigned &NumBytes);
181
182 private:
183 #include "PPCGenFastISel.inc"
184
185};
186
187}
188
190 switch (Pred) {
191
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
216 default:
217 return std::nullopt;
218
222
227
232
237
242
246
249
252 }
253}
254
255
256
257
258bool PPCFastISel::isTypeLegal(Type *Ty, MVT &VT) {
260
261
262 if (Evt == MVT::Other || !Evt.isSimple()) return false;
264
265
266
268}
269
270
271
272bool PPCFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) {
273 if (isTypeLegal(Ty, VT)) return true;
274
275
276
277 if (VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) {
278 return true;
279 }
280
281 return false;
282}
283
284bool PPCFastISel::isValueAvailable(const Value *V) const {
286 return true;
287
289 return FuncInfo.getMBB(I->getParent()) == FuncInfo.MBB;
290}
291
292
293
294bool PPCFastISel::PPCComputeAddress(const Value *Obj, Address &Addr) {
296 unsigned Opcode = Instruction::UserOp1;
298
299
300 if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(Obj)) ||
301 FuncInfo.getMBB(I->getParent()) == FuncInfo.MBB) {
302 Opcode = I->getOpcode();
304 }
306 Opcode = C->getOpcode();
308 }
309
310 switch (Opcode) {
311 default:
312 break;
313 case Instruction::BitCast:
314
315 return PPCComputeAddress(U->getOperand(0), Addr);
316 case Instruction::IntToPtr:
317
320 return PPCComputeAddress(U->getOperand(0), Addr);
321 break;
322 case Instruction::PtrToInt:
323
325 return PPCComputeAddress(U->getOperand(0), Addr);
326 break;
327 case Instruction::GetElementPtr: {
328 Address SavedAddr = Addr;
329 int64_t TmpOffset = Addr.Offset;
330
331
332
338 const StructLayout *SL = DL.getStructLayout(STy);
341 } else {
343 for (;;) {
345
346 TmpOffset += CI->getSExtValue() * S;
347 break;
348 }
349 if (canFoldAddIntoGEP(U, Op)) {
350
351 ConstantInt *CI =
354
356 continue;
357 }
358
359 goto unsupported_gep;
360 }
361 }
362 }
363
364
365 Addr.Offset = TmpOffset;
366 if (PPCComputeAddress(U->getOperand(0), Addr)) return true;
367
368
369 Addr = SavedAddr;
370
371 unsupported_gep:
372 break;
373 }
374 case Instruction::Alloca: {
376 DenseMap<const AllocaInst*, int>::iterator SI =
377 FuncInfo.StaticAllocaMap.find(AI);
378 if (SI != FuncInfo.StaticAllocaMap.end()) {
379 Addr.BaseType = Address::FrameIndexBase;
380 Addr.Base.FI = SI->second;
381 return true;
382 }
383 break;
384 }
385 }
386
387
388
389
390
391
392
393
394 if (Addr.Base.Reg == 0)
395 Addr.Base.Reg = getRegForValue(Obj);
396
397
398
399 if (Addr.Base.Reg != 0)
400 MRI.setRegClass(Addr.Base.Reg, &PPC::G8RC_and_G8RC_NOX0RegClass);
401
402 return Addr.Base.Reg != 0;
403}
404
405
406
407
408void PPCFastISel::PPCSimplifyAddress(Address &Addr, bool &UseOffset,
410
411
413 UseOffset = false;
414
415
416
417
418 if (!UseOffset && Addr.BaseType == Address::FrameIndexBase) {
419 Register ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
420 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ADDI8),
422 Addr.Base.Reg = ResultReg;
423 Addr.BaseType = Address::RegBase;
424 }
425
426 if (!UseOffset) {
427 IntegerType *OffsetTy = Type::getInt64Ty(*Context);
429 IndexReg = PPCMaterializeInt(Offset, MVT::i64);
430 assert(IndexReg && "Unexpected error in PPCMaterializeInt!");
431 }
432}
433
434
435
436
437bool PPCFastISel::PPCEmitLoad(MVT VT, Register &ResultReg, Address &Addr,
438 const TargetRegisterClass *RC,
439 bool IsZExt, unsigned FP64LoadOpc) {
440 unsigned Opc;
441 bool UseOffset = true;
442 bool HasSPE = Subtarget->hasSPE();
443
444
445
446
447
448
449
450
451 const TargetRegisterClass *UseRC =
452 (ResultReg ? MRI.getRegClass(ResultReg) :
453 (RC ? RC :
454 (VT == MVT::f64 ? (HasSPE ? &PPC::SPERCRegClass : &PPC::F8RCRegClass) :
455 (VT == MVT::f32 ? (HasSPE ? &PPC::GPRCRegClass : &PPC::F4RCRegClass) :
456 (VT == MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
457 &PPC::GPRC_and_GPRC_NOR0RegClass)))));
458
459 bool Is32BitInt = UseRC->hasSuperClassEq(&PPC::GPRCRegClass);
460
462 default:
463 return false;
464 case MVT::i8:
465 Opc = Is32BitInt ? PPC::LBZ : PPC::LBZ8;
466 break;
467 case MVT::i16:
468 Opc = (IsZExt ? (Is32BitInt ? PPC::LHZ : PPC::LHZ8)
469 : (Is32BitInt ? PPC::LHA : PPC::LHA8));
470 break;
471 case MVT::i32:
472 Opc = (IsZExt ? (Is32BitInt ? PPC::LWZ : PPC::LWZ8)
473 : (Is32BitInt ? PPC::LWA_32 : PPC::LWA));
474 if ((Opc == PPC::LWA || Opc == PPC::LWA_32) && ((Addr.Offset & 3) != 0))
475 UseOffset = false;
476 break;
477 case MVT::i64:
478 Opc = PPC::LD;
480 "64-bit load with 32-bit target??");
481 UseOffset = ((Addr.Offset & 3) == 0);
482 break;
483 case MVT::f32:
484 Opc = Subtarget->hasSPE() ? PPC::SPELWZ : PPC::LFS;
485 break;
486 case MVT::f64:
487 Opc = FP64LoadOpc;
488 break;
489 }
490
491
492
494 PPCSimplifyAddress(Addr, UseOffset, IndexReg);
495
496
497
498 bool IsVSSRC = isVSSRCRegClass(UseRC);
499 bool IsVSFRC = isVSFRCRegClass(UseRC);
500 bool Is32VSXLoad = IsVSSRC && Opc == PPC::LFS;
501 bool Is64VSXLoad = IsVSFRC && Opc == PPC::LFD;
502 if ((Is32VSXLoad || Is64VSXLoad) &&
503 (Addr.BaseType != Address::FrameIndexBase) && UseOffset &&
504 (Addr.Offset == 0)) {
505 UseOffset = false;
506 }
507
508 if (!ResultReg)
509 ResultReg = createResultReg(UseRC);
510
511
512
513
514 if (Addr.BaseType == Address::FrameIndexBase) {
515
516 if (Is32VSXLoad || Is64VSXLoad) return false;
517
518 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
520 Addr.Offset),
522 MFI.getObjectAlign(Addr.Base.FI));
523
524 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ResultReg)
526
527
528 } else if (UseOffset) {
529
530 if (Is32VSXLoad || Is64VSXLoad) return false;
531
532 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ResultReg)
534
535
536 } else {
537
538
539
540 switch (Opc) {
542 case PPC::LBZ: Opc = PPC::LBZX; break;
543 case PPC::LBZ8: Opc = PPC::LBZX8; break;
544 case PPC::LHZ: Opc = PPC::LHZX; break;
545 case PPC::LHZ8: Opc = PPC::LHZX8; break;
546 case PPC::LHA: Opc = PPC::LHAX; break;
547 case PPC::LHA8: Opc = PPC::LHAX8; break;
548 case PPC::LWZ: Opc = PPC::LWZX; break;
549 case PPC::LWZ8: Opc = PPC::LWZX8; break;
550 case PPC::LWA: Opc = PPC::LWAX; break;
551 case PPC::LWA_32: Opc = PPC::LWAX_32; break;
552 case PPC::LD: Opc = PPC::LDX; break;
553 case PPC::LFS: Opc = IsVSSRC ? PPC::LXSSPX : PPC::LFSX; break;
554 case PPC::LFD: Opc = IsVSFRC ? PPC::LXSDX : PPC::LFDX; break;
555 case PPC::EVLDD: Opc = PPC::EVLDDX; break;
556 case PPC::SPELWZ: Opc = PPC::SPELWZX; break;
557 }
558
559 auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc),
560 ResultReg);
561
562
563
564
565
566 if (IndexReg)
567 MIB.addReg(Addr.Base.Reg).addReg(IndexReg);
568 else
569 MIB.addReg(PPC::ZERO8).addReg(Addr.Base.Reg);
570 }
571
572 return true;
573}
574
575
576bool PPCFastISel::SelectLoad(const Instruction *I) {
577
579 return false;
580
581
582 MVT VT;
583 if (!isLoadTypeLegal(I->getType(), VT))
584 return false;
585
586
588 if (!PPCComputeAddress(I->getOperand(0), Addr))
589 return false;
590
591
592
593
594 Register AssignedReg = FuncInfo.ValueMap[I];
595 const TargetRegisterClass *RC =
596 AssignedReg ? MRI.getRegClass(AssignedReg) : nullptr;
597
599 if (!PPCEmitLoad(VT, ResultReg, Addr, RC, true,
600 Subtarget->hasSPE() ? PPC::EVLDD : PPC::LFD))
601 return false;
602 updateValueMap(I, ResultReg);
603 return true;
604}
605
606
607bool PPCFastISel::PPCEmitStore(MVT VT, Register SrcReg, Address &Addr) {
608 assert(SrcReg && "Nothing to store!");
609 unsigned Opc;
610 bool UseOffset = true;
611
612 const TargetRegisterClass *RC = MRI.getRegClass(SrcReg);
613 bool Is32BitInt = RC->hasSuperClassEq(&PPC::GPRCRegClass);
614
616 default:
617 return false;
618 case MVT::i8:
619 Opc = Is32BitInt ? PPC::STB : PPC::STB8;
620 break;
621 case MVT::i16:
622 Opc = Is32BitInt ? PPC::STH : PPC::STH8;
623 break;
624 case MVT::i32:
625 assert(Is32BitInt && "Not GPRC for i32??");
626 Opc = PPC::STW;
627 break;
628 case MVT::i64:
629 Opc = PPC::STD;
630 UseOffset = ((Addr.Offset & 3) == 0);
631 break;
632 case MVT::f32:
633 Opc = Subtarget->hasSPE() ? PPC::SPESTW : PPC::STFS;
634 break;
635 case MVT::f64:
636 Opc = Subtarget->hasSPE() ? PPC::EVSTDD : PPC::STFD;
637 break;
638 }
639
640
641
643 PPCSimplifyAddress(Addr, UseOffset, IndexReg);
644
645
646
647 bool IsVSSRC = isVSSRCRegClass(RC);
648 bool IsVSFRC = isVSFRCRegClass(RC);
649 bool Is32VSXStore = IsVSSRC && Opc == PPC::STFS;
650 bool Is64VSXStore = IsVSFRC && Opc == PPC::STFD;
651 if ((Is32VSXStore || Is64VSXStore) &&
652 (Addr.BaseType != Address::FrameIndexBase) && UseOffset &&
653 (Addr.Offset == 0)) {
654 UseOffset = false;
655 }
656
657
658
659
660 if (Addr.BaseType == Address::FrameIndexBase) {
661
662 if (Is32VSXStore || Is64VSXStore) return false;
663
664 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
666 Addr.Offset),
668 MFI.getObjectAlign(Addr.Base.FI));
669
670 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc))
675
676
677 } else if (UseOffset) {
678
679 if (Is32VSXStore || Is64VSXStore)
680 return false;
681
682 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc))
684
685
686 } else {
687
688
689
690 switch (Opc) {
692 case PPC::STB: Opc = PPC::STBX; break;
693 case PPC::STH : Opc = PPC::STHX; break;
694 case PPC::STW : Opc = PPC::STWX; break;
695 case PPC::STB8: Opc = PPC::STBX8; break;
696 case PPC::STH8: Opc = PPC::STHX8; break;
697 case PPC::STW8: Opc = PPC::STWX8; break;
698 case PPC::STD: Opc = PPC::STDX; break;
699 case PPC::STFS: Opc = IsVSSRC ? PPC::STXSSPX : PPC::STFSX; break;
700 case PPC::STFD: Opc = IsVSFRC ? PPC::STXSDX : PPC::STFDX; break;
701 case PPC::EVSTDD: Opc = PPC::EVSTDDX; break;
702 case PPC::SPESTW: Opc = PPC::SPESTWX; break;
703 }
704
705 auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc))
707
708
709
710
711
712 if (IndexReg)
714 else
715 MIB.addReg(PPC::ZERO8).addReg(Addr.Base.Reg);
716 }
717
718 return true;
719}
720
721
722bool PPCFastISel::SelectStore(const Instruction *I) {
723 Value *Op0 = I->getOperand(0);
725
726
728 return false;
729
730
731 MVT VT;
732 if (!isLoadTypeLegal(Op0->getType(), VT))
733 return false;
734
735
736 SrcReg = getRegForValue(Op0);
737 if (!SrcReg)
738 return false;
739
740
742 if (!PPCComputeAddress(I->getOperand(1), Addr))
743 return false;
744
745 if (!PPCEmitStore(VT, SrcReg, Addr))
746 return false;
747
748 return true;
749}
750
751
752bool PPCFastISel::SelectBranch(const Instruction *I) {
754 MachineBasicBlock *BrBB = FuncInfo.MBB;
755 MachineBasicBlock *TBB = FuncInfo.getMBB(BI->getSuccessor(0));
756 MachineBasicBlock *FBB = FuncInfo.getMBB(BI->getSuccessor(1));
757
758
760 if (isValueAvailable(CI)) {
761 std::optionalPPC::Predicate OptPPCPred =
763 if (!OptPPCPred)
764 return false;
765
767
768
769 if (FuncInfo.MBB->isLayoutSuccessor(TBB)) {
772 }
773
774 Register CondReg = createResultReg(&PPC::CRRCRegClass);
775
777 CondReg, PPCPred))
778 return false;
779
780 BuildMI(*BrBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::BCC))
785 return true;
786 }
787 } else if (const ConstantInt *CI =
790 MachineBasicBlock *Target = (Imm == 0) ? FBB : TBB;
791 fastEmitBranch(Target, MIMD.getDL());
792 return true;
793 }
794
795
796
797
798
799
800
801 return false;
802}
803
804
805
806bool PPCFastISel::PPCEmitCmp(const Value *SrcValue1, const Value *SrcValue2,
807 bool IsZExt, Register DestReg,
812 return false;
814
815 if (SrcVT == MVT::i1 && Subtarget->useCRBits())
816 return false;
817
818
819
820
821
822 int64_t Imm = 0;
823 bool UseImm = false;
824 const bool HasSPE = Subtarget->hasSPE();
825
826
827
829 if (SrcVT == MVT::i64 || SrcVT == MVT::i32 || SrcVT == MVT::i16 ||
830 SrcVT == MVT::i8 || SrcVT == MVT::i1) {
831 const APInt &CIVal = ConstInt->getValue();
835 UseImm = true;
836 }
837 }
838
839 Register SrcReg1 = getRegForValue(SrcValue1);
840 if (!SrcReg1)
841 return false;
842
844 if (!UseImm) {
845 SrcReg2 = getRegForValue(SrcValue2);
846 if (!SrcReg2)
847 return false;
848 }
849
850 unsigned CmpOpc;
851 bool NeedsExt = false;
852
853 auto RC1 = MRI.getRegClass(SrcReg1);
854 auto RC2 = SrcReg2 != 0 ? MRI.getRegClass(SrcReg2) : nullptr;
855
857 default: return false;
858 case MVT::f32:
859 if (HasSPE) {
860 switch (Pred) {
861 default: return false;
863 CmpOpc = PPC::EFSCMPEQ;
864 break;
866 CmpOpc = PPC::EFSCMPLT;
867 break;
869 CmpOpc = PPC::EFSCMPGT;
870 break;
871 }
872 } else {
873 CmpOpc = PPC::FCMPUS;
874 if (isVSSRCRegClass(RC1))
875 SrcReg1 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg1);
876 if (RC2 && isVSSRCRegClass(RC2))
877 SrcReg2 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg2);
878 }
879 break;
880 case MVT::f64:
881 if (HasSPE) {
882 switch (Pred) {
883 default: return false;
885 CmpOpc = PPC::EFDCMPEQ;
886 break;
888 CmpOpc = PPC::EFDCMPLT;
889 break;
891 CmpOpc = PPC::EFDCMPGT;
892 break;
893 }
894 } else if (isVSFRCRegClass(RC1) || (RC2 && isVSFRCRegClass(RC2))) {
895 CmpOpc = PPC::XSCMPUDP;
896 } else {
897 CmpOpc = PPC::FCMPUD;
898 }
899 break;
900 case MVT::i1:
901 case MVT::i8:
902 case MVT::i16:
903 NeedsExt = true;
904 [[fallthrough]];
905 case MVT::i32:
906 if (!UseImm)
907 CmpOpc = IsZExt ? PPC::CMPLW : PPC::CMPW;
908 else
909 CmpOpc = IsZExt ? PPC::CMPLWI : PPC::CMPWI;
910 break;
911 case MVT::i64:
912 if (!UseImm)
913 CmpOpc = IsZExt ? PPC::CMPLD : PPC::CMPD;
914 else
915 CmpOpc = IsZExt ? PPC::CMPLDI : PPC::CMPDI;
916 break;
917 }
918
919 if (NeedsExt) {
920 Register ExtReg = createResultReg(&PPC::GPRCRegClass);
921 if (!PPCEmitIntExt(SrcVT, SrcReg1, MVT::i32, ExtReg, IsZExt))
922 return false;
923 SrcReg1 = ExtReg;
924
925 if (!UseImm) {
926 Register ExtReg = createResultReg(&PPC::GPRCRegClass);
927 if (!PPCEmitIntExt(SrcVT, SrcReg2, MVT::i32, ExtReg, IsZExt))
928 return false;
929 SrcReg2 = ExtReg;
930 }
931 }
932
933 if (!UseImm)
934 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(CmpOpc), DestReg)
936 else
937 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(CmpOpc), DestReg)
939
940 return true;
941}
942
943
944bool PPCFastISel::SelectFPExt(const Instruction *I) {
945 Value *Src = I->getOperand(0);
946 EVT SrcVT = TLI.getValueType(DL, Src->getType(), true);
948
949 if (SrcVT != MVT::f32 || DestVT != MVT::f64)
950 return false;
951
952 Register SrcReg = getRegForValue(Src);
953 if (!SrcReg)
954 return false;
955
956
957 updateValueMap(I, SrcReg);
958 return true;
959}
960
961
962bool PPCFastISel::SelectFPTrunc(const Instruction *I) {
963 Value *Src = I->getOperand(0);
964 EVT SrcVT = TLI.getValueType(DL, Src->getType(), true);
966
967 if (SrcVT != MVT::f64 || DestVT != MVT::f32)
968 return false;
969
970 Register SrcReg = getRegForValue(Src);
971 if (!SrcReg)
972 return false;
973
974
976 auto RC = MRI.getRegClass(SrcReg);
977 if (Subtarget->hasSPE()) {
978 DestReg = createResultReg(&PPC::GPRCRegClass);
979 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::EFSCFD),
980 DestReg)
982 } else if (Subtarget->hasP8Vector() && isVSFRCRegClass(RC)) {
983 DestReg = createResultReg(&PPC::VSSRCRegClass);
984 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::XSRSP),
985 DestReg)
987 } else {
988 SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
989 DestReg = createResultReg(&PPC::F4RCRegClass);
990 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
991 TII.get(PPC::FRSP), DestReg)
993 }
994
995 updateValueMap(I, DestReg);
996 return true;
997}
998
999
1000
1001
1002
1003
1004
1005
1006Register PPCFastISel::PPCMoveToFPReg(MVT SrcVT, Register SrcReg,
1007 bool IsSigned) {
1008
1009
1010 if (SrcVT == MVT::i32) {
1011 Register TmpReg = createResultReg(&PPC::G8RCRegClass);
1012 if (!PPCEmitIntExt(MVT::i32, SrcReg, MVT::i64, TmpReg, !IsSigned))
1014 SrcReg = TmpReg;
1015 }
1016
1017
1019 Addr.BaseType = Address::FrameIndexBase;
1020 Addr.Base.FI = MFI.CreateStackObject(8, Align(8), false);
1021
1022
1023 if (!PPCEmitStore(MVT::i64, SrcReg, Addr))
1025
1026
1027
1028 unsigned LoadOpc = PPC::LFD;
1029
1030 if (SrcVT == MVT::i32) {
1031 if (!IsSigned) {
1032 LoadOpc = PPC::LFIWZX;
1033 Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;
1034 } else if (Subtarget->hasLFIWAX()) {
1035 LoadOpc = PPC::LFIWAX;
1036 Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;
1037 }
1038 }
1039
1040 const TargetRegisterClass *RC = &PPC::F8RCRegClass;
1042 if (!PPCEmitLoad(MVT::f64, ResultReg, Addr, RC, !IsSigned, LoadOpc))
1044
1045 return ResultReg;
1046}
1047
1048
1049
1050
1051bool PPCFastISel::SelectIToFP(const Instruction *I, bool IsSigned) {
1052 MVT DstVT;
1053 Type *DstTy = I->getType();
1054 if (!isTypeLegal(DstTy, DstVT))
1055 return false;
1056
1057 if (DstVT != MVT::f32 && DstVT != MVT::f64)
1058 return false;
1059
1060 Value *Src = I->getOperand(0);
1061 EVT SrcEVT = TLI.getValueType(DL, Src->getType(), true);
1063 return false;
1064
1066
1067 if (SrcVT != MVT::i8 && SrcVT != MVT::i16 &&
1068 SrcVT != MVT::i32 && SrcVT != MVT::i64)
1069 return false;
1070
1071 Register SrcReg = getRegForValue(Src);
1072 if (!SrcReg)
1073 return false;
1074
1075
1076 if (Subtarget->hasSPE()) {
1077 unsigned Opc;
1078 if (DstVT == MVT::f32)
1079 Opc = IsSigned ? PPC::EFSCFSI : PPC::EFSCFUI;
1080 else
1081 Opc = IsSigned ? PPC::EFDCFSI : PPC::EFDCFUI;
1082
1083 Register DestReg = createResultReg(&PPC::SPERCRegClass);
1084
1085 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
1087 updateValueMap(I, DestReg);
1088 return true;
1089 }
1090
1091
1092
1093 if (!IsSigned && !Subtarget->hasFPCVT())
1094 return false;
1095
1096
1097
1098
1099
1100
1101 if (DstVT == MVT::f32 && !Subtarget->hasFPCVT())
1102 return false;
1103
1104
1105 if (SrcVT == MVT::i8 || SrcVT == MVT::i16) {
1106 Register TmpReg = createResultReg(&PPC::G8RCRegClass);
1107 if (!PPCEmitIntExt(SrcVT, SrcReg, MVT::i64, TmpReg, !IsSigned))
1108 return false;
1109 SrcVT = MVT::i64;
1110 SrcReg = TmpReg;
1111 }
1112
1113
1114 Register FPReg = PPCMoveToFPReg(SrcVT, SrcReg, IsSigned);
1116 return false;
1117
1118
1119 const TargetRegisterClass *RC = &PPC::F8RCRegClass;
1120 Register DestReg = createResultReg(RC);
1121 unsigned Opc;
1122
1123 if (DstVT == MVT::f32)
1124 Opc = IsSigned ? PPC::FCFIDS : PPC::FCFIDUS;
1125 else
1126 Opc = IsSigned ? PPC::FCFID : PPC::FCFIDU;
1127
1128
1129 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
1131
1132 updateValueMap(I, DestReg);
1133 return true;
1134}
1135
1136
1137
1138
1139
1140
1141Register PPCFastISel::PPCMoveToIntReg(const Instruction *I, MVT VT,
1142 Register SrcReg, bool IsSigned) {
1143
1144
1145
1146
1148 Addr.BaseType = Address::FrameIndexBase;
1149 Addr.Base.FI = MFI.CreateStackObject(8, Align(8), false);
1150
1151
1152 if (!PPCEmitStore(MVT::f64, SrcReg, Addr))
1154
1155
1156
1157 if (VT == MVT::i32)
1158 Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;
1159
1160
1161
1162 Register AssignedReg = FuncInfo.ValueMap[I];
1163 const TargetRegisterClass *RC =
1164 AssignedReg ? MRI.getRegClass(AssignedReg) : nullptr;
1165
1167 if (!PPCEmitLoad(VT, ResultReg, Addr, RC, !IsSigned))
1169
1170 return ResultReg;
1171}
1172
1173
1174
1175
1176bool PPCFastISel::SelectFPToI(const Instruction *I, bool IsSigned) {
1177 MVT DstVT, SrcVT;
1178 Type *DstTy = I->getType();
1179 if (!isTypeLegal(DstTy, DstVT))
1180 return false;
1181
1182 if (DstVT != MVT::i32 && DstVT != MVT::i64)
1183 return false;
1184
1185
1186 if (DstVT == MVT::i64 && !IsSigned && !Subtarget->hasFPCVT() &&
1187 !Subtarget->hasSPE())
1188 return false;
1189
1190 Value *Src = I->getOperand(0);
1191 Type *SrcTy = Src->getType();
1192 if (!isTypeLegal(SrcTy, SrcVT))
1193 return false;
1194
1195 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
1196 return false;
1197
1198 Register SrcReg = getRegForValue(Src);
1199 if (!SrcReg)
1200 return false;
1201
1202
1203
1204 const TargetRegisterClass *InRC = MRI.getRegClass(SrcReg);
1205 if (InRC == &PPC::F4RCRegClass)
1206 SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
1207 else if (InRC == &PPC::VSSRCRegClass)
1208 SrcReg = copyRegToRegClass(&PPC::VSFRCRegClass, SrcReg);
1209
1210
1211
1213 unsigned Opc;
1214 auto RC = MRI.getRegClass(SrcReg);
1215
1216 if (Subtarget->hasSPE()) {
1217 DestReg = createResultReg(&PPC::GPRCRegClass);
1218 if (IsSigned)
1219 Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTSIZ : PPC::EFDCTSIZ;
1220 else
1221 Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTUIZ : PPC::EFDCTUIZ;
1222 } else if (isVSFRCRegClass(RC)) {
1223 DestReg = createResultReg(&PPC::VSFRCRegClass);
1224 if (DstVT == MVT::i32)
1225 Opc = IsSigned ? PPC::XSCVDPSXWS : PPC::XSCVDPUXWS;
1226 else
1227 Opc = IsSigned ? PPC::XSCVDPSXDS : PPC::XSCVDPUXDS;
1228 } else {
1229 DestReg = createResultReg(&PPC::F8RCRegClass);
1230 if (DstVT == MVT::i32)
1231 if (IsSigned)
1232 Opc = PPC::FCTIWZ;
1233 else
1234 Opc = Subtarget->hasFPCVT() ? PPC::FCTIWUZ : PPC::FCTIDZ;
1235 else
1236 Opc = IsSigned ? PPC::FCTIDZ : PPC::FCTIDUZ;
1237 }
1238
1239
1240 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
1242
1243
1244 Register IntReg = Subtarget->hasSPE()
1245 ? DestReg
1246 : PPCMoveToIntReg(I, DstVT, DestReg, IsSigned);
1247
1248 if (!IntReg)
1249 return false;
1250
1251 updateValueMap(I, IntReg);
1252 return true;
1253}
1254
1255
1256
1257bool PPCFastISel::SelectBinaryIntOp(const Instruction *I, unsigned ISDOpcode) {
1259
1260
1261
1262 if (DestVT != MVT::i16 && DestVT != MVT::i8)
1263 return false;
1264
1265
1266
1267
1268 Register AssignedReg = FuncInfo.ValueMap[I];
1269 const TargetRegisterClass *RC =
1270 (AssignedReg ? MRI.getRegClass(AssignedReg) :
1271 &PPC::GPRC_and_GPRC_NOR0RegClass);
1273
1274 unsigned Opc;
1275 switch (ISDOpcode) {
1276 default: return false;
1278 Opc = IsGPRC ? PPC::ADD4 : PPC::ADD8;
1279 break;
1281 Opc = IsGPRC ? PPC::OR : PPC::OR8;
1282 break;
1284 Opc = IsGPRC ? PPC::SUBF : PPC::SUBF8;
1285 break;
1286 }
1287
1288 Register ResultReg = createResultReg(RC ? RC : &PPC::G8RCRegClass);
1289 Register SrcReg1 = getRegForValue(I->getOperand(0));
1290 if (!SrcReg1)
1291 return false;
1292
1293
1295 const APInt &CIVal = ConstInt->getValue();
1297 bool UseImm = true;
1299 switch (Opc) {
1300 default:
1302 case PPC::ADD4:
1303 Opc = PPC::ADDI;
1304 MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);
1305 break;
1306 case PPC::ADD8:
1307 Opc = PPC::ADDI8;
1308 MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);
1309 break;
1310 case PPC::OR:
1311 Opc = PPC::ORI;
1312 break;
1313 case PPC::OR8:
1314 Opc = PPC::ORI8;
1315 break;
1316 case PPC::SUBF:
1317 if (Imm == -32768)
1318 UseImm = false;
1319 else {
1320 Opc = PPC::ADDI;
1321 MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);
1323 }
1324 break;
1325 case PPC::SUBF8:
1326 if (Imm == -32768)
1327 UseImm = false;
1328 else {
1329 Opc = PPC::ADDI8;
1330 MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);
1332 }
1333 break;
1334 }
1335
1336 if (UseImm) {
1337 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc),
1338 ResultReg)
1341 updateValueMap(I, ResultReg);
1342 return true;
1343 }
1344 }
1345 }
1346
1347
1348 Register SrcReg2 = getRegForValue(I->getOperand(1));
1349 if (!SrcReg2)
1350 return false;
1351
1352
1355
1356 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ResultReg)
1358 updateValueMap(I, ResultReg);
1359 return true;
1360}
1361
1362
1363
1364bool PPCFastISel::processCallArgs(SmallVectorImpl<Value *> &Args,
1365 SmallVectorImpl &ArgRegs,
1366 SmallVectorImpl &ArgVTs,
1367 SmallVectorImplISD::ArgFlagsTy &ArgFlags,
1368 SmallVectorImpl &RegArgs,
1369 CallingConv::ID CC, unsigned &NumBytes,
1370 bool IsVarArg) {
1372 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, ArgLocs, *Context);
1373
1374
1376 CCInfo.AllocateStack(LinkageSize, Align(8));
1377
1379 for (Value *Arg : Args)
1380 ArgTys.push_back(Arg->getType());
1381 CCInfo.AnalyzeCallOperands(ArgVTs, ArgFlags, ArgTys, CC_PPC64_ELF_FIS);
1382
1383
1384 for (const CCValAssign &VA : ArgLocs) {
1385 MVT ArgVT = ArgVTs[VA.getValNo()];
1386
1387
1388
1390 !VA.isRegLoc() || VA.needsCustom())
1391 return false;
1392
1393
1395 return false;
1396 }
1397
1398
1399 NumBytes = CCInfo.getStackSize();
1400
1401
1402
1403
1404
1405
1406
1407 NumBytes = std::max(NumBytes, LinkageSize + 64);
1408
1409
1410 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1413
1414
1415
1416
1417 unsigned NextGPR = PPC::X3;
1418 unsigned NextFPR = PPC::F1;
1419
1420
1421 for (const CCValAssign &VA : ArgLocs) {
1422 Register Arg = ArgRegs[VA.getValNo()];
1423 MVT ArgVT = ArgVTs[VA.getValNo()];
1424
1425
1426 switch (VA.getLocInfo()) {
1427 default:
1430 break;
1432 MVT DestVT = VA.getLocVT();
1433 const TargetRegisterClass *RC =
1434 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1435 Register TmpReg = createResultReg(RC);
1436 if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg, false))
1438 ArgVT = DestVT;
1439 Arg = TmpReg;
1440 break;
1441 }
1444 MVT DestVT = VA.getLocVT();
1445 const TargetRegisterClass *RC =
1446 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1447 Register TmpReg = createResultReg(RC);
1448 if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg, true))
1450 ArgVT = DestVT;
1451 Arg = TmpReg;
1452 break;
1453 }
1455
1456 llvm_unreachable("Should have bailed before getting here!");
1457 break;
1458 }
1459 }
1460
1461
1462 unsigned ArgReg;
1463 if (ArgVT == MVT::f32 || ArgVT == MVT::f64) {
1464 ArgReg = NextFPR++;
1465 if (CC != CallingConv::Fast)
1466 ++NextGPR;
1467 } else
1468 ArgReg = NextGPR++;
1469
1470 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1471 TII.get(TargetOpcode::COPY), ArgReg).addReg(Arg);
1473 }
1474
1475 return true;
1476}
1477
1478
1479
1480bool PPCFastISel::finishCall(MVT RetVT, CallLoweringInfo &CLI, unsigned &NumBytes) {
1481 CallingConv::ID CC = CLI.CallConv;
1482
1483
1484 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1487
1488
1489
1490
1491 if (RetVT != MVT::isVoid) {
1493 CCState CCInfo(CC, false, *FuncInfo.MF, RVLocs, *Context);
1495 CCValAssign &VA = RVLocs[0];
1496 assert(RVLocs.size() == 1 && "No support for multi-reg return values!");
1497 assert(VA.isRegLoc() && "Can only return in registers!");
1498
1500 MVT CopyVT = DestVT;
1501
1502
1503
1504 if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32)
1505 CopyVT = MVT::i64;
1506
1509
1510 if (RetVT == CopyVT) {
1511 const TargetRegisterClass *CpyRC = TLI.getRegClassFor(CopyVT);
1512 ResultReg = copyRegToRegClass(CpyRC, SourcePhysReg);
1513
1514
1515 } else if (CopyVT == MVT::f64) {
1516 ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
1517 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::FRSP),
1518 ResultReg).addReg(SourcePhysReg);
1519
1520
1521
1522
1523
1524 } else if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32) {
1525
1526 SourcePhysReg = (SourcePhysReg - PPC::X0) + PPC::R0;
1527 ResultReg = copyRegToRegClass(&PPC::GPRCRegClass, SourcePhysReg);
1528 }
1529
1530 assert(ResultReg && "ResultReg unset!");
1531 CLI.InRegs.push_back(SourcePhysReg);
1532 CLI.ResultReg = ResultReg;
1533 CLI.NumResultRegs = 1;
1534 }
1535
1536 return true;
1537}
1538
1539bool PPCFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1540 CallingConv::ID CC = CLI.CallConv;
1541 bool IsTailCall = CLI.IsTailCall;
1542 bool IsVarArg = CLI.IsVarArg;
1545
1546 if (!Callee && !Symbol)
1547 return false;
1548
1549
1550 if (IsTailCall || Subtarget->useLongCalls())
1551 return false;
1552
1553
1554 if (IsVarArg)
1555 return false;
1556
1557
1559 return false;
1560
1561
1562
1563 Type *RetTy = CLI.RetTy;
1564 MVT RetVT;
1566 RetVT = MVT::isVoid;
1567 else if (!isTypeLegal(RetTy, RetVT) && RetVT != MVT::i16 &&
1568 RetVT != MVT::i8)
1569 return false;
1570 else if (RetVT == MVT::i1 && Subtarget->useCRBits())
1571
1572 return false;
1573
1574
1575 if (RetVT != MVT::isVoid && RetVT != MVT::i8 && RetVT != MVT::i16 &&
1576 RetVT != MVT::i32 && RetVT != MVT::i64 && RetVT != MVT::f32 &&
1577 RetVT != MVT::f64) {
1579 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, RVLocs, *Context);
1581 if (RVLocs.size() > 1)
1582 return false;
1583 }
1584
1585
1586
1587 unsigned NumArgs = CLI.OutVals.size();
1588 if (NumArgs > 8)
1589 return false;
1590
1591
1592 SmallVector<Value*, 8> Args;
1596
1597 Args.reserve(NumArgs);
1598 ArgRegs.reserve(NumArgs);
1599 ArgVTs.reserve(NumArgs);
1600 ArgFlags.reserve(NumArgs);
1601
1602 for (unsigned i = 0, ie = NumArgs; i != ie; ++i) {
1603
1604
1605
1606 ISD::ArgFlagsTy Flags = CLI.OutFlags[i];
1608 return false;
1609
1610 Value *ArgValue = CLI.OutVals[i];
1612 MVT ArgVT;
1613 if (!isTypeLegal(ArgTy, ArgVT) && ArgVT != MVT::i16 && ArgVT != MVT::i8)
1614 return false;
1615
1616
1617
1618
1619 if (ArgVT.isVector() || ArgVT == MVT::f128)
1620 return false;
1621
1622 Register Arg = getRegForValue(ArgValue);
1623 if (!Arg)
1624 return false;
1625
1626 Args.push_back(ArgValue);
1630 }
1631
1632
1633 SmallVector<unsigned, 8> RegArgs;
1634 unsigned NumBytes;
1635
1636 if (!processCallArgs(Args, ArgRegs, ArgVTs, ArgFlags,
1637 RegArgs, CC, NumBytes, IsVarArg))
1638 return false;
1639
1640 MachineInstrBuilder MIB;
1641
1642
1644 if (!GV) {
1645
1646
1647
1648
1649
1650 if (CLI.IsPatchPoint)
1651 MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::NOP));
1652 else
1653 return false;
1654 } else {
1655
1656
1657 MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1659
1661 }
1662
1663
1664 for (unsigned Reg : RegArgs)
1666
1667
1668
1671
1672
1673
1674 MIB.addRegMask(TRI.getCallPreservedMask(*FuncInfo.MF, CC));
1675
1676 CLI.Call = MIB;
1677
1678
1679 return finishCall(RetVT, CLI, NumBytes);
1680}
1681
1682
1683bool PPCFastISel::SelectRet(const Instruction *I) {
1684
1685 if (!FuncInfo.CanLowerReturn)
1686 return false;
1687
1689 const Function &F = *I->getParent()->getParent();
1690
1691
1693 CallingConv::ID CC = F.getCallingConv();
1694
1697 GetReturnInfo(CC, F.getReturnType(), F.getAttributes(), Outs, TLI, DL);
1698
1699
1701 CCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, ValLocs, *Context);
1704
1705
1706 if (ValLocs.size() > 1)
1707 return false;
1708
1709
1710
1713 CCValAssign &VA = ValLocs[0];
1714
1716
1717
1718
1719
1722
1723 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1724 TII.get(TargetOpcode::COPY), RetReg).addReg(SrcReg);
1725
1727
1728 } else {
1730
1731 if ()
1732 return false;
1733
1734
1735 for (unsigned i = 0; i < ValLocs.size(); ++i) {
1736
1737 CCValAssign &VA = ValLocs[i];
1738 assert(VA.isRegLoc() && "Can only return in registers!");
1741
1744 return false;
1747
1748 if (RVVT != DestVT && RVVT != MVT::i8 &&
1749 RVVT != MVT::i16 && RVVT != MVT::i32)
1750 return false;
1751
1752 if (RVVT != DestVT) {
1754 default:
1757 llvm_unreachable("Full value assign but types don't match?");
1760 const TargetRegisterClass *RC =
1761 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1762 Register TmpReg = createResultReg(RC);
1763 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg, true))
1764 return false;
1765 SrcReg = TmpReg;
1766 break;
1767 }
1769 const TargetRegisterClass *RC =
1770 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1771 Register TmpReg = createResultReg(RC);
1772 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg, false))
1773 return false;
1774 SrcReg = TmpReg;
1775 break;
1776 }
1777 }
1778 }
1779
1780 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1781 TII.get(TargetOpcode::COPY), RetRegs[i])
1783 }
1784 }
1785 }
1786
1787 MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1789
1792
1793 return true;
1794}
1795
1796
1797
1798
1799bool PPCFastISel::PPCEmitIntExt(MVT SrcVT, Register SrcReg, MVT DestVT,
1800 Register DestReg, bool IsZExt) {
1801 if (DestVT != MVT::i32 && DestVT != MVT::i64)
1802 return false;
1803 if (SrcVT != MVT::i8 && SrcVT != MVT::i16 && SrcVT != MVT::i32)
1804 return false;
1805
1806
1807 if (!IsZExt) {
1808 unsigned Opc;
1809 if (SrcVT == MVT::i8)
1810 Opc = (DestVT == MVT::i32) ? PPC::EXTSB : PPC::EXTSB8_32_64;
1811 else if (SrcVT == MVT::i16)
1812 Opc = (DestVT == MVT::i32) ? PPC::EXTSH : PPC::EXTSH8_32_64;
1813 else {
1814 assert(DestVT == MVT::i64 && "Signed extend from i32 to i32??");
1815 Opc = PPC::EXTSW_32_64;
1816 }
1817 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
1819
1820
1821 } else if (DestVT == MVT::i32) {
1822 unsigned MB;
1823 if (SrcVT == MVT::i8)
1824 MB = 24;
1825 else {
1826 assert(SrcVT == MVT::i16 && "Unsigned extend from i32 to i32??");
1827 MB = 16;
1828 }
1829 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::RLWINM),
1830 DestReg)
1832
1833
1834 } else {
1835 unsigned MB;
1836 if (SrcVT == MVT::i8)
1837 MB = 56;
1838 else if (SrcVT == MVT::i16)
1839 MB = 48;
1840 else
1841 MB = 32;
1842 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1843 TII.get(PPC::RLDICL_32_64), DestReg)
1845 }
1846
1847 return true;
1848}
1849
1850
1851bool PPCFastISel::SelectIndirectBr(const Instruction *I) {
1852 Register AddrReg = getRegForValue(I->getOperand(0));
1853 if (!AddrReg)
1854 return false;
1855
1856 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::MTCTR8))
1858 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::BCTR8));
1859
1861 for (const BasicBlock *SuccBB : IB->successors())
1862 FuncInfo.MBB->addSuccessor(FuncInfo.getMBB(SuccBB));
1863
1864 return true;
1865}
1866
1867
1868bool PPCFastISel::SelectTrunc(const Instruction *I) {
1869 Value *Src = I->getOperand(0);
1870 EVT SrcVT = TLI.getValueType(DL, Src->getType(), true);
1872
1873 if (SrcVT != MVT::i64 && SrcVT != MVT::i32 && SrcVT != MVT::i16)
1874 return false;
1875
1876 if (DestVT != MVT::i32 && DestVT != MVT::i16 && DestVT != MVT::i8)
1877 return false;
1878
1879 Register SrcReg = getRegForValue(Src);
1880 if (!SrcReg)
1881 return false;
1882
1883
1884 if (SrcVT == MVT::i64)
1885 SrcReg = copyRegToRegClass(&PPC::GPRCRegClass, SrcReg, 0, PPC::sub_32);
1886
1887 updateValueMap(I, SrcReg);
1888 return true;
1889}
1890
1891
1892bool PPCFastISel::SelectIntExt(const Instruction *I) {
1893 Type *DestTy = I->getType();
1894 Value *Src = I->getOperand(0);
1895 Type *SrcTy = Src->getType();
1896
1898 Register SrcReg = getRegForValue(Src);
1899 if (!SrcReg) return false;
1900
1901 EVT SrcEVT, DestEVT;
1905 return false;
1907 return false;
1908
1911
1912
1913
1914
1915
1916 Register AssignedReg = FuncInfo.ValueMap[I];
1917 const TargetRegisterClass *RC =
1918 (AssignedReg ? MRI.getRegClass(AssignedReg) :
1919 (DestVT == MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
1920 &PPC::GPRC_and_GPRC_NOR0RegClass));
1921 Register ResultReg = createResultReg(RC);
1922
1923 if (!PPCEmitIntExt(SrcVT, SrcReg, DestVT, ResultReg, IsZExt))
1924 return false;
1925
1926 updateValueMap(I, ResultReg);
1927 return true;
1928}
1929
1930
1931
1932bool PPCFastISel::fastSelectInstruction(const Instruction *I) {
1933
1934 switch (I->getOpcode()) {
1935 case Instruction::Load:
1936 return SelectLoad(I);
1937 case Instruction::Store:
1938 return SelectStore(I);
1939 case Instruction::Br:
1940 return SelectBranch(I);
1941 case Instruction::IndirectBr:
1942 return SelectIndirectBr(I);
1943 case Instruction::FPExt:
1944 return SelectFPExt(I);
1945 case Instruction::FPTrunc:
1946 return SelectFPTrunc(I);
1947 case Instruction::SIToFP:
1948 return SelectIToFP(I, true);
1949 case Instruction::UIToFP:
1950 return SelectIToFP(I, false);
1951 case Instruction::FPToSI:
1952 return SelectFPToI(I, true);
1953 case Instruction::FPToUI:
1954 return SelectFPToI(I, false);
1955 case Instruction::Add:
1956 return SelectBinaryIntOp(I, ISD::ADD);
1957 case Instruction::Or:
1958 return SelectBinaryIntOp(I, ISD::OR);
1959 case Instruction::Sub:
1960 return SelectBinaryIntOp(I, ISD::SUB);
1961 case Instruction::Ret:
1962 return SelectRet(I);
1963 case Instruction::Trunc:
1964 return SelectTrunc(I);
1965 case Instruction::ZExt:
1966 case Instruction::SExt:
1967 return SelectIntExt(I);
1968
1969
1970
1971 default:
1972 break;
1973 }
1974 return false;
1975}
1976
1977
1978
1979Register PPCFastISel::PPCMaterializeFP(const ConstantFP *CFP, MVT VT) {
1980
1983
1984
1985 if (VT != MVT::f32 && VT != MVT::f64)
1987
1988
1989 Align Alignment = DL.getPrefTypeAlign(CFP->getType());
1990 unsigned Idx = MCP.getConstantPoolIndex(cast(CFP), Alignment);
1991 const bool HasSPE = Subtarget->hasSPE();
1992 const TargetRegisterClass *RC;
1993 if (HasSPE)
1994 RC = ((VT == MVT::f32) ? &PPC::GPRCRegClass : &PPC::SPERCRegClass);
1995 else
1996 RC = ((VT == MVT::f32) ? &PPC::F4RCRegClass : &PPC::F8RCRegClass);
1997
1998 Register DestReg = createResultReg(RC);
2000
2001 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
2004
2005 unsigned Opc;
2006
2007 if (HasSPE)
2008 Opc = ((VT == MVT::f32) ? PPC::SPELWZ : PPC::EVLDD);
2009 else
2010 Opc = ((VT == MVT::f32) ? PPC::LFS : PPC::LFD);
2011
2012 Register TmpReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2013
2015
2017 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::LDtocCPT),
2018 TmpReg)
2020 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
2022 } else {
2023
2024 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ADDIStocHA8),
2026
2027
2029 Register TmpReg2 = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2030 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::LDtocL),
2032 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
2035 } else
2036 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
2040 }
2041
2042 return DestReg;
2043}
2044
2045
2046
2047Register PPCFastISel::PPCMaterializeGV(const GlobalValue *GV, MVT VT) {
2048
2051
2052 assert(VT == MVT::i64 && "Non-address!");
2053 const TargetRegisterClass *RC = &PPC::G8RC_and_G8RC_NOX0RegClass;
2054 Register DestReg = createResultReg(RC);
2055
2056
2057
2058
2060
2061
2062
2063
2064
2065
2068
2073
2074
2077 *FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2078 IsAIXTocData ? TII.get(PPC::ADDItoc8) : TII.get(PPC::LDtoc), DestReg);
2079 if (IsAIXTocData)
2081 else
2083 } else {
2084
2085
2086
2087
2088
2089
2090
2091
2092 Register HighPartReg = createResultReg(RC);
2093 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ADDIStocHA8),
2095
2097 assert(!IsAIXTocData && "TOC data should always be direct.");
2098 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::LDtocL),
2100 } else {
2101
2102 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ADDItocL8),
2103 DestReg)
2104 .addReg(HighPartReg)
2106 }
2107 }
2108
2109 return DestReg;
2110}
2111
2112
2113
2114Register PPCFastISel::PPCMaterialize32BitInt(int64_t Imm,
2115 const TargetRegisterClass *RC) {
2116 unsigned Lo = Imm & 0xFFFF;
2117 unsigned Hi = (Imm >> 16) & 0xFFFF;
2118
2119 Register ResultReg = createResultReg(RC);
2121
2123 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2124 TII.get(IsGPRC ? PPC::LI : PPC::LI8), ResultReg)
2126 else if (Lo) {
2127
2128 Register TmpReg = createResultReg(RC);
2129 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2130 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), TmpReg)
2132 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2133 TII.get(IsGPRC ? PPC::ORI : PPC::ORI8), ResultReg)
2135 } else
2136
2137 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2138 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), ResultReg)
2140
2141 return ResultReg;
2142}
2143
2144
2145
2146Register PPCFastISel::PPCMaterialize64BitInt(int64_t Imm,
2147 const TargetRegisterClass *RC) {
2148 unsigned Remainder = 0;
2149 unsigned Shift = 0;
2150
2151
2152
2155 int64_t ImmSh = static_cast<uint64_t>(Imm) >> Shift;
2156
2158 Imm = ImmSh;
2159 else {
2160 Remainder = Imm;
2161 Shift = 32;
2162 Imm >>= 32;
2163 }
2164 }
2165
2166
2167
2168 Register TmpReg1 = PPCMaterialize32BitInt(Imm, RC);
2169 if (!Shift)
2170 return TmpReg1;
2171
2172
2173
2175 if (Imm) {
2176 TmpReg2 = createResultReg(RC);
2177 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::RLDICR),
2179 } else
2180 TmpReg2 = TmpReg1;
2181
2184 if ((Hi = (Remainder >> 16) & 0xFFFF)) {
2185 TmpReg3 = createResultReg(RC);
2186 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ORIS8),
2188 } else
2189 TmpReg3 = TmpReg2;
2190
2191 if ((Lo = Remainder & 0xFFFF)) {
2192 Register ResultReg = createResultReg(RC);
2193 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ORI8),
2195 return ResultReg;
2196 }
2197
2198 return TmpReg3;
2199}
2200
2201
2202
2203Register PPCFastISel::PPCMaterializeInt(const ConstantInt *CI, MVT VT,
2204 bool UseSExt) {
2205
2206
2207 if (VT == MVT::i1 && Subtarget->useCRBits()) {
2208 Register ImmReg = createResultReg(&PPC::CRBITRCRegClass);
2209 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2210 TII.get(CI->isZero() ? PPC::CRUNSET : PPC::CRSET), ImmReg);
2211 return ImmReg;
2212 }
2213
2214 if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 &&
2215 VT != MVT::i1)
2217
2218 const TargetRegisterClass *RC =
2219 ((VT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass);
2221
2222
2223
2224
2225
2227 unsigned Opc = (VT == MVT::i64) ? PPC::LI8 : PPC::LI;
2228 Register ImmReg = createResultReg(RC);
2229 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ImmReg)
2231 return ImmReg;
2232 }
2233
2234
2235 if (VT == MVT::i64)
2236 return PPCMaterialize64BitInt(Imm, RC);
2237 else if (VT == MVT::i32)
2238 return PPCMaterialize32BitInt(Imm, RC);
2239
2241}
2242
2243
2244
2245Register PPCFastISel::fastMaterializeConstant(const Constant *C) {
2247
2248
2252
2254 return PPCMaterializeFP(CFP, VT);
2256 return PPCMaterializeGV(GV, VT);
2258
2259
2260
2261
2262
2263 return PPCMaterializeInt(CI, VT, false);
2264
2266}
2267
2268
2269
2270Register PPCFastISel::fastMaterializeAlloca(const AllocaInst *AI) {
2271 DenseMap<const AllocaInst *, int>::iterator SI =
2272 FuncInfo.StaticAllocaMap.find(AI);
2273
2274
2275 if (SI == FuncInfo.StaticAllocaMap.end())
2277
2278 MVT VT;
2279 if (!isLoadTypeLegal(AI->getType(), VT))
2281
2282 if (SI != FuncInfo.StaticAllocaMap.end()) {
2283 Register ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2284 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ADDI8),
2286 return ResultReg;
2287 }
2288
2290}
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300bool PPCFastISel::tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,
2301 const LoadInst *LI) {
2302
2303 MVT VT;
2304 if (!isLoadTypeLegal(LI->getType(), VT))
2305 return false;
2306
2307
2308 bool IsZExt = false;
2309 switch(MI->getOpcode()) {
2310 default:
2311 return false;
2312
2313 case PPC::RLDICL:
2314 case PPC::RLDICL_32_64: {
2315 IsZExt = true;
2316 unsigned MB = MI->getOperand(3).getImm();
2317 if ((VT == MVT::i8 && MB <= 56) ||
2318 (VT == MVT::i16 && MB <= 48) ||
2319 (VT == MVT::i32 && MB <= 32))
2320 break;
2321 return false;
2322 }
2323
2324 case PPC::RLWINM:
2325 case PPC::RLWINM8: {
2326 IsZExt = true;
2327 unsigned MB = MI->getOperand(3).getImm();
2328 if ((VT == MVT::i8 && MB <= 24) ||
2329 (VT == MVT::i16 && MB <= 16))
2330 break;
2331 return false;
2332 }
2333
2334 case PPC::EXTSB:
2335 case PPC::EXTSB8:
2336 case PPC::EXTSB8_32_64:
2337
2338 return false;
2339
2340 case PPC::EXTSH:
2341 case PPC::EXTSH8:
2342 case PPC::EXTSH8_32_64: {
2343 if (VT != MVT::i16 && VT != MVT::i8)
2344 return false;
2345 break;
2346 }
2347
2348 case PPC::EXTSW:
2349 case PPC::EXTSW_32:
2350 case PPC::EXTSW_32_64: {
2351 if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8)
2352 return false;
2353 break;
2354 }
2355 }
2356
2357
2359 if (!PPCComputeAddress(LI->getOperand(0), Addr))
2360 return false;
2361
2362 Register ResultReg = MI->getOperand(0).getReg();
2363
2364 if (!PPCEmitLoad(VT, ResultReg, Addr, nullptr, IsZExt,
2365 Subtarget->hasSPE() ? PPC::EVLDD : PPC::LFD))
2366 return false;
2367
2369 removeDeadCode(I, std::next(I));
2370 return true;
2371}
2372
2373
2374
2375bool PPCFastISel::fastLowerArguments() {
2376
2377
2378
2379
2380 return false;
2381}
2382
2383
2384
2385Register PPCFastISel::fastEmit_i(MVT Ty, MVT VT, unsigned Opc, uint64_t Imm) {
2386
2389
2390
2391
2392 if (VT == MVT::i1 && Subtarget->useCRBits()) {
2393 Register ImmReg = createResultReg(&PPC::CRBITRCRegClass);
2394 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2395 TII.get(Imm == 0 ? PPC::CRUNSET : PPC::CRSET), ImmReg);
2396 return ImmReg;
2397 }
2398
2399 if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 &&
2400 VT != MVT::i1)
2402
2403 const TargetRegisterClass *RC = ((VT == MVT::i64) ? &PPC::G8RCRegClass :
2404 &PPC::GPRCRegClass);
2405 if (VT == MVT::i64)
2406 return PPCMaterialize64BitInt(Imm, RC);
2407 else
2408 return PPCMaterialize32BitInt(Imm, RC);
2409}
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422Register PPCFastISel::fastEmitInst_ri(unsigned MachineInstOpcode,
2423 const TargetRegisterClass *RC,
2424 Register Op0, uint64_t Imm) {
2425 if (MachineInstOpcode == PPC::ADDI)
2426 MRI.setRegClass(Op0, &PPC::GPRC_and_GPRC_NOR0RegClass);
2427 else if (MachineInstOpcode == PPC::ADDI8)
2428 MRI.setRegClass(Op0, &PPC::G8RC_and_G8RC_NOX0RegClass);
2429
2430 const TargetRegisterClass *UseRC =
2431 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2432 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2433
2435}
2436
2437
2438
2439
2440Register PPCFastISel::fastEmitInst_r(unsigned MachineInstOpcode,
2441 const TargetRegisterClass *RC,
2443 const TargetRegisterClass *UseRC =
2444 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2445 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2446
2448}
2449
2450
2451
2452
2453Register PPCFastISel::fastEmitInst_rr(unsigned MachineInstOpcode,
2454 const TargetRegisterClass *RC,
2456 const TargetRegisterClass *UseRC =
2457 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2458 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2459
2461}
2462
2463namespace llvm {
2464
2467
2469 if (Subtarget.isPPC64())
2470 return new PPCFastISel(FuncInfo, LibInfo);
2471 return nullptr;
2472 }
2473}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
static ARMCC::CondCodes getComparePred(CmpInst::Predicate Pred)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file defines the FastISel class.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register const TargetRegisterInfo * TRI
Promote Memory to Register
uint64_t IntrinsicInst * II
static std::optional< PPC::Predicate > getComparePred(CmpInst::Predicate Pred)
Definition PPCFastISel.cpp:189
static constexpr MCPhysReg FPReg
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file describes how to lower LLVM code to machine code.
uint64_t getZExtValue() const
Get zero extended value.
int64_t getSExtValue() const
Get sign 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
Register getLocReg() const
LocInfo getLocInfo() const
unsigned getValNo() const
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ 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
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ ICMP_ULT
unsigned less than
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
ConstantFP - Floating Point Values [float, double].
This is the shared class of boolean and integer constants.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
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_ri(unsigned MachineInstOpcode, const TargetRegisterClass *RC, Register Op0, uint64_t Imm)
Emit a MachineInstr with a register operand, an immediate, and a result register in the given registe...
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.
Register fastEmitInst_r(unsigned MachineInstOpcode, const TargetRegisterClass *RC, Register Op0)
Emit a MachineInstr with one register operand and a result register in the given register class.
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
MachineBasicBlock::iterator InsertPt
MBB - The current insert position inside the current block.
MachineBasicBlock * MBB
MBB - The current block.
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.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
bool isVector() const
Return true if this is a vector value type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
MachineInstrBundleIterator< MachineInstr > iterator
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 & addFrameIndex(int Idx) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) 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
Representation of each machine instruction.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
const PPCFrameLowering * getFrameLowering() const override
bool isUsingPCRelativeCalls() const
const PPCTargetLowering * getTargetLowering() const override
const PPCInstrInfo * getInstrInfo() const override
bool isLittleEndian() const
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
void push_back(const T &Elt)
TypeSize getElementOffset(unsigned Idx) const
TargetInstrInfo - Interface to description of machine instruction set.
unsigned getCallFrameSetupOpcode() const
These methods return the opcode of the frame setup/destroy instructions if they exist (-1 otherwise).
unsigned getCallFrameDestroyOpcode() const
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.
const Triple & getTargetTriple() const
CodeModel::Model getCodeModel() const
Returns the code model.
unsigned getID() const
Return the register class ID number.
bool hasSuperClassEq(const TargetRegisterClass *RC) const
Returns true if RC is a super-class of or equal to this class.
bool isOSAIX() const
Tests whether the OS is AIX.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isVoidTy() const
Return true if this is 'void'.
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.
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.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ ADD
Simple integer binary arithmetic operators.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo)
Definition PPCFastISel.cpp:2465
Predicate InvertPredicate(Predicate Opcode)
Invert the specified predicate. != -> ==, < -> >=.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ User
could "use" a pointer
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
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 RetCC_PPC64_ELF_FIS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
bool CC_PPC64_ELF_FIS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
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...
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.
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.