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

1

2

3

4

5

6

7

8

9

10

11

12

13

52#include

53

54using namespace llvm;

55

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

60 "branch-hint-probability-threshold",

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

63

64namespace {

65

66

67class X86MCInstLower {

73

74public:

76

80

83

84private:

86};

87

88}

89

90

91

98 }

102 return;

104 if (b)

106 else

108 }

109};

110

111

114

115void X86AsmPrinter::StackMapShadowTracker::count(MCInst &Inst,

118 if (InShadow) {

122 CurrentShadowSize += Code.size();

123 if (CurrentShadowSize >= RequiredShadowSize)

124 InShadow = false;

125 }

126}

127

128void X86AsmPrinter::StackMapShadowTracker::emitShadowPadding(

130 if (InShadow && CurrentShadowSize < RequiredShadowSize) {

131 InShadow = false;

132 emitX86Nops(OutStreamer, RequiredShadowSize - CurrentShadowSize,

134 }

135}

136

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

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

140}

141

144 : Ctx(mf.getContext()), MF(mf), TM(mf.getTarget()), MAI(*TM.getMCAsmInfo()),

146

149}

150

151

152

154 const Triple &TT = TM.getTargetTriple();

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

157

160 "Isn't a symbol reference");

161

165

168

169 Name += "__imp_";

170 break;

172 Name += ".refptr.";

173 break;

176 Suffix = "$non_lazy_ptr";

177 break;

178 }

179

180 if (!Suffix.empty())

181 Name += DL.getPrivateGlobalPrefix();

182

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

191 }

192

193 Name += Suffix;

194 if (Sym)

195 Sym = Ctx.getOrCreateSymbol(Name);

196

197

198

200 default:

201 break;

206 if (!StubSym.getPointer()) {

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

210 }

211 break;

212 }

216 getMachOMMI().getGVStubEntry(Sym);

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

222 }

223 break;

224 }

225 }

226

227 return Sym;

228}

229

232

233

234 const MCExpr *Expr = nullptr;

236

238 default:

241

245 break;

246

249 break;

252

255 break;

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;

307

310 if (MO.isJTI()) {

311 assert(MAI.doesSetDirectiveSuppressReloc());

312

313

314

315

319 }

320 break;

321 }

322

323 if (!Expr)

325

330}

331

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

334}

335

339 default:

343

354 Sym->setExternal(true);

356 }

367

369 }

370}

371

372

373

375 switch (Opcode) {

376 case X86::TAILJMPr:

377 Opcode = X86::JMP32r;

378 break;

379 case X86::TAILJMPm:

380 Opcode = X86::JMP32m;

381 break;

382 case X86::TAILJMPr64:

383 Opcode = X86::JMP64r;

384 break;

385 case X86::TAILJMPm64:

386 Opcode = X86::JMP64m;

387 break;

388 case X86::TAILJMPr64_REX:

389 Opcode = X86::JMP64r_REX;

390 break;

391 case X86::TAILJMPm64_REX:

392 Opcode = X86::JMP64m_REX;

393 break;

394 case X86::TAILJMPd:

395 case X86::TAILJMPd64:

396 Opcode = X86::JMP_1;

397 break;

398 case X86::TAILJMPd_CC:

399 case X86::TAILJMPd64_CC:

400 Opcode = X86::JCC_1;

401 break;

402 }

403

404 return Opcode;

405}

406

409

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

413

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

421 return;

422

423

425 case X86::LEA64_32r:

426 case X86::LEA64r:

427 case X86::LEA16r:

428 case X86::LEA32r:

429

431 "Unexpected # of LEA operands");

433 "LEA has segment specified!");

434 break;

435 case X86::MULX32Hrr:

436 case X86::MULX32Hrm:

437 case X86::MULX64Hrr:

438 case X86::MULX64Hrm: {

439

440 unsigned NewOpc;

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

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

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

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

447 }

449

452 break;

453 }

454

455

456

457

458 case X86::CALL64r:

459 case X86::CALL64pcrel32:

461 break;

462 case X86::EH_RETURN:

463 case X86::EH_RETURN64: {

466 break;

467 }

468 case X86::CLEANUPRET: {

469

472 break;

473 }

474 case X86::CATCHRET: {

475

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

481 break;

482 }

483

484

485 case X86::TAILJMPr:

486 case X86::TAILJMPr64:

487 case X86::TAILJMPr64_REX:

488 case X86::TAILJMPd:

489 case X86::TAILJMPd64:

492 break;

493 case X86::TAILJMPd_CC:

494 case X86::TAILJMPd64_CC:

497 break;

498 case X86::TAILJMPm:

499 case X86::TAILJMPm64:

500 case X86::TAILJMPm64_REX:

502 "Unexpected number of operands!");

504 break;

505 case X86::MASKMOVDQU:

506 case X86::VMASKMOVDQU:

507 if (In64BitMode)

509 break;

510 case X86::BSF16rm:

511 case X86::BSF16rr:

512 case X86::BSF32rm:

513 case X86::BSF32rr:

514 case X86::BSF64rm:

515 case X86::BSF64rr: {

516

517

518

519

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

522 if (!MF.getFunction().hasOptSize() && FlagDef && FlagDef->isDead())

524 break;

525 }

