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;
66 memset(RegMap, 0,
sizeof(RegMap));
79 const char *getPassName()
const override {
return "X86 FP Stackifier"; }
105 unsigned char FixStack[8];
107 LiveBundle() : Mask(0), FixCount(0) {}
110 bool isFixed()
const {
return !Mask || FixCount; }
126 if (Reg < X86::FP0 || Reg > X86::FP6)
128 Mask |= 1 << (Reg - X86::FP0);
153 unsigned RegMap[NumFPRegs];
156 void setupBlockStack();
159 void finishBlockStack();
161 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
162 void dumpStack()
const {
163 dbgs() <<
"Stack contents:";
164 for (
unsigned i = 0; i != StackTop; ++i) {
166 assert(RegMap[
Stack[i]] == i &&
"Stack[] doesn't match RegMap[]!");
173 unsigned getSlot(
unsigned RegNo)
const {
174 assert(RegNo < NumFPRegs &&
"Regno out of range!");
175 return RegMap[RegNo];
179 bool isLive(
unsigned RegNo)
const {
180 unsigned Slot = getSlot(RegNo);
181 return Slot < StackTop &&
Stack[
Slot] == RegNo;
185 unsigned getStackEntry(
unsigned STi)
const {
188 return Stack[StackTop-1-STi];
193 unsigned getSTReg(
unsigned RegNo)
const {
194 return StackTop - 1 - getSlot(RegNo) + X86::ST0;
198 void pushReg(
unsigned Reg) {
199 assert(Reg < NumFPRegs &&
"Register number out of range!");
203 RegMap[
Reg] = StackTop++;
206 bool isAtTop(
unsigned RegNo)
const {
return getSlot(RegNo) == StackTop-1; }
209 if (isAtTop(RegNo))
return;
211 unsigned STReg = getSTReg(RegNo);
212 unsigned RegOnTop = getStackEntry(0);
215 std::swap(RegMap[RegNo], RegMap[RegOnTop]);
218 if (RegMap[RegOnTop] >= StackTop)
223 BuildMI(*MBB, I, dl,
TII->get(X86::XCH_F)).addReg(STReg);
227 void duplicateToTop(
unsigned RegNo,
unsigned AsReg,
MachineInstr *I) {
229 unsigned STReg = getSTReg(RegNo);
232 BuildMI(*MBB, I, dl,
TII->get(X86::LD_Frr)).addReg(STReg);
256 void shuffleStackTop(
const unsigned char *FixStack,
unsigned FixCount,
275 return X86::RFP80RegClass.contains(DstReg) ||
276 X86::RFP80RegClass.contains(SrcReg);
289 assert(MO.
isReg() &&
"Expected an FP register!");
290 unsigned Reg = MO.
getReg();
291 assert(Reg >= X86::FP0 && Reg <= X86::FP6 &&
"Expected FP register!");
292 return Reg - X86::FP0;
301 bool FPIsUsed =
false;
303 static_assert(X86::FP6 == X86::FP0+6,
"Register enums aren't sorted right!");
304 for (
unsigned i = 0; i <= 6; ++i)
311 if (!FPIsUsed)
return false;
313 Bundles = &getAnalysis<EdgeBundles>();
326 bool Changed =
false;
328 Changed |= processBasicBlock(MF, *BB);
333 if (Processed.
insert(BB).second)
334 Changed |= processBasicBlock(MF, *BB);
347 assert(LiveBundles.empty() &&
"Stale data in LiveBundles");
348 LiveBundles.resize(Bundles->getNumBundles());
353 const unsigned Mask = calcLiveInMask(MBB);
357 LiveBundles[Bundles->getBundle(MBB->
getNumber(),
false)].Mask |= Mask;
365 bool Changed =
false;
379 if (MI->
isCopy() && isFPCopy(MI))
394 PrevMI = std::prev(I);
408 switch (FPInstClass) {
421 for (
unsigned i = 0, e = DeadRegs.
size(); i != e; ++i) {
422 unsigned Reg = DeadRegs[i];
425 if (Reg >= X86::FP0 && Reg <= X86::FP6 && isLive(Reg-X86::FP0)) {
426 DEBUG(
dbgs() <<
"Register FP#" << Reg-X86::FP0 <<
" is dead!\n");
427 freeStackSlotAfter(I, Reg-X86::FP0);
435 dbgs() <<
"Just deleted pseudo instruction\n";
439 while (Start != BB.
begin() && std::prev(Start) != PrevI) --Start;
440 dbgs() <<
"Inserted instructions:\n\t";
441 Start->print(
dbgs());
442 while (++Start != std::next(I)) {}
458 void FPS::setupBlockStack() {
460 <<
" derived from " << MBB->
getName() <<
".\n");
463 const LiveBundle &Bundle =
464 LiveBundles[Bundles->getBundle(MBB->
getNumber(),
false)];
467 DEBUG(
dbgs() <<
"Block has no FP live-ins.\n");
472 assert(Bundle.isFixed() &&
"Reached block before any predecessors");
475 for (
unsigned i = Bundle.FixCount; i > 0; --i) {
477 DEBUG(
dbgs() <<
"Live-in st(" << (i-1) <<
"): %FP"
478 <<
unsigned(Bundle.FixStack[i-1]) <<
'\n');
479 pushReg(Bundle.FixStack[i-1]);
485 adjustLiveRegs(calcLiveInMask(MBB), MBB->
begin());
493 void FPS::finishBlockStack() {
499 <<
" derived from " << MBB->
getName() <<
".\n");
502 unsigned BundleIdx = Bundles->getBundle(MBB->
getNumber(),
true);
503 LiveBundle &Bundle = LiveBundles[BundleIdx];
508 adjustLiveRegs(Bundle.Mask, Term);
516 DEBUG(
dbgs() <<
"LB#" << BundleIdx <<
": ");
517 if (Bundle.isFixed()) {
518 DEBUG(
dbgs() <<
"Shuffling stack to match.\n");
519 shuffleStackTop(Bundle.FixStack, Bundle.FixCount, Term);
522 DEBUG(
dbgs() <<
"Fixing stack order now.\n");
523 Bundle.FixCount = StackTop;
524 for (
unsigned i = 0; i < StackTop; ++i)
525 Bundle.FixStack[i] = getStackEntry(i);
538 bool operator<(
const TableEntry &TE)
const {
return from < TE.from; }
539 friend bool operator<(
const TableEntry &TE,
unsigned V) {
543 const TableEntry &TE) {
551 for (
unsigned i = 0; i != NumEntries-1; ++i)
552 if (!(Table[i] < Table[i+1]))
return false;
557 static int Lookup(
const TableEntry *Table,
unsigned N,
unsigned Opcode) {
558 const TableEntry *I = std::lower_bound(Table, Table+N, Opcode);
559 if (I != Table+N && I->from == Opcode)
565 #define ASSERT_SORTED(TABLE)
567 #define ASSERT_SORTED(TABLE) \
568 { static bool TABLE##Checked = false; \
569 if (!TABLE##Checked) { \
570 assert(TableIsSorted(TABLE, array_lengthof(TABLE)) && \
571 "All lookup tables must be sorted for efficient access!"); \
572 TABLE##Checked = true; \
586 { X86::ABS_Fp32 , X86::ABS_F },
587 { X86::ABS_Fp64 , X86::ABS_F },
588 { X86::ABS_Fp80 , X86::ABS_F },
589 { X86::ADD_Fp32m , X86::ADD_F32m },
590 { X86::ADD_Fp64m , X86::ADD_F64m },
591 { X86::ADD_Fp64m32 , X86::ADD_F32m },
592 { X86::ADD_Fp80m32 , X86::ADD_F32m },
593 { X86::ADD_Fp80m64 , X86::ADD_F64m },
594 { X86::ADD_FpI16m32 , X86::ADD_FI16m },
595 { X86::ADD_FpI16m64 , X86::ADD_FI16m },
596 { X86::ADD_FpI16m80 , X86::ADD_FI16m },
597 { X86::ADD_FpI32m32 , X86::ADD_FI32m },
598 { X86::ADD_FpI32m64 , X86::ADD_FI32m },
599 { X86::ADD_FpI32m80 , X86::ADD_FI32m },
600 { X86::CHS_Fp32 , X86::CHS_F },
601 { X86::CHS_Fp64 , X86::CHS_F },
602 { X86::CHS_Fp80 , X86::CHS_F },
603 { X86::CMOVBE_Fp32 , X86::CMOVBE_F },
604 { X86::CMOVBE_Fp64 , X86::CMOVBE_F },
605 { X86::CMOVBE_Fp80 , X86::CMOVBE_F },
606 { X86::CMOVB_Fp32 , X86::CMOVB_F },
607 { X86::CMOVB_Fp64 , X86::CMOVB_F },
608 { X86::CMOVB_Fp80 , X86::CMOVB_F },
609 { X86::CMOVE_Fp32 , X86::CMOVE_F },
610 { X86::CMOVE_Fp64 , X86::CMOVE_F },
611 { X86::CMOVE_Fp80 , X86::CMOVE_F },
612 { X86::CMOVNBE_Fp32 , X86::CMOVNBE_F },
613 { X86::CMOVNBE_Fp64 , X86::CMOVNBE_F },
614 { X86::CMOVNBE_Fp80 , X86::CMOVNBE_F },
615 { X86::CMOVNB_Fp32 , X86::CMOVNB_F },
616 { X86::CMOVNB_Fp64 , X86::CMOVNB_F },
617 { X86::CMOVNB_Fp80 , X86::CMOVNB_F },
618 { X86::CMOVNE_Fp32 , X86::CMOVNE_F },
619 { X86::CMOVNE_Fp64 , X86::CMOVNE_F },
620 { X86::CMOVNE_Fp80 , X86::CMOVNE_F },
621 { X86::CMOVNP_Fp32 , X86::CMOVNP_F },
622 { X86::CMOVNP_Fp64 , X86::CMOVNP_F },
623 { X86::CMOVNP_Fp80 , X86::CMOVNP_F },
624 { X86::CMOVP_Fp32 , X86::CMOVP_F },
625 { X86::CMOVP_Fp64 , X86::CMOVP_F },
626 { X86::CMOVP_Fp80 , X86::CMOVP_F },
627 { X86::COS_Fp32 , X86::COS_F },
628 { X86::COS_Fp64 , X86::COS_F },
629 { X86::COS_Fp80 , X86::COS_F },
630 { X86::DIVR_Fp32m , X86::DIVR_F32m },
631 { X86::DIVR_Fp64m , X86::DIVR_F64m },
632 { X86::DIVR_Fp64m32 , X86::DIVR_F32m },
633 { X86::DIVR_Fp80m32 , X86::DIVR_F32m },
634 { X86::DIVR_Fp80m64 , X86::DIVR_F64m },
635 { X86::DIVR_FpI16m32, X86::DIVR_FI16m},
636 { X86::DIVR_FpI16m64, X86::DIVR_FI16m},
637 { X86::DIVR_FpI16m80, X86::DIVR_FI16m},
638 { X86::DIVR_FpI32m32, X86::DIVR_FI32m},
639 { X86::DIVR_FpI32m64, X86::DIVR_FI32m},
640 { X86::DIVR_FpI32m80, X86::DIVR_FI32m},
641 { X86::DIV_Fp32m , X86::DIV_F32m },
642 { X86::DIV_Fp64m , X86::DIV_F64m },
643 { X86::DIV_Fp64m32 , X86::DIV_F32m },
644 { X86::DIV_Fp80m32 , X86::DIV_F32m },
645 { X86::DIV_Fp80m64 , X86::DIV_F64m },
646 { X86::DIV_FpI16m32 , X86::DIV_FI16m },
647 { X86::DIV_FpI16m64 , X86::DIV_FI16m },
648 { X86::DIV_FpI16m80 , X86::DIV_FI16m },
649 { X86::DIV_FpI32m32 , X86::DIV_FI32m },
650 { X86::DIV_FpI32m64 , X86::DIV_FI32m },
651 { X86::DIV_FpI32m80 , X86::DIV_FI32m },
652 { X86::ILD_Fp16m32 , X86::ILD_F16m },
653 { X86::ILD_Fp16m64 , X86::ILD_F16m },
654 { X86::ILD_Fp16m80 , X86::ILD_F16m },
655 { X86::ILD_Fp32m32 , X86::ILD_F32m },
656 { X86::ILD_Fp32m64 , X86::ILD_F32m },
657 { X86::ILD_Fp32m80 , X86::ILD_F32m },
658 { X86::ILD_Fp64m32 , X86::ILD_F64m },
659 { X86::ILD_Fp64m64 , X86::ILD_F64m },
660 { X86::ILD_Fp64m80 , X86::ILD_F64m },
661 { X86::ISTT_Fp16m32 , X86::ISTT_FP16m},
662 { X86::ISTT_Fp16m64 , X86::ISTT_FP16m},
663 { X86::ISTT_Fp16m80 , X86::ISTT_FP16m},
664 { X86::ISTT_Fp32m32 , X86::ISTT_FP32m},
665 { X86::ISTT_Fp32m64 , X86::ISTT_FP32m},
666 { X86::ISTT_Fp32m80 , X86::ISTT_FP32m},
667 { X86::ISTT_Fp64m32 , X86::ISTT_FP64m},
668 { X86::ISTT_Fp64m64 , X86::ISTT_FP64m},
669 { X86::ISTT_Fp64m80 , X86::ISTT_FP64m},
670 { X86::IST_Fp16m32 , X86::IST_F16m },
671 { X86::IST_Fp16m64 , X86::IST_F16m },
672 { X86::IST_Fp16m80 , X86::IST_F16m },
673 { X86::IST_Fp32m32 , X86::IST_F32m },
674 { X86::IST_Fp32m64 , X86::IST_F32m },
675 { X86::IST_Fp32m80 , X86::IST_F32m },
676 { X86::IST_Fp64m32 , X86::IST_FP64m },
677 { X86::IST_Fp64m64 , X86::IST_FP64m },
678 { X86::IST_Fp64m80 , X86::IST_FP64m },
679 { X86::LD_Fp032 , X86::LD_F0 },
680 { X86::LD_Fp064 , X86::LD_F0 },
681 { X86::LD_Fp080 , X86::LD_F0 },
682 { X86::LD_Fp132 , X86::LD_F1 },
683 { X86::LD_Fp164 , X86::LD_F1 },
684 { X86::LD_Fp180 , X86::LD_F1 },
685 { X86::LD_Fp32m , X86::LD_F32m },
686 { X86::LD_Fp32m64 , X86::LD_F32m },
687 { X86::LD_Fp32m80 , X86::LD_F32m },
688 { X86::LD_Fp64m , X86::LD_F64m },
689 { X86::LD_Fp64m80 , X86::LD_F64m },
690 { X86::LD_Fp80m , X86::LD_F80m },
691 { X86::MUL_Fp32m , X86::MUL_F32m },
692 { X86::MUL_Fp64m , X86::MUL_F64m },
693 { X86::MUL_Fp64m32 , X86::MUL_F32m },
694 { X86::MUL_Fp80m32 , X86::MUL_F32m },
695 { X86::MUL_Fp80m64 , X86::MUL_F64m },
696 { X86::MUL_FpI16m32 , X86::MUL_FI16m },
697 { X86::MUL_FpI16m64 , X86::MUL_FI16m },
698 { X86::MUL_FpI16m80 , X86::MUL_FI16m },
699 { X86::MUL_FpI32m32 , X86::MUL_FI32m },
700 { X86::MUL_FpI32m64 , X86::MUL_FI32m },
701 { X86::MUL_FpI32m80 , X86::MUL_FI32m },
702 { X86::SIN_Fp32 , X86::SIN_F },
703 { X86::SIN_Fp64 , X86::SIN_F },
704 { X86::SIN_Fp80 , X86::SIN_F },
705 { X86::SQRT_Fp32 , X86::SQRT_F },
706 { X86::SQRT_Fp64 , X86::SQRT_F },
707 { X86::SQRT_Fp80 , X86::SQRT_F },
708 { X86::ST_Fp32m , X86::ST_F32m },
709 { X86::ST_Fp64m , X86::ST_F64m },
710 { X86::ST_Fp64m32 , X86::ST_F32m },
711 { X86::ST_Fp80m32 , X86::ST_F32m },
712 { X86::ST_Fp80m64 , X86::ST_F64m },
713 { X86::ST_FpP80m , X86::ST_FP80m },
714 { X86::SUBR_Fp32m , X86::SUBR_F32m },
715 { X86::SUBR_Fp64m , X86::SUBR_F64m },
716 { X86::SUBR_Fp64m32 , X86::SUBR_F32m },
717 { X86::SUBR_Fp80m32 , X86::SUBR_F32m },
718 { X86::SUBR_Fp80m64 , X86::SUBR_F64m },
719 { X86::SUBR_FpI16m32, X86::SUBR_FI16m},
720 { X86::SUBR_FpI16m64, X86::SUBR_FI16m},
721 { X86::SUBR_FpI16m80, X86::SUBR_FI16m},
722 { X86::SUBR_FpI32m32, X86::SUBR_FI32m},
723 { X86::SUBR_FpI32m64, X86::SUBR_FI32m},
724 { X86::SUBR_FpI32m80, X86::SUBR_FI32m},
725 { X86::SUB_Fp32m , X86::SUB_F32m },
726 { X86::SUB_Fp64m , X86::SUB_F64m },
727 { X86::SUB_Fp64m32 , X86::SUB_F32m },
728 { X86::SUB_Fp80m32 , X86::SUB_F32m },
729 { X86::SUB_Fp80m64 , X86::SUB_F64m },
730 { X86::SUB_FpI16m32 , X86::SUB_FI16m },
731 { X86::SUB_FpI16m64 , X86::SUB_FI16m },
732 { X86::SUB_FpI16m80 , X86::SUB_FI16m },
733 { X86::SUB_FpI32m32 , X86::SUB_FI32m },
734 { X86::SUB_FpI32m64 , X86::SUB_FI32m },
735 { X86::SUB_FpI32m80 , X86::SUB_FI32m },
736 { X86::TST_Fp32 , X86::TST_F },
737 { X86::TST_Fp64 , X86::TST_F },
738 { X86::TST_Fp80 , X86::TST_F },
739 { X86::UCOM_FpIr32 , X86::UCOM_FIr },
740 { X86::UCOM_FpIr64 , X86::UCOM_FIr },
741 { X86::UCOM_FpIr80 , X86::UCOM_FIr },
742 { X86::UCOM_Fpr32 , X86::UCOM_Fr },
743 { X86::UCOM_Fpr64 , X86::UCOM_Fr },
744 { X86::UCOM_Fpr80 , X86::UCOM_Fr },
750 assert(Opc != -1 &&
"FP Stack instruction not in OpcodeTable!");
762 { X86::ADD_FrST0 , X86::ADD_FPrST0 },
764 { X86::DIVR_FrST0, X86::DIVR_FPrST0 },
765 { X86::DIV_FrST0 , X86::DIV_FPrST0 },
767 { X86::IST_F16m , X86::IST_FP16m },
768 { X86::IST_F32m , X86::IST_FP32m },
770 { X86::MUL_FrST0 , X86::MUL_FPrST0 },
772 { X86::ST_F32m , X86::ST_FP32m },
773 { X86::ST_F64m , X86::ST_FP64m },
774 { X86::ST_Frr , X86::ST_FPrr },
776 { X86::SUBR_FrST0, X86::SUBR_FPrST0 },
777 { X86::SUB_FrST0 , X86::SUB_FPrST0 },
779 { X86::UCOM_FIr , X86::UCOM_FIPr },
781 { X86::UCOM_FPr , X86::UCOM_FPPr },
782 { X86::UCOM_Fr , X86::UCOM_FPr },
797 RegMap[
Stack[--StackTop]] = ~0;
802 I->setDesc(TII->get(Opcode));
803 if (Opcode == X86::UCOM_FPPr)
806 I =
BuildMI(*MBB, ++I, dl, TII->
get(X86::ST_FPrr)).addReg(X86::ST0);
815 if (getStackEntry(0) == FPRegNo) {
823 I = freeStackSlotBefore(++I, FPRegNo);
830 unsigned STReg = getSTReg(FPRegNo);
831 unsigned OldSlot = getSlot(FPRegNo);
832 unsigned TopReg = Stack[StackTop-1];
833 Stack[OldSlot] = TopReg;
834 RegMap[TopReg] = OldSlot;
835 RegMap[FPRegNo] = ~0;
836 Stack[--StackTop] = ~0;
845 unsigned Defs = Mask;
847 for (
unsigned i = 0; i < StackTop; ++i) {
848 unsigned RegNo = Stack[i];
849 if (!(Defs & (1 << RegNo)))
851 Kills |= (1 << RegNo);
854 Defs &= ~(1 << RegNo);
856 assert((Kills & Defs) == 0 &&
"Register needs killing and def'ing?");
859 while (Kills && Defs) {
862 DEBUG(
dbgs() <<
"Renaming %FP" << KReg <<
" as imp %FP" << DReg <<
"\n");
863 std::swap(Stack[getSlot(KReg)], Stack[getSlot(DReg)]);
865 Kills &= ~(1 << KReg);
866 Defs &= ~(1 << DReg);
870 if (Kills && I != MBB->
begin()) {
873 unsigned KReg = getStackEntry(0);
874 if (!(Kills & (1 << KReg)))
876 DEBUG(
dbgs() <<
"Popping %FP" << KReg <<
"\n");
878 Kills &= ~(1 << KReg);
885 DEBUG(
dbgs() <<
"Killing %FP" << KReg <<
"\n");
886 freeStackSlotBefore(I, KReg);
887 Kills &= ~(1 << KReg);
893 DEBUG(
dbgs() <<
"Defining %FP" << DReg <<
" as 0\n");
896 Defs &= ~(1 << DReg);
907 void FPS::shuffleStackTop(
const unsigned char *FixStack,
913 unsigned OldReg = getStackEntry(FixCount);
915 unsigned Reg = FixStack[FixCount];
921 moveToTop(OldReg, I);
932 unsigned STReturns = 0;
934 for (
const auto &MO : I->operands()) {
938 unsigned R = MO.
getReg() - X86::FP0;
950 assert(STReturns == 0 || (
isMask_32(STReturns) && N <= 2));
952 for (
unsigned I = 0; I <
N; ++
I)
976 "Can only handle fst* & ftst instructions!");
1002 duplicateToTop(Reg, ScratchFPReg, I);
1011 if (MI->
getOpcode() == X86::IST_FP64m ||
1019 }
else if (KillsSrc) {
1037 assert(NumOps >= 2 &&
"FPRW instructions must have 2 ops!!");
1071 { X86::ADD_Fp32 , X86::ADD_FST0r },
1072 { X86::ADD_Fp64 , X86::ADD_FST0r },
1073 { X86::ADD_Fp80 , X86::ADD_FST0r },
1074 { X86::DIV_Fp32 , X86::DIV_FST0r },
1075 { X86::DIV_Fp64 , X86::DIV_FST0r },
1076 { X86::DIV_Fp80 , X86::DIV_FST0r },
1077 { X86::MUL_Fp32 , X86::MUL_FST0r },
1078 { X86::MUL_Fp64 , X86::MUL_FST0r },
1079 { X86::MUL_Fp80 , X86::MUL_FST0r },
1080 { X86::SUB_Fp32 , X86::SUB_FST0r },
1081 { X86::SUB_Fp64 , X86::SUB_FST0r },
1082 { X86::SUB_Fp80 , X86::SUB_FST0r },
1087 { X86::ADD_Fp32 , X86::ADD_FST0r },
1088 { X86::ADD_Fp64 , X86::ADD_FST0r },
1089 { X86::ADD_Fp80 , X86::ADD_FST0r },
1090 { X86::DIV_Fp32 , X86::DIVR_FST0r },
1091 { X86::DIV_Fp64 , X86::DIVR_FST0r },
1092 { X86::DIV_Fp80 , X86::DIVR_FST0r },
1093 { X86::MUL_Fp32 , X86::MUL_FST0r },
1094 { X86::MUL_Fp64 , X86::MUL_FST0r },
1095 { X86::MUL_Fp80 , X86::MUL_FST0r },
1096 { X86::SUB_Fp32 , X86::SUBR_FST0r },
1097 { X86::SUB_Fp64 , X86::SUBR_FST0r },
1098 { X86::SUB_Fp80 , X86::SUBR_FST0r },
1103 { X86::ADD_Fp32 , X86::ADD_FrST0 },
1104 { X86::ADD_Fp64 , X86::ADD_FrST0 },
1105 { X86::ADD_Fp80 , X86::ADD_FrST0 },
1106 { X86::DIV_Fp32 , X86::DIVR_FrST0 },
1107 { X86::DIV_Fp64 , X86::DIVR_FrST0 },
1108 { X86::DIV_Fp80 , X86::DIVR_FrST0 },
1109 { X86::MUL_Fp32 , X86::MUL_FrST0 },
1110 { X86::MUL_Fp64 , X86::MUL_FrST0 },
1111 { X86::MUL_Fp80 , X86::MUL_FrST0 },
1112 { X86::SUB_Fp32 , X86::SUBR_FrST0 },
1113 { X86::SUB_Fp64 , X86::SUBR_FrST0 },
1114 { X86::SUB_Fp80 , X86::SUBR_FrST0 },
1119 { X86::ADD_Fp32 , X86::ADD_FrST0 },
1120 { X86::ADD_Fp64 , X86::ADD_FrST0 },
1121 { X86::ADD_Fp80 , X86::ADD_FrST0 },
1122 { X86::DIV_Fp32 , X86::DIV_FrST0 },
1123 { X86::DIV_Fp64 , X86::DIV_FrST0 },
1124 { X86::DIV_Fp80 , X86::DIV_FrST0 },
1125 { X86::MUL_Fp32 , X86::MUL_FrST0 },
1126 { X86::MUL_Fp64 , X86::MUL_FrST0 },
1127 { X86::MUL_Fp80 , X86::MUL_FrST0 },
1128 { X86::SUB_Fp32 , X86::SUB_FrST0 },
1129 { X86::SUB_Fp64 , X86::SUB_FrST0 },
1130 { X86::SUB_Fp80 , X86::SUB_FrST0 },
1148 assert(NumOperands == 3 &&
"Illegal TwoArgFP instruction!");
1156 unsigned TOS = getStackEntry(0);
1160 if (Op0 != TOS && Op1 != TOS) {
1167 }
else if (KillsOp1) {
1176 duplicateToTop(Op0, Dest, I);
1180 }
else if (!KillsOp0 && !KillsOp1) {
1184 duplicateToTop(Op0, Dest, I);
1191 assert((TOS == Op0 || TOS == Op1) && (KillsOp0 || KillsOp1) &&
1192 "Stack conditions not set up right!");
1196 const TableEntry *InstTable;
1197 bool isForward = TOS == Op0;
1198 bool updateST0 = (TOS == Op0 && !KillsOp1) || (TOS == Op1 && !KillsOp0);
1213 assert(Opcode != -1 &&
"Unknown TwoArgFP pseudo instruction!");
1216 unsigned NotTOS = (TOS == Op0) ? Op1 : Op0;
1220 I =
BuildMI(*MBB, I, dl, TII->
get(Opcode)).addReg(getSTReg(NotTOS));
1224 if (KillsOp0 && KillsOp1 && Op0 != Op1) {
1225 assert(!updateST0 &&
"Should have updated other operand!");
1231 unsigned UpdatedSlot = getSlot(updateST0 ? TOS : NotTOS);
1232 assert(UpdatedSlot < StackTop && Dest < 7);
1233 Stack[UpdatedSlot] = Dest;
1234 RegMap[Dest] = UpdatedSlot;
1247 assert(NumOperands == 2 &&
"Illegal FUCOM* instruction!");
1263 if (KillsOp0) freeStackSlotAfter(I, Op0);
1264 if (KillsOp1 && Op0 != Op1) freeStackSlotAfter(I, Op1);
1289 if (Op0 != Op1 && KillsOp1) {
1291 freeStackSlotAfter(I, Op1);
1319 assert(isLive(SrcFP) &&
"Cannot copy dead register");
1323 unsigned Slot = getSlot(SrcFP);
1324 Stack[Slot] = DstFP;
1325 RegMap[DstFP] = Slot;
1329 duplicateToTop(SrcFP, DstFP, Inst);
1337 DEBUG(
dbgs() <<
"Emitting LD_F0 for implicit FP" << Reg <<
'\n');
1377 unsigned STUses = 0, STDefs = 0, STClobbers = 0, STDeadDefs = 0;
1378 unsigned NumOps = 0;
1392 unsigned STReg = MO.
getReg() - X86::FP0;
1405 STUses |= (1u << STReg);
1409 STDefs |= (1u << STReg);
1411 STDeadDefs |= (1u << STReg);
1414 STClobbers |= (1u << STReg);
1422 MI->
emitError(
"fixed input regs must be last on the x87 stack");
1427 MI->
emitError(
"output regs must be last on the x87 stack");
1433 if (STClobbers && !
isMask_32(STDefs | STClobbers))
1434 MI->
emitError(
"clobbers must be last on the x87 stack");
1437 unsigned STPopped = STUses & (STDefs | STClobbers);
1439 MI->
emitError(
"implicitly popped regs must be last on the x87 stack");
1442 DEBUG(
dbgs() <<
"Asm uses " << NumSTUses <<
" fixed regs, pops "
1443 << NumSTPopped <<
", and defines " << NumSTDefs <<
" regs.\n");
1449 if (FRegIdx.
count(I)) {
1451 "Operands with constraint \"f\" cannot overlap with defs");
1457 unsigned FPKills = ((1u << NumFPRegs) - 1) & ~0xff;
1468 FPKills |= 1U << FPReg;
1472 FPKills &= ~(STDefs | STClobbers);
1475 unsigned char STUsesArray[8];
1477 for (
unsigned I = 0; I < NumSTUses; ++
I)
1480 shuffleStackTop(STUsesArray, NumSTUses, Inst);
1481 DEBUG({
dbgs() <<
"Before asm: "; dumpStack();});
1491 if (FRegIdx.
count(i))
1493 Op.
setReg(getSTReg(FPReg));
1496 Op.
setReg(X86::ST0 + FPReg);
1500 StackTop -= NumSTPopped;
1502 for (
unsigned i = 0; i < NumSTDefs; ++i)
1503 pushReg(NumSTDefs - i - 1);
1515 freeStackSlotAfter(Inst, FPReg);
1516 FPKills &= ~(1U << FPReg);
1523 case X86::WIN_FTOL_32:
1524 case X86::WIN_FTOL_64: {
1531 moveToTop(FPReg, Inst);
1533 duplicateToTop(FPReg, ScratchFPReg, Inst);
1537 .addExternalSymbol(
"_ftol2")
1556 unsigned FirstFPRegOp = ~0U, SecondFPRegOp = ~0U;
1557 unsigned LiveMask = 0;
1565 assert(Op.
isUse() &&
1569 "Ret only defs operands, and values aren't live beyond it");
1571 if (FirstFPRegOp == ~0U)
1574 assert(SecondFPRegOp == ~0U &&
"More than two fp operands!");
1586 adjustLiveRegs(LiveMask, MI);
1587 if (!LiveMask)
return;
1593 if (SecondFPRegOp == ~0U) {
1595 assert(StackTop == 1 && FirstFPRegOp == getStackEntry(0) &&
1596 "Top of stack not the right register for RET!");
1608 if (StackTop == 1) {
1609 assert(FirstFPRegOp == SecondFPRegOp && FirstFPRegOp == getStackEntry(0)&&
1610 "Stack misconfiguration for RET!");
1614 unsigned NewReg = ScratchFPReg;
1615 duplicateToTop(FirstFPRegOp, NewReg, MI);
1616 FirstFPRegOp = NewReg;
1620 assert(StackTop == 2 &&
"Must have two values live!");
1624 if (getStackEntry(0) == SecondFPRegOp) {
1625 assert(getStackEntry(1) == FirstFPRegOp &&
"Unknown regs live");
1626 moveToTop(FirstFPRegOp, MI);
1631 assert(getStackEntry(0) == FirstFPRegOp &&
"Unknown regs live");
1632 assert(getStackEntry(1) == SecondFPRegOp &&
"Unknown regs live");
1637 Inst = MBB->
erase(Inst);
1641 if (Inst == MBB->
begin()) {
1642 DEBUG(
dbgs() <<
"Inserting dummy KILL\n");
1653 LPR.addLiveOuts(&MBB);
1657 if (I->isDebugValue())
1660 std::bitset<8> Defs;
1664 for (
auto &MO : I->operands()) {
1668 unsigned Reg = MO.
getReg() - X86::FP0;
1675 if (!LPR.contains(MO.
getReg()))
1681 for (
auto *MO : Uses)
1685 LPR.stepBackward(MI);
static bool TableIsSorted(const TableEntry *Table, unsigned NumEntries)
static const TableEntry OpcodeTable[]
void push_back(const T &Elt)
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
STATISTIC(NumFunctions,"Total number of functions")
static unsigned getConcreteOpcode(unsigned Opcode)
int getNumber() const
getNumber - MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a M...
char & MachineDominatorsID
MachineDominators - This pass is a machine dominators analysis pass.
std::vector< unsigned >::const_iterator livein_iterator
iterator getFirstTerminator()
getFirstTerminator - returns an iterator to the first terminator instruction of this basic block...
void addLiveIn(unsigned Reg)
Adds the specified register as a live in.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
void setIsDead(bool Val=true)
static const TableEntry ReverseSTiTable[]
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
COPY - Target-independent register copy.
livein_iterator livein_begin() const
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.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
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.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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[]
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...
static unsigned getFPReg(const MachineOperand &MO)
getFPReg - Return the X86::FPx register number for the specified operand.
AddrNumOperands - Total number of operands in a memory reference.
AnalysisUsage & addPreservedID(const void *ID)
reverse_iterator rbegin()
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static const TableEntry PopTable[]
TargetInstrInfo - Interface to description of machine instruction set.
LLVM_CONSTEXPR size_t array_lengthof(T(&)[N])
Find the length of an array.
bool isImplicitDef() const
IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
bundle_iterator< MachineInstr, instr_iterator > iterator
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[]
livein_iterator livein_end() const
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
const MachineOperand & getOperand(unsigned i) const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
static int Lookup(const TableEntry *Table, unsigned N, unsigned Opcode)
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.
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
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.
void setIsKill(bool Val=true)
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
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...
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()
createX86FloatingPointStackifierPass - This function returns a pass which converts floating point reg...
StringRef getName() const
getName - Return the name of the corresponding LLVM basic block, or "(null)".
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...
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
KILL - This instruction is a noop that is used only to adjust the liveness of registers.
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
unsigned getReg() const
getReg - Returns the register number.
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
std::reverse_iterator< iterator > reverse_iterator
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
#define ASSERT_SORTED(TABLE)
bool isPhysRegUsed(unsigned Reg) const
isPhysRegUsed - Return true if the specified register is used in this function.
BasicBlockListType::iterator iterator
void initializeEdgeBundlesPass(PassRegistry &)
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
addReg - Add a new virtual register operand...
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly. ...