LLVM: lib/Target/X86/X86MCInstLower.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

55#include

56

57using namespace llvm;

58

60 cl::desc("Enable branch hint."),

63 "branch-hint-probability-threshold",

64 cl::desc("The probability threshold of enabling branch hint."),

66

67namespace {

68

69

70class X86MCInstLower {

76

77public:

79

83

86

87private:

89};

90

91}

92

93

94

104 if (b == OS.getAllowAutoPadding())

105 return;

106 OS.setAllowAutoPadding(b);

107 if (b)

108 OS.emitRawComment("autopadding");

109 else

110 OS.emitRawComment("noautopadding");

111 }

112};

113

114

117

118void X86AsmPrinter::StackMapShadowTracker::count(const MCInst &Inst,

121 if (InShadow) {

122 SmallString<256> Code;

125 CurrentShadowSize += Code.size();

126 if (CurrentShadowSize >= RequiredShadowSize)

127 InShadow = false;

128 }

129}

130

131void X86AsmPrinter::StackMapShadowTracker::emitShadowPadding(

132 MCStreamer &OutStreamer, const MCSubtargetInfo &STI) {

133 if (InShadow && CurrentShadowSize < RequiredShadowSize) {

134 InShadow = false;

136 &MF->getSubtarget());

137 }

138}

139

140void X86AsmPrinter::EmitAndCountInstruction(MCInst &Inst) {

142 SMShadowTracker.count(Inst, getSubtargetInfo(), CodeEmitter.get());

143}

144

145X86MCInstLower::X86MCInstLower(const MachineFunction &mf,

147 : Ctx(asmprinter.OutContext), MF(mf), TM(mf.getTarget()),

149

152}

153

154

155

156MCSymbol *X86MCInstLower::GetSymbolFromOperand(const MachineOperand &MO) const {

158 if (MO.isGlobal() && TT.isOSBinFormatELF())

160

163 "Isn't a symbol reference");

164

166 SmallString<128> Name;

167 StringRef Suffix;

168

171

172 Name += "__imp_";

173 break;

175 Name += ".refptr.";

176 break;

179 Suffix = "$non_lazy_ptr";

180 break;

181 }

182

183 if (!Suffix.empty())

184 Name += DL.getPrivateGlobalPrefix();

185

187 const GlobalValue *GV = MO.getGlobal();

191 } else if (MO.isMBB()) {

194 }

195

196 Name += Suffix;

197 if (!Sym)

199

200

201

203 default:

204 break;

206 MachineModuleInfoCOFF &MMICOFF =

209 if (!StubSym.getPointer()) {

210 assert(MO.isGlobal() && "Extern symbol not handled yet");

213 }

214 break;

215 }

219 getMachOMMI().getGVStubEntry(Sym);

221 assert(MO.isGlobal() && "Extern symbol not handled yet");

225 }

226 break;

227 }

228 }

229

230 return Sym;

231}

232

233MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO,

234 MCSymbol *Sym) const {

235

236

237 const MCExpr *Expr = nullptr;

239

241 default:

244

248 break;

249

252 break;

255

258 break;

261 break;

264 break;

267 break;

270 break;

273 break;

276 break;

279 break;

282 break;

285 break;

288 break;

291 break;

294 break;

297 break;

300 break;

303 break;

306 break;

310

313 if (MO.isJTI()) {

315

316

317

318

320 AsmPrinter.OutStreamer->emitAssignment(Label, Expr);

322 }

323 break;

324 }

325

326 if (!Expr)

328

333}

334

336 return Subtarget.is64Bit() ? X86::RET64 : X86::RET32;

337}

338

339MCOperand X86MCInstLower::LowerMachineOperand(const MachineInstr *MI,

340 const MachineOperand &MO) const {

342 default:

346

348 return MCOperand();

366

367 return MCOperand();

368 }

369}

370

371

372

374 switch (Opcode) {

375 case X86::TAILJMPr:

376 Opcode = X86::JMP32r;

377 break;

378 case X86::TAILJMPm:

379 Opcode = X86::JMP32m;

380 break;

381 case X86::TAILJMPr64:

382 Opcode = X86::JMP64r;

383 break;

384 case X86::TAILJMPm64:

385 Opcode = X86::JMP64m;

386 break;

387 case X86::TAILJMPr64_REX:

388 Opcode = X86::JMP64r_REX;

389 break;

390 case X86::TAILJMPm64_REX:

391 Opcode = X86::JMP64m_REX;

392 break;

393 case X86::TAILJMPd:

394 case X86::TAILJMPd64:

395 Opcode = X86::JMP_1;

396 break;

397 case X86::TAILJMPd_CC:

398 case X86::TAILJMPd64_CC:

399 Opcode = X86::JCC_1;

400 break;

401 }

402

403 return Opcode;

404}

405

406void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {

408

409 for (const MachineOperand &MO : MI->operands())

410 if (auto Op = LowerMachineOperand(MI, MO); Op.isValid())

412

413 bool In64BitMode = AsmPrinter.getSubtarget().is64Bit();

420 return;

421

422

424 case X86::LEA64_32r:

425 case X86::LEA64r:

426 case X86::LEA16r:

427 case X86::LEA32r:

428

430 "Unexpected # of LEA operands");

432 "LEA has segment specified!");

433 break;

434 case X86::MULX32Hrr:

435 case X86::MULX32Hrm:

436 case X86::MULX64Hrr:

437 case X86::MULX64Hrm: {

438

439 unsigned NewOpc;

442 case X86::MULX32Hrr: NewOpc = X86::MULX32rr; break;

443 case X86::MULX32Hrm: NewOpc = X86::MULX32rm; break;

444 case X86::MULX64Hrr: NewOpc = X86::MULX64rr; break;

445 case X86::MULX64Hrm: NewOpc = X86::MULX64rm; break;

446 }

448

451 break;

452 }

453

454

455

456

457 case X86::CALL64r:

458 case X86::CALL64pcrel32:

460 break;

461 case X86::EH_RETURN:

462 case X86::EH_RETURN64: {

463 OutMI = MCInst();

465 break;

466 }

467 case X86::CLEANUPRET: {

468

469 OutMI = MCInst();

471 break;

472 }

473 case X86::CATCHRET: {

474

475 const X86Subtarget &Subtarget = AsmPrinter.getSubtarget();

476 unsigned ReturnReg = In64BitMode ? X86::RAX : X86::EAX;

477 OutMI = MCInst();

480 break;

481 }

482

483

484 case X86::TAILJMPr:

485 case X86::TAILJMPr64:

486 case X86::TAILJMPr64_REX:

487 case X86::TAILJMPd:

488 case X86::TAILJMPd64:

491 break;

492 case X86::TAILJMPd_CC:

493 case X86::TAILJMPd64_CC:

496 break;

497 case X86::TAILJMPm:

498 case X86::TAILJMPm64:

499 case X86::TAILJMPm64_REX:

501 "Unexpected number of operands!");

503 break;

504 case X86::MASKMOVDQU:

505 case X86::VMASKMOVDQU:

506 if (In64BitMode)

508 break;

509 case X86::BSF16rm:

510 case X86::BSF16rr:

511 case X86::BSF32rm:

512 case X86::BSF32rr:

513 case X86::BSF64rm:

514 case X86::BSF64rr: {

515

516

517

518

519 const MachineOperand *FlagDef =

520 MI->findRegisterDefOperand(X86::EFLAGS, nullptr);

523 break;

524 }

525 default:

526 break;

527 }

528}

529

530void X86AsmPrinter::LowerTlsAddr(X86MCInstLower &MCInstLowering,

531 const MachineInstr &MI) {

532 NoAutoPaddingScope NoPadScope(*OutStreamer);

533 bool Is64Bits = getSubtarget().is64Bit();

534 bool Is64BitsLP64 = getSubtarget().isTarget64BitLP64();

535 MCContext &Ctx = OutStreamer->getContext();

536

538 switch (MI.getOpcode()) {

539 case X86::TLS_addr32:

540 case X86::TLS_addr64:

541 case X86::TLS_addrX32:

543 break;

544 case X86::TLS_base_addr32:

546 break;

547 case X86::TLS_base_addr64:

548 case X86::TLS_base_addrX32:

550 break;

551 case X86::TLS_desc32:

552 case X86::TLS_desc64:

554 break;

555 default:

557 }

558

560 MCInstLowering.GetSymbolFromOperand(MI.getOperand(3)), Specifier, Ctx);

561

562

563

564

565

566

567 bool UseGot = MMI->getModule()->getRtLibUseGOT() &&

569

572 MCInstLowering.GetSymbolFromOperand(MI.getOperand(3)), X86::S_TLSCALL,

573 Ctx);

574 EmitAndCountInstruction(

575 MCInstBuilder(Is64BitsLP64 ? X86::LEA64r : X86::LEA32r)

576 .addReg(Is64BitsLP64 ? X86::RAX : X86::EAX)

577 .addReg(Is64Bits ? X86::RIP : X86::EBX)

578 .addImm(1)

579 .addReg(0)

580 .addExpr(Sym)

581 .addReg(0));

582 EmitAndCountInstruction(

583 MCInstBuilder(Is64Bits ? X86::CALL64m : X86::CALL32m)

584 .addReg(Is64BitsLP64 ? X86::RAX : X86::EAX)

585 .addImm(1)

586 .addReg(0)

587 .addExpr(Expr)

588 .addReg(0));

589 } else if (Is64Bits) {

591 if (NeedsPadding && Is64BitsLP64)

592 EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX));

593 EmitAndCountInstruction(MCInstBuilder(X86::LEA64r)

594 .addReg(X86::RDI)

595 .addReg(X86::RIP)

596 .addImm(1)

597 .addReg(0)

598 .addExpr(Sym)

599 .addReg(0));

601 if (NeedsPadding) {

602 if (!UseGot)

603 EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX));

604 EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX));

605 EmitAndCountInstruction(MCInstBuilder(X86::REX64_PREFIX));

606 }

607 if (UseGot) {

608 const MCExpr *Expr =

610 EmitAndCountInstruction(MCInstBuilder(X86::CALL64m)

611 .addReg(X86::RIP)

612 .addImm(1)

613 .addReg(0)

614 .addExpr(Expr)

615 .addReg(0));

616 } else {

617 EmitAndCountInstruction(

618 MCInstBuilder(X86::CALL64pcrel32)

620 }

621 } else {

623 EmitAndCountInstruction(MCInstBuilder(X86::LEA32r)

624 .addReg(X86::EAX)

625 .addReg(0)

626 .addImm(1)

627 .addReg(X86::EBX)

628 .addExpr(Sym)

629 .addReg(0));

630 } else {

631 EmitAndCountInstruction(MCInstBuilder(X86::LEA32r)

632 .addReg(X86::EAX)

633 .addReg(X86::EBX)

634 .addImm(1)

635 .addReg(0)

636 .addExpr(Sym)

637 .addReg(0));

638 }

639

641 if (UseGot) {

643 EmitAndCountInstruction(MCInstBuilder(X86::CALL32m)

644 .addReg(X86::EBX)

645 .addImm(1)

646 .addReg(0)

647 .addExpr(Expr)

648 .addReg(0));

649 } else {

650 EmitAndCountInstruction(

651 MCInstBuilder(X86::CALLpcrel32)

653 }

654 }