526 default:

527 break;

528 }

529}

530

531void X86AsmPrinter::LowerTlsAddr(X86MCInstLower &MCInstLowering,

537

539 switch (MI.getOpcode()) {

540 case X86::TLS_addr32:

541 case X86::TLS_addr64:

542 case X86::TLS_addrX32:

544 break;

545 case X86::TLS_base_addr32:

547 break;

548 case X86::TLS_base_addr64:

549 case X86::TLS_base_addrX32:

551 break;

552 case X86::TLS_desc32:

553 case X86::TLS_desc64:

555 break;

556 default:

558 }

559

561 MCInstLowering.GetSymbolFromOperand(MI.getOperand(3)), SRVK, Ctx);

562

563

564

565

566

567

570

573 MCInstLowering.GetSymbolFromOperand(MI.getOperand(3)),

575 EmitAndCountInstruction(

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

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

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

579 .addImm(1)

580 .addReg(0)

581 .addExpr(Sym)

582 .addReg(0));

583 EmitAndCountInstruction(

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

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

586 .addImm(1)

587 .addReg(0)

588 .addExpr(Expr)

589 .addReg(0));

590 } else if (Is64Bits) {

592 if (NeedsPadding && Is64BitsLP64)

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

594 EmitAndCountInstruction(MCInstBuilder(X86::LEA64r)

595 .addReg(X86::RDI)

596 .addReg(X86::RIP)

597 .addImm(1)

598 .addReg(0)

599 .addExpr(Sym)

600 .addReg(0));

602 if (NeedsPadding) {

603 if (!UseGot)

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

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

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

607 }

608 if (UseGot) {

611 EmitAndCountInstruction(MCInstBuilder(X86::CALL64m)

612 .addReg(X86::RIP)

613 .addImm(1)

614 .addReg(0)

615 .addExpr(Expr)

616 .addReg(0));

617 } else {

618 EmitAndCountInstruction(

622 }

623 } else {

625 EmitAndCountInstruction(MCInstBuilder(X86::LEA32r)

626 .addReg(X86::EAX)

627 .addReg(0)

628 .addImm(1)

629 .addReg(X86::EBX)

630 .addExpr(Sym)

631 .addReg(0));

632 } else {

633 EmitAndCountInstruction(MCInstBuilder(X86::LEA32r)

634 .addReg(X86::EAX)

635 .addReg(X86::EBX)

636 .addImm(1)

637 .addReg(0)

638 .addExpr(Sym)

639 .addReg(0));

640 }

641

643 if (UseGot) {

646 EmitAndCountInstruction(MCInstBuilder(X86::CALL32m)

647 .addReg(X86::EBX)

648 .addImm(1)

649 .addReg(0)

650 .addExpr(Expr)

651 .addReg(0));

652 } else {

653 EmitAndCountInstruction(

657 }

658 }

659}

660

661

662

665

666

667

668 unsigned MaxNopLength = 1;

669 if (Subtarget->is64Bit()) {

670

671

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

673 MaxNopLength = 7;

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

675 MaxNopLength = 15;

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

677 MaxNopLength = 11;

678 else

679 MaxNopLength = 10;

680 } if (Subtarget->is32Bit())

681 MaxNopLength = 2;

682

683

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

685

686 unsigned NopSize;

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

688 IndexReg = Displacement = SegmentReg = 0;

689 BaseReg = X86::RAX;

690 ScaleVal = 1;

691 switch (NumBytes) {

692 case 0:

694 break;

695 case 1:

696 NopSize = 1;

697 Opc = X86::NOOP;

698 break;

699 case 2:

700 NopSize = 2;

701 Opc = X86::XCHG16ar;

702 break;

703 case 3:

704 NopSize = 3;

705 Opc = X86::NOOPL;

706 break;

707 case 4:

708 NopSize = 4;

709 Opc = X86::NOOPL;

710 Displacement = 8;

711 break;

712 case 5:

713 NopSize = 5;

714 Opc = X86::NOOPL;

715 Displacement = 8;

716 IndexReg = X86::RAX;

717 break;

718 case 6:

719 NopSize = 6;

720 Opc = X86::NOOPW;

721 Displacement = 8;

722 IndexReg = X86::RAX;

723 break;

724 case 7:

725 NopSize = 7;

726 Opc = X86::NOOPL;

727 Displacement = 512;

728 break;

729 case 8:

730 NopSize = 8;

731 Opc = X86::NOOPL;

732 Displacement = 512;

733 IndexReg = X86::RAX;

734 break;

735 case 9:

736 NopSize = 9;

737 Opc = X86::NOOPW;

738 Displacement = 512;

739 IndexReg = X86::RAX;

740 break;

741 default:

742 NopSize = 10;

743 Opc = X86::NOOPW;

744 Displacement = 512;

745 IndexReg = X86::RAX;

746 SegmentReg = X86::CS;

747 break;

748 }

749

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

751 NopSize += NumPrefixes;

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

753 OS.emitBytes("\x66");

754

