51 #define DEBUG_TYPE "x86-codegen"
53 STATISTIC(NumFXCH,
"Number of fxch instructions inserted");
54 STATISTIC(NumFP ,
"Number of floating point instructions");
57 const unsigned ScratchFPReg = 7;
65 memset(Stack, 0,
sizeof(Stack));
66 memset(RegMap, 0,
sizeof(RegMap));
84 StringRef getPassName()
const override {
return "X86 FP Stackifier"; }
110 unsigned char FixStack[8];
112 LiveBundle() :
Mask(0), FixCount(0) {}
115 bool isFixed()
const {
return !
Mask || FixCount; }
128 for (
const auto &LI : MBB->
liveins()) {
129 if (LI.PhysReg < X86::FP0 || LI.PhysReg > X86::FP6)
131 Mask |= 1 << (LI.PhysReg - X86::FP0);
156 unsigned RegMap[NumFPRegs];
159 void setupBlockStack();
162 void finishBlockStack();
164 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
165 void dumpStack()
const {
166 dbgs() <<
"Stack contents:";
167 for (
unsigned i = 0;
i != StackTop; ++
i) {
169 assert(RegMap[Stack[
i]] ==
i &&
"Stack[] doesn't match RegMap[]!");
176 unsigned getSlot(
unsigned RegNo)
const {
177 assert(RegNo < NumFPRegs &&
"Regno out of range!");
178 return RegMap[RegNo];
182 bool isLive(
unsigned RegNo)
const {
183 unsigned Slot = getSlot(RegNo);
184 return Slot < StackTop &&
Stack[Slot] == RegNo;
188 unsigned getStackEntry(
unsigned STi)
const {
191 return Stack[StackTop-1-STi];
196 unsigned getSTReg(
unsigned RegNo)
const {
197 return StackTop - 1 - getSlot(RegNo) + X86::ST0;
201 void pushReg(
unsigned Reg) {
202 assert(Reg < NumFPRegs &&
"Register number out of range!");
206 RegMap[
Reg] = StackTop++;
213 RegMap[
Stack[--StackTop]] = ~0;
216 bool isAtTop(
unsigned RegNo)
const {
return getSlot(RegNo) == StackTop-1; }
219 if (isAtTop(RegNo))
return;
221 unsigned STReg = getSTReg(RegNo);
222 unsigned RegOnTop = getStackEntry(0);
225 std::swap(RegMap[RegNo], RegMap[RegOnTop]);
228 if (RegMap[RegOnTop] >= StackTop)
230 std::swap(Stack[RegMap[RegOnTop]], Stack[StackTop-1]);
233 BuildMI(*MBB, I, dl,
TII->get(X86::XCH_F)).addReg(STReg);
237 void duplicateToTop(
unsigned RegNo,
unsigned AsReg,
240 unsigned STReg = getSTReg(RegNo);
243 BuildMI(*MBB, I, dl,
TII->get(X86::LD_Frr)).addReg(STReg);
267 void shuffleStackTop(
const unsigned char *FixStack,
unsigned FixCount,
287 return X86::RFP80RegClass.contains(DstReg) ||
288 X86::RFP80RegClass.contains(SrcReg);
302 unsigned Reg = MO.
getReg();
303 assert(Reg >= X86::FP0 && Reg <= X86::FP6 &&
"Expected FP register!");
304 return Reg - X86::FP0;
313 bool FPIsUsed =
false;
315 static_assert(X86::FP6 == X86::FP0+6,
"Register enums aren't sorted right!");
317 for (
unsigned i = 0;
i <= 6; ++
i)
324 if (!FPIsUsed)
return false;
326 Bundles = &getAnalysis<EdgeBundles>();
340 LiveBundles[Bundles->getBundle(Entry->
getNumber(),
false)];
352 assert((Bundle.Mask & 0xFE) == 0 &&
353 "Only FP0 could be passed as an argument");
355 Bundle.FixStack[0] = 0;
358 bool Changed =
false;
360 Changed |= processBasicBlock(MF, *BB);
365 if (Processed.
insert(&BB).second)
366 Changed |= processBasicBlock(MF, BB);
379 assert(LiveBundles.empty() &&
"Stale data in LiveBundles");
380 LiveBundles.resize(Bundles->getNumBundles());
384 const unsigned Mask = calcLiveInMask(&MBB);
388 LiveBundles[Bundles->getBundle(MBB.
getNumber(),
false)].Mask |= Mask;
396 bool Changed =
false;
410 if (MI.
isCopy() && isFPCopy(MI))
425 PrevMI = &*std::prev(I);
439 switch (FPInstClass) {
452 for (
unsigned i = 0, e = DeadRegs.
size();
i != e; ++
i) {
453 unsigned Reg = DeadRegs[
i];
456 if (Reg >= X86::FP0 && Reg <= X86::FP6 && isLive(Reg-X86::FP0)) {
457 DEBUG(
dbgs() <<
"Register FP#" << Reg-X86::FP0 <<
" is dead!\n");
458 freeStackSlotAfter(I, Reg-X86::FP0);
466 dbgs() <<
"Just deleted pseudo instruction\n";
470 while (Start != BB.
begin() && std::prev(Start) != PrevI)
472 dbgs() <<
"Inserted instructions:\n\t";
473 Start->print(
dbgs());
474 while (++Start != std::next(I)) {
491 void FPS::setupBlockStack() {
493 <<
" derived from " << MBB->
getName() <<
".\n");
496 const LiveBundle &Bundle =
497 LiveBundles[Bundles->getBundle(MBB->
getNumber(),
false)];
500 DEBUG(
dbgs() <<
"Block has no FP live-ins.\n");
505 assert(Bundle.isFixed() &&
"Reached block before any predecessors");
508 for (
unsigned i = Bundle.FixCount;
i > 0; --
i) {
510 DEBUG(
dbgs() <<
"Live-in st(" << (
i-1) <<
"): %FP"
511 <<
unsigned(Bundle.FixStack[
i-1]) <<
'\n');
512 pushReg(Bundle.FixStack[
i-1]);
518 adjustLiveRegs(calcLiveInMask(MBB), MBB->
begin());
526 void FPS::finishBlockStack() {
532 <<
" derived from " << MBB->
getName() <<
".\n");
535 unsigned BundleIdx = Bundles->getBundle(MBB->
getNumber(),
true);
536 LiveBundle &Bundle = LiveBundles[BundleIdx];
541 adjustLiveRegs(Bundle.Mask, Term);
549 DEBUG(
dbgs() <<
"LB#" << BundleIdx <<
": ");
550 if (Bundle.isFixed()) {
551 DEBUG(
dbgs() <<
"Shuffling stack to match.\n");
552 shuffleStackTop(Bundle.FixStack, Bundle.FixCount, Term);
555 DEBUG(
dbgs() <<
"Fixing stack order now.\n");
556 Bundle.FixCount = StackTop;
557 for (
unsigned i = 0;
i < StackTop; ++
i)
558 Bundle.FixStack[
i] = getStackEntry(
i);
571 bool operator<(
const TableEntry &TE)
const {
return from < TE.from; }
572 friend bool operator<(
const TableEntry &TE,
unsigned V) {
576 const TableEntry &TE) {
583 const TableEntry *I = std::lower_bound(Table.
begin(), Table.
end(), Opcode);
584 if (I != Table.
end() && I->from == Opcode)
590 #define ASSERT_SORTED(TABLE)
592 #define ASSERT_SORTED(TABLE) \
593 { static bool TABLE##Checked = false; \
594 if (!TABLE##Checked) { \
595 assert(std::is_sorted(std::begin(TABLE), std::end(TABLE)) && \
596 "All lookup tables must be sorted for efficient access!"); \
597 TABLE##Checked = true; \
611 { X86::ABS_Fp32 , X86::ABS_F },
612 { X86::ABS_Fp64 , X86::ABS_F },
613 { X86::ABS_Fp80 , X86::ABS_F },
614 { X86::ADD_Fp32m , X86::ADD_F32m },
615 { X86::ADD_Fp64m , X86::ADD_F64m },
616 { X86::ADD_Fp64m32 , X86::ADD_F32m },
617 { X86::ADD_Fp80m32 , X86::ADD_F32m },
618 { X86::ADD_Fp80m64 , X86::ADD_F64m },
619 { X86::ADD_FpI16m32 , X86::ADD_FI16m },
620 { X86::ADD_FpI16m64 , X86::ADD_FI16m },
621 { X86::ADD_FpI16m80 , X86::ADD_FI16m },
622 { X86::ADD_FpI32m32 , X86::ADD_FI32m },
623 { X86::ADD_FpI32m64 , X86::ADD_FI32m },
624 { X86::ADD_FpI32m80 , X86::ADD_FI32m },
625 { X86::CHS_Fp32 , X86::CHS_F },
626 { X86::CHS_Fp64 , X86::CHS_F },
627 { X86::CHS_Fp80 , X86::CHS_F },
628 { X86::CMOVBE_Fp32 , X86::CMOVBE_F },
629 { X86::CMOVBE_Fp64 , X86::CMOVBE_F },
630 { X86::CMOVBE_Fp80 , X86::CMOVBE_F },
631 { X86::CMOVB_Fp32 , X86::CMOVB_F },
632 { X86::CMOVB_Fp64 , X86::CMOVB_F },
633 { X86::CMOVB_Fp80 , X86::CMOVB_F },
634 { X86::CMOVE_Fp32 , X86::CMOVE_F },
635 { X86::CMOVE_Fp64 , X86::CMOVE_F },
636 { X86::CMOVE_Fp80 , X86::CMOVE_F },
637 { X86::CMOVNBE_Fp32 , X86::CMOVNBE_F },
638 { X86::CMOVNBE_Fp64 , X86::CMOVNBE_F },
639 { X86::CMOVNBE_Fp80 , X86::CMOVNBE_F },
640 { X86::CMOVNB_Fp32 , X86::CMOVNB_F },
641 { X86::CMOVNB_Fp64 , X86::CMOVNB_F },
642 { X86::CMOVNB_Fp80 , X86::CMOVNB_F },
643 { X86::CMOVNE_Fp32 , X86::CMOVNE_F },
644 { X86::CMOVNE_Fp64 , X86::CMOVNE_F },
645 { X86::CMOVNE_Fp80 , X86::CMOVNE_F },
646 { X86::CMOVNP_Fp32 , X86::CMOVNP_F },
647 { X86::CMOVNP_Fp64 , X86::CMOVNP_F },
648 { X86::CMOVNP_Fp80 , X86::CMOVNP_F },
649 { X86::CMOVP_Fp32 , X86::CMOVP_F },
650 { X86::CMOVP_Fp64 , X86::CMOVP_F },
651 { X86::CMOVP_Fp80 , X86::CMOVP_F },
652 { X86::COS_Fp32 , X86::COS_F },
653 { X86::COS_Fp64 , X86::COS_F },
654 { X86::COS_Fp80 , X86::COS_F },
655 { X86::DIVR_Fp32m , X86::DIVR_F32m },
656 { X86::DIVR_Fp64m , X86::DIVR_F64m },
657 { X86::DIVR_Fp64m32 , X86::DIVR_F32m },
658 { X86::DIVR_Fp80m32 , X86::DIVR_F32m },
659 { X86::DIVR_Fp80m64 , X86::DIVR_F64m },
660 { X86::DIVR_FpI16m32, X86::DIVR_FI16m},
661 { X86::DIVR_FpI16m64, X86::DIVR_FI16m},
662 { X86::DIVR_FpI16m80, X86::DIVR_FI16m},
663 { X86::DIVR_FpI32m32, X86::DIVR_FI32m},
664 { X86::DIVR_FpI32m64, X86::DIVR_FI32m},
665 { X86::DIVR_FpI32m80, X86::DIVR_FI32m},
666 { X86::DIV_Fp32m , X86::DIV_F32m },
667 { X86::DIV_Fp64m , X86::DIV_F64m },
668 { X86::DIV_Fp64m32 , X86::DIV_F32m },
669 { X86::DIV_Fp80m32 , X86::DIV_F32m },
670 { X86::DIV_Fp80m64 , X86::DIV_F64m },
671 { X86::DIV_FpI16m32 , X86::DIV_FI16m },
672 { X86::DIV_FpI16m64 , X86::DIV_FI16m },
673 { X86::DIV_FpI16m80 , X86::DIV_FI16m },
674 { X86::DIV_FpI32m32 , X86::DIV_FI32m },
675 { X86::DIV_FpI32m64 , X86::DIV_FI32m },
676 { X86::DIV_FpI32m80 , X86::DIV_FI32m },
677 { X86::ILD_Fp16m32 , X86::ILD_F16m },
678 { X86::ILD_Fp16m64 , X86::ILD_F16m },
679 { X86::ILD_Fp16m80 , X86::ILD_F16m },
680 { X86::ILD_Fp32m32 , X86::ILD_F32m },
681 { X86::ILD_Fp32m64 , X86::ILD_F32m },
682 { X86::ILD_Fp32m80 , X86::ILD_F32m },
683 { X86::ILD_Fp64m32 , X86::ILD_F64m },
684 { X86::ILD_Fp64m64 , X86::ILD_F64m },
685 { X86::ILD_Fp64m80 , X86::ILD_F64m },
686 { X86::ISTT_Fp16m32 , X86::ISTT_FP16m},
687 { X86::ISTT_Fp16m64 , X86::ISTT_FP16m},
688 { X86::ISTT_Fp16m80 , X86::ISTT_FP16m},
689 { X86::ISTT_Fp32m32 , X86::ISTT_FP32m},
690 { X86::ISTT_Fp32m64 , X86::ISTT_FP32m},
691 { X86::ISTT_Fp32m80 , X86::ISTT_FP32m},
692 { X86::ISTT_Fp64m32 , X86::ISTT_FP64m},
693 { X86::ISTT_Fp64m64 , X86::ISTT_FP64m},
694 { X86::ISTT_Fp64m80 , X86::ISTT_FP64m},
695 { X86::IST_Fp16m32 , X86::IST_F16m },
696 { X86::IST_Fp16m64 , X86::IST_F16m },
697 { X86::IST_Fp16m80 , X86::IST_F16m },
698 { X86::IST_Fp32m32 , X86::IST_F32m },
699 { X86::IST_Fp32m64 , X86::IST_F32m },
700 { X86::IST_Fp32m80 , X86::IST_F32m },
701 { X86::IST_Fp64m32 , X86::IST_FP64m },
702 { X86::IST_Fp64m64 , X86::IST_FP64m },
703 { X86::IST_Fp64m80 , X86::IST_FP64m },
704 { X86::LD_Fp032 , X86::LD_F0 },
705 { X86::LD_Fp064 , X86::LD_F0 },
706 { X86::LD_Fp080 , X86::LD_F0 },
707 { X86::LD_Fp132 , X86::LD_F1 },
708 { X86::LD_Fp164 , X86::LD_F1 },
709 { X86::LD_Fp180 , X86::LD_F1 },
710 { X86::LD_Fp32m , X86::LD_F32m },
711 { X86::LD_Fp32m64 , X86::LD_F32m },
712 { X86::LD_Fp32m80 , X86::LD_F32m },
713 { X86::LD_Fp64m , X86::LD_F64m },
714 { X86::LD_Fp64m80 , X86::LD_F64m },
715 { X86::LD_Fp80m , X86::LD_F80m },
716 { X86::MUL_Fp32m , X86::MUL_F32m },
717 { X86::MUL_Fp64m , X86::MUL_F64m },
718 { X86::MUL_Fp64m32 , X86::MUL_F32m },
719 { X86::MUL_Fp80m32 , X86::MUL_F32m },
720 { X86::MUL_Fp80m64 , X86::MUL_F64m },
721 { X86::MUL_FpI16m32 , X86::MUL_FI16m },
722 { X86::MUL_FpI16m64 , X86::MUL_FI16m },
723 { X86::MUL_FpI16m80 , X86::MUL_FI16m },
724 { X86::MUL_FpI32m32 , X86::MUL_FI32m },
725 { X86::MUL_FpI32m64 , X86::MUL_FI32m },
726 { X86::MUL_FpI32m80 , X86::MUL_FI32m },
727 { X86::SIN_Fp32 , X86::SIN_F },
728 { X86::SIN_Fp64 , X86::SIN_F },
729 { X86::SIN_Fp80 , X86::SIN_F },
730 { X86::SQRT_Fp32 , X86::SQRT_F },
731 { X86::SQRT_Fp64 , X86::SQRT_F },
732 { X86::SQRT_Fp80 , X86::SQRT_F },
733 { X86::ST_Fp32m , X86::ST_F32m },
734 { X86::ST_Fp64m , X86::ST_F64m },
735 { X86::ST_Fp64m32 , X86::ST_F32m },
736 { X86::ST_Fp80m32 , X86::ST_F32m },
737 { X86::ST_Fp80m64 , X86::ST_F64m },
738 { X86::ST_FpP80m , X86::ST_FP80m },
739 { X86::SUBR_Fp32m , X86::SUBR_F32m },
740 { X86::SUBR_Fp64m , X86::SUBR_F64m },
741 { X86::SUBR_Fp64m32 , X86::SUBR_F32m },
742 { X86::SUBR_Fp80m32 , X86::SUBR_F32m },
743 { X86::SUBR_Fp80m64 , X86::SUBR_F64m },
744 { X86::SUBR_FpI16m32, X86::SUBR_FI16m},
745 { X86::SUBR_FpI16m64, X86::SUBR_FI16m},
746 { X86::SUBR_FpI16m80, X86::SUBR_FI16m},
747 { X86::SUBR_FpI32m32, X86::SUBR_FI32m},
748 { X86::SUBR_FpI32m64, X86::SUBR_FI32m},
749 { X86::SUBR_FpI32m80, X86::SUBR_FI32m},
750 { X86::SUB_Fp32m , X86::SUB_F32m },
751 { X86::SUB_Fp64m , X86::SUB_F64m },
752 { X86::SUB_Fp64m32 , X86::SUB_F32m },
753 { X86::SUB_Fp80m32 , X86::SUB_F32m },
754 { X86::SUB_Fp80m64 , X86::SUB_F64m },
755 { X86::SUB_FpI16m32 , X86::SUB_FI16m },
756 { X86::SUB_FpI16m64 , X86::SUB_FI16m },
757 { X86::SUB_FpI16m80 , X86::SUB_FI16m },
758 { X86::SUB_FpI32m32 , X86::SUB_FI32m },
759 { X86::SUB_FpI32m64 , X86::SUB_FI32m },
760 { X86::SUB_FpI32m80 , X86::SUB_FI32m },
761 { X86::TST_Fp32 , X86::TST_F },
762 { X86::TST_Fp64 , X86::TST_F },
763 { X86::TST_Fp80 , X86::TST_F },
764 { X86::UCOM_FpIr32 , X86::UCOM_FIr },
765 { X86::UCOM_FpIr64 , X86::UCOM_FIr },
766 { X86::UCOM_FpIr80 , X86::UCOM_FIr },
767 { X86::UCOM_Fpr32 , X86::UCOM_Fr },
768 { X86::UCOM_Fpr64 , X86::UCOM_Fr },
769 { X86::UCOM_Fpr80 , X86::UCOM_Fr },
775 assert(Opc != -1 &&
"FP Stack instruction not in OpcodeTable!");
787 { X86::ADD_FrST0 , X86::ADD_FPrST0 },
789 { X86::DIVR_FrST0, X86::DIVR_FPrST0 },
790 { X86::DIV_FrST0 , X86::DIV_FPrST0 },
792 { X86::IST_F16m , X86::IST_FP16m },
793 { X86::IST_F32m , X86::IST_FP32m },
795 { X86::MUL_FrST0 , X86::MUL_FPrST0 },
797 { X86::ST_F32m , X86::ST_FP32m },
798 { X86::ST_F64m , X86::ST_FP64m },
799 { X86::ST_Frr , X86::ST_FPrr },
801 { X86::SUBR_FrST0, X86::SUBR_FPrST0 },
802 { X86::SUB_FrST0 , X86::SUB_FPrST0 },
804 { X86::UCOM_FIr , X86::UCOM_FIPr },
806 { X86::UCOM_FPr , X86::UCOM_FPPr },
807 { X86::UCOM_Fr , X86::UCOM_FPr },
826 I->setDesc(TII->get(Opcode));
827 if (Opcode == X86::UCOM_FPPr)
830 I =
BuildMI(*MBB, ++I, dl, TII->
get(X86::ST_FPrr)).addReg(X86::ST0);
839 if (getStackEntry(0) == FPRegNo) {
847 I = freeStackSlotBefore(++I, FPRegNo);
854 unsigned STReg = getSTReg(FPRegNo);
855 unsigned OldSlot = getSlot(FPRegNo);
856 unsigned TopReg =
Stack[StackTop-1];
857 Stack[OldSlot] = TopReg;
858 RegMap[TopReg] = OldSlot;
859 RegMap[FPRegNo] = ~0;
860 Stack[--StackTop] = ~0;
869 unsigned Defs =
Mask;
871 for (
unsigned i = 0;
i < StackTop; ++
i) {
872 unsigned RegNo =
Stack[
i];
873 if (!(Defs & (1 << RegNo)))
875 Kills |= (1 << RegNo);
878 Defs &= ~(1 << RegNo);
880 assert((Kills & Defs) == 0 &&
"Register needs killing and def'ing?");
883 while (Kills && Defs) {
886 DEBUG(
dbgs() <<
"Renaming %FP" << KReg <<
" as imp %FP" << DReg <<
"\n");
887 std::swap(Stack[getSlot(KReg)], Stack[getSlot(DReg)]);
889 Kills &= ~(1 << KReg);
890 Defs &= ~(1 << DReg);
894 if (Kills && I != MBB->
begin()) {
897 unsigned KReg = getStackEntry(0);
898 if (!(Kills & (1 << KReg)))
900 DEBUG(
dbgs() <<
"Popping %FP" << KReg <<
"\n");
902 Kills &= ~(1 << KReg);
909 DEBUG(
dbgs() <<
"Killing %FP" << KReg <<
"\n");
910 freeStackSlotBefore(I, KReg);
911 Kills &= ~(1 << KReg);
917 DEBUG(
dbgs() <<
"Defining %FP" << DReg <<
" as 0\n");
920 Defs &= ~(1 << DReg);
931 void FPS::shuffleStackTop(
const unsigned char *FixStack,
937 unsigned OldReg = getStackEntry(FixCount);
939 unsigned Reg = FixStack[FixCount];
945 moveToTop(OldReg, I);
956 unsigned STReturns = 0;
959 for (
const auto &MO : I->operands()) {
963 unsigned R = MO.
getReg() - X86::FP0;
986 for (
unsigned I = 0; I <
N; ++
I)
996 unsigned FirstFPRegOp = ~0U, SecondFPRegOp = ~0U;
997 unsigned LiveMask = 0;
1009 "Ret only defs operands, and values aren't live beyond it");
1011 if (FirstFPRegOp == ~0U)
1014 assert(SecondFPRegOp == ~0U &&
"More than two fp operands!");
1027 adjustLiveRegs(LiveMask, MI);
1028 if (!LiveMask)
return;
1034 if (SecondFPRegOp == ~0U) {
1036 assert(StackTop == 1 && FirstFPRegOp == getStackEntry(0) &&
1037 "Top of stack not the right register for RET!");
1049 if (StackTop == 1) {
1050 assert(FirstFPRegOp == SecondFPRegOp && FirstFPRegOp == getStackEntry(0)&&
1051 "Stack misconfiguration for RET!");
1055 unsigned NewReg = ScratchFPReg;
1056 duplicateToTop(FirstFPRegOp, NewReg, MI);
1057 FirstFPRegOp = NewReg;
1061 assert(StackTop == 2 &&
"Must have two values live!");
1065 if (getStackEntry(0) == SecondFPRegOp) {
1066 assert(getStackEntry(1) == FirstFPRegOp &&
"Unknown regs live");
1067 moveToTop(FirstFPRegOp, MI);
1072 assert(getStackEntry(0) == FirstFPRegOp &&
"Unknown regs live");
1073 assert(getStackEntry(1) == SecondFPRegOp &&
"Unknown regs live");
1097 "Can only handle fst* & ftst instructions!");
1109 if (!KillsSrc && (MI.
getOpcode() == X86::IST_Fp64m32 ||
1122 duplicateToTop(Reg, ScratchFPReg, I);
1137 }
else if (KillsSrc) {
1155 assert(NumOps >= 2 &&
"FPRW instructions must have 2 ops!!");
1189 { X86::ADD_Fp32 , X86::ADD_FST0r },
1190 { X86::ADD_Fp64 , X86::ADD_FST0r },
1191 { X86::ADD_Fp80 , X86::ADD_FST0r },
1192 { X86::DIV_Fp32 , X86::DIV_FST0r },
1193 { X86::DIV_Fp64 , X86::DIV_FST0r },
1194 { X86::DIV_Fp80 , X86::DIV_FST0r },
1195 { X86::MUL_Fp32 , X86::MUL_FST0r },
1196 { X86::MUL_Fp64 , X86::MUL_FST0r },
1197 { X86::MUL_Fp80 , X86::MUL_FST0r },
1198 { X86::SUB_Fp32 , X86::SUB_FST0r },
1199 { X86::SUB_Fp64 , X86::SUB_FST0r },
1200 { X86::SUB_Fp80 , X86::SUB_FST0r },
1205 { X86::ADD_Fp32 , X86::ADD_FST0r },
1206 { X86::ADD_Fp64 , X86::ADD_FST0r },
1207 { X86::ADD_Fp80 , X86::ADD_FST0r },
1208 { X86::DIV_Fp32 , X86::DIVR_FST0r },
1209 { X86::DIV_Fp64 , X86::DIVR_FST0r },
1210 { X86::DIV_Fp80 , X86::DIVR_FST0r },
1211 { X86::MUL_Fp32 , X86::MUL_FST0r },
1212 { X86::MUL_Fp64 , X86::MUL_FST0r },
1213 { X86::MUL_Fp80 , X86::MUL_FST0r },
1214 { X86::SUB_Fp32 , X86::SUBR_FST0r },
1215 { X86::SUB_Fp64 , X86::SUBR_FST0r },
1216 { X86::SUB_Fp80 , X86::SUBR_FST0r },
1221 { X86::ADD_Fp32 , X86::ADD_FrST0 },
1222 { X86::ADD_Fp64 , X86::ADD_FrST0 },
1223 { X86::ADD_Fp80 , X86::ADD_FrST0 },
1224 { X86::DIV_Fp32 , X86::DIVR_FrST0 },
1225 { X86::DIV_Fp64 , X86::DIVR_FrST0 },
1226 { X86::DIV_Fp80 , X86::DIVR_FrST0 },
1227 { X86::MUL_Fp32 , X86::MUL_FrST0 },
1228 { X86::MUL_Fp64 , X86::MUL_FrST0 },
1229 { X86::MUL_Fp80 , X86::MUL_FrST0 },
1230 { X86::SUB_Fp32 , X86::SUBR_FrST0 },
1231 { X86::SUB_Fp64 , X86::SUBR_FrST0 },
1232 { X86::SUB_Fp80 , X86::SUBR_FrST0 },
1237 { X86::ADD_Fp32 , X86::ADD_FrST0 },
1238 { X86::ADD_Fp64 , X86::ADD_FrST0 },
1239 { X86::ADD_Fp80 , X86::ADD_FrST0 },
1240 { X86::DIV_Fp32 , X86::DIV_FrST0 },
1241 { X86::DIV_Fp64 , X86::DIV_FrST0 },
1242 { X86::DIV_Fp80 , X86::DIV_FrST0 },
1243 { X86::MUL_Fp32 , X86::MUL_FrST0 },
1244 { X86::MUL_Fp64 , X86::MUL_FrST0 },
1245 { X86::MUL_Fp80 , X86::MUL_FrST0 },
1246 { X86::SUB_Fp32 , X86::SUB_FrST0 },
1247 { X86::SUB_Fp64 , X86::SUB_FrST0 },
1248 { X86::SUB_Fp80 , X86::SUB_FrST0 },
1266 assert(NumOperands == 3 &&
"Illegal TwoArgFP instruction!");
1274 unsigned TOS = getStackEntry(0);
1278 if (Op0 != TOS && Op1 != TOS) {
1285 }
else if (KillsOp1) {
1294 duplicateToTop(Op0, Dest, I);
1298 }
else if (!KillsOp0 && !KillsOp1) {
1302 duplicateToTop(Op0, Dest, I);
1309 assert((TOS == Op0 || TOS == Op1) && (KillsOp0 || KillsOp1) &&
1310 "Stack conditions not set up right!");
1315 bool isForward = TOS == Op0;
1316 bool updateST0 = (TOS == Op0 && !KillsOp1) || (TOS == Op1 && !KillsOp0);
1330 assert(Opcode != -1 &&
"Unknown TwoArgFP pseudo instruction!");
1333 unsigned NotTOS = (TOS == Op0) ? Op1 : Op0;
1337 I =
BuildMI(*MBB, I, dl, TII->
get(Opcode)).addReg(getSTReg(NotTOS));
1341 if (KillsOp0 && KillsOp1 && Op0 != Op1) {
1342 assert(!updateST0 &&
"Should have updated other operand!");
1348 unsigned UpdatedSlot = getSlot(updateST0 ? TOS : NotTOS);
1349 assert(UpdatedSlot < StackTop && Dest < 7);
1350 Stack[UpdatedSlot] = Dest;
1351 RegMap[Dest] = UpdatedSlot;
1364 assert(NumOperands == 2 &&
"Illegal FUCOM* instruction!");
1380 if (KillsOp0) freeStackSlotAfter(I, Op0);
1381 if (KillsOp1 && Op0 != Op1) freeStackSlotAfter(I, Op1);
1406 if (Op0 != Op1 && KillsOp1) {
1408 freeStackSlotAfter(I, Op1);
1432 case TargetOpcode::COPY: {
1441 assert(isLive(SrcFP) &&
"Cannot copy dead register");
1445 unsigned Slot = getSlot(SrcFP);
1446 Stack[Slot] = DstFP;
1447 RegMap[DstFP] = Slot;
1451 duplicateToTop(SrcFP, DstFP, Inst);
1456 case TargetOpcode::IMPLICIT_DEF: {
1459 DEBUG(
dbgs() <<
"Emitting LD_F0 for implicit FP" << Reg <<
'\n');
1499 unsigned STUses = 0, STDefs = 0, STClobbers = 0, STDeadDefs = 0;
1500 unsigned NumOps = 0;
1514 unsigned STReg = MO.
getReg() - X86::FP0;
1527 STUses |= (1u << STReg);
1531 STDefs |= (1u << STReg);
1533 STDeadDefs |= (1u << STReg);
1536 STClobbers |= (1u << STReg);
1544 MI.
emitError(
"fixed input regs must be last on the x87 stack");
1549 MI.
emitError(
"output regs must be last on the x87 stack");
1555 if (STClobbers && !
isMask_32(STDefs | STClobbers))
1556 MI.
emitError(
"clobbers must be last on the x87 stack");
1559 unsigned STPopped = STUses & (STDefs | STClobbers);
1561 MI.
emitError(
"implicitly popped regs must be last on the x87 stack");
1564 DEBUG(
dbgs() <<
"Asm uses " << NumSTUses <<
" fixed regs, pops "
1565 << NumSTPopped <<
", and defines " << NumSTDefs <<
" regs.\n");
1571 if (FRegIdx.
count(I)) {
1573 "Operands with constraint \"f\" cannot overlap with defs");
1579 unsigned FPKills = ((1u << NumFPRegs) - 1) & ~0xff;
1590 FPKills |= 1U << FPReg;
1594 FPKills &= ~(STDefs | STClobbers);
1597 unsigned char STUsesArray[8];
1599 for (
unsigned I = 0; I < NumSTUses; ++
I)
1602 shuffleStackTop(STUsesArray, NumSTUses, Inst);
1603 DEBUG({
dbgs() <<
"Before asm: "; dumpStack();});
1615 Op.
setReg(getSTReg(FPReg));
1618 Op.
setReg(X86::ST0 + FPReg);
1622 StackTop -= NumSTPopped;
1624 for (
unsigned i = 0;
i < NumSTDefs; ++
i)
1625 pushReg(NumSTDefs -
i - 1);
1637 freeStackSlotAfter(Inst, FPReg);
1638 FPKills &= ~(1U << FPReg);
1646 Inst = MBB->
erase(Inst);
1650 if (Inst == MBB->
begin()) {
1651 DEBUG(
dbgs() <<
"Inserting dummy KILL\n");
1662 LPR.addLiveOuts(MBB);
1666 if (I->isDebugValue())
1669 std::bitset<8> Defs;
1673 for (
auto &MO : I->operands()) {
1677 unsigned Reg = MO.
getReg() - X86::FP0;
1684 if (!LPR.contains(MO.
getReg()))
1690 for (
auto *MO : Uses)
1694 LPR.stepBackward(MI);
static const TableEntry OpcodeTable[]
void push_back(const T &Elt)
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
iterator_range< livein_iterator > liveins() const
STATISTIC(NumFunctions,"Total number of functions")
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
static unsigned getConcreteOpcode(unsigned Opcode)
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
char & MachineDominatorsID
MachineDominators - This pass is a machine dominators analysis pass.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
void setIsDead(bool Val=true)
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
static const TableEntry ReverseSTiTable[]
constexpr bool isMask_32(uint32_t Value)
isMask_32 - This function returns true if the argument is a non-empty sequence of ones starting at th...
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
AnalysisUsage & addRequired()
char & MachineLoopInfoID
MachineLoopInfo - This pass is a loop analysis pass.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
struct fuzzer::@269 Flags
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
std::size_t countTrailingOnes(T Value, ZeroBehavior ZB=ZB_Width)
Count the number of ones from the least significant bit to the first zero bit.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
static int Lookup(ArrayRef< TableEntry > Table, unsigned Opcode)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Reg
All possible values of the reg field in the ModR/M byte.
static const TableEntry ForwardST0Table[]
Register calling convention used for parameters transfer optimization.
INLINEASM - Represents an inline asm block.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
void RemoveOperand(unsigned i)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
const MachineBasicBlock & front() const
static unsigned getFPReg(const MachineOperand &MO)
getFPReg - Return the X86::FPx register number for the specified operand.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
AnalysisUsage & addPreservedID(const void *ID)
reverse_iterator rbegin()
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
static const TableEntry PopTable[]
TargetInstrInfo - Interface to description of machine instruction set.
bool isImplicitDef() const
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool isReturn(QueryType Type=AnyInBundle) const
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
AddrNumOperands - Total number of operands in a memory reference.
unsigned const MachineRegisterInfo * MRI
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static const TableEntry ForwardSTiTable[]
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
const MachineOperand & getOperand(unsigned i) const
static unsigned getNumOperandRegisters(unsigned Flag)
getNumOperandRegisters - Extract the number of registers field from the inline asm operand flag...
iterator_range< df_ext_iterator< T, SetTy > > depth_first_ext(const T &G, SetTy &S)
Represent the analysis usage information of a pass.
#define LLVM_ATTRIBUTE_UNUSED
static unsigned getKind(unsigned Flags)
FunctionPass class - This class is used to implement most global optimizations.
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
void DeleteMachineInstr(MachineInstr *MI)
DeleteMachineInstr - Delete the given MachineInstr.
uint64_t NextPowerOf2(uint64_t A)
NextPowerOf2 - Returns the next power of two (in 64-bits) that is strictly greater than A...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
void emitError(StringRef Msg) const
Emit an error referring to the source location of this instruction.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void setIsKill(bool Val=true)
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
unsigned countPopulation(T Value)
Count the number of set bits in a value.
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
std::pair< iterator, bool > insert(NodeRef N)
void setPreservesCFG()
This function should be called by the pass, iff they do not:
MachineInstr * remove(MachineInstr *I)
Remove the unbundled instruction from the instruction list without deleting it.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
FunctionPass * createX86FloatingPointStackifierPass()
This function returns a pass which converts floating-point register references and pseudo instruction...
StringRef getName() const
Return the name of the corresponding LLVM basic block, or "(null)".
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
MachineFunctionProperties & set(Property P)
static bool hasRegClassConstraint(unsigned Flag, unsigned &RC)
hasRegClassConstraint - Returns true if the flag contains a register class constraint.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Representation of each machine instruction.
static const TableEntry ReverseST0Table[]
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
A set of live physical registers with functions to track liveness when walking backward/forward throu...
void setReg(unsigned Reg)
Change the register this operand corresponds to.
bool isCall(QueryType Type=AnyInBundle) const
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool killsRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr kills the specified register.
bool operator<(int64_t V1, const APSInt &V2)
virtual const TargetInstrInfo * getInstrInfo() const
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
#define ASSERT_SORTED(TABLE)
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
void initializeEdgeBundlesPass(PassRegistry &)
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
StringRef - Represent a constant reference to a string, i.e.
bool reg_nodbg_empty(unsigned RegNo) const
reg_nodbg_empty - Return true if the only instructions using or defining Reg are Debug instructions...
Properties which a MachineFunction may have at a given point in time.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly. ...