655}

656

657

658

661

662

663

664 unsigned MaxNopLength = 1;

665 if (Subtarget->is64Bit()) {

666

667

668 if (Subtarget->hasFeature(X86::TuningFast7ByteNOP))

669 MaxNopLength = 7;

670 else if (Subtarget->hasFeature(X86::TuningFast15ByteNOP))

671 MaxNopLength = 15;

672 else if (Subtarget->hasFeature(X86::TuningFast11ByteNOP))

673 MaxNopLength = 11;

674 else

675 MaxNopLength = 10;

676 } if (Subtarget->is32Bit())

677 MaxNopLength = 2;

678

679

680 NumBytes = std::min(NumBytes, MaxNopLength);

681

682 unsigned NopSize;

683 unsigned Opc, BaseReg, ScaleVal, IndexReg, Displacement, SegmentReg;

684 IndexReg = Displacement = SegmentReg = 0;

685 BaseReg = X86::RAX;

686 ScaleVal = 1;

687 switch (NumBytes) {

688 case 0:

690 break;

691 case 1:

692 NopSize = 1;

693 Opc = X86::NOOP;

694 break;

695 case 2:

696 NopSize = 2;

697 Opc = X86::XCHG16ar;

698 break;

699 case 3:

700 NopSize = 3;

701 Opc = X86::NOOPL;

702 break;

703 case 4:

704 NopSize = 4;

705 Opc = X86::NOOPL;

706 Displacement = 8;

707 break;

708 case 5:

709 NopSize = 5;

710 Opc = X86::NOOPL;

711 Displacement = 8;

712 IndexReg = X86::RAX;

713 break;

714 case 6:

715 NopSize = 6;

716 Opc = X86::NOOPW;

717 Displacement = 8;

718 IndexReg = X86::RAX;

719 break;

720 case 7:

721 NopSize = 7;

722 Opc = X86::NOOPL;

723 Displacement = 512;

724 break;

725 case 8:

726 NopSize = 8;

727 Opc = X86::NOOPL;

728 Displacement = 512;

729 IndexReg = X86::RAX;

730 break;

731 case 9:

732 NopSize = 9;

733 Opc = X86::NOOPW;

734 Displacement = 512;

735 IndexReg = X86::RAX;

736 break;

737 default:

738 NopSize = 10;

739 Opc = X86::NOOPW;

740 Displacement = 512;

741 IndexReg = X86::RAX;

742 SegmentReg = X86::CS;

743 break;

744 }

745

746 unsigned NumPrefixes = std::min(NumBytes - NopSize, 5U);

747 NopSize += NumPrefixes;

748 for (unsigned i = 0; i != NumPrefixes; ++i)

750

751 switch (Opc) {

753 case X86::NOOP:

755 break;

756 case X86::XCHG16ar:

758 *Subtarget);

759 break;

760 case X86::NOOPL:

761 case X86::NOOPW:

763 .addReg(BaseReg)

764 .addImm(ScaleVal)

765 .addReg(IndexReg)

766 .addImm(Displacement)

767 .addReg(SegmentReg),

768 *Subtarget);

769 break;

770 }

771 assert(NopSize <= NumBytes && "We overemitted?");

772 return NopSize;

773}

774

775

778 unsigned NopsToEmit = NumBytes;

779 (void)NopsToEmit;

780 while (NumBytes) {

781 NumBytes -= emitNop(OS, NumBytes, Subtarget);

782 assert(NopsToEmit >= NumBytes && "Emitted more than I asked for!");

783 }

784}

785

786void X86AsmPrinter::LowerSTATEPOINT(const MachineInstr &MI,

787 X86MCInstLower &MCIL) {

788 assert(Subtarget->is64Bit() && "Statepoint currently only supports X86-64");

789

790 NoAutoPaddingScope NoPadScope(*OutStreamer);

791

792 StatepointOpers SOpers(&MI);

793 if (unsigned PatchBytes = SOpers.getNumPatchBytes()) {

794 emitX86Nops(*OutStreamer, PatchBytes, Subtarget);

795 } else {

796

797 const MachineOperand &CallTarget = SOpers.getCallTarget();

798 MCOperand CallTargetMCOp;

799 unsigned CallOpcode;

800 switch (CallTarget.getType()) {

803 CallTargetMCOp = MCIL.LowerSymbolOperand(

804 CallTarget, MCIL.GetSymbolFromOperand(CallTarget));

805 CallOpcode = X86::CALL64pcrel32;

806

807

808

809

810 break;

813 CallOpcode = X86::CALL64pcrel32;

814

815

816

817

818 break;

820

823 "yet implemented.");

825 CallOpcode = X86::CALL64r;

826 break;

827 default:

828 llvm_unreachable("Unsupported operand type in statepoint call target");

829 break;

830 }

831

832

833 MCInst CallInst;

836 OutStreamer->emitInstruction(CallInst, getSubtargetInfo());

837 maybeEmitNopAfterCallForWindowsEH(&MI);

838 }

839

840

841

842 auto &Ctx = OutStreamer->getContext();

845 SM.recordStatepoint(*MILabel, MI);

846}

847

848void X86AsmPrinter::LowerFAULTING_OP(const MachineInstr &FaultingMI,

849 X86MCInstLower &MCIL) {

850

851

852

853 NoAutoPaddingScope NoPadScope(*OutStreamer);

854

860 unsigned OperandsBeginIdx = 4;

861

862 auto &Ctx = OutStreamer->getContext();

864 OutStreamer->emitLabel(FaultingLabel);

865

867 FM.recordFaultingOp(FK, FaultingLabel, HandlerLabel);

868

869 MCInst MI;

870 MI.setOpcode(Opcode);

871

872 if (DefRegister != X86::NoRegister)

874

875 for (const MachineOperand &MO :

877 if (auto Op = MCIL.LowerMachineOperand(&FaultingMI, MO); Op.isValid())

878 MI.addOperand(Op);

879

882}

883

884void X86AsmPrinter::LowerFENTRY_CALL(const MachineInstr &MI,

885 X86MCInstLower &MCIL) {

886 bool Is64Bits = Subtarget->is64Bit();

887 MCContext &Ctx = OutStreamer->getContext();

890

891 EmitAndCountInstruction(

892 MCInstBuilder(Is64Bits ? X86::CALL64pcrel32 : X86::CALLpcrel32)

893 .addExpr(Op));

894}

895

896void X86AsmPrinter::LowerKCFI_CHECK(const MachineInstr &MI) {

897 assert(std::next(MI.getIterator())->isCall() &&

898 "KCFI_CHECK not followed by a call instruction");

899

900

901

902

903

904 const MachineFunction &MF = *MI.getMF();

905 int64_t PrefixNops = 0;

910

911

912

913

914

915

916 const Register AddrReg = MI.getOperand(0).getReg();

917 const uint32_t Type = MI.getOperand(1).getImm();

918

919

920 unsigned TempReg = AddrReg == X86::R10 ? X86::R11D : X86::R10D;

921 EmitAndCountInstruction(

922 MCInstBuilder(X86::MOV32ri).addReg(TempReg).addImm(-MaskKCFIType(Type)));

923 EmitAndCountInstruction(MCInstBuilder(X86::ADD32rm)

924 .addReg(X86::NoRegister)

925 .addReg(TempReg)

926 .addReg(AddrReg)

927 .addImm(1)

928 .addReg(X86::NoRegister)

929 .addImm(-(PrefixNops + 4))

930 .addReg(X86::NoRegister));

931

932 MCSymbol *Pass = OutContext.createTempSymbol();

933 EmitAndCountInstruction(

934 MCInstBuilder(X86::JCC_1)

937

938 MCSymbol *Trap = OutContext.createTempSymbol();

940 EmitAndCountInstruction(MCInstBuilder(X86::TRAP));

941 emitKCFITrapEntry(MF, Trap);

943}

944

945void X86AsmPrinter::LowerASAN_CHECK_MEMACCESS(const MachineInstr &MI) {

946

947 if (!TM.getTargetTriple().isOSBinFormatELF()) {

948 report_fatal_error("llvm.asan.check.memaccess only supported on ELF");

949 return;

950 }

951

952 const auto &Reg = MI.getOperand(0).getReg();

953 ASanAccessInfo AccessInfo(MI.getOperand(1).getImm());

954

955 uint64_t ShadowBase;

956 int MappingScale;

957 bool OrShadowOffset;

959 &ShadowBase, &MappingScale, &OrShadowOffset);

960

961 StringRef Name = AccessInfo.IsWrite ? "store" : "load";

962 StringRef Op = OrShadowOffset ? "or" : "add";

963 std::string SymName = ("__asan_check_" + Name + "_" + Op + "_" +

964 Twine(1ULL << AccessInfo.AccessSizeIndex) + "_" +

965 TM.getMCRegisterInfo()->getName(Reg.asMCReg()))

966 .str();

967 if (OrShadowOffset)

969 "OrShadowOffset is not supported with optimized callbacks");

970

971 EmitAndCountInstruction(

972 MCInstBuilder(X86::CALL64pcrel32)

974 OutContext.getOrCreateSymbol(SymName), OutContext)));

975}

976

977void X86AsmPrinter::LowerPATCHABLE_OP(const MachineInstr &MI,

978 X86MCInstLower &MCIL) {

979

980

981 NoAutoPaddingScope NoPadScope(*OutStreamer);

982

983 auto NextMI = std::find_if(std::next(MI.getIterator()),

984 MI.getParent()->end().getInstrIterator(),

985 [](auto &II) { return !II.isMetaInstruction(); });

986

987 SmallString<256> Code;

988 unsigned MinSize = MI.getOperand(0).getImm();

989

990 if (NextMI != MI.getParent()->end() && !NextMI->isInlineAsm()) {

991

992

993

994 MCInst MCI;

995 MCIL.Lower(&*NextMI, MCI);

996

998 CodeEmitter->encodeInstruction(MCI, Code, Fixups, getSubtargetInfo());

999 }

1000

1001 if (Code.size() < MinSize) {

1002 if (MinSize == 2 && Subtarget->is32Bit() &&

1004 (Subtarget->getCPU().empty() || Subtarget->getCPU() == "pentium3")) {

1005

1006

1007

1008

1010 MCInstBuilder(X86::MOV32rr_REV).addReg(X86::EDI).addReg(X86::EDI),

1011 *Subtarget);

1012 } else {

1013 unsigned NopSize = emitNop(*OutStreamer, MinSize, Subtarget);

1014 assert(NopSize == MinSize && "Could not implement MinSize!");

1015 (void)NopSize;

1016 }

1017 }

1018}

1019

1020

1021

1022void X86AsmPrinter::LowerSTACKMAP(const MachineInstr &MI) {

1023 SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());

1024

1025 auto &Ctx = OutStreamer->getContext();

1027 OutStreamer->emitLabel(MILabel);

1028

1029 SM.recordStackMap(*MILabel, MI);

1030 unsigned NumShadowBytes = MI.getOperand(1).getImm();

1031 SMShadowTracker.reset(NumShadowBytes);

1032}

1033

1034

1035

1036void X86AsmPrinter::LowerPATCHPOINT(const MachineInstr &MI,

1037 X86MCInstLower &MCIL) {

1038 assert(Subtarget->is64Bit() && "Patchpoint currently only supports X86-64");

1039

1040 SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());