755 switch (Opc) {

757 case X86::NOOP:

759 break;

760 case X86::XCHG16ar:

761 OS.emitInstruction(MCInstBuilder(Opc).addReg(X86::AX).addReg(X86::AX),

762 *Subtarget);

763 break;

764 case X86::NOOPL:

765 case X86::NOOPW:

767 .addReg(BaseReg)

768 .addImm(ScaleVal)

769 .addReg(IndexReg)

770 .addImm(Displacement)

771 .addReg(SegmentReg),

772 *Subtarget);

773 break;

774 }

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

776 return NopSize;

777}

778

779

782 unsigned NopsToEmit = NumBytes;

783 (void)NopsToEmit;

784 while (NumBytes) {

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

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

787 }

788}

789

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

791 X86MCInstLower &MCIL) {

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

793

795

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

799 } else {

800

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

803 unsigned CallOpcode;

804 switch (CallTarget.getType()) {

807 CallTargetMCOp = MCIL.LowerSymbolOperand(

808 CallTarget, MCIL.GetSymbolFromOperand(CallTarget));

809 CallOpcode = X86::CALL64pcrel32;

810

811

812

813

814 break;

817 CallOpcode = X86::CALL64pcrel32;

818

819

820

821

822 break;

824

827 "yet implemented.");

829 CallOpcode = X86::CALL64r;

830 break;

831 default:

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

833 break;

834 }

835

836

838 CallInst.setOpcode(CallOpcode);

839 CallInst.addOperand(CallTargetMCOp);

841 }

842

843

844

849}

850

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

852 X86MCInstLower &MCIL) {

853

854

855

857

863 unsigned OperandsBeginIdx = 4;

864

868

871

873 MI.setOpcode(Opcode);

874

875 if (DefRegister != X86::NoRegister)

877

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

881 MI.addOperand(Op);

882

885}

886

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

888 X86MCInstLower &MCIL) {

889 bool Is64Bits = Subtarget->is64Bit();

894

895 EmitAndCountInstruction(

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

897 .addExpr(Op));

898}

899

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

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

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

903

904

905

906

907

909 int64_t PrefixNops = 0;

914

915

916

917

918

919

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

922

923

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

925 EmitAndCountInstruction(

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

927 EmitAndCountInstruction(MCInstBuilder(X86::ADD32rm)

928 .addReg(X86::NoRegister)

929 .addReg(TempReg)

930 .addReg(AddrReg)

931 .addImm(1)

932 .addReg(X86::NoRegister)

933 .addImm(-(PrefixNops + 4))

934 .addReg(X86::NoRegister));

935

937 EmitAndCountInstruction(

941

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

947}

948

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

950

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

953 return;

954 }

955

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

958

960 int MappingScale;

961 bool OrShadowOffset;

963 AccessInfo.CompileKernel, &ShadowBase,

964 &MappingScale, &OrShadowOffset);

965

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

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

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

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

971 .str();

972 if (OrShadowOffset)

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

975

976 EmitAndCountInstruction(

980}

981

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

983 X86MCInstLower &MCIL) {

984

985

987

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

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

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

991

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

994

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

996

997

998

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

1001

1004 }

1005

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

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

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

1010

1011

1012

1013

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

1016 *Subtarget);

1017 } else {

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

1020 (void)NopSize;

1021 }

1022 }

1023}

1024

1025

1026

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

1029

1033

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

1036 SMShadowTracker.reset(NumShadowBytes);

1037}

1038

1039

1040

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

1042 X86MCInstLower &MCIL) {

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

1044

1046

1048

1053

1055 unsigned ScratchIdx = opers.getNextScratchIdx();

1056 unsigned EncodedBytes = 0;

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

1058

1059

1060

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

1063 switch (CalleeMO.getType()) {

1064 default:

1065

1068 if (CalleeMO.getImm())

1070 break;

1073 CalleeMCOp = MCIL.LowerSymbolOperand(CalleeMO,

1074 MCIL.GetSymbolFromOperand(CalleeMO));

1075 break;

1076 }

1077

1078

1079

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

1082 EncodedBytes = 13;

1083 else

1084 EncodedBytes = 12;

1085

1086 EmitAndCountInstruction(

1088

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

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

1093 }

1094

1095

1096 unsigned NumBytes = opers.getNumPatchBytes();

1097 assert(NumBytes >= EncodedBytes &&

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

1099

1101}

1102

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

1104 X86MCInstLower &MCIL) {

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

1106

1108

1109

1110

1111

1112

1113

1114

1115

1116

1117

1118

1119

1120

1121

1122

1123

1124

1125

1126

1127

1128

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

1133

1134

1135

1136

1137 OutStreamer->emitBinaryData("\xeb\x0f");

1138

1139

1140

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

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

1143

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

1145

1146

1147

1148

1149

1150

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

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

1153 Op.isValid()) {

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

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

1158 UsedMask[I] = true;

1159 EmitAndCountInstruction(

1161 } else {

1163 }

1164 }

1165

1166

1167

1168

1169

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

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

