xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp (revision 52418fc2be8efa5172b90a3a9e617017173612c4)
10b57cec5SDimitry Andric //===-- X86AsmBackend.cpp - X86 Assembler Backend -------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "MCTargetDesc/X86BaseInfo.h"
1006c3fb27SDimitry Andric #include "MCTargetDesc/X86EncodingOptimization.h"
110fca6ea1SDimitry Andric #include "MCTargetDesc/X86FixupKinds.h"
120b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
130b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h"
140b57cec5SDimitry Andric #include "llvm/BinaryFormat/MachO.h"
150b57cec5SDimitry Andric #include "llvm/MC/MCAsmBackend.h"
16480093f4SDimitry Andric #include "llvm/MC/MCAssembler.h"
175ffd83dbSDimitry Andric #include "llvm/MC/MCCodeEmitter.h"
18480093f4SDimitry Andric #include "llvm/MC/MCContext.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCDwarf.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCELFObjectWriter.h"
210fca6ea1SDimitry Andric #include "llvm/MC/MCELFStreamer.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
230b57cec5SDimitry Andric #include "llvm/MC/MCFixupKindInfo.h"
240b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
25480093f4SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
260b57cec5SDimitry Andric #include "llvm/MC/MCMachObjectWriter.h"
27480093f4SDimitry Andric #include "llvm/MC/MCObjectStreamer.h"
280b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h"
290b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
300b57cec5SDimitry Andric #include "llvm/MC/MCSectionMachO.h"
310b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
32480093f4SDimitry Andric #include "llvm/MC/MCValue.h"
33349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
34480093f4SDimitry Andric #include "llvm/Support/CommandLine.h"
350b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
360b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
37480093f4SDimitry Andric 
380b57cec5SDimitry Andric using namespace llvm;
390b57cec5SDimitry Andric 
40480093f4SDimitry Andric namespace {
41480093f4SDimitry Andric /// A wrapper for holding a mask of the values from X86::AlignBranchBoundaryKind
42480093f4SDimitry Andric class X86AlignBranchKind {
43480093f4SDimitry Andric private:
44480093f4SDimitry Andric   uint8_t AlignBranchKind = 0;
45480093f4SDimitry Andric 
46480093f4SDimitry Andric public:
47480093f4SDimitry Andric   void operator=(const std::string &Val) {
48480093f4SDimitry Andric     if (Val.empty())
49480093f4SDimitry Andric       return;
50480093f4SDimitry Andric     SmallVector<StringRef, 6> BranchTypes;
51480093f4SDimitry Andric     StringRef(Val).split(BranchTypes, '+', -1, false);
52480093f4SDimitry Andric     for (auto BranchType : BranchTypes) {
53480093f4SDimitry Andric       if (BranchType == "fused")
54480093f4SDimitry Andric         addKind(X86::AlignBranchFused);
55480093f4SDimitry Andric       else if (BranchType == "jcc")
56480093f4SDimitry Andric         addKind(X86::AlignBranchJcc);
57480093f4SDimitry Andric       else if (BranchType == "jmp")
58480093f4SDimitry Andric         addKind(X86::AlignBranchJmp);
59480093f4SDimitry Andric       else if (BranchType == "call")
60480093f4SDimitry Andric         addKind(X86::AlignBranchCall);
61480093f4SDimitry Andric       else if (BranchType == "ret")
62480093f4SDimitry Andric         addKind(X86::AlignBranchRet);
63480093f4SDimitry Andric       else if (BranchType == "indirect")
64480093f4SDimitry Andric         addKind(X86::AlignBranchIndirect);
65480093f4SDimitry Andric       else {
665ffd83dbSDimitry Andric         errs() << "invalid argument " << BranchType.str()
675ffd83dbSDimitry Andric                << " to -x86-align-branch=; each element must be one of: fused, "
685ffd83dbSDimitry Andric                   "jcc, jmp, call, ret, indirect.(plus separated)\n";
69480093f4SDimitry Andric       }
700b57cec5SDimitry Andric     }
710b57cec5SDimitry Andric   }
720b57cec5SDimitry Andric 
73480093f4SDimitry Andric   operator uint8_t() const { return AlignBranchKind; }
74480093f4SDimitry Andric   void addKind(X86::AlignBranchBoundaryKind Value) { AlignBranchKind |= Value; }
75480093f4SDimitry Andric };
76480093f4SDimitry Andric 
77480093f4SDimitry Andric X86AlignBranchKind X86AlignBranchKindLoc;
78480093f4SDimitry Andric 
79480093f4SDimitry Andric cl::opt<unsigned> X86AlignBranchBoundary(
80480093f4SDimitry Andric     "x86-align-branch-boundary", cl::init(0),
81480093f4SDimitry Andric     cl::desc(
82480093f4SDimitry Andric         "Control how the assembler should align branches with NOP. If the "
83480093f4SDimitry Andric         "boundary's size is not 0, it should be a power of 2 and no less "
84480093f4SDimitry Andric         "than 32. Branches will be aligned to prevent from being across or "
85480093f4SDimitry Andric         "against the boundary of specified size. The default value 0 does not "
86480093f4SDimitry Andric         "align branches."));
87480093f4SDimitry Andric 
88480093f4SDimitry Andric cl::opt<X86AlignBranchKind, true, cl::parser<std::string>> X86AlignBranch(
89480093f4SDimitry Andric     "x86-align-branch",
9013138422SDimitry Andric     cl::desc(
915ffd83dbSDimitry Andric         "Specify types of branches to align (plus separated list of types):"
925ffd83dbSDimitry Andric              "\njcc      indicates conditional jumps"
935ffd83dbSDimitry Andric              "\nfused    indicates fused conditional jumps"
945ffd83dbSDimitry Andric              "\njmp      indicates direct unconditional jumps"
955ffd83dbSDimitry Andric              "\ncall     indicates direct and indirect calls"
965ffd83dbSDimitry Andric              "\nret      indicates rets"
975ffd83dbSDimitry Andric              "\nindirect indicates indirect unconditional jumps"),
98480093f4SDimitry Andric     cl::location(X86AlignBranchKindLoc));
99480093f4SDimitry Andric 
100480093f4SDimitry Andric cl::opt<bool> X86AlignBranchWithin32BBoundaries(
101480093f4SDimitry Andric     "x86-branches-within-32B-boundaries", cl::init(false),
102480093f4SDimitry Andric     cl::desc(
103480093f4SDimitry Andric         "Align selected instructions to mitigate negative performance impact "
104480093f4SDimitry Andric         "of Intel's micro code update for errata skx102.  May break "
105480093f4SDimitry Andric         "assumptions about labels corresponding to particular instructions, "
106480093f4SDimitry Andric         "and should be used with caution."));
1070b57cec5SDimitry Andric 
1085ffd83dbSDimitry Andric cl::opt<unsigned> X86PadMaxPrefixSize(
1095ffd83dbSDimitry Andric     "x86-pad-max-prefix-size", cl::init(0),
1105ffd83dbSDimitry Andric     cl::desc("Maximum number of prefixes to use for padding"));
1115ffd83dbSDimitry Andric 
1125ffd83dbSDimitry Andric cl::opt<bool> X86PadForAlign(
113e8d8bef9SDimitry Andric     "x86-pad-for-align", cl::init(false), cl::Hidden,
1145ffd83dbSDimitry Andric     cl::desc("Pad previous instructions to implement align directives"));
1155ffd83dbSDimitry Andric 
1165ffd83dbSDimitry Andric cl::opt<bool> X86PadForBranchAlign(
1175ffd83dbSDimitry Andric     "x86-pad-for-branch-align", cl::init(true), cl::Hidden,
1185ffd83dbSDimitry Andric     cl::desc("Pad previous instructions to implement branch alignment"));
1195ffd83dbSDimitry Andric 
1200b57cec5SDimitry Andric class X86AsmBackend : public MCAsmBackend {
1210b57cec5SDimitry Andric   const MCSubtargetInfo &STI;
122480093f4SDimitry Andric   std::unique_ptr<const MCInstrInfo> MCII;
123480093f4SDimitry Andric   X86AlignBranchKind AlignBranchType;
124480093f4SDimitry Andric   Align AlignBoundary;
1255ffd83dbSDimitry Andric   unsigned TargetPrefixMax = 0;
126480093f4SDimitry Andric 
127480093f4SDimitry Andric   MCInst PrevInst;
1280fca6ea1SDimitry Andric   unsigned PrevInstOpcode = 0;
1295ffd83dbSDimitry Andric   MCBoundaryAlignFragment *PendingBA = nullptr;
1305ffd83dbSDimitry Andric   std::pair<MCFragment *, size_t> PrevInstPosition;
1310fca6ea1SDimitry Andric   bool IsRightAfterData = false;
1325ffd83dbSDimitry Andric 
1335ffd83dbSDimitry Andric   uint8_t determinePaddingPrefix(const MCInst &Inst) const;
1345ffd83dbSDimitry Andric   bool isMacroFused(const MCInst &Cmp, const MCInst &Jcc) const;
1355ffd83dbSDimitry Andric   bool needAlign(const MCInst &Inst) const;
1365ffd83dbSDimitry Andric   bool canPadBranches(MCObjectStreamer &OS) const;
1375ffd83dbSDimitry Andric   bool canPadInst(const MCInst &Inst, MCObjectStreamer &OS) const;
138480093f4SDimitry Andric 
1390b57cec5SDimitry Andric public:
1400b57cec5SDimitry Andric   X86AsmBackend(const Target &T, const MCSubtargetInfo &STI)
1415f757f3fSDimitry Andric       : MCAsmBackend(llvm::endianness::little), STI(STI),
142480093f4SDimitry Andric         MCII(T.createMCInstrInfo()) {
143480093f4SDimitry Andric     if (X86AlignBranchWithin32BBoundaries) {
144480093f4SDimitry Andric       // At the moment, this defaults to aligning fused branches, unconditional
145480093f4SDimitry Andric       // jumps, and (unfused) conditional jumps with nops.  Both the
146480093f4SDimitry Andric       // instructions aligned and the alignment method (nop vs prefix) may
147480093f4SDimitry Andric       // change in the future.
14806c3fb27SDimitry Andric       AlignBoundary = assumeAligned(32);
149480093f4SDimitry Andric       AlignBranchType.addKind(X86::AlignBranchFused);
150480093f4SDimitry Andric       AlignBranchType.addKind(X86::AlignBranchJcc);
151480093f4SDimitry Andric       AlignBranchType.addKind(X86::AlignBranchJmp);
152480093f4SDimitry Andric     }
1534824e7fdSDimitry Andric     // Allow overriding defaults set by main flag
154480093f4SDimitry Andric     if (X86AlignBranchBoundary.getNumOccurrences())
155480093f4SDimitry Andric       AlignBoundary = assumeAligned(X86AlignBranchBoundary);
156480093f4SDimitry Andric     if (X86AlignBranch.getNumOccurrences())
157480093f4SDimitry Andric       AlignBranchType = X86AlignBranchKindLoc;
1585ffd83dbSDimitry Andric     if (X86PadMaxPrefixSize.getNumOccurrences())
1595ffd83dbSDimitry Andric       TargetPrefixMax = X86PadMaxPrefixSize;
160480093f4SDimitry Andric   }
161480093f4SDimitry Andric 
162480093f4SDimitry Andric   bool allowAutoPadding() const override;
1635ffd83dbSDimitry Andric   bool allowEnhancedRelaxation() const override;
164349cc55cSDimitry Andric   void emitInstructionBegin(MCObjectStreamer &OS, const MCInst &Inst,
1650fca6ea1SDimitry Andric                             const MCSubtargetInfo &STI);
1660fca6ea1SDimitry Andric   void emitInstructionEnd(MCObjectStreamer &OS, const MCInst &Inst);
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric   unsigned getNumFixupKinds() const override {
1690b57cec5SDimitry Andric     return X86::NumTargetFixupKinds;
1700b57cec5SDimitry Andric   }
1710b57cec5SDimitry Andric 
172bdd1243dSDimitry Andric   std::optional<MCFixupKind> getFixupKind(StringRef Name) const override;
1730b57cec5SDimitry Andric 
174480093f4SDimitry Andric   const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric   bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
1775f757f3fSDimitry Andric                              const MCValue &Target,
1785f757f3fSDimitry Andric                              const MCSubtargetInfo *STI) override;
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
1810b57cec5SDimitry Andric                   const MCValue &Target, MutableArrayRef<char> Data,
1820b57cec5SDimitry Andric                   uint64_t Value, bool IsResolved,
183480093f4SDimitry Andric                   const MCSubtargetInfo *STI) const override;
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric   bool mayNeedRelaxation(const MCInst &Inst,
1860b57cec5SDimitry Andric                          const MCSubtargetInfo &STI) const override;
1870b57cec5SDimitry Andric 
1880fca6ea1SDimitry Andric   bool fixupNeedsRelaxation(const MCFixup &Fixup,
1890fca6ea1SDimitry Andric                             uint64_t Value) const override;
1900b57cec5SDimitry Andric 
1915ffd83dbSDimitry Andric   void relaxInstruction(MCInst &Inst,
1925ffd83dbSDimitry Andric                         const MCSubtargetInfo &STI) const override;
1935ffd83dbSDimitry Andric 
1945ffd83dbSDimitry Andric   bool padInstructionViaRelaxation(MCRelaxableFragment &RF,
1955ffd83dbSDimitry Andric                                    MCCodeEmitter &Emitter,
1965ffd83dbSDimitry Andric                                    unsigned &RemainingSize) const;
1975ffd83dbSDimitry Andric 
1985ffd83dbSDimitry Andric   bool padInstructionViaPrefix(MCRelaxableFragment &RF, MCCodeEmitter &Emitter,
1995ffd83dbSDimitry Andric                                unsigned &RemainingSize) const;
2005ffd83dbSDimitry Andric 
2015ffd83dbSDimitry Andric   bool padInstructionEncoding(MCRelaxableFragment &RF, MCCodeEmitter &Emitter,
2025ffd83dbSDimitry Andric                               unsigned &RemainingSize) const;
2035ffd83dbSDimitry Andric 
204*52418fc2SDimitry Andric   void finishLayout(const MCAssembler &Asm) const override;
2050b57cec5SDimitry Andric 
206349cc55cSDimitry Andric   unsigned getMaximumNopSize(const MCSubtargetInfo &STI) const override;
207e8d8bef9SDimitry Andric 
208349cc55cSDimitry Andric   bool writeNopData(raw_ostream &OS, uint64_t Count,
209349cc55cSDimitry Andric                     const MCSubtargetInfo *STI) const override;
2100b57cec5SDimitry Andric };
2110b57cec5SDimitry Andric } // end anonymous namespace
2120b57cec5SDimitry Andric 
21306c3fb27SDimitry Andric static bool isRelaxableBranch(unsigned Opcode) {
21406c3fb27SDimitry Andric   return Opcode == X86::JCC_1 || Opcode == X86::JMP_1;
21506c3fb27SDimitry Andric }
21606c3fb27SDimitry Andric 
21706c3fb27SDimitry Andric static unsigned getRelaxedOpcodeBranch(unsigned Opcode,
21806c3fb27SDimitry Andric                                        bool Is16BitMode = false) {
21906c3fb27SDimitry Andric   switch (Opcode) {
2200b57cec5SDimitry Andric   default:
22106c3fb27SDimitry Andric     llvm_unreachable("invalid opcode for branch");
2220b57cec5SDimitry Andric   case X86::JCC_1:
2235ffd83dbSDimitry Andric     return (Is16BitMode) ? X86::JCC_2 : X86::JCC_4;
2240b57cec5SDimitry Andric   case X86::JMP_1:
2255ffd83dbSDimitry Andric     return (Is16BitMode) ? X86::JMP_2 : X86::JMP_4;
2260b57cec5SDimitry Andric   }
2270b57cec5SDimitry Andric }
2280b57cec5SDimitry Andric 
22906c3fb27SDimitry Andric static unsigned getRelaxedOpcode(const MCInst &MI, bool Is16BitMode) {
23006c3fb27SDimitry Andric   unsigned Opcode = MI.getOpcode();
23106c3fb27SDimitry Andric   return isRelaxableBranch(Opcode) ? getRelaxedOpcodeBranch(Opcode, Is16BitMode)
23206c3fb27SDimitry Andric                                    : X86::getOpcodeForLongImmediateForm(Opcode);
2330b57cec5SDimitry Andric }
2340b57cec5SDimitry Andric 
235480093f4SDimitry Andric static X86::CondCode getCondFromBranch(const MCInst &MI,
236480093f4SDimitry Andric                                        const MCInstrInfo &MCII) {
237480093f4SDimitry Andric   unsigned Opcode = MI.getOpcode();
238480093f4SDimitry Andric   switch (Opcode) {
239480093f4SDimitry Andric   default:
240480093f4SDimitry Andric     return X86::COND_INVALID;
241480093f4SDimitry Andric   case X86::JCC_1: {
242480093f4SDimitry Andric     const MCInstrDesc &Desc = MCII.get(Opcode);
243480093f4SDimitry Andric     return static_cast<X86::CondCode>(
244480093f4SDimitry Andric         MI.getOperand(Desc.getNumOperands() - 1).getImm());
245480093f4SDimitry Andric   }
246480093f4SDimitry Andric   }
247480093f4SDimitry Andric }
248480093f4SDimitry Andric 
249480093f4SDimitry Andric static X86::SecondMacroFusionInstKind
250480093f4SDimitry Andric classifySecondInstInMacroFusion(const MCInst &MI, const MCInstrInfo &MCII) {
251480093f4SDimitry Andric   X86::CondCode CC = getCondFromBranch(MI, MCII);
252480093f4SDimitry Andric   return classifySecondCondCodeInMacroFusion(CC);
253480093f4SDimitry Andric }
254480093f4SDimitry Andric 
255480093f4SDimitry Andric /// Check if the instruction uses RIP relative addressing.
256480093f4SDimitry Andric static bool isRIPRelative(const MCInst &MI, const MCInstrInfo &MCII) {
257480093f4SDimitry Andric   unsigned Opcode = MI.getOpcode();
258480093f4SDimitry Andric   const MCInstrDesc &Desc = MCII.get(Opcode);
259480093f4SDimitry Andric   uint64_t TSFlags = Desc.TSFlags;
260480093f4SDimitry Andric   unsigned CurOp = X86II::getOperandBias(Desc);
261480093f4SDimitry Andric   int MemoryOperand = X86II::getMemoryOperandNo(TSFlags);
262480093f4SDimitry Andric   if (MemoryOperand < 0)
263480093f4SDimitry Andric     return false;
264480093f4SDimitry Andric   unsigned BaseRegNum = MemoryOperand + CurOp + X86::AddrBaseReg;
265480093f4SDimitry Andric   unsigned BaseReg = MI.getOperand(BaseRegNum).getReg();
266480093f4SDimitry Andric   return (BaseReg == X86::RIP);
267480093f4SDimitry Andric }
268480093f4SDimitry Andric 
2695ffd83dbSDimitry Andric /// Check if the instruction is a prefix.
2700fca6ea1SDimitry Andric static bool isPrefix(unsigned Opcode, const MCInstrInfo &MCII) {
2710fca6ea1SDimitry Andric   return X86II::isPrefix(MCII.get(Opcode).TSFlags);
2725ffd83dbSDimitry Andric }
2735ffd83dbSDimitry Andric 
274480093f4SDimitry Andric /// Check if the instruction is valid as the first instruction in macro fusion.
275480093f4SDimitry Andric static bool isFirstMacroFusibleInst(const MCInst &Inst,
276480093f4SDimitry Andric                                     const MCInstrInfo &MCII) {
277480093f4SDimitry Andric   // An Intel instruction with RIP relative addressing is not macro fusible.
278480093f4SDimitry Andric   if (isRIPRelative(Inst, MCII))
279480093f4SDimitry Andric     return false;
280480093f4SDimitry Andric   X86::FirstMacroFusionInstKind FIK =
281480093f4SDimitry Andric       X86::classifyFirstOpcodeInMacroFusion(Inst.getOpcode());
282480093f4SDimitry Andric   return FIK != X86::FirstMacroFusionInstKind::Invalid;
283480093f4SDimitry Andric }
284480093f4SDimitry Andric 
2855ffd83dbSDimitry Andric /// X86 can reduce the bytes of NOP by padding instructions with prefixes to
2865ffd83dbSDimitry Andric /// get a better peformance in some cases. Here, we determine which prefix is
2875ffd83dbSDimitry Andric /// the most suitable.
2885ffd83dbSDimitry Andric ///
2895ffd83dbSDimitry Andric /// If the instruction has a segment override prefix, use the existing one.
2905ffd83dbSDimitry Andric /// If the target is 64-bit, use the CS.
2915ffd83dbSDimitry Andric /// If the target is 32-bit,
2925ffd83dbSDimitry Andric ///   - If the instruction has a ESP/EBP base register, use SS.
2935ffd83dbSDimitry Andric ///   - Otherwise use DS.
2945ffd83dbSDimitry Andric uint8_t X86AsmBackend::determinePaddingPrefix(const MCInst &Inst) const {
29581ad6265SDimitry Andric   assert((STI.hasFeature(X86::Is32Bit) || STI.hasFeature(X86::Is64Bit)) &&
2965ffd83dbSDimitry Andric          "Prefixes can be added only in 32-bit or 64-bit mode.");
2975ffd83dbSDimitry Andric   const MCInstrDesc &Desc = MCII->get(Inst.getOpcode());
2985ffd83dbSDimitry Andric   uint64_t TSFlags = Desc.TSFlags;
2995ffd83dbSDimitry Andric 
3005ffd83dbSDimitry Andric   // Determine where the memory operand starts, if present.
3015ffd83dbSDimitry Andric   int MemoryOperand = X86II::getMemoryOperandNo(TSFlags);
3025ffd83dbSDimitry Andric   if (MemoryOperand != -1)
3035ffd83dbSDimitry Andric     MemoryOperand += X86II::getOperandBias(Desc);
3045ffd83dbSDimitry Andric 
3055ffd83dbSDimitry Andric   unsigned SegmentReg = 0;
3065ffd83dbSDimitry Andric   if (MemoryOperand >= 0) {
3075ffd83dbSDimitry Andric     // Check for explicit segment override on memory operand.
3085ffd83dbSDimitry Andric     SegmentReg = Inst.getOperand(MemoryOperand + X86::AddrSegmentReg).getReg();
3095ffd83dbSDimitry Andric   }
3105ffd83dbSDimitry Andric 
3115ffd83dbSDimitry Andric   switch (TSFlags & X86II::FormMask) {
3125ffd83dbSDimitry Andric   default:
3135ffd83dbSDimitry Andric     break;
3145ffd83dbSDimitry Andric   case X86II::RawFrmDstSrc: {
3155ffd83dbSDimitry Andric     // Check segment override opcode prefix as needed (not for %ds).
3165ffd83dbSDimitry Andric     if (Inst.getOperand(2).getReg() != X86::DS)
3175ffd83dbSDimitry Andric       SegmentReg = Inst.getOperand(2).getReg();
3185ffd83dbSDimitry Andric     break;
3195ffd83dbSDimitry Andric   }
3205ffd83dbSDimitry Andric   case X86II::RawFrmSrc: {
3215ffd83dbSDimitry Andric     // Check segment override opcode prefix as needed (not for %ds).
3225ffd83dbSDimitry Andric     if (Inst.getOperand(1).getReg() != X86::DS)
3235ffd83dbSDimitry Andric       SegmentReg = Inst.getOperand(1).getReg();
3245ffd83dbSDimitry Andric     break;
3255ffd83dbSDimitry Andric   }
3265ffd83dbSDimitry Andric   case X86II::RawFrmMemOffs: {
3275ffd83dbSDimitry Andric     // Check segment override opcode prefix as needed.
3285ffd83dbSDimitry Andric     SegmentReg = Inst.getOperand(1).getReg();
3295ffd83dbSDimitry Andric     break;
3305ffd83dbSDimitry Andric   }
3315ffd83dbSDimitry Andric   }
3325ffd83dbSDimitry Andric 
3335ffd83dbSDimitry Andric   if (SegmentReg != 0)
3345ffd83dbSDimitry Andric     return X86::getSegmentOverridePrefixForReg(SegmentReg);
3355ffd83dbSDimitry Andric 
33681ad6265SDimitry Andric   if (STI.hasFeature(X86::Is64Bit))
3375ffd83dbSDimitry Andric     return X86::CS_Encoding;
3385ffd83dbSDimitry Andric 
3395ffd83dbSDimitry Andric   if (MemoryOperand >= 0) {
3405ffd83dbSDimitry Andric     unsigned BaseRegNum = MemoryOperand + X86::AddrBaseReg;
3415ffd83dbSDimitry Andric     unsigned BaseReg = Inst.getOperand(BaseRegNum).getReg();
3425ffd83dbSDimitry Andric     if (BaseReg == X86::ESP || BaseReg == X86::EBP)
3435ffd83dbSDimitry Andric       return X86::SS_Encoding;
3445ffd83dbSDimitry Andric   }
3455ffd83dbSDimitry Andric   return X86::DS_Encoding;
3465ffd83dbSDimitry Andric }
3475ffd83dbSDimitry Andric 
348480093f4SDimitry Andric /// Check if the two instructions will be macro-fused on the target cpu.
349480093f4SDimitry Andric bool X86AsmBackend::isMacroFused(const MCInst &Cmp, const MCInst &Jcc) const {
350480093f4SDimitry Andric   const MCInstrDesc &InstDesc = MCII->get(Jcc.getOpcode());
351480093f4SDimitry Andric   if (!InstDesc.isConditionalBranch())
352480093f4SDimitry Andric     return false;
353480093f4SDimitry Andric   if (!isFirstMacroFusibleInst(Cmp, *MCII))
354480093f4SDimitry Andric     return false;
355480093f4SDimitry Andric   const X86::FirstMacroFusionInstKind CmpKind =
356480093f4SDimitry Andric       X86::classifyFirstOpcodeInMacroFusion(Cmp.getOpcode());
357480093f4SDimitry Andric   const X86::SecondMacroFusionInstKind BranchKind =
358480093f4SDimitry Andric       classifySecondInstInMacroFusion(Jcc, *MCII);
359480093f4SDimitry Andric   return X86::isMacroFused(CmpKind, BranchKind);
360480093f4SDimitry Andric }
361480093f4SDimitry Andric 
362480093f4SDimitry Andric /// Check if the instruction has a variant symbol operand.
363480093f4SDimitry Andric static bool hasVariantSymbol(const MCInst &MI) {
364480093f4SDimitry Andric   for (auto &Operand : MI) {
365480093f4SDimitry Andric     if (!Operand.isExpr())
366480093f4SDimitry Andric       continue;
367480093f4SDimitry Andric     const MCExpr &Expr = *Operand.getExpr();
368480093f4SDimitry Andric     if (Expr.getKind() == MCExpr::SymbolRef &&
369480093f4SDimitry Andric         cast<MCSymbolRefExpr>(Expr).getKind() != MCSymbolRefExpr::VK_None)
370480093f4SDimitry Andric       return true;
371480093f4SDimitry Andric   }
372480093f4SDimitry Andric   return false;
373480093f4SDimitry Andric }
374480093f4SDimitry Andric 
375480093f4SDimitry Andric bool X86AsmBackend::allowAutoPadding() const {
3765ffd83dbSDimitry Andric   return (AlignBoundary != Align(1) && AlignBranchType != X86::AlignBranchNone);
377480093f4SDimitry Andric }
378480093f4SDimitry Andric 
3795ffd83dbSDimitry Andric bool X86AsmBackend::allowEnhancedRelaxation() const {
3805ffd83dbSDimitry Andric   return allowAutoPadding() && TargetPrefixMax != 0 && X86PadForBranchAlign;
3815ffd83dbSDimitry Andric }
3825ffd83dbSDimitry Andric 
3835ffd83dbSDimitry Andric /// X86 has certain instructions which enable interrupts exactly one
3845ffd83dbSDimitry Andric /// instruction *after* the instruction which stores to SS.  Return true if the
3850fca6ea1SDimitry Andric /// given instruction may have such an interrupt delay slot.
3860fca6ea1SDimitry Andric static bool mayHaveInterruptDelaySlot(unsigned InstOpcode) {
3870fca6ea1SDimitry Andric   switch (InstOpcode) {
3885ffd83dbSDimitry Andric   case X86::POPSS16:
3895ffd83dbSDimitry Andric   case X86::POPSS32:
3905ffd83dbSDimitry Andric   case X86::STI:
3915ffd83dbSDimitry Andric     return true;
3925ffd83dbSDimitry Andric 
3935ffd83dbSDimitry Andric   case X86::MOV16sr:
3945ffd83dbSDimitry Andric   case X86::MOV32sr:
3955ffd83dbSDimitry Andric   case X86::MOV64sr:
3965ffd83dbSDimitry Andric   case X86::MOV16sm:
3970fca6ea1SDimitry Andric     // In fact, this is only the case if the first operand is SS. However, as
3980fca6ea1SDimitry Andric     // segment moves occur extremely rarely, this is just a minor pessimization.
3995ffd83dbSDimitry Andric     return true;
4005ffd83dbSDimitry Andric   }
4015ffd83dbSDimitry Andric   return false;
4025ffd83dbSDimitry Andric }
4035ffd83dbSDimitry Andric 
4045ffd83dbSDimitry Andric /// Check if the instruction to be emitted is right after any data.
4055ffd83dbSDimitry Andric static bool
4065ffd83dbSDimitry Andric isRightAfterData(MCFragment *CurrentFragment,
4075ffd83dbSDimitry Andric                  const std::pair<MCFragment *, size_t> &PrevInstPosition) {
4085ffd83dbSDimitry Andric   MCFragment *F = CurrentFragment;
4095ffd83dbSDimitry Andric   // Since data is always emitted into a DataFragment, our check strategy is
4105ffd83dbSDimitry Andric   // simple here.
4115ffd83dbSDimitry Andric   //   - If the fragment is a DataFragment
4120fca6ea1SDimitry Andric   //     - If it's empty (section start or data after align), return false.
4135ffd83dbSDimitry Andric   //     - If it's not the fragment where the previous instruction is,
4145ffd83dbSDimitry Andric   //       returns true.
4155ffd83dbSDimitry Andric   //     - If it's the fragment holding the previous instruction but its
4165f757f3fSDimitry Andric   //       size changed since the previous instruction was emitted into
4175ffd83dbSDimitry Andric   //       it, returns true.
4185ffd83dbSDimitry Andric   //     - Otherwise returns false.
4195ffd83dbSDimitry Andric   //   - If the fragment is not a DataFragment, returns false.
4205ffd83dbSDimitry Andric   if (auto *DF = dyn_cast_or_null<MCDataFragment>(F))
4210fca6ea1SDimitry Andric     return DF->getContents().size() &&
4220fca6ea1SDimitry Andric            (DF != PrevInstPosition.first ||
4230fca6ea1SDimitry Andric             DF->getContents().size() != PrevInstPosition.second);
4245ffd83dbSDimitry Andric 
4255ffd83dbSDimitry Andric   return false;
4265ffd83dbSDimitry Andric }
4275ffd83dbSDimitry Andric 
4285ffd83dbSDimitry Andric /// \returns the fragment size if it has instructions, otherwise returns 0.
4295ffd83dbSDimitry Andric static size_t getSizeForInstFragment(const MCFragment *F) {
4305ffd83dbSDimitry Andric   if (!F || !F->hasInstructions())
4315ffd83dbSDimitry Andric     return 0;
4325ffd83dbSDimitry Andric   // MCEncodedFragmentWithContents being templated makes this tricky.
4335ffd83dbSDimitry Andric   switch (F->getKind()) {
4345ffd83dbSDimitry Andric   default:
4355ffd83dbSDimitry Andric     llvm_unreachable("Unknown fragment with instructions!");
4365ffd83dbSDimitry Andric   case MCFragment::FT_Data:
4375ffd83dbSDimitry Andric     return cast<MCDataFragment>(*F).getContents().size();
4385ffd83dbSDimitry Andric   case MCFragment::FT_Relaxable:
4395ffd83dbSDimitry Andric     return cast<MCRelaxableFragment>(*F).getContents().size();
4405ffd83dbSDimitry Andric   case MCFragment::FT_CompactEncodedInst:
4415ffd83dbSDimitry Andric     return cast<MCCompactEncodedInstFragment>(*F).getContents().size();
4425ffd83dbSDimitry Andric   }
4435ffd83dbSDimitry Andric }
4445ffd83dbSDimitry Andric 
4455ffd83dbSDimitry Andric /// Return true if we can insert NOP or prefixes automatically before the
4465ffd83dbSDimitry Andric /// the instruction to be emitted.
4475ffd83dbSDimitry Andric bool X86AsmBackend::canPadInst(const MCInst &Inst, MCObjectStreamer &OS) const {
4485ffd83dbSDimitry Andric   if (hasVariantSymbol(Inst))
4495ffd83dbSDimitry Andric     // Linker may rewrite the instruction with variant symbol operand(e.g.
4505ffd83dbSDimitry Andric     // TLSCALL).
4515ffd83dbSDimitry Andric     return false;
4525ffd83dbSDimitry Andric 
4530fca6ea1SDimitry Andric   if (mayHaveInterruptDelaySlot(PrevInstOpcode))
4545ffd83dbSDimitry Andric     // If this instruction follows an interrupt enabling instruction with a one
4555ffd83dbSDimitry Andric     // instruction delay, inserting a nop would change behavior.
4565ffd83dbSDimitry Andric     return false;
4575ffd83dbSDimitry Andric 
4580fca6ea1SDimitry Andric   if (isPrefix(PrevInstOpcode, *MCII))
4595ffd83dbSDimitry Andric     // If this instruction follows a prefix, inserting a nop/prefix would change
4605ffd83dbSDimitry Andric     // semantic.
4615ffd83dbSDimitry Andric     return false;
4625ffd83dbSDimitry Andric 
4630fca6ea1SDimitry Andric   if (isPrefix(Inst.getOpcode(), *MCII))
4645ffd83dbSDimitry Andric     // If this instruction is a prefix, inserting a prefix would change
4655ffd83dbSDimitry Andric     // semantic.
4665ffd83dbSDimitry Andric     return false;
4675ffd83dbSDimitry Andric 
4680fca6ea1SDimitry Andric   if (IsRightAfterData)
4695ffd83dbSDimitry Andric     // If this instruction follows any data, there is no clear
4705ffd83dbSDimitry Andric     // instruction boundary, inserting a nop/prefix would change semantic.
4715ffd83dbSDimitry Andric     return false;
4725ffd83dbSDimitry Andric 
4735ffd83dbSDimitry Andric   return true;
4745ffd83dbSDimitry Andric }
4755ffd83dbSDimitry Andric 
4765ffd83dbSDimitry Andric bool X86AsmBackend::canPadBranches(MCObjectStreamer &OS) const {
477480093f4SDimitry Andric   if (!OS.getAllowAutoPadding())
478480093f4SDimitry Andric     return false;
479480093f4SDimitry Andric   assert(allowAutoPadding() && "incorrect initialization!");
480480093f4SDimitry Andric 
4815ffd83dbSDimitry Andric   // We only pad in text section.
4820fca6ea1SDimitry Andric   if (!OS.getCurrentSectionOnly()->isText())
4835ffd83dbSDimitry Andric     return false;
4845ffd83dbSDimitry Andric 
485480093f4SDimitry Andric   // To be Done: Currently don't deal with Bundle cases.
4865ffd83dbSDimitry Andric   if (OS.getAssembler().isBundlingEnabled())
487480093f4SDimitry Andric     return false;
488480093f4SDimitry Andric 
489480093f4SDimitry Andric   // Branches only need to be aligned in 32-bit or 64-bit mode.
49081ad6265SDimitry Andric   if (!(STI.hasFeature(X86::Is64Bit) || STI.hasFeature(X86::Is32Bit)))
491480093f4SDimitry Andric     return false;
492480093f4SDimitry Andric 
493480093f4SDimitry Andric   return true;
494480093f4SDimitry Andric }
495480093f4SDimitry Andric 
4965ffd83dbSDimitry Andric /// Check if the instruction operand needs to be aligned.
4975ffd83dbSDimitry Andric bool X86AsmBackend::needAlign(const MCInst &Inst) const {
4985ffd83dbSDimitry Andric   const MCInstrDesc &Desc = MCII->get(Inst.getOpcode());
4995ffd83dbSDimitry Andric   return (Desc.isConditionalBranch() &&
500480093f4SDimitry Andric           (AlignBranchType & X86::AlignBranchJcc)) ||
5015ffd83dbSDimitry Andric          (Desc.isUnconditionalBranch() &&
502480093f4SDimitry Andric           (AlignBranchType & X86::AlignBranchJmp)) ||
5035ffd83dbSDimitry Andric          (Desc.isCall() && (AlignBranchType & X86::AlignBranchCall)) ||
5045ffd83dbSDimitry Andric          (Desc.isReturn() && (AlignBranchType & X86::AlignBranchRet)) ||
5055ffd83dbSDimitry Andric          (Desc.isIndirectBranch() &&
506480093f4SDimitry Andric           (AlignBranchType & X86::AlignBranchIndirect));
507480093f4SDimitry Andric }
508480093f4SDimitry Andric 
5095ffd83dbSDimitry Andric /// Insert BoundaryAlignFragment before instructions to align branches.
5105ffd83dbSDimitry Andric void X86AsmBackend::emitInstructionBegin(MCObjectStreamer &OS,
511349cc55cSDimitry Andric                                          const MCInst &Inst, const MCSubtargetInfo &STI) {
5120fca6ea1SDimitry Andric   // Used by canPadInst. Done here, because in emitInstructionEnd, the current
5130fca6ea1SDimitry Andric   // fragment will have changed.
5140fca6ea1SDimitry Andric   IsRightAfterData =
5150fca6ea1SDimitry Andric       isRightAfterData(OS.getCurrentFragment(), PrevInstPosition);
5165ffd83dbSDimitry Andric 
5175ffd83dbSDimitry Andric   if (!canPadBranches(OS))
518480093f4SDimitry Andric     return;
519480093f4SDimitry Andric 
5200fca6ea1SDimitry Andric   // NB: PrevInst only valid if canPadBranches is true.
5215ffd83dbSDimitry Andric   if (!isMacroFused(PrevInst, Inst))
5225ffd83dbSDimitry Andric     // Macro fusion doesn't happen indeed, clear the pending.
5235ffd83dbSDimitry Andric     PendingBA = nullptr;
5245ffd83dbSDimitry Andric 
5250fca6ea1SDimitry Andric   // When branch padding is enabled (basically the skx102 erratum => unlikely),
5260fca6ea1SDimitry Andric   // we call canPadInst (not cheap) twice. However, in the common case, we can
5270fca6ea1SDimitry Andric   // avoid unnecessary calls to that, as this is otherwise only used for
5280fca6ea1SDimitry Andric   // relaxable fragments.
5290fca6ea1SDimitry Andric   if (!canPadInst(Inst, OS))
5305ffd83dbSDimitry Andric     return;
5315ffd83dbSDimitry Andric 
5320fca6ea1SDimitry Andric   if (PendingBA && PendingBA->getNext() == OS.getCurrentFragment()) {
533480093f4SDimitry Andric     // Macro fusion actually happens and there is no other fragment inserted
5345ffd83dbSDimitry Andric     // after the previous instruction.
5355ffd83dbSDimitry Andric     //
5365ffd83dbSDimitry Andric     // Do nothing here since we already inserted a BoudaryAlign fragment when
5375ffd83dbSDimitry Andric     // we met the first instruction in the fused pair and we'll tie them
5385ffd83dbSDimitry Andric     // together in emitInstructionEnd.
5395ffd83dbSDimitry Andric     //
540480093f4SDimitry Andric     // Note: When there is at least one fragment, such as MCAlignFragment,
541480093f4SDimitry Andric     // inserted after the previous instruction, e.g.
542480093f4SDimitry Andric     //
543480093f4SDimitry Andric     // \code
544480093f4SDimitry Andric     //   cmp %rax %rcx
545480093f4SDimitry Andric     //   .align 16
546480093f4SDimitry Andric     //   je .Label0
547480093f4SDimitry Andric     // \ endcode
548480093f4SDimitry Andric     //
549480093f4SDimitry Andric     // We will treat the JCC as a unfused branch although it may be fused
550480093f4SDimitry Andric     // with the CMP.
551480093f4SDimitry Andric     return;
5525ffd83dbSDimitry Andric   }
5535ffd83dbSDimitry Andric 
5545ffd83dbSDimitry Andric   if (needAlign(Inst) || ((AlignBranchType & X86::AlignBranchFused) &&
5555ffd83dbSDimitry Andric                           isFirstMacroFusibleInst(Inst, *MCII))) {
5565ffd83dbSDimitry Andric     // If we meet a unfused branch or the first instuction in a fusiable pair,
5575ffd83dbSDimitry Andric     // insert a BoundaryAlign fragment.
5580fca6ea1SDimitry Andric     PendingBA = OS.getContext().allocFragment<MCBoundaryAlignFragment>(
5590fca6ea1SDimitry Andric         AlignBoundary, STI);
5600fca6ea1SDimitry Andric     OS.insert(PendingBA);
5615ffd83dbSDimitry Andric   }
5625ffd83dbSDimitry Andric }
5635ffd83dbSDimitry Andric 
5645ffd83dbSDimitry Andric /// Set the last fragment to be aligned for the BoundaryAlignFragment.
5650fca6ea1SDimitry Andric void X86AsmBackend::emitInstructionEnd(MCObjectStreamer &OS,
5660fca6ea1SDimitry Andric                                        const MCInst &Inst) {
5675ffd83dbSDimitry Andric   MCFragment *CF = OS.getCurrentFragment();
5685ffd83dbSDimitry Andric   if (auto *F = dyn_cast_or_null<MCRelaxableFragment>(CF))
5690fca6ea1SDimitry Andric     F->setAllowAutoPadding(canPadInst(Inst, OS));
5700fca6ea1SDimitry Andric 
5710fca6ea1SDimitry Andric   // Update PrevInstOpcode here, canPadInst() reads that.
5720fca6ea1SDimitry Andric   PrevInstOpcode = Inst.getOpcode();
5730fca6ea1SDimitry Andric   PrevInstPosition = std::make_pair(CF, getSizeForInstFragment(CF));
5745ffd83dbSDimitry Andric 
5755ffd83dbSDimitry Andric   if (!canPadBranches(OS))
5765ffd83dbSDimitry Andric     return;
5775ffd83dbSDimitry Andric 
5780fca6ea1SDimitry Andric   // PrevInst is only needed if canPadBranches. Copying an MCInst isn't cheap.
5790fca6ea1SDimitry Andric   PrevInst = Inst;
5800fca6ea1SDimitry Andric 
5815ffd83dbSDimitry Andric   if (!needAlign(Inst) || !PendingBA)
5825ffd83dbSDimitry Andric     return;
5835ffd83dbSDimitry Andric 
5845f757f3fSDimitry Andric   // Tie the aligned instructions into a pending BoundaryAlign.
5855ffd83dbSDimitry Andric   PendingBA->setLastFragment(CF);
5865ffd83dbSDimitry Andric   PendingBA = nullptr;
5875ffd83dbSDimitry Andric 
5885ffd83dbSDimitry Andric   // We need to ensure that further data isn't added to the current
5895ffd83dbSDimitry Andric   // DataFragment, so that we can get the size of instructions later in
5905ffd83dbSDimitry Andric   // MCAssembler::relaxBoundaryAlign. The easiest way is to insert a new empty
5915ffd83dbSDimitry Andric   // DataFragment.
5925ffd83dbSDimitry Andric   if (isa_and_nonnull<MCDataFragment>(CF))
5930fca6ea1SDimitry Andric     OS.insert(OS.getContext().allocFragment<MCDataFragment>());
594480093f4SDimitry Andric 
595480093f4SDimitry Andric   // Update the maximum alignment on the current section if necessary.
596480093f4SDimitry Andric   MCSection *Sec = OS.getCurrentSectionOnly();
597bdd1243dSDimitry Andric   Sec->ensureMinAlignment(AlignBoundary);
598480093f4SDimitry Andric }
599480093f4SDimitry Andric 
600bdd1243dSDimitry Andric std::optional<MCFixupKind> X86AsmBackend::getFixupKind(StringRef Name) const {
6010b57cec5SDimitry Andric   if (STI.getTargetTriple().isOSBinFormatELF()) {
6025ffd83dbSDimitry Andric     unsigned Type;
6030b57cec5SDimitry Andric     if (STI.getTargetTriple().getArch() == Triple::x86_64) {
6045ffd83dbSDimitry Andric       Type = llvm::StringSwitch<unsigned>(Name)
6055ffd83dbSDimitry Andric #define ELF_RELOC(X, Y) .Case(#X, Y)
6065ffd83dbSDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
6075ffd83dbSDimitry Andric #undef ELF_RELOC
608fe6060f1SDimitry Andric                  .Case("BFD_RELOC_NONE", ELF::R_X86_64_NONE)
609fe6060f1SDimitry Andric                  .Case("BFD_RELOC_8", ELF::R_X86_64_8)
610fe6060f1SDimitry Andric                  .Case("BFD_RELOC_16", ELF::R_X86_64_16)
611fe6060f1SDimitry Andric                  .Case("BFD_RELOC_32", ELF::R_X86_64_32)
612fe6060f1SDimitry Andric                  .Case("BFD_RELOC_64", ELF::R_X86_64_64)
6135ffd83dbSDimitry Andric                  .Default(-1u);
6140b57cec5SDimitry Andric     } else {
6155ffd83dbSDimitry Andric       Type = llvm::StringSwitch<unsigned>(Name)
6165ffd83dbSDimitry Andric #define ELF_RELOC(X, Y) .Case(#X, Y)
6175ffd83dbSDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/i386.def"
6185ffd83dbSDimitry Andric #undef ELF_RELOC
619fe6060f1SDimitry Andric                  .Case("BFD_RELOC_NONE", ELF::R_386_NONE)
620fe6060f1SDimitry Andric                  .Case("BFD_RELOC_8", ELF::R_386_8)
621fe6060f1SDimitry Andric                  .Case("BFD_RELOC_16", ELF::R_386_16)
622fe6060f1SDimitry Andric                  .Case("BFD_RELOC_32", ELF::R_386_32)
6235ffd83dbSDimitry Andric                  .Default(-1u);
6240b57cec5SDimitry Andric     }
6255ffd83dbSDimitry Andric     if (Type == -1u)
626bdd1243dSDimitry Andric       return std::nullopt;
6275ffd83dbSDimitry Andric     return static_cast<MCFixupKind>(FirstLiteralRelocationKind + Type);
6280b57cec5SDimitry Andric   }
6290b57cec5SDimitry Andric   return MCAsmBackend::getFixupKind(Name);
6300b57cec5SDimitry Andric }
6310b57cec5SDimitry Andric 
632480093f4SDimitry Andric const MCFixupKindInfo &X86AsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
633480093f4SDimitry Andric   const static MCFixupKindInfo Infos[X86::NumTargetFixupKinds] = {
634480093f4SDimitry Andric       {"reloc_riprel_4byte", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
635480093f4SDimitry Andric       {"reloc_riprel_4byte_movq_load", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
636480093f4SDimitry Andric       {"reloc_riprel_4byte_relax", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
637480093f4SDimitry Andric       {"reloc_riprel_4byte_relax_rex", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
638480093f4SDimitry Andric       {"reloc_signed_4byte", 0, 32, 0},
639480093f4SDimitry Andric       {"reloc_signed_4byte_relax", 0, 32, 0},
640480093f4SDimitry Andric       {"reloc_global_offset_table", 0, 32, 0},
641480093f4SDimitry Andric       {"reloc_global_offset_table8", 0, 64, 0},
642480093f4SDimitry Andric       {"reloc_branch_4byte_pcrel", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
643480093f4SDimitry Andric   };
644480093f4SDimitry Andric 
6455ffd83dbSDimitry Andric   // Fixup kinds from .reloc directive are like R_386_NONE/R_X86_64_NONE. They
6465ffd83dbSDimitry Andric   // do not require any extra processing.
6475ffd83dbSDimitry Andric   if (Kind >= FirstLiteralRelocationKind)
6485ffd83dbSDimitry Andric     return MCAsmBackend::getFixupKindInfo(FK_NONE);
6495ffd83dbSDimitry Andric 
650480093f4SDimitry Andric   if (Kind < FirstTargetFixupKind)
651480093f4SDimitry Andric     return MCAsmBackend::getFixupKindInfo(Kind);
652480093f4SDimitry Andric 
653480093f4SDimitry Andric   assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
654480093f4SDimitry Andric          "Invalid kind!");
655480093f4SDimitry Andric   assert(Infos[Kind - FirstTargetFixupKind].Name && "Empty fixup name!");
656480093f4SDimitry Andric   return Infos[Kind - FirstTargetFixupKind];
657480093f4SDimitry Andric }
658480093f4SDimitry Andric 
6590b57cec5SDimitry Andric bool X86AsmBackend::shouldForceRelocation(const MCAssembler &,
6605f757f3fSDimitry Andric                                           const MCFixup &Fixup, const MCValue &,
6615f757f3fSDimitry Andric                                           const MCSubtargetInfo *STI) {
6625ffd83dbSDimitry Andric   return Fixup.getKind() >= FirstLiteralRelocationKind;
6630b57cec5SDimitry Andric }
6640b57cec5SDimitry Andric 
665480093f4SDimitry Andric static unsigned getFixupKindSize(unsigned Kind) {
666480093f4SDimitry Andric   switch (Kind) {
667480093f4SDimitry Andric   default:
668480093f4SDimitry Andric     llvm_unreachable("invalid fixup kind!");
669480093f4SDimitry Andric   case FK_NONE:
670480093f4SDimitry Andric     return 0;
671480093f4SDimitry Andric   case FK_PCRel_1:
672480093f4SDimitry Andric   case FK_SecRel_1:
673480093f4SDimitry Andric   case FK_Data_1:
674480093f4SDimitry Andric     return 1;
675480093f4SDimitry Andric   case FK_PCRel_2:
676480093f4SDimitry Andric   case FK_SecRel_2:
677480093f4SDimitry Andric   case FK_Data_2:
678480093f4SDimitry Andric     return 2;
679480093f4SDimitry Andric   case FK_PCRel_4:
680480093f4SDimitry Andric   case X86::reloc_riprel_4byte:
681480093f4SDimitry Andric   case X86::reloc_riprel_4byte_relax:
682480093f4SDimitry Andric   case X86::reloc_riprel_4byte_relax_rex:
683480093f4SDimitry Andric   case X86::reloc_riprel_4byte_movq_load:
684480093f4SDimitry Andric   case X86::reloc_signed_4byte:
685480093f4SDimitry Andric   case X86::reloc_signed_4byte_relax:
686480093f4SDimitry Andric   case X86::reloc_global_offset_table:
687480093f4SDimitry Andric   case X86::reloc_branch_4byte_pcrel:
688480093f4SDimitry Andric   case FK_SecRel_4:
689480093f4SDimitry Andric   case FK_Data_4:
690480093f4SDimitry Andric     return 4;
691480093f4SDimitry Andric   case FK_PCRel_8:
692480093f4SDimitry Andric   case FK_SecRel_8:
693480093f4SDimitry Andric   case FK_Data_8:
694480093f4SDimitry Andric   case X86::reloc_global_offset_table8:
695480093f4SDimitry Andric     return 8;
696480093f4SDimitry Andric   }
697480093f4SDimitry Andric }
698480093f4SDimitry Andric 
699480093f4SDimitry Andric void X86AsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
700480093f4SDimitry Andric                                const MCValue &Target,
701480093f4SDimitry Andric                                MutableArrayRef<char> Data,
702480093f4SDimitry Andric                                uint64_t Value, bool IsResolved,
703480093f4SDimitry Andric                                const MCSubtargetInfo *STI) const {
7045ffd83dbSDimitry Andric   unsigned Kind = Fixup.getKind();
7055ffd83dbSDimitry Andric   if (Kind >= FirstLiteralRelocationKind)
7065ffd83dbSDimitry Andric     return;
7075ffd83dbSDimitry Andric   unsigned Size = getFixupKindSize(Kind);
708480093f4SDimitry Andric 
709480093f4SDimitry Andric   assert(Fixup.getOffset() + Size <= Data.size() && "Invalid fixup offset!");
710480093f4SDimitry Andric 
711480093f4SDimitry Andric   int64_t SignedValue = static_cast<int64_t>(Value);
712480093f4SDimitry Andric   if ((Target.isAbsolute() || IsResolved) &&
713480093f4SDimitry Andric       getFixupKindInfo(Fixup.getKind()).Flags &
714480093f4SDimitry Andric       MCFixupKindInfo::FKF_IsPCRel) {
715480093f4SDimitry Andric     // check that PC relative fixup fits into the fixup size.
716480093f4SDimitry Andric     if (Size > 0 && !isIntN(Size * 8, SignedValue))
717480093f4SDimitry Andric       Asm.getContext().reportError(
718480093f4SDimitry Andric                                    Fixup.getLoc(), "value of " + Twine(SignedValue) +
719480093f4SDimitry Andric                                    " is too large for field of " + Twine(Size) +
720480093f4SDimitry Andric                                    ((Size == 1) ? " byte." : " bytes."));
721480093f4SDimitry Andric   } else {
722480093f4SDimitry Andric     // Check that uppper bits are either all zeros or all ones.
723480093f4SDimitry Andric     // Specifically ignore overflow/underflow as long as the leakage is
724480093f4SDimitry Andric     // limited to the lower bits. This is to remain compatible with
725480093f4SDimitry Andric     // other assemblers.
726480093f4SDimitry Andric     assert((Size == 0 || isIntN(Size * 8 + 1, SignedValue)) &&
727480093f4SDimitry Andric            "Value does not fit in the Fixup field");
728480093f4SDimitry Andric   }
729480093f4SDimitry Andric 
730480093f4SDimitry Andric   for (unsigned i = 0; i != Size; ++i)
731480093f4SDimitry Andric     Data[Fixup.getOffset() + i] = uint8_t(Value >> (i * 8));
732480093f4SDimitry Andric }
733480093f4SDimitry Andric 
73406c3fb27SDimitry Andric bool X86AsmBackend::mayNeedRelaxation(const MCInst &MI,
7350b57cec5SDimitry Andric                                       const MCSubtargetInfo &STI) const {
73606c3fb27SDimitry Andric   unsigned Opcode = MI.getOpcode();
7370fca6ea1SDimitry Andric   unsigned SkipOperands = X86::isCCMPCC(Opcode) ? 2 : 0;
73806c3fb27SDimitry Andric   return isRelaxableBranch(Opcode) ||
73906c3fb27SDimitry Andric          (X86::getOpcodeForLongImmediateForm(Opcode) != Opcode &&
7400fca6ea1SDimitry Andric           MI.getOperand(MI.getNumOperands() - 1 - SkipOperands).isExpr());
7410b57cec5SDimitry Andric }
7420b57cec5SDimitry Andric 
7430b57cec5SDimitry Andric bool X86AsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
7440fca6ea1SDimitry Andric                                          uint64_t Value) const {
7450b57cec5SDimitry Andric   // Relax if the value is too big for a (signed) i8.
7468bcb0991SDimitry Andric   return !isInt<8>(Value);
7470b57cec5SDimitry Andric }
7480b57cec5SDimitry Andric 
7490b57cec5SDimitry Andric // FIXME: Can tblgen help at all here to verify there aren't other instructions
7500b57cec5SDimitry Andric // we can relax?
7515ffd83dbSDimitry Andric void X86AsmBackend::relaxInstruction(MCInst &Inst,
7525ffd83dbSDimitry Andric                                      const MCSubtargetInfo &STI) const {
7530b57cec5SDimitry Andric   // The only relaxations X86 does is from a 1byte pcrel to a 4byte pcrel.
75406c3fb27SDimitry Andric   bool Is16BitMode = STI.hasFeature(X86::Is16Bit);
7555ffd83dbSDimitry Andric   unsigned RelaxedOp = getRelaxedOpcode(Inst, Is16BitMode);
7560b57cec5SDimitry Andric 
7570b57cec5SDimitry Andric   if (RelaxedOp == Inst.getOpcode()) {
7580b57cec5SDimitry Andric     SmallString<256> Tmp;
7590b57cec5SDimitry Andric     raw_svector_ostream OS(Tmp);
7600b57cec5SDimitry Andric     Inst.dump_pretty(OS);
7610b57cec5SDimitry Andric     OS << "\n";
7620b57cec5SDimitry Andric     report_fatal_error("unexpected instruction to relax: " + OS.str());
7630b57cec5SDimitry Andric   }
7640b57cec5SDimitry Andric 
7655ffd83dbSDimitry Andric   Inst.setOpcode(RelaxedOp);
7665ffd83dbSDimitry Andric }
7675ffd83dbSDimitry Andric 
7685ffd83dbSDimitry Andric bool X86AsmBackend::padInstructionViaPrefix(MCRelaxableFragment &RF,
7695ffd83dbSDimitry Andric                                             MCCodeEmitter &Emitter,
7705ffd83dbSDimitry Andric                                             unsigned &RemainingSize) const {
7715ffd83dbSDimitry Andric   if (!RF.getAllowAutoPadding())
7725ffd83dbSDimitry Andric     return false;
7735ffd83dbSDimitry Andric   // If the instruction isn't fully relaxed, shifting it around might require a
7745ffd83dbSDimitry Andric   // larger value for one of the fixups then can be encoded.  The outer loop
7755ffd83dbSDimitry Andric   // will also catch this before moving to the next instruction, but we need to
7765ffd83dbSDimitry Andric   // prevent padding this single instruction as well.
77706c3fb27SDimitry Andric   if (mayNeedRelaxation(RF.getInst(), *RF.getSubtargetInfo()))
7785ffd83dbSDimitry Andric     return false;
7795ffd83dbSDimitry Andric 
7805ffd83dbSDimitry Andric   const unsigned OldSize = RF.getContents().size();
7815ffd83dbSDimitry Andric   if (OldSize == 15)
7825ffd83dbSDimitry Andric     return false;
7835ffd83dbSDimitry Andric 
7845ffd83dbSDimitry Andric   const unsigned MaxPossiblePad = std::min(15 - OldSize, RemainingSize);
7855ffd83dbSDimitry Andric   const unsigned RemainingPrefixSize = [&]() -> unsigned {
7865ffd83dbSDimitry Andric     SmallString<15> Code;
7870fca6ea1SDimitry Andric     X86_MC::emitPrefix(Emitter, RF.getInst(), Code, STI);
7885ffd83dbSDimitry Andric     assert(Code.size() < 15 && "The number of prefixes must be less than 15.");
7895ffd83dbSDimitry Andric 
7905ffd83dbSDimitry Andric     // TODO: It turns out we need a decent amount of plumbing for the target
7915ffd83dbSDimitry Andric     // specific bits to determine number of prefixes its safe to add.  Various
7925ffd83dbSDimitry Andric     // targets (older chips mostly, but also Atom family) encounter decoder
7935ffd83dbSDimitry Andric     // stalls with too many prefixes.  For testing purposes, we set the value
7945ffd83dbSDimitry Andric     // externally for the moment.
7955ffd83dbSDimitry Andric     unsigned ExistingPrefixSize = Code.size();
7965ffd83dbSDimitry Andric     if (TargetPrefixMax <= ExistingPrefixSize)
7975ffd83dbSDimitry Andric       return 0;
7985ffd83dbSDimitry Andric     return TargetPrefixMax - ExistingPrefixSize;
7995ffd83dbSDimitry Andric   }();
8005ffd83dbSDimitry Andric   const unsigned PrefixBytesToAdd =
8015ffd83dbSDimitry Andric       std::min(MaxPossiblePad, RemainingPrefixSize);
8025ffd83dbSDimitry Andric   if (PrefixBytesToAdd == 0)
8035ffd83dbSDimitry Andric     return false;
8045ffd83dbSDimitry Andric 
8055ffd83dbSDimitry Andric   const uint8_t Prefix = determinePaddingPrefix(RF.getInst());
8065ffd83dbSDimitry Andric 
8075ffd83dbSDimitry Andric   SmallString<256> Code;
8085ffd83dbSDimitry Andric   Code.append(PrefixBytesToAdd, Prefix);
8095ffd83dbSDimitry Andric   Code.append(RF.getContents().begin(), RF.getContents().end());
8105ffd83dbSDimitry Andric   RF.getContents() = Code;
8115ffd83dbSDimitry Andric 
8125ffd83dbSDimitry Andric   // Adjust the fixups for the change in offsets
8135ffd83dbSDimitry Andric   for (auto &F : RF.getFixups()) {
8145ffd83dbSDimitry Andric     F.setOffset(F.getOffset() + PrefixBytesToAdd);
8155ffd83dbSDimitry Andric   }
8165ffd83dbSDimitry Andric 
8175ffd83dbSDimitry Andric   RemainingSize -= PrefixBytesToAdd;
8185ffd83dbSDimitry Andric   return true;
8195ffd83dbSDimitry Andric }
8205ffd83dbSDimitry Andric 
8215ffd83dbSDimitry Andric bool X86AsmBackend::padInstructionViaRelaxation(MCRelaxableFragment &RF,
8225ffd83dbSDimitry Andric                                                 MCCodeEmitter &Emitter,
8235ffd83dbSDimitry Andric                                                 unsigned &RemainingSize) const {
82406c3fb27SDimitry Andric   if (!mayNeedRelaxation(RF.getInst(), *RF.getSubtargetInfo()))
8255ffd83dbSDimitry Andric     // TODO: There are lots of other tricks we could apply for increasing
8265ffd83dbSDimitry Andric     // encoding size without impacting performance.
8275ffd83dbSDimitry Andric     return false;
8285ffd83dbSDimitry Andric 
8295ffd83dbSDimitry Andric   MCInst Relaxed = RF.getInst();
8305ffd83dbSDimitry Andric   relaxInstruction(Relaxed, *RF.getSubtargetInfo());
8315ffd83dbSDimitry Andric 
8325ffd83dbSDimitry Andric   SmallVector<MCFixup, 4> Fixups;
8335ffd83dbSDimitry Andric   SmallString<15> Code;
83406c3fb27SDimitry Andric   Emitter.encodeInstruction(Relaxed, Code, Fixups, *RF.getSubtargetInfo());
8355ffd83dbSDimitry Andric   const unsigned OldSize = RF.getContents().size();
8365ffd83dbSDimitry Andric   const unsigned NewSize = Code.size();
8375ffd83dbSDimitry Andric   assert(NewSize >= OldSize && "size decrease during relaxation?");
8385ffd83dbSDimitry Andric   unsigned Delta = NewSize - OldSize;
8395ffd83dbSDimitry Andric   if (Delta > RemainingSize)
8405ffd83dbSDimitry Andric     return false;
8415ffd83dbSDimitry Andric   RF.setInst(Relaxed);
8425ffd83dbSDimitry Andric   RF.getContents() = Code;
8435ffd83dbSDimitry Andric   RF.getFixups() = Fixups;
8445ffd83dbSDimitry Andric   RemainingSize -= Delta;
8455ffd83dbSDimitry Andric   return true;
8465ffd83dbSDimitry Andric }
8475ffd83dbSDimitry Andric 
8485ffd83dbSDimitry Andric bool X86AsmBackend::padInstructionEncoding(MCRelaxableFragment &RF,
8495ffd83dbSDimitry Andric                                            MCCodeEmitter &Emitter,
8505ffd83dbSDimitry Andric                                            unsigned &RemainingSize) const {
8515ffd83dbSDimitry Andric   bool Changed = false;
8525ffd83dbSDimitry Andric   if (RemainingSize != 0)
8535ffd83dbSDimitry Andric     Changed |= padInstructionViaRelaxation(RF, Emitter, RemainingSize);
8545ffd83dbSDimitry Andric   if (RemainingSize != 0)
8555ffd83dbSDimitry Andric     Changed |= padInstructionViaPrefix(RF, Emitter, RemainingSize);
8565ffd83dbSDimitry Andric   return Changed;
8575ffd83dbSDimitry Andric }
8585ffd83dbSDimitry Andric 
859*52418fc2SDimitry Andric void X86AsmBackend::finishLayout(MCAssembler const &Asm) const {
8605ffd83dbSDimitry Andric   // See if we can further relax some instructions to cut down on the number of
8615ffd83dbSDimitry Andric   // nop bytes required for code alignment.  The actual win is in reducing
8625ffd83dbSDimitry Andric   // instruction count, not number of bytes.  Modern X86-64 can easily end up
8635ffd83dbSDimitry Andric   // decode limited.  It is often better to reduce the number of instructions
8645ffd83dbSDimitry Andric   // (i.e. eliminate nops) even at the cost of increasing the size and
8655ffd83dbSDimitry Andric   // complexity of others.
8665ffd83dbSDimitry Andric   if (!X86PadForAlign && !X86PadForBranchAlign)
867*52418fc2SDimitry Andric     return;
8685ffd83dbSDimitry Andric 
869e8d8bef9SDimitry Andric   // The processed regions are delimitered by LabeledFragments. -g may have more
870e8d8bef9SDimitry Andric   // MCSymbols and therefore different relaxation results. X86PadForAlign is
871e8d8bef9SDimitry Andric   // disabled by default to eliminate the -g vs non -g difference.
8725ffd83dbSDimitry Andric   DenseSet<MCFragment *> LabeledFragments;
8735ffd83dbSDimitry Andric   for (const MCSymbol &S : Asm.symbols())
8745ffd83dbSDimitry Andric     LabeledFragments.insert(S.getFragment(false));
8755ffd83dbSDimitry Andric 
8765ffd83dbSDimitry Andric   for (MCSection &Sec : Asm) {
8770fca6ea1SDimitry Andric     if (!Sec.isText())
8785ffd83dbSDimitry Andric       continue;
8795ffd83dbSDimitry Andric 
8805ffd83dbSDimitry Andric     SmallVector<MCRelaxableFragment *, 4> Relaxable;
8815ffd83dbSDimitry Andric     for (MCSection::iterator I = Sec.begin(), IE = Sec.end(); I != IE; ++I) {
8825ffd83dbSDimitry Andric       MCFragment &F = *I;
8835ffd83dbSDimitry Andric 
8845ffd83dbSDimitry Andric       if (LabeledFragments.count(&F))
8855ffd83dbSDimitry Andric         Relaxable.clear();
8865ffd83dbSDimitry Andric 
8875ffd83dbSDimitry Andric       if (F.getKind() == MCFragment::FT_Data ||
8885ffd83dbSDimitry Andric           F.getKind() == MCFragment::FT_CompactEncodedInst)
8895ffd83dbSDimitry Andric         // Skip and ignore
8905ffd83dbSDimitry Andric         continue;
8915ffd83dbSDimitry Andric 
8925ffd83dbSDimitry Andric       if (F.getKind() == MCFragment::FT_Relaxable) {
8935ffd83dbSDimitry Andric         auto &RF = cast<MCRelaxableFragment>(*I);
8945ffd83dbSDimitry Andric         Relaxable.push_back(&RF);
8955ffd83dbSDimitry Andric         continue;
8965ffd83dbSDimitry Andric       }
8975ffd83dbSDimitry Andric 
8985ffd83dbSDimitry Andric       auto canHandle = [](MCFragment &F) -> bool {
8995ffd83dbSDimitry Andric         switch (F.getKind()) {
9005ffd83dbSDimitry Andric         default:
9015ffd83dbSDimitry Andric           return false;
9025ffd83dbSDimitry Andric         case MCFragment::FT_Align:
9035ffd83dbSDimitry Andric           return X86PadForAlign;
9045ffd83dbSDimitry Andric         case MCFragment::FT_BoundaryAlign:
9055ffd83dbSDimitry Andric           return X86PadForBranchAlign;
9065ffd83dbSDimitry Andric         }
9075ffd83dbSDimitry Andric       };
9085ffd83dbSDimitry Andric       // For any unhandled kind, assume we can't change layout.
9095ffd83dbSDimitry Andric       if (!canHandle(F)) {
9105ffd83dbSDimitry Andric         Relaxable.clear();
9115ffd83dbSDimitry Andric         continue;
9125ffd83dbSDimitry Andric       }
9135ffd83dbSDimitry Andric 
914*52418fc2SDimitry Andric #ifndef NDEBUG
915*52418fc2SDimitry Andric       const uint64_t OrigOffset = Asm.getFragmentOffset(F);
916*52418fc2SDimitry Andric #endif
9170fca6ea1SDimitry Andric       const uint64_t OrigSize = Asm.computeFragmentSize(F);
9185ffd83dbSDimitry Andric 
9195ffd83dbSDimitry Andric       // To keep the effects local, prefer to relax instructions closest to
9205ffd83dbSDimitry Andric       // the align directive.  This is purely about human understandability
9215ffd83dbSDimitry Andric       // of the resulting code.  If we later find a reason to expand
9225ffd83dbSDimitry Andric       // particular instructions over others, we can adjust.
9235ffd83dbSDimitry Andric       unsigned RemainingSize = OrigSize;
9245ffd83dbSDimitry Andric       while (!Relaxable.empty() && RemainingSize != 0) {
9255ffd83dbSDimitry Andric         auto &RF = *Relaxable.pop_back_val();
9265ffd83dbSDimitry Andric         // Give the backend a chance to play any tricks it wishes to increase
9275ffd83dbSDimitry Andric         // the encoding size of the given instruction.  Target independent code
9285ffd83dbSDimitry Andric         // will try further relaxation, but target's may play further tricks.
929*52418fc2SDimitry Andric         if (padInstructionEncoding(RF, Asm.getEmitter(), RemainingSize))
930*52418fc2SDimitry Andric           Sec.setHasLayout(false);
9315ffd83dbSDimitry Andric 
9325ffd83dbSDimitry Andric         // If we have an instruction which hasn't been fully relaxed, we can't
9335ffd83dbSDimitry Andric         // skip past it and insert bytes before it.  Changing its starting
9345ffd83dbSDimitry Andric         // offset might require a larger negative offset than it can encode.
9355ffd83dbSDimitry Andric         // We don't need to worry about larger positive offsets as none of the
9365ffd83dbSDimitry Andric         // possible offsets between this and our align are visible, and the
9375ffd83dbSDimitry Andric         // ones afterwards aren't changing.
93806c3fb27SDimitry Andric         if (mayNeedRelaxation(RF.getInst(), *RF.getSubtargetInfo()))
9395ffd83dbSDimitry Andric           break;
9405ffd83dbSDimitry Andric       }
9415ffd83dbSDimitry Andric       Relaxable.clear();
9425ffd83dbSDimitry Andric 
9435ffd83dbSDimitry Andric       // BoundaryAlign explicitly tracks it's size (unlike align)
9445ffd83dbSDimitry Andric       if (F.getKind() == MCFragment::FT_BoundaryAlign)
9455ffd83dbSDimitry Andric         cast<MCBoundaryAlignFragment>(F).setSize(RemainingSize);
9465ffd83dbSDimitry Andric 
947*52418fc2SDimitry Andric #ifndef NDEBUG
948*52418fc2SDimitry Andric       const uint64_t FinalOffset = Asm.getFragmentOffset(F);
949*52418fc2SDimitry Andric       const uint64_t FinalSize = Asm.computeFragmentSize(F);
950*52418fc2SDimitry Andric       assert(OrigOffset + OrigSize == FinalOffset + FinalSize &&
951*52418fc2SDimitry Andric              "can't move start of next fragment!");
952*52418fc2SDimitry Andric       assert(FinalSize == RemainingSize && "inconsistent size computation?");
953*52418fc2SDimitry Andric #endif
954*52418fc2SDimitry Andric 
9555ffd83dbSDimitry Andric       // If we're looking at a boundary align, make sure we don't try to pad
9565ffd83dbSDimitry Andric       // its target instructions for some following directive.  Doing so would
9575ffd83dbSDimitry Andric       // break the alignment of the current boundary align.
9585ffd83dbSDimitry Andric       if (auto *BF = dyn_cast<MCBoundaryAlignFragment>(&F)) {
9595ffd83dbSDimitry Andric         const MCFragment *LastFragment = BF->getLastFragment();
9605ffd83dbSDimitry Andric         if (!LastFragment)
9615ffd83dbSDimitry Andric           continue;
9625ffd83dbSDimitry Andric         while (&*I != LastFragment)
9635ffd83dbSDimitry Andric           ++I;
9645ffd83dbSDimitry Andric       }
9655ffd83dbSDimitry Andric     }
9665ffd83dbSDimitry Andric   }
9675ffd83dbSDimitry Andric 
968*52418fc2SDimitry Andric   // The layout is done. Mark every fragment as valid.
969*52418fc2SDimitry Andric   for (MCSection &Section : Asm) {
970*52418fc2SDimitry Andric     Asm.getFragmentOffset(*Section.curFragList()->Tail);
971*52418fc2SDimitry Andric     Asm.computeFragmentSize(*Section.curFragList()->Tail);
972*52418fc2SDimitry Andric   }
9730b57cec5SDimitry Andric }
9740b57cec5SDimitry Andric 
975349cc55cSDimitry Andric unsigned X86AsmBackend::getMaximumNopSize(const MCSubtargetInfo &STI) const {
97681ad6265SDimitry Andric   if (STI.hasFeature(X86::Is16Bit))
977fe6060f1SDimitry Andric     return 4;
97881ad6265SDimitry Andric   if (!STI.hasFeature(X86::FeatureNOPL) && !STI.hasFeature(X86::Is64Bit))
979e8d8bef9SDimitry Andric     return 1;
98006c3fb27SDimitry Andric   if (STI.hasFeature(X86::TuningFast7ByteNOP))
981e8d8bef9SDimitry Andric     return 7;
98206c3fb27SDimitry Andric   if (STI.hasFeature(X86::TuningFast15ByteNOP))
983e8d8bef9SDimitry Andric     return 15;
98406c3fb27SDimitry Andric   if (STI.hasFeature(X86::TuningFast11ByteNOP))
985e8d8bef9SDimitry Andric     return 11;
986e8d8bef9SDimitry Andric   // FIXME: handle 32-bit mode
987e8d8bef9SDimitry Andric   // 15-bytes is the longest single NOP instruction, but 10-bytes is
988e8d8bef9SDimitry Andric   // commonly the longest that can be efficiently decoded.
989e8d8bef9SDimitry Andric   return 10;
990e8d8bef9SDimitry Andric }
991e8d8bef9SDimitry Andric 
9920b57cec5SDimitry Andric /// Write a sequence of optimal nops to the output, covering \p Count
9930b57cec5SDimitry Andric /// bytes.
9940b57cec5SDimitry Andric /// \return - true on success, false on failure
995349cc55cSDimitry Andric bool X86AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
996349cc55cSDimitry Andric                                  const MCSubtargetInfo *STI) const {
997fe6060f1SDimitry Andric   static const char Nops32Bit[10][11] = {
9980b57cec5SDimitry Andric       // nop
9990b57cec5SDimitry Andric       "\x90",
10000b57cec5SDimitry Andric       // xchg %ax,%ax
10010b57cec5SDimitry Andric       "\x66\x90",
10020b57cec5SDimitry Andric       // nopl (%[re]ax)
10030b57cec5SDimitry Andric       "\x0f\x1f\x00",
10040b57cec5SDimitry Andric       // nopl 0(%[re]ax)
10050b57cec5SDimitry Andric       "\x0f\x1f\x40\x00",
10060b57cec5SDimitry Andric       // nopl 0(%[re]ax,%[re]ax,1)
10070b57cec5SDimitry Andric       "\x0f\x1f\x44\x00\x00",
10080b57cec5SDimitry Andric       // nopw 0(%[re]ax,%[re]ax,1)
10090b57cec5SDimitry Andric       "\x66\x0f\x1f\x44\x00\x00",
10100b57cec5SDimitry Andric       // nopl 0L(%[re]ax)
10110b57cec5SDimitry Andric       "\x0f\x1f\x80\x00\x00\x00\x00",
10120b57cec5SDimitry Andric       // nopl 0L(%[re]ax,%[re]ax,1)
10130b57cec5SDimitry Andric       "\x0f\x1f\x84\x00\x00\x00\x00\x00",
10140b57cec5SDimitry Andric       // nopw 0L(%[re]ax,%[re]ax,1)
10150b57cec5SDimitry Andric       "\x66\x0f\x1f\x84\x00\x00\x00\x00\x00",
10160b57cec5SDimitry Andric       // nopw %cs:0L(%[re]ax,%[re]ax,1)
10170b57cec5SDimitry Andric       "\x66\x2e\x0f\x1f\x84\x00\x00\x00\x00\x00",
10180b57cec5SDimitry Andric   };
10190b57cec5SDimitry Andric 
1020fe6060f1SDimitry Andric   // 16-bit mode uses different nop patterns than 32-bit.
1021fe6060f1SDimitry Andric   static const char Nops16Bit[4][11] = {
1022fe6060f1SDimitry Andric       // nop
1023fe6060f1SDimitry Andric       "\x90",
1024fe6060f1SDimitry Andric       // xchg %eax,%eax
1025fe6060f1SDimitry Andric       "\x66\x90",
1026fe6060f1SDimitry Andric       // lea 0(%si),%si
1027fe6060f1SDimitry Andric       "\x8d\x74\x00",
1028fe6060f1SDimitry Andric       // lea 0w(%si),%si
1029fe6060f1SDimitry Andric       "\x8d\xb4\x00\x00",
1030fe6060f1SDimitry Andric   };
1031fe6060f1SDimitry Andric 
1032fe6060f1SDimitry Andric   const char(*Nops)[11] =
103306c3fb27SDimitry Andric       STI->hasFeature(X86::Is16Bit) ? Nops16Bit : Nops32Bit;
1034fe6060f1SDimitry Andric 
1035349cc55cSDimitry Andric   uint64_t MaxNopLength = (uint64_t)getMaximumNopSize(*STI);
10360b57cec5SDimitry Andric 
10370b57cec5SDimitry Andric   // Emit as many MaxNopLength NOPs as needed, then emit a NOP of the remaining
10380b57cec5SDimitry Andric   // length.
10390b57cec5SDimitry Andric   do {
10400b57cec5SDimitry Andric     const uint8_t ThisNopLength = (uint8_t) std::min(Count, MaxNopLength);
10410b57cec5SDimitry Andric     const uint8_t Prefixes = ThisNopLength <= 10 ? 0 : ThisNopLength - 10;
10420b57cec5SDimitry Andric     for (uint8_t i = 0; i < Prefixes; i++)
10430b57cec5SDimitry Andric       OS << '\x66';
10440b57cec5SDimitry Andric     const uint8_t Rest = ThisNopLength - Prefixes;
10450b57cec5SDimitry Andric     if (Rest != 0)
10460b57cec5SDimitry Andric       OS.write(Nops[Rest - 1], Rest);
10470b57cec5SDimitry Andric     Count -= ThisNopLength;
10480b57cec5SDimitry Andric   } while (Count != 0);
10490b57cec5SDimitry Andric 
10500b57cec5SDimitry Andric   return true;
10510b57cec5SDimitry Andric }
10520b57cec5SDimitry Andric 
10530b57cec5SDimitry Andric /* *** */
10540b57cec5SDimitry Andric 
10550b57cec5SDimitry Andric namespace {
10560b57cec5SDimitry Andric 
10570b57cec5SDimitry Andric class ELFX86AsmBackend : public X86AsmBackend {
10580b57cec5SDimitry Andric public:
10590b57cec5SDimitry Andric   uint8_t OSABI;
10600b57cec5SDimitry Andric   ELFX86AsmBackend(const Target &T, uint8_t OSABI, const MCSubtargetInfo &STI)
10610b57cec5SDimitry Andric       : X86AsmBackend(T, STI), OSABI(OSABI) {}
10620b57cec5SDimitry Andric };
10630b57cec5SDimitry Andric 
10640b57cec5SDimitry Andric class ELFX86_32AsmBackend : public ELFX86AsmBackend {
10650b57cec5SDimitry Andric public:
10660b57cec5SDimitry Andric   ELFX86_32AsmBackend(const Target &T, uint8_t OSABI,
10670b57cec5SDimitry Andric                       const MCSubtargetInfo &STI)
10680b57cec5SDimitry Andric     : ELFX86AsmBackend(T, OSABI, STI) {}
10690b57cec5SDimitry Andric 
10700b57cec5SDimitry Andric   std::unique_ptr<MCObjectTargetWriter>
10710b57cec5SDimitry Andric   createObjectTargetWriter() const override {
10720b57cec5SDimitry Andric     return createX86ELFObjectWriter(/*IsELF64*/ false, OSABI, ELF::EM_386);
10730b57cec5SDimitry Andric   }
10740b57cec5SDimitry Andric };
10750b57cec5SDimitry Andric 
10760b57cec5SDimitry Andric class ELFX86_X32AsmBackend : public ELFX86AsmBackend {
10770b57cec5SDimitry Andric public:
10780b57cec5SDimitry Andric   ELFX86_X32AsmBackend(const Target &T, uint8_t OSABI,
10790b57cec5SDimitry Andric                        const MCSubtargetInfo &STI)
10800b57cec5SDimitry Andric       : ELFX86AsmBackend(T, OSABI, STI) {}
10810b57cec5SDimitry Andric 
10820b57cec5SDimitry Andric   std::unique_ptr<MCObjectTargetWriter>
10830b57cec5SDimitry Andric   createObjectTargetWriter() const override {
10840b57cec5SDimitry Andric     return createX86ELFObjectWriter(/*IsELF64*/ false, OSABI,
10850b57cec5SDimitry Andric                                     ELF::EM_X86_64);
10860b57cec5SDimitry Andric   }
10870b57cec5SDimitry Andric };
10880b57cec5SDimitry Andric 
10890b57cec5SDimitry Andric class ELFX86_IAMCUAsmBackend : public ELFX86AsmBackend {
10900b57cec5SDimitry Andric public:
10910b57cec5SDimitry Andric   ELFX86_IAMCUAsmBackend(const Target &T, uint8_t OSABI,
10920b57cec5SDimitry Andric                          const MCSubtargetInfo &STI)
10930b57cec5SDimitry Andric       : ELFX86AsmBackend(T, OSABI, STI) {}
10940b57cec5SDimitry Andric 
10950b57cec5SDimitry Andric   std::unique_ptr<MCObjectTargetWriter>
10960b57cec5SDimitry Andric   createObjectTargetWriter() const override {
10970b57cec5SDimitry Andric     return createX86ELFObjectWriter(/*IsELF64*/ false, OSABI,
10980b57cec5SDimitry Andric                                     ELF::EM_IAMCU);
10990b57cec5SDimitry Andric   }
11000b57cec5SDimitry Andric };
11010b57cec5SDimitry Andric 
11020b57cec5SDimitry Andric class ELFX86_64AsmBackend : public ELFX86AsmBackend {
11030b57cec5SDimitry Andric public:
11040b57cec5SDimitry Andric   ELFX86_64AsmBackend(const Target &T, uint8_t OSABI,
11050b57cec5SDimitry Andric                       const MCSubtargetInfo &STI)
11060b57cec5SDimitry Andric     : ELFX86AsmBackend(T, OSABI, STI) {}
11070b57cec5SDimitry Andric 
11080b57cec5SDimitry Andric   std::unique_ptr<MCObjectTargetWriter>
11090b57cec5SDimitry Andric   createObjectTargetWriter() const override {
11100b57cec5SDimitry Andric     return createX86ELFObjectWriter(/*IsELF64*/ true, OSABI, ELF::EM_X86_64);
11110b57cec5SDimitry Andric   }
11120b57cec5SDimitry Andric };
11130b57cec5SDimitry Andric 
11140b57cec5SDimitry Andric class WindowsX86AsmBackend : public X86AsmBackend {
11150b57cec5SDimitry Andric   bool Is64Bit;
11160b57cec5SDimitry Andric 
11170b57cec5SDimitry Andric public:
11180b57cec5SDimitry Andric   WindowsX86AsmBackend(const Target &T, bool is64Bit,
11190b57cec5SDimitry Andric                        const MCSubtargetInfo &STI)
11200b57cec5SDimitry Andric     : X86AsmBackend(T, STI)
11210b57cec5SDimitry Andric     , Is64Bit(is64Bit) {
11220b57cec5SDimitry Andric   }
11230b57cec5SDimitry Andric 
1124bdd1243dSDimitry Andric   std::optional<MCFixupKind> getFixupKind(StringRef Name) const override {
1125bdd1243dSDimitry Andric     return StringSwitch<std::optional<MCFixupKind>>(Name)
11260b57cec5SDimitry Andric         .Case("dir32", FK_Data_4)
11270b57cec5SDimitry Andric         .Case("secrel32", FK_SecRel_4)
11280b57cec5SDimitry Andric         .Case("secidx", FK_SecRel_2)
11290b57cec5SDimitry Andric         .Default(MCAsmBackend::getFixupKind(Name));
11300b57cec5SDimitry Andric   }
11310b57cec5SDimitry Andric 
11320b57cec5SDimitry Andric   std::unique_ptr<MCObjectTargetWriter>
11330b57cec5SDimitry Andric   createObjectTargetWriter() const override {
11340b57cec5SDimitry Andric     return createX86WinCOFFObjectWriter(Is64Bit);
11350b57cec5SDimitry Andric   }
11360b57cec5SDimitry Andric };
11370b57cec5SDimitry Andric 
11380b57cec5SDimitry Andric namespace CU {
11390b57cec5SDimitry Andric 
11400b57cec5SDimitry Andric   /// Compact unwind encoding values.
11410b57cec5SDimitry Andric   enum CompactUnwindEncodings {
11420b57cec5SDimitry Andric     /// [RE]BP based frame where [RE]BP is pused on the stack immediately after
11430b57cec5SDimitry Andric     /// the return address, then [RE]SP is moved to [RE]BP.
11440b57cec5SDimitry Andric     UNWIND_MODE_BP_FRAME                   = 0x01000000,
11450b57cec5SDimitry Andric 
11460b57cec5SDimitry Andric     /// A frameless function with a small constant stack size.
11470b57cec5SDimitry Andric     UNWIND_MODE_STACK_IMMD                 = 0x02000000,
11480b57cec5SDimitry Andric 
11490b57cec5SDimitry Andric     /// A frameless function with a large constant stack size.
11500b57cec5SDimitry Andric     UNWIND_MODE_STACK_IND                  = 0x03000000,
11510b57cec5SDimitry Andric 
11520b57cec5SDimitry Andric     /// No compact unwind encoding is available.
11530b57cec5SDimitry Andric     UNWIND_MODE_DWARF                      = 0x04000000,
11540b57cec5SDimitry Andric 
11550b57cec5SDimitry Andric     /// Mask for encoding the frame registers.
11560b57cec5SDimitry Andric     UNWIND_BP_FRAME_REGISTERS              = 0x00007FFF,
11570b57cec5SDimitry Andric 
11580b57cec5SDimitry Andric     /// Mask for encoding the frameless registers.
11590b57cec5SDimitry Andric     UNWIND_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF
11600b57cec5SDimitry Andric   };
11610b57cec5SDimitry Andric 
1162e8d8bef9SDimitry Andric } // namespace CU
11630b57cec5SDimitry Andric 
11640b57cec5SDimitry Andric class DarwinX86AsmBackend : public X86AsmBackend {
11650b57cec5SDimitry Andric   const MCRegisterInfo &MRI;
11660b57cec5SDimitry Andric 
11670b57cec5SDimitry Andric   /// Number of registers that can be saved in a compact unwind encoding.
11680b57cec5SDimitry Andric   enum { CU_NUM_SAVED_REGS = 6 };
11690b57cec5SDimitry Andric 
11700b57cec5SDimitry Andric   mutable unsigned SavedRegs[CU_NUM_SAVED_REGS];
11715ffd83dbSDimitry Andric   Triple TT;
11720b57cec5SDimitry Andric   bool Is64Bit;
11730b57cec5SDimitry Andric 
11740b57cec5SDimitry Andric   unsigned OffsetSize;                   ///< Offset of a "push" instruction.
11750b57cec5SDimitry Andric   unsigned MoveInstrSize;                ///< Size of a "move" instruction.
11760b57cec5SDimitry Andric   unsigned StackDivide;                  ///< Amount to adjust stack size by.
11770b57cec5SDimitry Andric protected:
11780b57cec5SDimitry Andric   /// Size of a "push" instruction for the given register.
11790b57cec5SDimitry Andric   unsigned PushInstrSize(unsigned Reg) const {
11800b57cec5SDimitry Andric     switch (Reg) {
11810b57cec5SDimitry Andric       case X86::EBX:
11820b57cec5SDimitry Andric       case X86::ECX:
11830b57cec5SDimitry Andric       case X86::EDX:
11840b57cec5SDimitry Andric       case X86::EDI:
11850b57cec5SDimitry Andric       case X86::ESI:
11860b57cec5SDimitry Andric       case X86::EBP:
11870b57cec5SDimitry Andric       case X86::RBX:
11880b57cec5SDimitry Andric       case X86::RBP:
11890b57cec5SDimitry Andric         return 1;
11900b57cec5SDimitry Andric       case X86::R12:
11910b57cec5SDimitry Andric       case X86::R13:
11920b57cec5SDimitry Andric       case X86::R14:
11930b57cec5SDimitry Andric       case X86::R15:
11940b57cec5SDimitry Andric         return 2;
11950b57cec5SDimitry Andric     }
11960b57cec5SDimitry Andric     return 1;
11970b57cec5SDimitry Andric   }
11980b57cec5SDimitry Andric 
11990b57cec5SDimitry Andric private:
12000b57cec5SDimitry Andric   /// Get the compact unwind number for a given register. The number
12010b57cec5SDimitry Andric   /// corresponds to the enum lists in compact_unwind_encoding.h.
12020b57cec5SDimitry Andric   int getCompactUnwindRegNum(unsigned Reg) const {
12030b57cec5SDimitry Andric     static const MCPhysReg CU32BitRegs[7] = {
12040b57cec5SDimitry Andric       X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0
12050b57cec5SDimitry Andric     };
12060b57cec5SDimitry Andric     static const MCPhysReg CU64BitRegs[] = {
12070b57cec5SDimitry Andric       X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0
12080b57cec5SDimitry Andric     };
12090b57cec5SDimitry Andric     const MCPhysReg *CURegs = Is64Bit ? CU64BitRegs : CU32BitRegs;
12100b57cec5SDimitry Andric     for (int Idx = 1; *CURegs; ++CURegs, ++Idx)
12110b57cec5SDimitry Andric       if (*CURegs == Reg)
12120b57cec5SDimitry Andric         return Idx;
12130b57cec5SDimitry Andric 
12140b57cec5SDimitry Andric     return -1;
12150b57cec5SDimitry Andric   }
12160b57cec5SDimitry Andric 
12170b57cec5SDimitry Andric   /// Return the registers encoded for a compact encoding with a frame
12180b57cec5SDimitry Andric   /// pointer.
12190b57cec5SDimitry Andric   uint32_t encodeCompactUnwindRegistersWithFrame() const {
12200b57cec5SDimitry Andric     // Encode the registers in the order they were saved --- 3-bits per
12210b57cec5SDimitry Andric     // register. The list of saved registers is assumed to be in reverse
12220b57cec5SDimitry Andric     // order. The registers are numbered from 1 to CU_NUM_SAVED_REGS.
12230b57cec5SDimitry Andric     uint32_t RegEnc = 0;
12240b57cec5SDimitry Andric     for (int i = 0, Idx = 0; i != CU_NUM_SAVED_REGS; ++i) {
12250b57cec5SDimitry Andric       unsigned Reg = SavedRegs[i];
12260b57cec5SDimitry Andric       if (Reg == 0) break;
12270b57cec5SDimitry Andric 
12280b57cec5SDimitry Andric       int CURegNum = getCompactUnwindRegNum(Reg);
12290b57cec5SDimitry Andric       if (CURegNum == -1) return ~0U;
12300b57cec5SDimitry Andric 
12310b57cec5SDimitry Andric       // Encode the 3-bit register number in order, skipping over 3-bits for
12320b57cec5SDimitry Andric       // each register.
12330b57cec5SDimitry Andric       RegEnc |= (CURegNum & 0x7) << (Idx++ * 3);
12340b57cec5SDimitry Andric     }
12350b57cec5SDimitry Andric 
12360b57cec5SDimitry Andric     assert((RegEnc & 0x3FFFF) == RegEnc &&
12370b57cec5SDimitry Andric            "Invalid compact register encoding!");
12380b57cec5SDimitry Andric     return RegEnc;
12390b57cec5SDimitry Andric   }
12400b57cec5SDimitry Andric 
12410b57cec5SDimitry Andric   /// Create the permutation encoding used with frameless stacks. It is
12420b57cec5SDimitry Andric   /// passed the number of registers to be saved and an array of the registers
12430b57cec5SDimitry Andric   /// saved.
12440b57cec5SDimitry Andric   uint32_t encodeCompactUnwindRegistersWithoutFrame(unsigned RegCount) const {
12450b57cec5SDimitry Andric     // The saved registers are numbered from 1 to 6. In order to encode the
12460b57cec5SDimitry Andric     // order in which they were saved, we re-number them according to their
12470b57cec5SDimitry Andric     // place in the register order. The re-numbering is relative to the last
12480b57cec5SDimitry Andric     // re-numbered register. E.g., if we have registers {6, 2, 4, 5} saved in
12490b57cec5SDimitry Andric     // that order:
12500b57cec5SDimitry Andric     //
12510b57cec5SDimitry Andric     //    Orig  Re-Num
12520b57cec5SDimitry Andric     //    ----  ------
12530b57cec5SDimitry Andric     //     6       6
12540b57cec5SDimitry Andric     //     2       2
12550b57cec5SDimitry Andric     //     4       3
12560b57cec5SDimitry Andric     //     5       3
12570b57cec5SDimitry Andric     //
12580b57cec5SDimitry Andric     for (unsigned i = 0; i < RegCount; ++i) {
12590b57cec5SDimitry Andric       int CUReg = getCompactUnwindRegNum(SavedRegs[i]);
12600b57cec5SDimitry Andric       if (CUReg == -1) return ~0U;
12610b57cec5SDimitry Andric       SavedRegs[i] = CUReg;
12620b57cec5SDimitry Andric     }
12630b57cec5SDimitry Andric 
12640b57cec5SDimitry Andric     // Reverse the list.
12650b57cec5SDimitry Andric     std::reverse(&SavedRegs[0], &SavedRegs[CU_NUM_SAVED_REGS]);
12660b57cec5SDimitry Andric 
12670b57cec5SDimitry Andric     uint32_t RenumRegs[CU_NUM_SAVED_REGS];
12680b57cec5SDimitry Andric     for (unsigned i = CU_NUM_SAVED_REGS - RegCount; i < CU_NUM_SAVED_REGS; ++i){
12690b57cec5SDimitry Andric       unsigned Countless = 0;
12700b57cec5SDimitry Andric       for (unsigned j = CU_NUM_SAVED_REGS - RegCount; j < i; ++j)
12710b57cec5SDimitry Andric         if (SavedRegs[j] < SavedRegs[i])
12720b57cec5SDimitry Andric           ++Countless;
12730b57cec5SDimitry Andric 
12740b57cec5SDimitry Andric       RenumRegs[i] = SavedRegs[i] - Countless - 1;
12750b57cec5SDimitry Andric     }
12760b57cec5SDimitry Andric 
12770b57cec5SDimitry Andric     // Take the renumbered values and encode them into a 10-bit number.
12780b57cec5SDimitry Andric     uint32_t permutationEncoding = 0;
12790b57cec5SDimitry Andric     switch (RegCount) {
12800b57cec5SDimitry Andric     case 6:
12810b57cec5SDimitry Andric       permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1]
12820b57cec5SDimitry Andric                              + 6 * RenumRegs[2] +  2 * RenumRegs[3]
12830b57cec5SDimitry Andric                              +     RenumRegs[4];
12840b57cec5SDimitry Andric       break;
12850b57cec5SDimitry Andric     case 5:
12860b57cec5SDimitry Andric       permutationEncoding |= 120 * RenumRegs[1] + 24 * RenumRegs[2]
12870b57cec5SDimitry Andric                              + 6 * RenumRegs[3] +  2 * RenumRegs[4]
12880b57cec5SDimitry Andric                              +     RenumRegs[5];
12890b57cec5SDimitry Andric       break;
12900b57cec5SDimitry Andric     case 4:
12910b57cec5SDimitry Andric       permutationEncoding |=  60 * RenumRegs[2] + 12 * RenumRegs[3]
12920b57cec5SDimitry Andric                              + 3 * RenumRegs[4] +      RenumRegs[5];
12930b57cec5SDimitry Andric       break;
12940b57cec5SDimitry Andric     case 3:
12950b57cec5SDimitry Andric       permutationEncoding |=  20 * RenumRegs[3] +  4 * RenumRegs[4]
12960b57cec5SDimitry Andric                              +     RenumRegs[5];
12970b57cec5SDimitry Andric       break;
12980b57cec5SDimitry Andric     case 2:
12990b57cec5SDimitry Andric       permutationEncoding |=   5 * RenumRegs[4] +      RenumRegs[5];
13000b57cec5SDimitry Andric       break;
13010b57cec5SDimitry Andric     case 1:
13020b57cec5SDimitry Andric       permutationEncoding |=       RenumRegs[5];
13030b57cec5SDimitry Andric       break;
13040b57cec5SDimitry Andric     }
13050b57cec5SDimitry Andric 
13060b57cec5SDimitry Andric     assert((permutationEncoding & 0x3FF) == permutationEncoding &&
13070b57cec5SDimitry Andric            "Invalid compact register encoding!");
13080b57cec5SDimitry Andric     return permutationEncoding;
13090b57cec5SDimitry Andric   }
13100b57cec5SDimitry Andric 
13110b57cec5SDimitry Andric public:
13120b57cec5SDimitry Andric   DarwinX86AsmBackend(const Target &T, const MCRegisterInfo &MRI,
13135ffd83dbSDimitry Andric                       const MCSubtargetInfo &STI)
13145ffd83dbSDimitry Andric       : X86AsmBackend(T, STI), MRI(MRI), TT(STI.getTargetTriple()),
13155ffd83dbSDimitry Andric         Is64Bit(TT.isArch64Bit()) {
13160b57cec5SDimitry Andric     memset(SavedRegs, 0, sizeof(SavedRegs));
13170b57cec5SDimitry Andric     OffsetSize = Is64Bit ? 8 : 4;
13180b57cec5SDimitry Andric     MoveInstrSize = Is64Bit ? 3 : 2;
13190b57cec5SDimitry Andric     StackDivide = Is64Bit ? 8 : 4;
13200b57cec5SDimitry Andric   }
13210b57cec5SDimitry Andric 
13220b57cec5SDimitry Andric   std::unique_ptr<MCObjectTargetWriter>
13230b57cec5SDimitry Andric   createObjectTargetWriter() const override {
13245ffd83dbSDimitry Andric     uint32_t CPUType = cantFail(MachO::getCPUType(TT));
13255ffd83dbSDimitry Andric     uint32_t CPUSubType = cantFail(MachO::getCPUSubType(TT));
13265ffd83dbSDimitry Andric     return createX86MachObjectWriter(Is64Bit, CPUType, CPUSubType);
13270b57cec5SDimitry Andric   }
13280b57cec5SDimitry Andric 
13295ffd83dbSDimitry Andric   /// Implementation of algorithm to generate the compact unwind encoding
13305ffd83dbSDimitry Andric   /// for the CFI instructions.
133136b606aeSDimitry Andric   uint64_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI,
133206c3fb27SDimitry Andric                                          const MCContext *Ctxt) const override {
133306c3fb27SDimitry Andric     ArrayRef<MCCFIInstruction> Instrs = FI->Instructions;
13345ffd83dbSDimitry Andric     if (Instrs.empty()) return 0;
133506c3fb27SDimitry Andric     if (!isDarwinCanonicalPersonality(FI->Personality) &&
133606c3fb27SDimitry Andric         !Ctxt->emitCompactUnwindNonCanonical())
133706c3fb27SDimitry Andric       return CU::UNWIND_MODE_DWARF;
13385ffd83dbSDimitry Andric 
13395ffd83dbSDimitry Andric     // Reset the saved registers.
13405ffd83dbSDimitry Andric     unsigned SavedRegIdx = 0;
13415ffd83dbSDimitry Andric     memset(SavedRegs, 0, sizeof(SavedRegs));
13425ffd83dbSDimitry Andric 
13435ffd83dbSDimitry Andric     bool HasFP = false;
13445ffd83dbSDimitry Andric 
13455ffd83dbSDimitry Andric     // Encode that we are using EBP/RBP as the frame pointer.
134636b606aeSDimitry Andric     uint64_t CompactUnwindEncoding = 0;
13475ffd83dbSDimitry Andric 
13485ffd83dbSDimitry Andric     unsigned SubtractInstrIdx = Is64Bit ? 3 : 2;
13495ffd83dbSDimitry Andric     unsigned InstrOffset = 0;
13505ffd83dbSDimitry Andric     unsigned StackAdjust = 0;
135136b606aeSDimitry Andric     uint64_t StackSize = 0;
135236b606aeSDimitry Andric     int64_t MinAbsOffset = std::numeric_limits<int64_t>::max();
13535ffd83dbSDimitry Andric 
13544824e7fdSDimitry Andric     for (const MCCFIInstruction &Inst : Instrs) {
13555ffd83dbSDimitry Andric       switch (Inst.getOperation()) {
13565ffd83dbSDimitry Andric       default:
13575ffd83dbSDimitry Andric         // Any other CFI directives indicate a frame that we aren't prepared
13585ffd83dbSDimitry Andric         // to represent via compact unwind, so just bail out.
135981ad6265SDimitry Andric         return CU::UNWIND_MODE_DWARF;
13605ffd83dbSDimitry Andric       case MCCFIInstruction::OpDefCfaRegister: {
13615ffd83dbSDimitry Andric         // Defines a frame pointer. E.g.
13625ffd83dbSDimitry Andric         //
13635ffd83dbSDimitry Andric         //     movq %rsp, %rbp
13645ffd83dbSDimitry Andric         //  L0:
13655ffd83dbSDimitry Andric         //     .cfi_def_cfa_register %rbp
13665ffd83dbSDimitry Andric         //
13675ffd83dbSDimitry Andric         HasFP = true;
13685ffd83dbSDimitry Andric 
13695ffd83dbSDimitry Andric         // If the frame pointer is other than esp/rsp, we do not have a way to
13705ffd83dbSDimitry Andric         // generate a compact unwinding representation, so bail out.
13715ffd83dbSDimitry Andric         if (*MRI.getLLVMRegNum(Inst.getRegister(), true) !=
13725ffd83dbSDimitry Andric             (Is64Bit ? X86::RBP : X86::EBP))
137381ad6265SDimitry Andric           return CU::UNWIND_MODE_DWARF;
13745ffd83dbSDimitry Andric 
13755ffd83dbSDimitry Andric         // Reset the counts.
13765ffd83dbSDimitry Andric         memset(SavedRegs, 0, sizeof(SavedRegs));
13775ffd83dbSDimitry Andric         StackAdjust = 0;
13785ffd83dbSDimitry Andric         SavedRegIdx = 0;
137936b606aeSDimitry Andric         MinAbsOffset = std::numeric_limits<int64_t>::max();
13805ffd83dbSDimitry Andric         InstrOffset += MoveInstrSize;
13815ffd83dbSDimitry Andric         break;
13820b57cec5SDimitry Andric       }
13835ffd83dbSDimitry Andric       case MCCFIInstruction::OpDefCfaOffset: {
13845ffd83dbSDimitry Andric         // Defines a new offset for the CFA. E.g.
13855ffd83dbSDimitry Andric         //
13865ffd83dbSDimitry Andric         //  With frame:
13875ffd83dbSDimitry Andric         //
13885ffd83dbSDimitry Andric         //     pushq %rbp
13895ffd83dbSDimitry Andric         //  L0:
13905ffd83dbSDimitry Andric         //     .cfi_def_cfa_offset 16
13915ffd83dbSDimitry Andric         //
13925ffd83dbSDimitry Andric         //  Without frame:
13935ffd83dbSDimitry Andric         //
13945ffd83dbSDimitry Andric         //     subq $72, %rsp
13955ffd83dbSDimitry Andric         //  L0:
13965ffd83dbSDimitry Andric         //     .cfi_def_cfa_offset 80
13975ffd83dbSDimitry Andric         //
13985ffd83dbSDimitry Andric         StackSize = Inst.getOffset() / StackDivide;
13995ffd83dbSDimitry Andric         break;
14005ffd83dbSDimitry Andric       }
14015ffd83dbSDimitry Andric       case MCCFIInstruction::OpOffset: {
14025ffd83dbSDimitry Andric         // Defines a "push" of a callee-saved register. E.g.
14035ffd83dbSDimitry Andric         //
14045ffd83dbSDimitry Andric         //     pushq %r15
14055ffd83dbSDimitry Andric         //     pushq %r14
14065ffd83dbSDimitry Andric         //     pushq %rbx
14075ffd83dbSDimitry Andric         //  L0:
14085ffd83dbSDimitry Andric         //     subq $120, %rsp
14095ffd83dbSDimitry Andric         //  L1:
14105ffd83dbSDimitry Andric         //     .cfi_offset %rbx, -40
14115ffd83dbSDimitry Andric         //     .cfi_offset %r14, -32
14125ffd83dbSDimitry Andric         //     .cfi_offset %r15, -24
14135ffd83dbSDimitry Andric         //
14145ffd83dbSDimitry Andric         if (SavedRegIdx == CU_NUM_SAVED_REGS)
14155ffd83dbSDimitry Andric           // If there are too many saved registers, we cannot use a compact
14165ffd83dbSDimitry Andric           // unwind encoding.
14175ffd83dbSDimitry Andric           return CU::UNWIND_MODE_DWARF;
14180b57cec5SDimitry Andric 
14195ffd83dbSDimitry Andric         unsigned Reg = *MRI.getLLVMRegNum(Inst.getRegister(), true);
14205ffd83dbSDimitry Andric         SavedRegs[SavedRegIdx++] = Reg;
14215ffd83dbSDimitry Andric         StackAdjust += OffsetSize;
142236b606aeSDimitry Andric         MinAbsOffset = std::min(MinAbsOffset, std::abs(Inst.getOffset()));
14235ffd83dbSDimitry Andric         InstrOffset += PushInstrSize(Reg);
14245ffd83dbSDimitry Andric         break;
14255ffd83dbSDimitry Andric       }
14265ffd83dbSDimitry Andric       }
14270b57cec5SDimitry Andric     }
14280b57cec5SDimitry Andric 
14295ffd83dbSDimitry Andric     StackAdjust /= StackDivide;
14305ffd83dbSDimitry Andric 
14315ffd83dbSDimitry Andric     if (HasFP) {
14325ffd83dbSDimitry Andric       if ((StackAdjust & 0xFF) != StackAdjust)
14335ffd83dbSDimitry Andric         // Offset was too big for a compact unwind encoding.
14345ffd83dbSDimitry Andric         return CU::UNWIND_MODE_DWARF;
14355ffd83dbSDimitry Andric 
1436fe6060f1SDimitry Andric       // We don't attempt to track a real StackAdjust, so if the saved registers
1437fe6060f1SDimitry Andric       // aren't adjacent to rbp we can't cope.
1438fe6060f1SDimitry Andric       if (SavedRegIdx != 0 && MinAbsOffset != 3 * (int)OffsetSize)
1439fe6060f1SDimitry Andric         return CU::UNWIND_MODE_DWARF;
1440fe6060f1SDimitry Andric 
14415ffd83dbSDimitry Andric       // Get the encoding of the saved registers when we have a frame pointer.
14425ffd83dbSDimitry Andric       uint32_t RegEnc = encodeCompactUnwindRegistersWithFrame();
14435ffd83dbSDimitry Andric       if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF;
14445ffd83dbSDimitry Andric 
14455ffd83dbSDimitry Andric       CompactUnwindEncoding |= CU::UNWIND_MODE_BP_FRAME;
14465ffd83dbSDimitry Andric       CompactUnwindEncoding |= (StackAdjust & 0xFF) << 16;
14475ffd83dbSDimitry Andric       CompactUnwindEncoding |= RegEnc & CU::UNWIND_BP_FRAME_REGISTERS;
14485ffd83dbSDimitry Andric     } else {
14495ffd83dbSDimitry Andric       SubtractInstrIdx += InstrOffset;
14505ffd83dbSDimitry Andric       ++StackAdjust;
14515ffd83dbSDimitry Andric 
14525ffd83dbSDimitry Andric       if ((StackSize & 0xFF) == StackSize) {
14535ffd83dbSDimitry Andric         // Frameless stack with a small stack size.
14545ffd83dbSDimitry Andric         CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IMMD;
14555ffd83dbSDimitry Andric 
14565ffd83dbSDimitry Andric         // Encode the stack size.
14575ffd83dbSDimitry Andric         CompactUnwindEncoding |= (StackSize & 0xFF) << 16;
14585ffd83dbSDimitry Andric       } else {
14595ffd83dbSDimitry Andric         if ((StackAdjust & 0x7) != StackAdjust)
14605ffd83dbSDimitry Andric           // The extra stack adjustments are too big for us to handle.
14615ffd83dbSDimitry Andric           return CU::UNWIND_MODE_DWARF;
14625ffd83dbSDimitry Andric 
14635ffd83dbSDimitry Andric         // Frameless stack with an offset too large for us to encode compactly.
14645ffd83dbSDimitry Andric         CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IND;
14655ffd83dbSDimitry Andric 
14665ffd83dbSDimitry Andric         // Encode the offset to the nnnnnn value in the 'subl $nnnnnn, ESP'
14675ffd83dbSDimitry Andric         // instruction.
14685ffd83dbSDimitry Andric         CompactUnwindEncoding |= (SubtractInstrIdx & 0xFF) << 16;
14695ffd83dbSDimitry Andric 
14705ffd83dbSDimitry Andric         // Encode any extra stack adjustments (done via push instructions).
14715ffd83dbSDimitry Andric         CompactUnwindEncoding |= (StackAdjust & 0x7) << 13;
14725ffd83dbSDimitry Andric       }
14735ffd83dbSDimitry Andric 
14745ffd83dbSDimitry Andric       // Encode the number of registers saved. (Reverse the list first.)
14755ffd83dbSDimitry Andric       std::reverse(&SavedRegs[0], &SavedRegs[SavedRegIdx]);
14765ffd83dbSDimitry Andric       CompactUnwindEncoding |= (SavedRegIdx & 0x7) << 10;
14775ffd83dbSDimitry Andric 
14785ffd83dbSDimitry Andric       // Get the encoding of the saved registers when we don't have a frame
14795ffd83dbSDimitry Andric       // pointer.
14805ffd83dbSDimitry Andric       uint32_t RegEnc = encodeCompactUnwindRegistersWithoutFrame(SavedRegIdx);
14815ffd83dbSDimitry Andric       if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF;
14825ffd83dbSDimitry Andric 
14835ffd83dbSDimitry Andric       // Encode the register encoding.
14845ffd83dbSDimitry Andric       CompactUnwindEncoding |=
14855ffd83dbSDimitry Andric         RegEnc & CU::UNWIND_FRAMELESS_STACK_REG_PERMUTATION;
14865ffd83dbSDimitry Andric     }
14875ffd83dbSDimitry Andric 
14885ffd83dbSDimitry Andric     return CompactUnwindEncoding;
14890b57cec5SDimitry Andric   }
14900b57cec5SDimitry Andric };
14910b57cec5SDimitry Andric 
14920b57cec5SDimitry Andric } // end anonymous namespace
14930b57cec5SDimitry Andric 
14940b57cec5SDimitry Andric MCAsmBackend *llvm::createX86_32AsmBackend(const Target &T,
14950b57cec5SDimitry Andric                                            const MCSubtargetInfo &STI,
14960b57cec5SDimitry Andric                                            const MCRegisterInfo &MRI,
14970b57cec5SDimitry Andric                                            const MCTargetOptions &Options) {
14980b57cec5SDimitry Andric   const Triple &TheTriple = STI.getTargetTriple();
14990b57cec5SDimitry Andric   if (TheTriple.isOSBinFormatMachO())
15005ffd83dbSDimitry Andric     return new DarwinX86AsmBackend(T, MRI, STI);
15010b57cec5SDimitry Andric 
15020b57cec5SDimitry Andric   if (TheTriple.isOSWindows() && TheTriple.isOSBinFormatCOFF())
15030b57cec5SDimitry Andric     return new WindowsX86AsmBackend(T, false, STI);
15040b57cec5SDimitry Andric 
15050b57cec5SDimitry Andric   uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
15060b57cec5SDimitry Andric 
15070b57cec5SDimitry Andric   if (TheTriple.isOSIAMCU())
15080b57cec5SDimitry Andric     return new ELFX86_IAMCUAsmBackend(T, OSABI, STI);
15090b57cec5SDimitry Andric 
15100b57cec5SDimitry Andric   return new ELFX86_32AsmBackend(T, OSABI, STI);
15110b57cec5SDimitry Andric }
15120b57cec5SDimitry Andric 
15130b57cec5SDimitry Andric MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T,
15140b57cec5SDimitry Andric                                            const MCSubtargetInfo &STI,
15150b57cec5SDimitry Andric                                            const MCRegisterInfo &MRI,
15160b57cec5SDimitry Andric                                            const MCTargetOptions &Options) {
15170b57cec5SDimitry Andric   const Triple &TheTriple = STI.getTargetTriple();
15185ffd83dbSDimitry Andric   if (TheTriple.isOSBinFormatMachO())
15195ffd83dbSDimitry Andric     return new DarwinX86AsmBackend(T, MRI, STI);
15200b57cec5SDimitry Andric 
15210b57cec5SDimitry Andric   if (TheTriple.isOSWindows() && TheTriple.isOSBinFormatCOFF())
15220b57cec5SDimitry Andric     return new WindowsX86AsmBackend(T, true, STI);
15230b57cec5SDimitry Andric 
152406c3fb27SDimitry Andric   if (TheTriple.isUEFI()) {
152506c3fb27SDimitry Andric     assert(TheTriple.isOSBinFormatCOFF() &&
152606c3fb27SDimitry Andric          "Only COFF format is supported in UEFI environment.");
152706c3fb27SDimitry Andric     return new WindowsX86AsmBackend(T, true, STI);
152806c3fb27SDimitry Andric   }
152906c3fb27SDimitry Andric 
15300b57cec5SDimitry Andric   uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
15310b57cec5SDimitry Andric 
1532fe6060f1SDimitry Andric   if (TheTriple.isX32())
15330b57cec5SDimitry Andric     return new ELFX86_X32AsmBackend(T, OSABI, STI);
15340b57cec5SDimitry Andric   return new ELFX86_64AsmBackend(T, OSABI, STI);
15350b57cec5SDimitry Andric }
15360fca6ea1SDimitry Andric 
15370fca6ea1SDimitry Andric namespace {
15380fca6ea1SDimitry Andric class X86ELFStreamer : public MCELFStreamer {
15390fca6ea1SDimitry Andric public:
15400fca6ea1SDimitry Andric   X86ELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
15410fca6ea1SDimitry Andric                  std::unique_ptr<MCObjectWriter> OW,
15420fca6ea1SDimitry Andric                  std::unique_ptr<MCCodeEmitter> Emitter)
15430fca6ea1SDimitry Andric       : MCELFStreamer(Context, std::move(TAB), std::move(OW),
15440fca6ea1SDimitry Andric                       std::move(Emitter)) {}
15450fca6ea1SDimitry Andric 
15460fca6ea1SDimitry Andric   void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
15470fca6ea1SDimitry Andric };
15480fca6ea1SDimitry Andric } // end anonymous namespace
15490fca6ea1SDimitry Andric 
15500fca6ea1SDimitry Andric void X86_MC::emitInstruction(MCObjectStreamer &S, const MCInst &Inst,
15510fca6ea1SDimitry Andric                              const MCSubtargetInfo &STI) {
15520fca6ea1SDimitry Andric   auto &Backend = static_cast<X86AsmBackend &>(S.getAssembler().getBackend());
15530fca6ea1SDimitry Andric   Backend.emitInstructionBegin(S, Inst, STI);
15540fca6ea1SDimitry Andric   S.MCObjectStreamer::emitInstruction(Inst, STI);
15550fca6ea1SDimitry Andric   Backend.emitInstructionEnd(S, Inst);
15560fca6ea1SDimitry Andric }
15570fca6ea1SDimitry Andric 
15580fca6ea1SDimitry Andric void X86ELFStreamer::emitInstruction(const MCInst &Inst,
15590fca6ea1SDimitry Andric                                      const MCSubtargetInfo &STI) {
15600fca6ea1SDimitry Andric   X86_MC::emitInstruction(*this, Inst, STI);
15610fca6ea1SDimitry Andric }
15620fca6ea1SDimitry Andric 
15630fca6ea1SDimitry Andric MCStreamer *llvm::createX86ELFStreamer(const Triple &T, MCContext &Context,
15640fca6ea1SDimitry Andric                                        std::unique_ptr<MCAsmBackend> &&MAB,
15650fca6ea1SDimitry Andric                                        std::unique_ptr<MCObjectWriter> &&MOW,
15660fca6ea1SDimitry Andric                                        std::unique_ptr<MCCodeEmitter> &&MCE) {
15670fca6ea1SDimitry Andric   return new X86ELFStreamer(Context, std::move(MAB), std::move(MOW),
15680fca6ea1SDimitry Andric                             std::move(MCE));
15690fca6ea1SDimitry Andric }
1570