1041

1042 NoAutoPaddingScope NoPadScope(*OutStreamer);

1043

1044 auto &Ctx = OutStreamer->getContext();

1046 OutStreamer->emitLabel(MILabel);

1047 SM.recordPatchPoint(*MILabel, MI);

1048

1049 PatchPointOpers opers(&MI);

1050 unsigned ScratchIdx = opers.getNextScratchIdx();

1051 unsigned EncodedBytes = 0;

1052 const MachineOperand &CalleeMO = opers.getCallTarget();

1053

1054

1055

1056 if (!(CalleeMO.isImm() && !CalleeMO.getImm())) {

1057 MCOperand CalleeMCOp;

1058 switch (CalleeMO.getType()) {

1059 default:

1060

1063 if (CalleeMO.getImm())

1065 break;

1068 CalleeMCOp = MCIL.LowerSymbolOperand(CalleeMO,

1069 MCIL.GetSymbolFromOperand(CalleeMO));

1070 break;

1071 }

1072

1073

1074

1075 Register ScratchReg = MI.getOperand(ScratchIdx).getReg();

1077 EncodedBytes = 13;

1078 else

1079 EncodedBytes = 12;

1080

1081 EmitAndCountInstruction(

1082 MCInstBuilder(X86::MOV64ri).addReg(ScratchReg).addOperand(CalleeMCOp));

1083

1086 "Lowering patchpoint with thunks not yet implemented.");

1087 EmitAndCountInstruction(MCInstBuilder(X86::CALL64r).addReg(ScratchReg));

1088 }

1089

1090

1091 unsigned NumBytes = opers.getNumPatchBytes();

1092 assert(NumBytes >= EncodedBytes &&

1093 "Patchpoint can't request size less than the length of a call.");

1094

1095 emitX86Nops(*OutStreamer, NumBytes - EncodedBytes, Subtarget);

1096}

1097

1098void X86AsmPrinter::LowerPATCHABLE_EVENT_CALL(const MachineInstr &MI,

1099 X86MCInstLower &MCIL) {

1100 assert(Subtarget->is64Bit() && "XRay custom events only supports X86-64");

1101

1102 NoAutoPaddingScope NoPadScope(*OutStreamer);

1103

1104

1105

1106

1107

1108

1109

1110

1111

1112

1113

1114

1115

1116

1117

1118

1119

1120

1121

1122

1123

1124 auto CurSled = OutContext.createTempSymbol("xray_event_sled_", true);

1125 OutStreamer->AddComment("# XRay Custom Event Log");

1127 OutStreamer->emitLabel(CurSled);

1128

1129

1130

1131

1133

1134

1135

1136 const Register DestRegs[] = {X86::RDI, X86::RSI};

1137 bool UsedMask[] = {false, false};

1138

1139 Register SrcRegs[] = {0, 0};

1140

1141

1142

1143

1144

1145

1146 for (unsigned I = 0; I < MI.getNumOperands(); ++I)

1147 if (auto Op = MCIL.LowerMachineOperand(&MI, MI.getOperand(I));

1148 Op.isValid()) {

1149 assert(Op.isReg() && "Only support arguments in registers");

1152 if (SrcRegs[I] != DestRegs[I]) {

1153 UsedMask[I] = true;

1154 EmitAndCountInstruction(

1155 MCInstBuilder(X86::PUSH64r).addReg(DestRegs[I]));

1156 } else {

1157 emitX86Nops(*OutStreamer, 4, Subtarget);

1158 }

1159 }

1160

1161

1162

1163

1164

1165 for (unsigned I = 0; I < MI.getNumOperands(); ++I)

1166 if (SrcRegs[I] != DestRegs[I])

1167 EmitAndCountInstruction(

1168 MCInstBuilder(X86::MOV64rr).addReg(DestRegs[I]).addReg(SrcRegs[I]));

1169

1170

1171

1172 auto TSym = OutContext.getOrCreateSymbol("__xray_CustomEvent");

1174 if (isPositionIndependent())

1176

1177

1178 EmitAndCountInstruction(MCInstBuilder(X86::CALL64pcrel32)

1179 .addOperand(MCIL.LowerSymbolOperand(TOp, TSym)));

1180

1181

1182 for (unsigned I = sizeof UsedMask; I-- > 0;)

1183 if (UsedMask[I])

1184 EmitAndCountInstruction(MCInstBuilder(X86::POP64r).addReg(DestRegs[I]));

1185 else

1186 emitX86Nops(*OutStreamer, 1, Subtarget);

1187

1188 OutStreamer->AddComment("xray custom event end.");

1189

1190

1191

1192

1193 recordSled(CurSled, MI, SledKind::CUSTOM_EVENT, 2);

1194}

1195

1196void X86AsmPrinter::LowerPATCHABLE_TYPED_EVENT_CALL(const MachineInstr &MI,

1197 X86MCInstLower &MCIL) {

1198 assert(Subtarget->is64Bit() && "XRay typed events only supports X86-64");

1199

1200 NoAutoPaddingScope NoPadScope(*OutStreamer);

1201

1202

1203

1204

1205

1206

1207

1208

1209

1210

1211

1212

1213

1214

1215

1216

1217

1218

1219

1220

1221

1222 auto CurSled = OutContext.createTempSymbol("xray_typed_event_sled_", true);

1223 OutStreamer->AddComment("# XRay Typed Event Log");

1225 OutStreamer->emitLabel(CurSled);

1226

1227

1228

1229

1231

1232

1233

1234

1235 const Register DestRegs[] = {X86::RDI, X86::RSI, X86::RDX};

1236 bool UsedMask[] = {false, false, false};

1237

1238

1239 Register SrcRegs[] = {0, 0, 0};

1240

1241

1242

1243

1244

1245 for (unsigned I = 0; I < MI.getNumOperands(); ++I)

1246 if (auto Op = MCIL.LowerMachineOperand(&MI, MI.getOperand(I));

1247 Op.isValid()) {

1248

1249 assert(Op.isReg() && "Only supports arguments in registers");

1252 if (SrcRegs[I] != DestRegs[I]) {

1253 UsedMask[I] = true;

1254 EmitAndCountInstruction(

1255 MCInstBuilder(X86::PUSH64r).addReg(DestRegs[I]));

1256 } else {

1257 emitX86Nops(*OutStreamer, 4, Subtarget);

1258 }

1259 }

1260

1261

1262

1263

1264

1265

1266

1267

1268

1269

1270 for (unsigned I = 0; I < MI.getNumOperands(); ++I)

1271 if (UsedMask[I])

1272 EmitAndCountInstruction(

1273 MCInstBuilder(X86::MOV64rr).addReg(DestRegs[I]).addReg(SrcRegs[I]));

1274

1275

1276

1277 auto TSym = OutContext.getOrCreateSymbol("__xray_TypedEvent");

1279 if (isPositionIndependent())

1281

1282

1283 EmitAndCountInstruction(MCInstBuilder(X86::CALL64pcrel32)

1284 .addOperand(MCIL.LowerSymbolOperand(TOp, TSym)));

1285

1286

1287 for (unsigned I = sizeof UsedMask; I-- > 0;)

1288 if (UsedMask[I])

1289 EmitAndCountInstruction(MCInstBuilder(X86::POP64r).addReg(DestRegs[I]));

1290 else

1291 emitX86Nops(*OutStreamer, 1, Subtarget);

1292

1293 OutStreamer->AddComment("xray typed event end.");

1294

1295

1296 recordSled(CurSled, MI, SledKind::TYPED_EVENT, 2);

1297}

1298

1299void X86AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI,

1300 X86MCInstLower &MCIL) {

1301

1302 NoAutoPaddingScope NoPadScope(*OutStreamer);

1303

1305 if (F.hasFnAttribute("patchable-function-entry")) {

1306 unsigned Num;

1307 if (F.getFnAttribute("patchable-function-entry")

1308 .getValueAsString()

1309 .getAsInteger(10, Num))

1310 return;

1311 emitX86Nops(*OutStreamer, Num, Subtarget);

1312 return;

1313 }

1314

1315

1316

1317

1318

1319

1320

1321

1322

1323

1324

1325

1326

1327 auto CurSled = OutContext.createTempSymbol("xray_sled_", true);

1329 OutStreamer->emitLabel(CurSled);

1330

1331

1332

1333

1334 OutStreamer->emitBytes("\xeb\x09");

1335 emitX86Nops(*OutStreamer, 9, Subtarget);

1336 recordSled(CurSled, MI, SledKind::FUNCTION_ENTER, 2);

1337}

1338

1339void X86AsmPrinter::LowerPATCHABLE_RET(const MachineInstr &MI,

1340 X86MCInstLower &MCIL) {

1341 NoAutoPaddingScope NoPadScope(*OutStreamer);

1342

1343

1344

1345

1346

1347

1348

1349

1350

1351

1352

1353

1354

1355

1356

1357 auto CurSled = OutContext.createTempSymbol("xray_sled_", true);

1359 OutStreamer->emitLabel(CurSled);

1360 unsigned OpCode = MI.getOperand(0).getImm();

1361 MCInst Ret;

1364 if (auto Op = MCIL.LowerMachineOperand(&MI, MO); Op.isValid())

1367 emitX86Nops(*OutStreamer, 10, Subtarget);

1368 recordSled(CurSled, MI, SledKind::FUNCTION_EXIT, 2);

1369}

1370

1371void X86AsmPrinter::LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI,

1372 X86MCInstLower &MCIL) {

1373 MCInst TC;

1375

1376 auto TCOperands = drop_begin(MI.operands());

1377 bool IsConditional = TC.getOpcode() == X86::JCC_1;

1379 if (IsConditional) {

1380

1381

1382

1383

1384

1385

1386

1387

1388

1389

1390 FallthroughLabel = OutContext.createTempSymbol();

1391 EmitToStreamer(

1392 *OutStreamer,

1393 MCInstBuilder(X86::JCC_1)

1396 static_cast<X86::CondCode>(MI.getOperand(2).getImm()))));

1398

1399 TCOperands = drop_end(TCOperands);

1400 }

1401

1402 NoAutoPaddingScope NoPadScope(*OutStreamer);

1403

1404

1405

1406

1407

1408

1409

1410 auto CurSled = OutContext.createTempSymbol("xray_sled_", true);

1412 OutStreamer->emitLabel(CurSled);

1413 auto Target = OutContext.createTempSymbol();

1414

1415

1416

1417

1418 OutStreamer->emitBytes("\xeb\x09");

1419 emitX86Nops(*OutStreamer, 9, Subtarget);

1421 recordSled(CurSled, MI, SledKind::TAIL_CALL, 2);

1422

1423

1424

1425 OutStreamer->AddComment("TAILCALL");

1426 for (auto &MO : TCOperands)

1427 if (auto Op = MCIL.LowerMachineOperand(&MI, MO); Op.isValid())

1430

1431 if (IsConditional)

1432 OutStreamer->emitLabel(FallthroughLabel);

1433}

1434

1437

1438 ++SrcIdx;

1440

1441 ++SrcIdx;

1442 }

1443 }

1444 return SrcIdx;

1445}

1446