1172 EmitAndCountInstruction(

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

1174

1175

1176

1181

1182

1183 EmitAndCountInstruction(MCInstBuilder(X86::CALL64pcrel32)

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

1185

1186

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

1188 if (UsedMask[I])

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

1190 else

1192

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

1194

1195

1196

1197

1199}

1200

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

1202 X86MCInstLower &MCIL) {

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

1204

1206

1207

1208

1209

1210

1211

1212

1213

1214

1215

1216

1217

1218

1219

1220

1221

1222

1223

1224

1225

1226

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

1231

1232

1233

1234

1235 OutStreamer->emitBinaryData("\xeb\x14");

1236

1237

1238

1239

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

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

1242

1243

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

1245

1246

1247

1248

1249

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

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

1252 Op.isValid()) {

1253

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

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

1258 UsedMask[I] = true;

1259 EmitAndCountInstruction(

1261 } else {

1263 }

1264 }

1265

1266

1267

1268

1269

1270

1271

1272

1273

1274

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

1276 if (UsedMask[I])

1277 EmitAndCountInstruction(

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

1279

1280

1281

1286

1287

1288 EmitAndCountInstruction(MCInstBuilder(X86::CALL64pcrel32)

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

1290

1291

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

1293 if (UsedMask[I])

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

1295 else

1297

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

1299

1300

1302}

1303

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

1305 X86MCInstLower &MCIL) {

1306

1308

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

1311 unsigned Num;

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

1313 .getValueAsString()

1314 .getAsInteger(10, Num))

1315 return;

1317 return;

1318 }

1319

1320

1321

1322

1323

1324

1325

1326

1327

1328

1329

1330

1331

1335

1336

1337

1338

1342}

1343

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

1345 X86MCInstLower &MCIL) {

1347

1348

1349

1350

1351

1352

1353

1354

1355

1356

1357

1358

1359

1360

1361

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

1367 Ret.setOpcode(OpCode);

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

1370 Ret.addOperand(Op);

1374}

1375

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

1377 X86MCInstLower &MCIL) {

1380

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

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

1384 if (IsConditional) {

1385

1386

1387

1388

1389

1390

1391

1392

1393

1394

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

1403

1404 TCOperands = drop_end(TCOperands);

1405 }

1406

1408

1409

1410

1411

1412

1413

1414

1419

1420

1421

1422

1427

1428

1429

1431 for (auto &MO : TCOperands)

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

1435

1436 if (IsConditional)

1437 OutStreamer->emitLabel(FallthroughLabel);

1438}

1439

1440

1441

1450 }

1452 return MBBI;

1453}

1454

1457

1458 ++SrcIdx;

1460

1461 ++SrcIdx;

1462 }

1463 }

1464 return SrcIdx;

1465}

1466

1468 unsigned SrcOpIdx) {

1471

1472

1473

1474

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

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

1480 CS << " {z}";

1481 }

1482 }

1483}

1484

1487

1489 if (Src1Name == Src2Name)

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

1491 if (ShuffleMask[i] >= e)

1492 ShuffleMask[i] -= e;

1493

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

1495 if (i != 0)

1496 CS << ",";

1498 CS << "zero";

1499 continue;

1500 }

1501

1502

1503

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

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

1506

1507 bool IsFirst = true;

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

1510 if (!IsFirst)

1511 CS << ',';

1512 else

1513 IsFirst = false;

1515 CS << "u";

1516 else

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

1518 ++i;

1519 }

1520 CS << ']';

1521 --i;

1522 }

1523}

1524

1527 std::string Comment;

1528

1533 : "mem";

1536 : "mem";

1537

1540 CS << " = ";

1542

1543 return Comment;

1544}

1545

1547 bool PrintZero = false) {

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

1550 } else {

1551

1552 CS << "(";

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

1554 if (i > 0)

1555 CS << ",";

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

1557 }

1558 CS << ")";

1559 }

1560}

1561

1563 bool PrintZero = false) {

1565

1566 if (PrintZero)

1568 else

1569 Flt.toString(Str, 0, 0);

1570 CS << Str;

1571}

1572