1448 unsigned SrcOpIdx) {

1451

1452

1453

1454

1456 const MachineOperand &WriteMaskOp = MI->getOperand(SrcOpIdx - 1);

1458 CS << " {%" << Mask << "}";

1460 CS << " {z}";

1461 }

1462 }

1463}

1464

1467

1469 if (Src1Name == Src2Name)

1470 for (int i = 0, e = ShuffleMask.size(); i != e; ++i)

1471 if (ShuffleMask[i] >= e)

1472 ShuffleMask[i] -= e;

1473

1474 for (int i = 0, e = ShuffleMask.size(); i != e; ++i) {

1475 if (i != 0)

1476 CS << ",";

1478 CS << "zero";

1479 continue;

1480 }

1481

1482

1483

1484 bool isSrc1 = ShuffleMask[i] < (int)e;

1485 CS << (isSrc1 ? Src1Name : Src2Name) << '[';

1486

1487 bool IsFirst = true;

1489 (ShuffleMask[i] < (int)e) == isSrc1) {

1490 if (!IsFirst)

1491 CS << ',';

1492 else

1493 IsFirst = false;

1495 CS << "u";

1496 else

1497 CS << ShuffleMask[i] % (int)e;

1498 ++i;

1499 }

1500 CS << ']';

1501 --i;

1502 }

1503}

1504

1507 std::string Comment;

1508

1513 : "mem";

1516 : "mem";

1517

1520 CS << " = ";

1522

1523 return Comment;

1524}

1525

1527 bool PrintZero = false) {

1529 CS << (PrintZero ? 0ULL : Val.getZExtValue());

1530 } else {

1531

1532 CS << "(";

1533 for (int i = 0, N = Val.getNumWords(); i < N; ++i) {

1534 if (i > 0)

1535 CS << ",";

1536 CS << (PrintZero ? 0ULL : Val.getRawData()[i]);

1537 }

1538 CS << ")";

1539 }

1540}

1541

1543 bool PrintZero = false) {

1545

1546 if (PrintZero)

1548 else

1550 CS << Str;

1551}

1552

1554 raw_ostream &CS, bool PrintZero = false) {

1556 CS << "u";

1559 for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) {

1560 if (I != 0)

1561 CS << ',';

1563 }

1564 } else

1568 for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) {

1569 if (I != 0)

1570 CS << ',';

1571 printConstant(CF->getValueAPF(), CS, PrintZero);

1572 }

1573 } else

1574 printConstant(CF->getValueAPF(), CS, PrintZero);

1576 Type *EltTy = CDS->getElementType();

1580 unsigned E = std::min(BitWidth / EltBits, (unsigned)CDS->getNumElements());

1581 if ((BitWidth % EltBits) == 0) {

1582 for (unsigned I = 0; I != E; ++I) {

1583 if (I != 0)

1584 CS << ",";

1585 if (IsInteger)

1586 printConstant(CDS->getElementAsAPInt(I), CS, PrintZero);

1587 else if (IsFP)

1588 printConstant(CDS->getElementAsAPFloat(I), CS, PrintZero);

1589 else

1590 CS << "?";

1591 }

1592 } else {

1593 CS << "?";

1594 }

1596 unsigned EltBits = CV->getType()->getScalarSizeInBits();

1597 unsigned E = std::min(BitWidth / EltBits, CV->getNumOperands());

1598 if ((BitWidth % EltBits) == 0) {

1599 for (unsigned I = 0; I != E; ++I) {

1600 if (I != 0)

1601 CS << ",";

1602 printConstant(CV->getOperand(I), EltBits, CS, PrintZero);

1603 }

1604 } else {

1605 CS << "?";

1606 }

1607 } else {

1608 CS << "?";

1609 }

1610}

1611

1613 int SclWidth, int VecWidth,

1614 const char *ShuffleComment) {

1616

1617 std::string Comment;

1620 CS << " = ";

1621

1623 CS << "[";

1625 for (int I = 1, E = VecWidth / SclWidth; I < E; ++I) {

1626 CS << ",";

1628 }

1629 CS << "]";

1631 return;

1632 }

1633

1634

1635 CS << ShuffleComment;

1637}

1638

1640 int Repeats, int BitWidth) {

1643 std::string Comment;

1646 CS << " = [";

1647 for (int l = 0; l != Repeats; ++l) {

1648 if (l != 0)

1649 CS << ",";

1651 }

1652 CS << "]";

1654 }

1655}

1656

1658 int SrcEltBits, int DstEltBits, bool IsSext) {

1661 if (C && C->getType()->getScalarSizeInBits() == unsigned(SrcEltBits)) {

1663 int NumElts = CDS->getNumElements();

1664 std::string Comment;

1667 CS << " = [";

1668 for (int i = 0; i != NumElts; ++i) {

1669 if (i != 0)

1670 CS << ",";

1671 if (CDS->getElementType()->isIntegerTy()) {

1672 APInt Elt = CDS->getElementAsAPInt(i);

1673 Elt = IsSext ? Elt.sext(DstEltBits) : Elt.zext(DstEltBits);

1675 } else

1676 CS << "?";

1677 }

1678 CS << "]";

1680 return true;

1681 }

1682 }

1683

1684 return false;

1685}

1687 int SrcEltBits, int DstEltBits) {

1688 printExtend(MI, OutStreamer, SrcEltBits, DstEltBits, true);

1689}

1691 int SrcEltBits, int DstEltBits) {

1692 if (printExtend(MI, OutStreamer, SrcEltBits, DstEltBits, false))

1693 return;

1694

1695

1696 std::string Comment;

1699 CS << " = ";

1700

1703 assert((Width % DstEltBits) == 0 && (DstEltBits % SrcEltBits) == 0 &&

1704 "Illegal extension ratio");

1705 DecodeZeroExtendMask(SrcEltBits, DstEltBits, Width / DstEltBits, false, Mask);

1707

1709}

1710

1711void X86AsmPrinter::EmitSEHInstruction(const MachineInstr *MI) {

1712 assert(MF->hasWinCFI() && "SEH_ instruction in function without WinCFI?");

1713 assert((getSubtarget().isOSWindows() || getSubtarget().isUEFI()) &&

1714 "SEH_ instruction Windows and UEFI only");

1715

1716

1717 if (EmitFPOData) {

1718 X86TargetStreamer *XTS =

1719 static_cast<X86TargetStreamer *>(OutStreamer->getTargetStreamer());

1720 switch (MI->getOpcode()) {

1721 case X86::SEH_PushReg:

1723 break;

1724 case X86::SEH_StackAlloc:

1726 break;

1727 case X86::SEH_StackAlign:

1729 break;

1730 case X86::SEH_SetFrame:

1731 assert(MI->getOperand(1).getImm() == 0 &&

1732 ".cv_fpo_setframe takes no offset");

1734 break;

1735 case X86::SEH_EndPrologue:

1737 break;

1738 case X86::SEH_SaveReg:

1739 case X86::SEH_SaveXMM:

1740 case X86::SEH_PushFrame:

1742 break;

1743 default:

1745 }

1746 return;

1747 }

1748

1749

1750 switch (MI->getOpcode()) {

1751 case X86::SEH_PushReg:

1753 break;

1754

1755 case X86::SEH_SaveReg:

1757 MI->getOperand(1).getImm());

1758 break;

1759

1760 case X86::SEH_SaveXMM:

1762 MI->getOperand(1).getImm());

1763 break;

1764

1765 case X86::SEH_StackAlloc:

1767 break;

1768

1769 case X86::SEH_SetFrame:

1771 MI->getOperand(1).getImm());

1772 break;

1773

1774 case X86::SEH_PushFrame:

1776 break;

1777

1778 case X86::SEH_EndPrologue:

1780 break;

1781

1782 case X86::SEH_BeginEpilogue:

1784 break;

1785

1786 case X86::SEH_EndEpilogue:

1788 break;

1789

1790 case X86::SEH_UnwindV2Start:

1792 break;

1793

1794 case X86::SEH_UnwindVersion:

1796 break;

1797

1798 default:

1800 }

1801}

1802

1805 switch (MI->getOpcode()) {

1806

1807

1808

1809 case X86::PSHUFBrm:

1810 case X86::VPSHUFBrm:

1811 case X86::VPSHUFBYrm:

1812 case X86::VPSHUFBZ128rm:

1813 case X86::VPSHUFBZ128rmk:

1814 case X86::VPSHUFBZ128rmkz:

1815 case X86::VPSHUFBZ256rm:

1816 case X86::VPSHUFBZ256rmk:

1817 case X86::VPSHUFBZ256rmkz:

1818 case X86::VPSHUFBZrm:

1819 case X86::VPSHUFBZrmk:

1820 case X86::VPSHUFBZrmkz: {

1826 if (!Mask.empty())

1828 }

1829 break;

1830 }

1831

1832 case X86::VPERMILPSrm:

1833 case X86::VPERMILPSYrm:

1834 case X86::VPERMILPSZ128rm:

1835 case X86::VPERMILPSZ128rmk:

1836 case X86::VPERMILPSZ128rmkz:

1837 case X86::VPERMILPSZ256rm:

1838 case X86::VPERMILPSZ256rmk:

1839 case X86::VPERMILPSZ256rmkz:

1840 case X86::VPERMILPSZrm:

1841 case X86::VPERMILPSZrmk:

1842 case X86::VPERMILPSZrmkz: {

1848 if (!Mask.empty())

1850 }

1851 break;

1852 }

1853 case X86::VPERMILPDrm:

1854 case X86::VPERMILPDYrm:

1855 case X86::VPERMILPDZ128rm:

1856 case X86::VPERMILPDZ128rmk:

1857 case X86::VPERMILPDZ128rmkz:

1858 case X86::VPERMILPDZ256rm:

1859 case X86::VPERMILPDZ256rmk:

1860 case X86::VPERMILPDZ256rmkz:

1861 case X86::VPERMILPDZrm:

1862 case X86::VPERMILPDZrmk:

1863 case X86::VPERMILPDZrmkz: {

1869 if (!Mask.empty())

1871 }

1872 break;

1873 }

1874

1875 case X86::VPERMIL2PDrm:

1876 case X86::VPERMIL2PSrm:

1877 case X86::VPERMIL2PDYrm:

1878 case X86::VPERMIL2PSYrm: {

1880 "Unexpected number of operands!");

1881

1882 const MachineOperand &CtrlOp = MI->getOperand(MI->getNumOperands() - 1);

1883 if (!CtrlOp.isImm())

1884 break;

1885

1886 unsigned ElSize;

1887 switch (MI->getOpcode()) {

1889 case X86::VPERMIL2PSrm: case X86::VPERMIL2PSYrm: ElSize = 32; break;

1890 case X86::VPERMIL2PDrm: case X86::VPERMIL2PDYrm: ElSize = 64; break;

1891 }

1892

1897 if (!Mask.empty())

1899 }

1900 break;

1901 }

1902

1903 case X86::VPPERMrrm: {

1908 if (!Mask.empty())

1910 }

1911 break;

1912 }

1913

1914 case X86::MMX_MOVQ64rm: {

1916 std::string Comment;

1921 CS << "0x" << toString(CF->getValueAPF().bitcastToAPInt(), 16, false);

1923 }

1924 }

1925 break;

1926 }

1927

1928#define INSTR_CASE(Prefix, Instr, Suffix, Postfix) \

1929 case X86::Prefix##Instr##Suffix##rm##Postfix:

1930

1931#define CASE_AVX512_ARITH_RM(Instr) \

1932 INSTR_CASE(V, Instr, Z128, ) \

1933 INSTR_CASE(V, Instr, Z128, k) \

1934 INSTR_CASE(V, Instr, Z128, kz) \

1935 INSTR_CASE(V, Instr, Z256, ) \

1936 INSTR_CASE(V, Instr, Z256, k) \

1937 INSTR_CASE(V, Instr, Z256, kz) \

1938 INSTR_CASE(V, Instr, Z, ) \

1939 INSTR_CASE(V, Instr, Z, k) \

1940 INSTR_CASE(V, Instr, Z, kz)

1941

1942#define CASE_ARITH_RM(Instr) \

1943 INSTR_CASE(, Instr, , ) \

1944 INSTR_CASE(V, Instr, , ) \

1945 INSTR_CASE(V, Instr, Y, ) \

1946 INSTR_CASE(V, Instr, Z128, ) \

1947 INSTR_CASE(V, Instr, Z128, k) \

1948 INSTR_CASE(V, Instr, Z128, kz) \

1949 INSTR_CASE(V, Instr, Z256, ) \

1950 INSTR_CASE(V, Instr, Z256, k) \

1951 INSTR_CASE(V, Instr, Z256, kz) \

1952 INSTR_CASE(V, Instr, Z, ) \

1953 INSTR_CASE(V, Instr, Z, k) \

1954 INSTR_CASE(V, Instr, Z, kz)

1955

1956

1969 std::string Comment;

1971 unsigned VectorWidth =

1973 CS << "[";

1975 CS << "]";

1977 }

1978 break;

1979 }

1980

1981#define MASK_AVX512_CASE(Instr) \

1982 case Instr: \

1983 case Instr##k: \

1984 case Instr##kz:

1985

1986 case X86::MOVSDrm:

1987 case X86::VMOVSDrm:

1989 case X86::MOVSDrm_alt:

1990 case X86::VMOVSDrm_alt:

1991 case X86::VMOVSDZrm_alt:

1992 case X86::MOVQI2PQIrm:

1993 case X86::VMOVQI2PQIrm:

1994 case X86::VMOVQI2PQIZrm:

1996 break;

1997

1999 case X86::VMOVSHZrm_alt:

2001 "mem[0],zero,zero,zero,zero,zero,zero,zero");

2002 break;

2003

2004 case X86::MOVSSrm:

2005 case X86::VMOVSSrm:

2007 case X86::MOVSSrm_alt:

2008 case X86::VMOVSSrm_alt:

2009 case X86::VMOVSSZrm_alt:

2010 case X86::MOVDI2PDIrm:

2011 case X86::VMOVDI2PDIrm:

2012 case X86::VMOVDI2PDIZrm:

2014 break;

2015

2016#define MOV_CASE(Prefix, Suffix) \

2017 case X86::Prefix##MOVAPD##Suffix##rm: \

2018 case X86::Prefix##MOVAPS##Suffix##rm: \

2019 case X86::Prefix##MOVUPD##Suffix##rm: \

2020 case X86::Prefix##MOVUPS##Suffix##rm: \

2021 case X86::Prefix##MOVDQA##Suffix##rm: \

2022 case X86::Prefix##MOVDQU##Suffix##rm:

2023

2024#define MOV_AVX512_CASE(Suffix, Postfix) \

2025 case X86::VMOVDQA64##Suffix##rm##Postfix: \

2026 case X86::VMOVDQA32##Suffix##rm##Postfix: \

2027 case X86::VMOVDQU64##Suffix##rm##Postfix: \

2028 case X86::VMOVDQU32##Suffix##rm##Postfix: \

2029 case X86::VMOVDQU16##Suffix##rm##Postfix: \

2030 case X86::VMOVDQU8##Suffix##rm##Postfix: \

2031 case X86::VMOVAPS##Suffix##rm##Postfix: \

2032 case X86::VMOVAPD##Suffix##rm##Postfix: \

2033 case X86::VMOVUPS##Suffix##rm##Postfix: \

2034 case X86::VMOVUPD##Suffix##rm##Postfix:

2035

2036#define CASE_128_MOV_RM() \

2037 MOV_CASE(, ) \

2038 MOV_CASE(V, ) \

2039 MOV_AVX512_CASE(Z128, ) \

2040 MOV_AVX512_CASE(Z128, k) \

2041 MOV_AVX512_CASE(Z128, kz)

2042

2043#define CASE_256_MOV_RM() \

2044 MOV_CASE(V, Y) \

2045 MOV_AVX512_CASE(Z256, ) \

2046 MOV_AVX512_CASE(Z256, k) \

2047 MOV_AVX512_CASE(Z256, kz) \

2048

2049#define CASE_512_MOV_RM() \

2050 MOV_AVX512_CASE(Z, ) \

2051 MOV_AVX512_CASE(Z, k) \

2052 MOV_AVX512_CASE(Z, kz) \

2053

2054

2055

2058 break;

2061 break;

2064 break;

2065 case X86::VBROADCASTF128rm:

2066 case X86::VBROADCASTI128rm:

2072 break;

2078 break;

2084 break;

2085

2086

2087

2088 case X86::MOVDDUPrm:

2089 case X86::VMOVDDUPrm:

2091 case X86::VPBROADCASTQrm:

2094 break;

2095 case X86::VBROADCASTSDYrm:

2097 case X86::VPBROADCASTQYrm:

2100 break;

2104 break;

2105 case X86::VBROADCASTSSrm:

2107 case X86::VPBROADCASTDrm:

2110 break;

2111 case X86::VBROADCASTSSYrm:

2113 case X86::VPBROADCASTDYrm:

2116 break;

2120 break;

2121 case X86::VPBROADCASTWrm:

2124 break;

2125 case X86::VPBROADCASTWYrm:

2128 break;

2131 break;

2132 case X86::VPBROADCASTBrm:

2135 break;

2136 case X86::VPBROADCASTBYrm:

2139 break;

2142 break;

2143

2144#define MOVX_CASE(Prefix, Ext, Type, Suffix, Postfix) \

2145 case X86::Prefix##PMOV##Ext##Type##Suffix##rm##Postfix:

2146

2147#define CASE_MOVX_RM(Ext, Type) \

2148 MOVX_CASE(, Ext, Type, , ) \

2149 MOVX_CASE(V, Ext, Type, , ) \

2150 MOVX_CASE(V, Ext, Type, Y, ) \

2151 MOVX_CASE(V, Ext, Type, Z128, ) \

2152 MOVX_CASE(V, Ext, Type, Z128, k ) \

2153 MOVX_CASE(V, Ext, Type, Z128, kz ) \

2154 MOVX_CASE(V, Ext, Type, Z256, ) \

2155 MOVX_CASE(V, Ext, Type, Z256, k ) \

2156 MOVX_CASE(V, Ext, Type, Z256, kz ) \

2157 MOVX_CASE(V, Ext, Type, Z, ) \

2158 MOVX_CASE(V, Ext, Type, Z, k ) \

2159 MOVX_CASE(V, Ext, Type, Z, kz )

2160

2163 break;

2166 break;

2169 break;

2172 break;

2175 break;

2178 break;

2179

2182 break;

2185 break;

2188 break;

2191 break;

2194 break;

2197 break;

2198 }

2199}

2200

2201

2205

2206

2208 assert(MI->getOpcode() == X86::TAILJMPm64_REX ||

2209 MI->getOpcode() == X86::CALL64m);

2213}

2214

2215

2216

2219 for (auto I = MBB.instr_rbegin(), E = MBB.instr_rend(); I != E; ++I)

2220 if (I->isJumpTableDebugInfo())

2221 return true;

2222

2223 return false;

2224}

2225

2227

2228

2229

2230

2231 X86MCInstLower MCInstLowering(*MF, *this);

2234

2235 if (MI->getOpcode() == X86::OR64rm) {

2236 for (auto &Opd : MI->operands()) {

2237 if (Opd.isSymbol() && StringRef(Opd.getSymbolName()) ==

2238 "swift_async_extendedFramePointerFlags") {

2239 ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags = true;

2240 }

2241 }

2242 }

2243

2244

2247

2248

2249 if (TM.Options.MCOptions.ShowMCEncoding) {

2251 OutStreamer->AddComment("EVEX TO LEGACY Compression ", false);

2253 OutStreamer->AddComment("EVEX TO VEX Compression ", false);

2255 OutStreamer->AddComment("EVEX TO EVEX Compression ", false);

2256 }

2257

2258

2259 bool IsTailJump = false;

2260

2261 switch (MI->getOpcode()) {

2262 case TargetOpcode::DBG_VALUE:

2264

2265 case X86::EH_RETURN:

2266 case X86::EH_RETURN64: {

2267

2268 Register Reg = MI->getOperand(0).getReg();

2271 break;

2272 }

2273 case X86::CLEANUPRET: {

2274

2276 break;

2277 }

2278

2279 case X86::CATCHRET: {

2280

2282 break;

2283 }

2284

2285 case X86::ENDBR32:

2286 case X86::ENDBR64: {

2287

2288

2289

2290

2293 MI == &MF->front().front()) {

2295 MCInstLowering.Lower(MI, Inst);

2296 EmitAndCountInstruction(Inst);

2299 return;

2300 }

2301 break;

2302 }

2303

2304 case X86::TAILJMPd64:

2305 if (IndCSPrefix && MI->hasRegisterImplicitUseOperand(X86::R11))

2306 EmitAndCountInstruction(MCInstBuilder(X86::CS_PREFIX));

2307

2308 if (EnableImportCallOptimization && isImportedFunction(MI->getOperand(0))) {

2309 emitLabelAndRecordForImportCallOptimization(

2310 IMAGE_RETPOLINE_AMD64_IMPORT_BR);

2311 }

2312

2313

2315 IsTailJump = true;

2316 break;

2317

2318 case X86::TAILJMPr:

2319 case X86::TAILJMPm:

2320 case X86::TAILJMPd:

2321 case X86::TAILJMPd_CC:

2322 case X86::TAILJMPr64:

2323 case X86::TAILJMPm64:

2324 case X86::TAILJMPd64_CC:

2325 if (EnableImportCallOptimization)

2326 report_fatal_error("Unexpected TAILJMP instruction was emitted when "

2327 "import call optimization was enabled");

2328

2329

2331 IsTailJump = true;

2332 break;

2333

2334 case X86::TAILJMPm64_REX:

2336 emitLabelAndRecordForImportCallOptimization(

2337 IMAGE_RETPOLINE_AMD64_CFG_BR_REX);

2338 }

2339

2341 IsTailJump = true;

2342 break;

2343

2344 case X86::TAILJMPr64_REX: {

2345 if (EnableImportCallOptimization) {

2346 assert(MI->getOperand(0).getReg() == X86::RAX &&

2347 "Indirect tail calls with impcall enabled must go through RAX (as "

2348 "enforced by TCRETURNImpCallri64)");

2349 emitLabelAndRecordForImportCallOptimization(

2350 IMAGE_RETPOLINE_AMD64_INDIR_BR);

2351 }

2352

2354 IsTailJump = true;

2355 break;

2356 }