1574 raw_ostream &CS, bool PrintZero = false) {

1575 if (isa(COp)) {

1576 CS << "u";

1577 } else if (auto *CI = dyn_cast(COp)) {

1579 } else if (auto *CF = dyn_cast(COp)) {

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

1581 } else if (auto *CDS = dyn_cast(COp)) {

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

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

1587 assert((BitWidth % EltBits) == 0 && "Element size mismatch");

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

1589 if (I != 0)

1590 CS << ",";

1591 if (IsInteger)

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

1593 else if (IsFP)

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

1595 else

1596 CS << "?";

1597 }

1598 } else if (auto *CV = dyn_cast(COp)) {

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

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

1601 assert((BitWidth % EltBits) == 0 && "Element size mismatch");

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

1603 if (I != 0)

1604 CS << ",";

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

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)) {

1662 if (auto *CDS = dyn_cast(C)) {

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?");

1714 "SEH_ instruction Windows and UEFI only");

1715

1716

1717 if (EmitFPOData) {

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:

1752 OutStreamer->emitWinCFIPushReg(MI->getOperand(0).getImm());

1753 break;

1754

1755 case X86::SEH_SaveReg:

1756 OutStreamer->emitWinCFISaveReg(MI->getOperand(0).getImm(),

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

1758 break;

1759

1760 case X86::SEH_SaveXMM:

1761 OutStreamer->emitWinCFISaveXMM(MI->getOperand(0).getImm(),

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

1763 break;

1764

1765 case X86::SEH_StackAlloc:

1766 OutStreamer->emitWinCFIAllocStack(MI->getOperand(0).getImm());

1767 break;

1768

1769 case X86::SEH_SetFrame:

1770 OutStreamer->emitWinCFISetFrame(MI->getOperand(0).getImm(),

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

1772 break;

1773

1774 case X86::SEH_PushFrame:

1775 OutStreamer->emitWinCFIPushFrame(MI->getOperand(0).getImm());

1776 break;

1777

1778 case X86::SEH_EndPrologue:

1780 break;

1781

1782 default:

1784 }

1785}

1786

1789 switch (MI->getOpcode()) {

1790

1791

1792

1793 case X86::PSHUFBrm:

1794 case X86::VPSHUFBrm:

1795 case X86::VPSHUFBYrm:

1796 case X86::VPSHUFBZ128rm:

1797 case X86::VPSHUFBZ128rmk:

1798 case X86::VPSHUFBZ128rmkz:

1799 case X86::VPSHUFBZ256rm:

1800 case X86::VPSHUFBZ256rmk:

1801 case X86::VPSHUFBZ256rmkz:

1802 case X86::VPSHUFBZrm:

1803 case X86::VPSHUFBZrmk:

1804 case X86::VPSHUFBZrmkz: {

1810 if (!Mask.empty())

1812 }

1813 break;

1814 }

1815

1816 case X86::VPERMILPSrm:

1817 case X86::VPERMILPSYrm:

1818 case X86::VPERMILPSZ128rm:

1819 case X86::VPERMILPSZ128rmk:

1820 case X86::VPERMILPSZ128rmkz:

1821 case X86::VPERMILPSZ256rm:

1822 case X86::VPERMILPSZ256rmk:

1823 case X86::VPERMILPSZ256rmkz:

1824 case X86::VPERMILPSZrm:

1825 case X86::VPERMILPSZrmk:

1826 case X86::VPERMILPSZrmkz: {

1832 if (!Mask.empty())

1834 }

1835 break;

1836 }

1837 case X86::VPERMILPDrm:

1838 case X86::VPERMILPDYrm:

1839 case X86::VPERMILPDZ128rm:

1840 case X86::VPERMILPDZ128rmk:

1841 case X86::VPERMILPDZ128rmkz:

1842 case X86::VPERMILPDZ256rm:

1843 case X86::VPERMILPDZ256rmk:

1844 case X86::VPERMILPDZ256rmkz:

1845 case X86::VPERMILPDZrm:

1846 case X86::VPERMILPDZrmk:

1847 case X86::VPERMILPDZrmkz: {

1853 if (!Mask.empty())

1855 }

1856 break;

1857 }

1858

1859 case X86::VPERMIL2PDrm:

1860 case X86::VPERMIL2PSrm:

1861 case X86::VPERMIL2PDYrm:

1862 case X86::VPERMIL2PSYrm: {

1864 "Unexpected number of operands!");

1865

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

1867 if (!CtrlOp.isImm())

1868 break;

1869

1870 unsigned ElSize;

1871 switch (MI->getOpcode()) {

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

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

1875 }

1876

1881 if (!Mask.empty())

1883 }

1884 break;

1885 }

1886

1887 case X86::VPPERMrrm: {

1892 if (!Mask.empty())

1894 }

1895 break;

1896 }

1897

1898 case X86::MMX_MOVQ64rm: {

1900 std::string Comment;

1904 if (auto *CF = dyn_cast(C)) {

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

1907 }

1908 }

1909 break;

1910 }

1911

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

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

1914

1915#define CASE_ARITH_RM(Instr) \

1916 INSTR_CASE(, Instr, , ) \

1917 INSTR_CASE(V, Instr, , ) \

1918 INSTR_CASE(V, Instr, Y, ) \

1919 INSTR_CASE(V, Instr, Z128, ) \

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

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

1922 INSTR_CASE(V, Instr, Z256, ) \

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

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

1925 INSTR_CASE(V, Instr, Z, ) \

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

1927 INSTR_CASE(V, Instr, Z, kz)

1928

1929

1933 if (C->getType()->getScalarSizeInBits() == 8) {

1934 std::string Comment;

1936 unsigned VectorWidth =

1938 CS << "[";

1940 CS << "]";

1942 }

1943 }

1944 break;

1945 }

1946

1954 if (C->getType()->getScalarSizeInBits() == 16) {

1955 std::string Comment;

1957 unsigned VectorWidth =

1959 CS << "[";

1961 CS << "]";

1963 }

1964 }

1965 break;

1966 }

1967

1968#define MASK_AVX512_CASE(Instr) \

1969 case Instr: \

1970 case Instr##k: \

1971 case Instr##kz:

1972

1973 case X86::MOVSDrm:

1974 case X86::VMOVSDrm:

1976 case X86::MOVSDrm_alt:

1977 case X86::VMOVSDrm_alt:

1978 case X86::VMOVSDZrm_alt:

1979 case X86::MOVQI2PQIrm:

1980 case X86::VMOVQI2PQIrm:

1981 case X86::VMOVQI2PQIZrm:

1983 break;

1984

1986 case X86::VMOVSHZrm_alt:

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

1989 break;

1990

1991 case X86::MOVSSrm:

1992 case X86::VMOVSSrm:

1994 case X86::MOVSSrm_alt:

1995 case X86::VMOVSSrm_alt:

1996 case X86::VMOVSSZrm_alt:

1997 case X86::MOVDI2PDIrm:

1998 case X86::VMOVDI2PDIrm:

1999 case X86::VMOVDI2PDIZrm:

2001 break;

2002

2003#define MOV_CASE(Prefix, Suffix) \

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

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

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

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

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

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

2010

2011#define MOV_AVX512_CASE(Suffix, Postfix) \

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

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

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

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

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

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

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

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

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

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

2022

2023#define CASE_128_MOV_RM() \

2024 MOV_CASE(, ) \

2025 MOV_CASE(V, ) \

2026 MOV_AVX512_CASE(Z128, ) \

2027 MOV_AVX512_CASE(Z128, k) \

2028 MOV_AVX512_CASE(Z128, kz)

2029

2030#define CASE_256_MOV_RM() \

2031 MOV_CASE(V, Y) \

2032 MOV_AVX512_CASE(Z256, ) \

2033 MOV_AVX512_CASE(Z256, k) \

2034 MOV_AVX512_CASE(Z256, kz) \

2035

2036#define CASE_512_MOV_RM() \

2037 MOV_AVX512_CASE(Z, ) \

2038 MOV_AVX512_CASE(Z, k) \

2039 MOV_AVX512_CASE(Z, kz) \

2040

2041

2042

2045 break;

2048 break;

2051 break;

2052 case X86::VBROADCASTF128rm:

2053 case X86::VBROADCASTI128rm:

2059 break;

2065 break;

2071 break;

2072

2073

2074

2075 case X86::MOVDDUPrm:

2076 case X86::VMOVDDUPrm:

2078 case X86::VPBROADCASTQrm:

2081 break;

2082 case X86::VBROADCASTSDYrm:

2084 case X86::VPBROADCASTQYrm:

2087 break;

2091 break;

2092 case X86::VBROADCASTSSrm:

2094 case X86::VPBROADCASTDrm:

2097 break;

2098 case X86::VBROADCASTSSYrm:

2100 case X86::VPBROADCASTDYrm:

2103 break;

2107 break;

2108 case X86::VPBROADCASTWrm:

2111 break;

2112 case X86::VPBROADCASTWYrm:

2115 break;

2118 break;

2119 case X86::VPBROADCASTBrm:

2122 break;

2123 case X86::VPBROADCASTBYrm:

2126 break;

2129 break;

2130

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

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

2133

2134#define CASE_MOVX_RM(Ext, Type) \

2135 MOVX_CASE(, Ext, Type, , ) \

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

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

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

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

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

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

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

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

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

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

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

2147

2150 break;

2153 break;

2156 break;

2159 break;

2162 break;

2165 break;

2166

2169 break;

2172 break;

2175 break;

2178 break;

2181 break;

2184 break;

2185 }

2186}

2187

2189

2190

2191

2192

2193 X86MCInstLower MCInstLowering(*MF, *this);

2196

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

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

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

2200 "swift_async_extendedFramePointerFlags") {

2201 ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags = true;

2202 }

2203 }

2204 }

2205

2206

2209

2210

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

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

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

2218 }

2219

2220 switch (MI->getOpcode()) {

2221 case TargetOpcode::DBG_VALUE:

2223

2224 case X86::EH_RETURN:

2225 case X86::EH_RETURN64: {

2226

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

2230 break;

2231 }

2232 case X86::CLEANUPRET: {

2233

2235 break;

2236 }

2237

2238 case X86::CATCHRET: {

2239

2241 break;

2242 }

2243

2244 case X86::ENDBR32:

2245 case X86::ENDBR64: {

2246

2247

2248

2249

2254 MCInstLowering.Lower(MI, Inst);

2255 EmitAndCountInstruction(Inst);

2258 return;

2259 }

2260 break;

2261 }

2262

2263 case X86::TAILJMPd64:

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

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

2266 [[fallthrough]];

2267 case X86::TAILJMPr:

2268 case X86::TAILJMPm:

2269 case X86::TAILJMPd:

2270 case X86::TAILJMPd_CC:

2271 case X86::TAILJMPr64:

2272 case X86::TAILJMPm64:

2273 case X86::TAILJMPd64_CC:

2274 case X86::TAILJMPr64_REX:

2275 case X86::TAILJMPm64_REX:

2276

2278 break;

2279

2280 case X86::TLS_addr32:

2281 case X86::TLS_addr64:

2282 case X86::TLS_addrX32:

2283 case X86::TLS_base_addr32:

2284 case X86::TLS_base_addr64:

2285 case X86::TLS_base_addrX32:

2286 case X86::TLS_desc32:

2287 case X86::TLS_desc64:

2288 return LowerTlsAddr(MCInstLowering, *MI);

2289