2357

2358 case X86::JMP64r:

2361 this->getSubtarget().getRegisterInfo()->getEncodingValue(

2362 MI->getOperand(0).getReg().asMCReg());

2363 emitLabelAndRecordForImportCallOptimization(

2364 (ImportCallKind)(IMAGE_RETPOLINE_AMD64_SWITCHTABLE_FIRST +

2365 EncodedReg));

2366 }

2367 break;

2368

2369 case X86::JMP16r:

2370 case X86::JMP16m:

2371 case X86::JMP32r:

2372 case X86::JMP32m:

2373 case X86::JMP64m:

2376 "Unexpected JMP instruction was emitted for a jump-table when import "

2377 "call optimization was enabled");

2378 break;

2379

2380 case X86::TLS_addr32:

2381 case X86::TLS_addr64:

2382 case X86::TLS_addrX32:

2383 case X86::TLS_base_addr32:

2384 case X86::TLS_base_addr64:

2385 case X86::TLS_base_addrX32:

2386 case X86::TLS_desc32:

2387 case X86::TLS_desc64:

2388 return LowerTlsAddr(MCInstLowering, *MI);

2389

2390 case X86::MOVPC32r: {

2391

2392

2393

2394

2395

2396

2397

2398 MCSymbol *PICBase = MF->getPICBaseSymbol();

2399

2400

2401 EmitAndCountInstruction(

2404

2406 MF->getSubtarget<X86Subtarget>().getFrameLowering();

2407 bool hasFP = FrameLowering->hasFP(*MF);

2408

2409

2410 bool HasActiveDwarfFrame = OutStreamer->getNumFrameInfos() &&

2411 OutStreamer->getDwarfFrameInfos().back().End;

2412

2414

2415 if (HasActiveDwarfFrame && !hasFP) {

2416 OutStreamer->emitCFIAdjustCfaOffset(-stackGrowth);

2418 }

2419

2420

2422

2423

2424 EmitAndCountInstruction(

2425 MCInstBuilder(X86::POP32r).addReg(MI->getOperand(0).getReg()));

2426

2427 if (HasActiveDwarfFrame && !hasFP) {

2428 OutStreamer->emitCFIAdjustCfaOffset(stackGrowth);

2429 }

2430 return;

2431 }

2432

2433 case X86::ADD32ri: {

2434

2436 break;

2437

2438

2439

2440

2441

2442

2443

2444

2447

2448

2449 MCSymbol *OpSym = MCInstLowering.GetSymbolFromOperand(MI->getOperand(2));

2450

2452 const MCExpr *PICBase =

2455

2458

2459 EmitAndCountInstruction(MCInstBuilder(X86::ADD32ri)

2460 .addReg(MI->getOperand(0).getReg())

2461 .addReg(MI->getOperand(1).getReg())

2463 return;

2464 }

2465 case TargetOpcode::STATEPOINT:

2466 return LowerSTATEPOINT(*MI, MCInstLowering);

2467

2468 case TargetOpcode::FAULTING_OP:

2469 return LowerFAULTING_OP(*MI, MCInstLowering);

2470

2471 case TargetOpcode::FENTRY_CALL:

2472 return LowerFENTRY_CALL(*MI, MCInstLowering);

2473

2474 case TargetOpcode::PATCHABLE_OP:

2475 return LowerPATCHABLE_OP(*MI, MCInstLowering);

2476

2477 case TargetOpcode::STACKMAP:

2478 return LowerSTACKMAP(*MI);

2479

2480 case TargetOpcode::PATCHPOINT:

2481 return LowerPATCHPOINT(*MI, MCInstLowering);

2482

2483 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:

2484 return LowerPATCHABLE_FUNCTION_ENTER(*MI, MCInstLowering);

2485

2486 case TargetOpcode::PATCHABLE_RET:

2487 return LowerPATCHABLE_RET(*MI, MCInstLowering);

2488

2489 case TargetOpcode::PATCHABLE_TAIL_CALL:

2490 return LowerPATCHABLE_TAIL_CALL(*MI, MCInstLowering);

2491

2492 case TargetOpcode::PATCHABLE_EVENT_CALL:

2493 return LowerPATCHABLE_EVENT_CALL(*MI, MCInstLowering);

2494

2495 case TargetOpcode::PATCHABLE_TYPED_EVENT_CALL:

2496 return LowerPATCHABLE_TYPED_EVENT_CALL(*MI, MCInstLowering);

2497

2498 case X86::MORESTACK_RET:

2500 return;

2501

2502 case X86::KCFI_CHECK:

2503 return LowerKCFI_CHECK(*MI);

2504

2505 case X86::ASAN_CHECK_MEMACCESS:

2506 return LowerASAN_CHECK_MEMACCESS(*MI);

2507

2508 case X86::MORESTACK_RET_RESTORE_R10:

2509

2511 EmitAndCountInstruction(

2512 MCInstBuilder(X86::MOV64rr).addReg(X86::R10).addReg(X86::RAX));

2513 return;

2514

2515 case X86::SEH_PushReg:

2516 case X86::SEH_SaveReg:

2517 case X86::SEH_SaveXMM:

2518 case X86::SEH_StackAlloc:

2519 case X86::SEH_StackAlign:

2520 case X86::SEH_SetFrame:

2521 case X86::SEH_PushFrame:

2522 case X86::SEH_EndPrologue:

2523 case X86::SEH_EndEpilogue:

2524 case X86::SEH_UnwindV2Start:

2525 case X86::SEH_UnwindVersion:

2526 EmitSEHInstruction(MI);

2527 return;

2528

2529 case X86::SEH_BeginEpilogue: {

2530 assert(MF->hasWinCFI() && "SEH_ instruction in function without WinCFI?");

2531 EmitSEHInstruction(MI);

2532 return;

2533 }

2534 case X86::UBSAN_UD1:

2535 EmitAndCountInstruction(MCInstBuilder(X86::UD1Lm)

2536 .addReg(X86::EAX)

2537 .addReg(X86::EAX)

2538 .addImm(1)

2539 .addReg(X86::NoRegister)

2540 .addImm(MI->getOperand(0).getImm())

2541 .addReg(X86::NoRegister));

2542 return;

2543 case X86::CALL64pcrel32:

2544 if (IndCSPrefix && MI->hasRegisterImplicitUseOperand(X86::R11))

2545 EmitAndCountInstruction(MCInstBuilder(X86::CS_PREFIX));

2546

2547 if (EnableImportCallOptimization && isImportedFunction(MI->getOperand(0))) {

2548 emitLabelAndRecordForImportCallOptimization(

2549 IMAGE_RETPOLINE_AMD64_IMPORT_CALL);

2550

2552 MCInstLowering.Lower(MI, TmpInst);

2553

2554

2555

2556 EmitAndCountInstruction(MCInstBuilder(X86::REX64_PREFIX));

2557 emitCallInstruction(TmpInst);

2559 maybeEmitNopAfterCallForWindowsEH(MI);

2560 return;

2561 }

2562

2563 break;

2564

2565 case X86::CALL64r:

2566 if (EnableImportCallOptimization) {

2567 assert(MI->getOperand(0).getReg() == X86::RAX &&

2568 "Indirect calls with impcall enabled must go through RAX (as "

2569 "enforced by CALL64r_ImpCall)");

2570

2571 emitLabelAndRecordForImportCallOptimization(

2572 IMAGE_RETPOLINE_AMD64_INDIR_CALL);

2574 MCInstLowering.Lower(MI, TmpInst);

2575 emitCallInstruction(TmpInst);

2576

2577

2578

2580 maybeEmitNopAfterCallForWindowsEH(MI);

2581 return;

2582 }

2583 break;

2584

2585 case X86::CALL64m:

2587 emitLabelAndRecordForImportCallOptimization(

2588 IMAGE_RETPOLINE_AMD64_CFG_CALL);

2589 }

2590 break;

2591

2592 case X86::JCC_1:

2593

2594

2595

2603 if (EdgeProb > Threshold)

2604 EmitAndCountInstruction(MCInstBuilder(X86::DS_PREFIX));

2605 }

2606 break;

2607 }

2608

2610 MCInstLowering.Lower(MI, TmpInst);

2611

2612 if (MI->isCall()) {

2613 emitCallInstruction(TmpInst);

2614

2615

2616 if (!IsTailJump)

2617 maybeEmitNopAfterCallForWindowsEH(MI);

2618 return;

2619 }

2620

2621 EmitAndCountInstruction(TmpInst);

2622}

2623

2624void X86AsmPrinter::emitCallInstruction(const llvm::MCInst &MCI) {

2625

2626

2627

2628

2629

2630

2631 SMShadowTracker.count(MCI, getSubtargetInfo(), CodeEmitter.get());

2632

2633

2634 SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());

2635

2637}

2638

2639

2640

2641

2642

2643

2644

2645

2646

2647

2648

2649

2650

2651

2652

2653

2654

2655

2656

2657

2658

2659

2660

2661

2662

2663

2664

2665

2666

2667

2668

2669

2670

2671

2672

2673

2674

2675

2676

2677

2678

2679

2680

2681

2682

2683

2684

2685

2686

2687

2688

2689

2690

2691

2692

2693

2694

2695

2696

2697

2698void X86AsmPrinter::maybeEmitNopAfterCallForWindowsEH(const MachineInstr *MI) {

2699

2700

2701

2704 return;

2705 }

2706

2708

2709

2712

2713

2716 ++MBBI;

2717

2718

2719 for (;;) {

2720

2721 for (; MBBI != MBBE; ++MBBI) {

2722

2723 const MachineInstr &NextMI = *MBBI;

2724

2725

2726

2727

2729 if (HasEHPersonality) {

2730 EmitAndCountInstruction(MCInstBuilder(X86::NOOP));

2731 return;

2732 }

2733

2734

2735

2736

2737

2738 continue;

2739 }

2740

2741

2742

2743

2744

2745

2746

2747

2748

2749 if (NextMI.getOpcode() == X86::SEH_BeginEpilogue) {

2750 EmitAndCountInstruction(MCInstBuilder(X86::NOOP));

2751 return;

2752 }

2753

2755

2756

2757

2758

2759

2760 return;

2761 }

2762

2763

2764

2765

2766

2767 }

2768

2769

2770

2771

2772 ++MFI;

2773 if (MFI == MFE) {

2774

2775

2776 if (HasEHPersonality) {

2777

2778

2779

2780

2781

2782 if (MI->getParent()->succ_empty())

2783 EmitAndCountInstruction(MCInstBuilder(X86::INT3));

2784 else

2785 EmitAndCountInstruction(MCInstBuilder(X86::NOOP));

2786 }

2787 return;

2788 }

2789

2790

2791 const MachineBasicBlock *NextMBB = &*MFI;

2794 }

2795}

2796

2797void X86AsmPrinter::emitLabelAndRecordForImportCallOptimization(

2798 ImportCallKind Kind) {

2799 assert(EnableImportCallOptimization);

2800

2801 MCSymbol *CallSiteSymbol = MMI->getContext().createNamedTempSymbol("impcall");

2802 OutStreamer->emitLabel(CallSiteSymbol);

2803

2805 .push_back({CallSiteSymbol, Kind});

2806}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

MachineBasicBlock MachineBasicBlock::iterator MBBI

static void printShuffleMask(raw_ostream &Out, Type *Ty, ArrayRef< int > Mask)

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

print mir2vec MIR2Vec Vocabulary Printer Pass

This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...

Promote Memory to Register

uint64_t IntrinsicInst * II

static cl::opt< bool > EnableBranchHint("ppc-use-branch-hint", cl::init(true), cl::desc("Enable static hinting of branches on ppc"), cl::Hidden)

static MCSymbol * GetSymbolFromOperand(const MachineOperand &MO, AsmPrinter &AP)

static bool isValid(const char C)

Returns true if C is a valid mangled character: <0-9a-zA-Z_>.

This file defines the SmallString class.

static MCOperand LowerSymbolOperand(const MachineInstr *MI, const MachineOperand &MO, const MCSymbol *Symbol, AsmPrinter &AP)

static void emitX86Nops(MCStreamer &OS, unsigned NumBytes, const X86Subtarget *Subtarget)

Emit the optimal amount of multi-byte nops on X86.

Definition X86MCInstLower.cpp:776

static unsigned getRetOpcode(const X86Subtarget &Subtarget)

Definition X86MCInstLower.cpp:335

static void printSignExtend(const MachineInstr *MI, MCStreamer &OutStreamer, int SrcEltBits, int DstEltBits)

Definition X86MCInstLower.cpp:1686

static unsigned convertTailJumpOpcode(unsigned Opcode)

Definition X86MCInstLower.cpp:373

static unsigned getSrcIdx(const MachineInstr *MI, unsigned SrcIdx)

Definition X86MCInstLower.cpp:1435

static void printBroadcast(const MachineInstr *MI, MCStreamer &OutStreamer, int Repeats, int BitWidth)

Definition X86MCInstLower.cpp:1639

static bool printExtend(const MachineInstr *MI, MCStreamer &OutStreamer, int SrcEltBits, int DstEltBits, bool IsSext)

Definition X86MCInstLower.cpp:1657

static void printZeroUpperMove(const MachineInstr *MI, MCStreamer &OutStreamer, int SclWidth, int VecWidth, const char *ShuffleComment)

Definition X86MCInstLower.cpp:1612

#define MASK_AVX512_CASE(Instr)

#define CASE_ARITH_RM(Instr)

static void addConstantComments(const MachineInstr *MI, MCStreamer &OutStreamer)

Definition X86MCInstLower.cpp:1803

#define CASE_256_MOV_RM()

#define CASE_AVX512_ARITH_RM(Instr)

bool hasJumpTableInfoInBlock(const llvm::MachineInstr *MI)

Definition X86MCInstLower.cpp:2217

static unsigned emitNop(MCStreamer &OS, unsigned NumBytes, const X86Subtarget *Subtarget)

Emit the largest nop instruction smaller than or equal to NumBytes bytes.

Definition X86MCInstLower.cpp:659

static void printDstRegisterName(raw_ostream &CS, const MachineInstr *MI, unsigned SrcOpIdx)

Definition X86MCInstLower.cpp:1447

#define CASE_MOVX_RM(Ext, Type)

bool isImportedFunction(const MachineOperand &MO)

Definition X86MCInstLower.cpp:2202

static cl::opt< bool > EnableBranchHint("enable-branch-hint", cl::desc("Enable branch hint."), cl::init(false), cl::Hidden)

static void printConstant(const APInt &Val, raw_ostream &CS, bool PrintZero=false)

Definition X86MCInstLower.cpp:1526

static void printZeroExtend(const MachineInstr *MI, MCStreamer &OutStreamer, int SrcEltBits, int DstEltBits)

Definition X86MCInstLower.cpp:1690

static std::string getShuffleComment(const MachineInstr *MI, unsigned SrcOp1Idx, unsigned SrcOp2Idx, ArrayRef< int > Mask)

Definition X86MCInstLower.cpp:1505

bool isCallToCFGuardFunction(const MachineInstr *MI)

Definition X86MCInstLower.cpp:2207

#define CASE_512_MOV_RM()

static cl::opt< unsigned > BranchHintProbabilityThreshold("branch-hint-probability-threshold", cl::desc("The probability threshold of enabling branch hint."), cl::init(50), cl::Hidden)

#define CASE_128_MOV_RM()

void toString(SmallVectorImpl< char > &Str, unsigned FormatPrecision=0, unsigned FormatMaxPadding=3, bool TruncateZero=true) const

const fltSemantics & getSemantics() const

static APFloat getZero(const fltSemantics &Sem, bool Negative=false)

Factory for Positive and Negative Zero.

Class for arbitrary precision integers.

LLVM_ABI APInt zext(unsigned width) const

Zero extend to a new width.

uint64_t getZExtValue() const

Get zero extended value.

unsigned getBitWidth() const

Return the number of bits in the APInt.

unsigned getNumWords() const

Get the number of words.

LLVM_ABI APInt sext(unsigned width) const

Sign extend to a new width.

const uint64_t * getRawData() const

This function returns a pointer to the internal storage of the APInt.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

This class is intended to be used as a driving class for all asm writers.

MCSymbol * getSymbol(const GlobalValue *GV) const

MCSymbol * CurrentFnBegin

TargetMachine & TM

Target machine description.

virtual MCSymbol * GetCPISymbol(unsigned CPID) const

Return the symbol for the specified constant pool entry.

const MCAsmInfo * MAI

Target Asm Printer information.

MachineFunction * MF

The current machine function.

MCSymbol * GetJTISymbol(unsigned JTID, bool isLinkerPrivate=false) const

Return the symbol for the specified jump table entry.

AsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer, char &ID=AsmPrinter::ID)

MCSymbol * getSymbolPreferLocal(const GlobalValue &GV) const

Similar to getSymbol() but preferred for references.

MachineModuleInfo * MMI

This is a pointer to the current MachineModuleInfo.

MCContext & OutContext

This is the context for the output file that we are streaming.

MCSymbol * createTempSymbol(const Twine &Name) const

MCSymbol * CurrentPatchableFunctionEntrySym

The symbol for the entry in __patchable_function_entires.

std::unique_ptr< MCStreamer > OutStreamer

This is the MCStreamer object for the file we are generating.

void getNameWithPrefix(SmallVectorImpl< char > &Name, const GlobalValue *GV) const

MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const

Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.

const MCSubtargetInfo & getSubtargetInfo() const

Return information about subtarget.

LLVM_ABI StringRef getValueAsString() const

Return the attribute's value as a string.

This is an important base class in LLVM.

bool hasOptSize() const

Optimize this function for size (-Os) or minimum size (-Oz).

Attribute getFnAttribute(Attribute::AttrKind Kind) const

Return the attribute for the given attribute kind.

bool hasInternalLinkage() const

This class is intended to be used as a base class for asm properties and features specific to the tar...

bool doesSetDirectiveSuppressReloc() const

static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())

static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)

MCCodeEmitter - Generic instruction encoding interface.

virtual void encodeInstruction(const MCInst &Inst, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0

Encode the given Inst to bytes and append to CB.

static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

Context object for machine code objects.

LLVM_ABI MCSymbol * createTempSymbol()

Create a temporary symbol with a unique name.

LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)

Lookup the symbol inside with the specified Name.

const MCTargetOptions * getTargetOptions() const

Base class for the full range of assembler expressions which are needed for parsing.

MCInstBuilder & addReg(MCRegister Reg)

Add a new register operand.

MCInstBuilder & addExpr(const MCExpr *Val)

Add a new MCExpr operand.

Instances of this class represent a single low-level machine instruction.

unsigned getNumOperands() const

unsigned getOpcode() const

iterator insert(iterator I, const MCOperand &Op)

void setFlags(unsigned F)

void addOperand(const MCOperand Op)

void setOpcode(unsigned Op)

const MCOperand & getOperand(unsigned i) const

Instances of this class represent operands of the MCInst class.

static MCOperand createExpr(const MCExpr *Val)

static MCOperand createReg(MCRegister Reg)

static MCOperand createImm(int64_t Val)

MCRegister getReg() const

Returns the register number.

Streaming machine code generation interface.

virtual void emitWinCFIUnwindVersion(uint8_t Version, SMLoc Loc=SMLoc())

virtual void emitWinCFIPushReg(MCRegister Register, SMLoc Loc=SMLoc())

virtual void emitBinaryData(StringRef Data)

Functionally identical to EmitBytes.

virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)

Emit the given Instruction into the current section.

virtual void emitWinCFIUnwindV2Start(SMLoc Loc=SMLoc())

virtual void emitWinCFIEndEpilogue(SMLoc Loc=SMLoc())

virtual void emitWinCFIPushFrame(bool Code, SMLoc Loc=SMLoc())

virtual void emitWinCFISaveXMM(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())

MCContext & getContext() const

virtual void AddComment(const Twine &T, bool EOL=true)

Add a textual comment.

virtual void emitWinCFIBeginEpilogue(SMLoc Loc=SMLoc())

virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())

Emit a label for Symbol into the current section.

MCTargetStreamer * getTargetStreamer()

virtual void emitWinCFISaveReg(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())

virtual void emitWinCFIEndProlog(SMLoc Loc=SMLoc())

virtual void emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI, unsigned MaxBytesToEmit=0)

Emit nops until the byte alignment ByteAlignment is reached.

virtual void emitWinCFISetFrame(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())

virtual void emitWinCFIAllocStack(unsigned Size, SMLoc Loc=SMLoc())

MCSection * getCurrentSectionOnly() const

virtual void emitBytes(StringRef Data)

Emit the bytes in Data into the output.

Generic base class for all target subtargets.

static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())

MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...

StringRef getName() const

getName - Get the symbol name.

instr_iterator instr_begin()

MachineInstrBundleIterator< const MachineInstr > const_iterator

LLVM_ABI MCSymbol * getSymbol() const

Return the MCSymbol for this basic block.

instr_iterator instr_end()

BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const

const WinEHFuncInfo * getWinEHFuncInfo() const

getWinEHFuncInfo - Return information about how the current function uses Windows exception handling.

MCSymbol * getPICBaseSymbol() const

getPICBaseSymbol - Return a function-local symbol to represent the PIC base.

const DataLayout & getDataLayout() const

Return the DataLayout attached to the Module associated to this MF.

Function & getFunction()

Return the LLVM function that this machine code represents.

BasicBlockListType::const_iterator const_iterator

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

bool isPseudo(QueryType Type=IgnoreBundle) const

Return true if this is a pseudo instruction that doesn't correspond to a real machine instruction.

const MachineOperand & getOperand(unsigned i) const

bool isMetaInstruction(QueryType Type=IgnoreBundle) const

Return true if this instruction doesn't produce any output in the form of executable instructions.

StubValueTy & getGVStubEntry(MCSymbol *Sym)

PointerIntPair< MCSymbol *, 1, bool > StubValueTy

MachineModuleInfoMachO - This is a MachineModuleInfoImpl implementation for MachO targets.

Ty & getObjFileInfo()

Keep track of various per-module pieces of information for backends that would like to do so.

MachineOperand class - Representation of each machine instruction operand.

static MachineOperand CreateMCSymbol(MCSymbol *Sym, unsigned TargetFlags=0)