2290 case X86::MOVPC32r: {

2291

2292

2293

2294

2295

2296

2297

2299

2300

2301 EmitAndCountInstruction(

2304

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

2308

2309

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

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

2312

2314

2315 if (HasActiveDwarfFrame && !hasFP) {

2316 OutStreamer->emitCFIAdjustCfaOffset(-stackGrowth);

2318 }

2319

2320

2322

2323

2324 EmitAndCountInstruction(

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

2326

2327 if (HasActiveDwarfFrame && !hasFP) {

2328 OutStreamer->emitCFIAdjustCfaOffset(stackGrowth);

2329 }

2330 return;

2331 }

2332

2333 case X86::ADD32ri: {

2334

2336 break;

2337

2338

2339

2340

2341

2342

2343

2344

2347

2348

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

2350

2352 const MCExpr *PICBase =

2355

2358

2359 EmitAndCountInstruction(MCInstBuilder(X86::ADD32ri)

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

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

2363 return;

2364 }

2365 case TargetOpcode::STATEPOINT:

2366 return LowerSTATEPOINT(*MI, MCInstLowering);

2367

2368 case TargetOpcode::FAULTING_OP:

2369 return LowerFAULTING_OP(*MI, MCInstLowering);

2370

2371 case TargetOpcode::FENTRY_CALL:

2372 return LowerFENTRY_CALL(*MI, MCInstLowering);

2373

2374 case TargetOpcode::PATCHABLE_OP:

2375 return LowerPATCHABLE_OP(*MI, MCInstLowering);

2376

2377 case TargetOpcode::STACKMAP:

2378 return LowerSTACKMAP(*MI);

2379

2380 case TargetOpcode::PATCHPOINT:

2381 return LowerPATCHPOINT(*MI, MCInstLowering);

2382

2383 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:

2384 return LowerPATCHABLE_FUNCTION_ENTER(*MI, MCInstLowering);

2385

2386 case TargetOpcode::PATCHABLE_RET:

2387 return LowerPATCHABLE_RET(*MI, MCInstLowering);

2388

2389 case TargetOpcode::PATCHABLE_TAIL_CALL:

2390 return LowerPATCHABLE_TAIL_CALL(*MI, MCInstLowering);

2391

2392 case TargetOpcode::PATCHABLE_EVENT_CALL:

2393 return LowerPATCHABLE_EVENT_CALL(*MI, MCInstLowering);

2394

2395 case TargetOpcode::PATCHABLE_TYPED_EVENT_CALL:

2396 return LowerPATCHABLE_TYPED_EVENT_CALL(*MI, MCInstLowering);

2397

2398 case X86::MORESTACK_RET:

2400 return;

2401

2402 case X86::KCFI_CHECK:

2403 return LowerKCFI_CHECK(*MI);

2404

2405 case X86::ASAN_CHECK_MEMACCESS:

2406 return LowerASAN_CHECK_MEMACCESS(*MI);

2407

2408 case X86::MORESTACK_RET_RESTORE_R10:

2409

2411 EmitAndCountInstruction(

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

2413 return;

2414

2415 case X86::SEH_PushReg:

2416 case X86::SEH_SaveReg:

2417 case X86::SEH_SaveXMM:

2418 case X86::SEH_StackAlloc:

2419 case X86::SEH_StackAlign:

2420 case X86::SEH_SetFrame:

2421 case X86::SEH_PushFrame:

2422 case X86::SEH_EndPrologue:

2423 EmitSEHInstruction(MI);

2424 return;

2425

2426 case X86::SEH_Epilogue: {

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

2429

2433

2434

2435

2436 if (MBBI->isCall() || MBBI->isPseudo()) {

2437 if (MBBI->isCall())

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

2439 break;

2440 }

2441 }

2442 return;

2443 }

2444 case X86::UBSAN_UD1:

2445 EmitAndCountInstruction(MCInstBuilder(X86::UD1Lm)

2446 .addReg(X86::EAX)

2447 .addReg(X86::EAX)

2448 .addImm(1)

2449 .addReg(X86::NoRegister)

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

2451 .addReg(X86::NoRegister));

2452 return;

2453 case X86::CALL64pcrel32:

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

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

2456 break;

2457 case X86::JCC_1:

2458

2459

2460

2463 &getAnalysis().getMBPI();

2468 if (EdgeProb > Threshold)

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

2470 }

2471 break;

2472 }

2473

2475 MCInstLowering.Lower(MI, TmpInst);

2476

2477

2478

2479

2480

2481 if (MI->isCall()) {

2482

2483 SMShadowTracker.count(TmpInst, getSubtargetInfo(), CodeEmitter.get());

2484

2485

2487

2489 return;

2490 }

2491

2492 EmitAndCountInstruction(TmpInst);

2493}

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

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

MachineBasicBlock MachineBasicBlock::iterator MBBI

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

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

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This file defines the SmallString class.

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

static void printShuffleMask(raw_ostream &CS, StringRef Src1Name, StringRef Src2Name, ArrayRef< int > Mask)

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

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

static unsigned getRetOpcode(const X86Subtarget &Subtarget)

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

static unsigned convertTailJumpOpcode(unsigned Opcode)

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

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

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

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