const GlobalValue * getGlobal() const

bool isReg() const

isReg - Tests if this is a MO_Register operand.

MachineBasicBlock * getMBB() const

bool isImm() const

isImm - Tests if this is a MO_Immediate operand.

bool isSymbol() const

isSymbol - Tests if this is a MO_ExternalSymbol operand.

bool isJTI() const

isJTI - Tests if this is a MO_JumpTableIndex operand.

const BlockAddress * getBlockAddress() const

unsigned getTargetFlags() const

bool isGlobal() const

isGlobal - Tests if this is a MO_GlobalAddress operand.

MachineOperandType getType() const

getType - Returns the MachineOperandType for this operand.

const char * getSymbolName() const

Register getReg() const

getReg - Returns the register number.

void setTargetFlags(unsigned F)

MCSymbol * getMCSymbol() const

@ MO_Immediate

Immediate operand.

@ MO_ConstantPoolIndex

Address of indexed Constant in Constant Pool.

@ MO_MCSymbol

MCSymbol reference (for debug/eh info)

@ MO_GlobalAddress

Address of a global value.

@ MO_RegisterMask

Mask of preserved registers.

@ MO_BlockAddress

Address of a basic block.

@ MO_MachineBasicBlock

MachineBasicBlock reference.

@ MO_Register

Register operand.

@ MO_ExternalSymbol

Name of external global symbol.

@ MO_JumpTableIndex

Address of indexed Jump Table for switch.

int64_t getOffset() const

Return the offset from the symbol in this operand.

bool isMBB() const

isMBB - Tests if this is a MO_MachineBasicBlock operand.

LLVM_ABI void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const

Print the appropriate prefix and the specified global variable's name.

virtual void print(raw_ostream &OS, const Module *M) const

print - Print out the internal state of the pass.

AnalysisType & getAnalysis() const

getAnalysis() - This function is used by subclasses to get to the analysis information ...

PointerTy getPointer() const

Wrapper class representing virtual and physical registers.

MCRegister asMCReg() const

Utility to check-convert this value to a MCRegister.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringRef - Represent a constant reference to a string, i.e.

bool getAsInteger(unsigned Radix, T &Result) const

Parse the current string as an integer of the specified radix.

constexpr bool empty() const

empty - Check if the string is empty.

bool hasFP(const MachineFunction &MF) const

hasFP - Return true if the specified function should have a dedicated frame pointer register.

Primary interface to the complete machine description for the target machine.

const Triple & getTargetTriple() const

The instances of the Type class are immutable: once they are created, they are never changed.

bool isFloatTy() const

Return true if this is 'float', a 32-bit IEEE fp type.

LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY

Return the basic size of this type if it is a primitive type.

bool isHalfTy() const

Return true if this is 'half', a 16-bit IEEE fp type.

bool isDoubleTy() const

Return true if this is 'double', a 64-bit IEEE fp type.

bool isIntegerTy() const

True if this is an instance of IntegerType.

static const char * getRegisterName(MCRegister Reg)

void emitInstruction(const MachineInstr *MI) override

Targets should implement this to emit instructions.

Definition X86MCInstLower.cpp:2226

const X86Subtarget & getSubtarget() const

X86AsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer)

X86MachineFunctionInfo - This class is derived from MachineFunction and contains private X86 target-s...

unsigned getSlotSize() const

bool isTargetWindowsMSVC() const

bool useIndirectThunkCalls() const

virtual bool emitFPOPushReg(MCRegister Reg, SMLoc L={})

virtual bool emitFPOEndPrologue(SMLoc L={})

virtual bool emitFPOStackAlign(unsigned Align, SMLoc L={})

virtual bool emitFPOSetFrame(MCRegister Reg, SMLoc L={})

virtual bool emitFPOStackAlloc(unsigned StackAlloc, SMLoc L={})

This class implements an extremely fast bulk output stream that can only output to a stream.

A raw_ostream that writes to an std::string.

std::string & str()

Returns the string's reference.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

constexpr char Align[]

Key for Kernel::Arg::Metadata::mAlign.

@ C

The default llvm calling convention, compatible with C.

@ Itanium

Windows CE ARM, PowerPC, SH3, SH4.

bool isKMergeMasked(uint64_t TSFlags)

@ MO_TLSLD

MO_TLSLD - On a symbol operand this indicates that the immediate is the offset of the GOT entry with ...

@ MO_GOTPCREL_NORELAX

MO_GOTPCREL_NORELAX - Same as MO_GOTPCREL except that R_X86_64_GOTPCREL relocations are guaranteed to...

@ MO_GOTOFF

MO_GOTOFF - On a symbol operand this indicates that the immediate is the offset to the location of th...

@ MO_DARWIN_NONLAZY_PIC_BASE

MO_DARWIN_NONLAZY_PIC_BASE - On a symbol operand "FOO", this indicates that the reference is actually...

@ MO_GOT_ABSOLUTE_ADDRESS

MO_GOT_ABSOLUTE_ADDRESS - On a symbol operand, this represents a relocation of: SYMBOL_LABEL + [.

@ MO_COFFSTUB

MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "....

@ MO_NTPOFF

MO_NTPOFF - On a symbol operand this indicates that the immediate is the negative thread-pointer offs...

@ MO_DARWIN_NONLAZY

MO_DARWIN_NONLAZY - On a symbol operand "FOO", this indicates that the reference is actually to the "...

@ MO_INDNTPOFF

MO_INDNTPOFF - On a symbol operand this indicates that the immediate is the absolute address of the G...

@ MO_GOTNTPOFF

MO_GOTNTPOFF - On a symbol operand this indicates that the immediate is the offset of the GOT entry w...

@ MO_TPOFF

MO_TPOFF - On a symbol operand this indicates that the immediate is the thread-pointer offset for the...

@ MO_TLVP_PIC_BASE

MO_TLVP_PIC_BASE - On a symbol operand this indicates that the immediate is some TLS offset from the ...

@ MO_GOT

MO_GOT - On a symbol operand this indicates that the immediate is the offset to the GOT entry for the...

@ MO_ABS8

MO_ABS8 - On a symbol operand this indicates that the symbol is known to be an absolute symbol in ran...

@ MO_PLT

MO_PLT - On a symbol operand this indicates that the immediate is offset to the PLT entry of symbol n...

@ MO_TLSGD

MO_TLSGD - On a symbol operand this indicates that the immediate is the offset of the GOT entry with ...

@ MO_NO_FLAG

MO_NO_FLAG - No flag for the operand.

@ MO_TLVP

MO_TLVP - On a symbol operand this indicates that the immediate is some TLS offset.

@ MO_DLLIMPORT

MO_DLLIMPORT - On a symbol operand "FOO", this indicates that the reference is actually to the "__imp...

@ MO_GOTTPOFF

MO_GOTTPOFF - On a symbol operand this indicates that the immediate is the offset of the GOT entry wi...

@ MO_SECREL

MO_SECREL - On a symbol operand this indicates that the immediate is the offset from beginning of sec...

@ MO_DTPOFF

MO_DTPOFF - On a symbol operand this indicates that the immediate is the offset of the GOT entry with...

@ MO_PIC_BASE_OFFSET

MO_PIC_BASE_OFFSET - On a symbol operand this indicates that the immediate should get the value of th...

@ MO_TLSLDM

MO_TLSLDM - On a symbol operand this indicates that the immediate is the offset of the GOT entry with...

@ MO_GOTPCREL

MO_GOTPCREL - On a symbol operand this indicates that the immediate is offset to the GOT entry for th...

bool isKMasked(uint64_t TSFlags)

bool isX86_64ExtendedReg(MCRegister Reg)

bool optimizeToFixedRegisterOrShortImmediateForm(MCInst &MI)

bool optimizeMOV(MCInst &MI, bool In64BitMode)

Simplify things like MOV32rm to MOV32o32a.

CondCode GetOppositeBranchCondition(CondCode CC)

GetOppositeBranchCondition - Return the inverse of the specified cond, e.g.

bool optimizeMOVSX(MCInst &MI)

bool optimizeVPCMPWithImmediateOneOrSix(MCInst &MI)

bool optimizeShiftRotateWithImmediateOne(MCInst &MI)

bool optimizeInstFromVEX3ToVEX2(MCInst &MI, const MCInstrDesc &Desc)

const Constant * getConstantFromPool(const MachineInstr &MI, unsigned OpNo)

Find any constant pool entry associated with a specific instruction operand.

bool optimizeINCDEC(MCInst &MI, bool In64BitMode)

unsigned getVectorRegisterWidth(const MCOperandInfo &Info)

Get the width of the vector register operand.

initializer< Ty > init(const Ty &Val)

NodeAddr< CodeNode * > Code

This is an optimization pass for GlobalISel generic memory operations.

void DecodeZeroExtendMask(unsigned SrcScalarBits, unsigned DstScalarBits, unsigned NumDstElts, bool IsAnyExtend, SmallVectorImpl< int > &ShuffleMask)

Decode a zero extension instruction as a shuffle mask.

auto drop_begin(T &&RangeOrContainer, size_t N=1)

Return a range covering RangeOrContainer with the first N elements excluded.

void DecodeVPERMILPMask(unsigned NumElts, unsigned ScalarBits, ArrayRef< uint64_t > RawMask, const APInt &UndefElts, SmallVectorImpl< int > &ShuffleMask)

Decode a VPERMILPD/VPERMILPS variable mask from a raw array of constants.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

MCRegister getX86SubSuperRegister(MCRegister Reg, unsigned Size, bool High=false)

bool isCFGuardFunction(const GlobalValue *GV)

@ WinEH

Windows Exception Handling.

void DecodeVPERMIL2PMask(unsigned NumElts, unsigned ScalarBits, unsigned M2Z, ArrayRef< uint64_t > RawMask, const APInt &UndefElts, SmallVectorImpl< int > &ShuffleMask)

Decode a VPERMIL2PD/VPERMIL2PS variable mask from a raw array of constants.

MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

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...

LLVM_ABI raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

auto drop_end(T &&RangeOrContainer, size_t N=1)

Return a range covering RangeOrContainer with the last N elements excluded.

void DecodeVPPERMMask(ArrayRef< uint64_t > RawMask, const APInt &UndefElts, SmallVectorImpl< int > &ShuffleMask)

Decode a VPPERM mask from a raw array of constants such as from BUILD_VECTOR.

DWARFExpression::Operation Op

std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)

constexpr unsigned BitWidth

void getAddressSanitizerParams(const Triple &TargetTriple, int LongSize, bool IsKasan, uint64_t *ShadowBase, int *MappingScale, bool *OrShadowOffset)

void DecodePSHUFBMask(ArrayRef< uint64_t > RawMask, const APInt &UndefElts, SmallVectorImpl< int > &ShuffleMask)

Decode a PSHUFB mask from a raw array of constants such as from BUILD_VECTOR.

void changeAndComment(bool b)

Definition X86MCInstLower.cpp:103

~NoAutoPaddingScope()

Definition X86MCInstLower.cpp:102

NoAutoPaddingScope(MCStreamer &OS)

Definition X86MCInstLower.cpp:98

const bool OldAllowAutoPadding

Definition X86MCInstLower.cpp:97

MCStreamer & OS

Definition X86MCInstLower.cpp:96