#define MASK_AVX512_CASE(Instr)

#define CASE_ARITH_RM(Instr)

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

#define CASE_256_MOV_RM()

static MachineBasicBlock::const_iterator PrevCrossBBInst(MachineBasicBlock::const_iterator MBBI)

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

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

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

#define CASE_MOVX_RM(Ext, Type)

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)

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

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

#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

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

Factory for Positive and Negative Zero.

Class for arbitrary precision integers.

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.

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

void EmitToStreamer(MCStreamer &S, const MCInst &Inst)

TargetMachine & TM

Target machine description.

virtual MCSymbol * GetCPISymbol(unsigned CPID) const

Return the symbol for the specified constant pool entry.

void emitKCFITrapEntry(const MachineFunction &MF, const MCSymbol *Symbol)

MachineFunction * MF

The current machine function.

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

Return the symbol for the specified jump table entry.

void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind, uint8_t Version=0)

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

bool isPositionIndependent() 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.

StringRef getValueAsString() const

Return the attribute's value as a string.

This class represents a function call, abstracting a target machine's calling convention.

This is an important base class in LLVM.

This class represents an Operation in the Expression.

A parsed version of the target data layout string in and methods for querying it.

void recordFaultingOp(FaultKind FaultTy, const MCSymbol *FaultingLabel, const MCSymbol *HandlerLabel)

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

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

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 const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

Context object for machine code objects.

MCSymbol * createTempSymbol()

Create a temporary symbol with a unique name.

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.

const char * getName(MCRegister RegNo) const

Return the human-readable symbolic target-specific name for the specified physical register.

Streaming machine code generation interface.

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

Add a textual comment.

virtual void emitRawComment(const Twine &T, bool TabPrefix=true)

Print T and prefix it with the comment string (normally #) and optionally a tab.

void setAllowAutoPadding(bool v)

bool getAllowAutoPadding() const

Generic base class for all target subtargets.

Represent a reference to a symbol from inside an expression.

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

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.

MachineInstrBundleIterator< const MachineInstr > const_iterator

MCSymbol * getSymbol() const

Return the MCSymbol for this basic block.

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

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

MCSymbol * getPICBaseSymbol() const

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

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

Function & getFunction()

Return the LLVM function that this machine code represents.

Ty * getInfo()

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

const MachineBasicBlock & front() const

Representation of each machine instruction.

iterator_range< mop_iterator > operands()

const MachineOperand & getOperand(unsigned i) const

MachineModuleInfoCOFF - This is a MachineModuleInfoImpl implementation for COFF targets.

StubValueTy & getGVStubEntry(MCSymbol *Sym)

PointerIntPair< MCSymbol *, 1, bool > StubValueTy

MachineModuleInfoMachO - This is a MachineModuleInfoImpl implementation for MachO targets.

const Module * getModule() const

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.

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

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

bool getRtLibUseGOT() const

Returns true if PLT should be avoided for RTLib calls.

Pass interface - Implemented by all 'passes'.

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

print - Print out the internal state of the pass.

MI-level patchpoint operands.

PointerIntPair - This class implements a pair of a pointer and small integer.

PointerTy getPointer() const

Wrapper class representing virtual and physical registers.

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.

void recordStatepoint(const MCSymbol &L, const MachineInstr &MI)

Generate a stackmap record for a statepoint instruction.

void recordPatchPoint(const MCSymbol &L, const MachineInstr &MI)

Generate a stackmap record for a patchpoint instruction.

void recordStackMap(const MCSymbol &L, const MachineInstr &MI)

Generate a stackmap record for a stackmap instruction.

MI-level Statepoint operands.

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

const MCRegisterInfo * getMCRegisterInfo() const

MCTargetOptions MCOptions

Machine level options.

Target - Wrapper for Target specific information.

Triple - Helper class for working with autoconf configuration names.

bool isUEFI() const

Tests whether the OS is UEFI.

bool isOSBinFormatELF() const

Tests whether the OS uses the ELF binary format.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

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.

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.

TypeSize getPrimitiveSizeInBits() const LLVM_READONLY

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

static const char * getRegisterName(MCRegister Reg)

void emitInstruction(const MachineInstr *MI) override

Targets should implement this to emit instructions.

const X86Subtarget & getSubtarget() const

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

unsigned getSlotSize() const

bool isTargetWindowsMSVC() const

bool isTarget64BitLP64() const

Is this x86_64 with the LP64 programming model (standard AMD64, no x32)?

bool useIndirectThunkCalls() const

X86 target streamer implementing x86-only assembly directives.

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.

@ C

The default llvm calling convention, compatible with C.

Reg

All possible values of the reg field in the ModR/M byte.

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.

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

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.

void report_fatal_error(Error Err, bool gen_crash_diag=true)

Report a serious error, calling any installed error handler.

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.

constexpr unsigned BitWidth

const char * toString(DWARFSectionKind Kind)

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.

A RAII helper which defines a region of instructions which can't have padding added between them for ...

void changeAndComment(bool b)

NoAutoPaddingScope(MCStreamer &OS)

const bool OldAllowAutoPadding

This struct is a compact representation of a valid (non-zero power of two) alignment.