101 using namespace llvm;
104 "asan-instrument-assembly",
109 std::numeric_limits<int32_t>::min();
114 return std::max(std::min(MaxAllowedDisplacement, Displacement),
115 MinAllowedDisplacement);
119 assert(Displacement >= MinAllowedDisplacement &&
120 Displacement <= MaxAllowedDisplacement);
124 return Reg == X86::RSP || Reg ==
X86::ESP;
133 struct RegisterContext {
136 REG_OFFSET_ADDRESS = 0,
142 RegisterContext(
unsigned AddressReg,
unsigned ShadowReg,
143 unsigned ScratchReg) {
144 BusyRegs.push_back(convReg(AddressReg, 64));
145 BusyRegs.push_back(convReg(ShadowReg, 64));
146 BusyRegs.push_back(convReg(ScratchReg, 64));
149 unsigned AddressReg(
unsigned Size)
const {
150 return convReg(BusyRegs[REG_OFFSET_ADDRESS], Size);
153 unsigned ShadowReg(
unsigned Size)
const {
154 return convReg(BusyRegs[REG_OFFSET_SHADOW], Size);
157 unsigned ScratchReg(
unsigned Size)
const {
158 return convReg(BusyRegs[REG_OFFSET_SCRATCH], Size);
161 void AddBusyReg(
unsigned Reg) {
162 if (Reg != X86::NoRegister)
163 BusyRegs.push_back(convReg(Reg, 64));
171 unsigned ChooseFrameReg(
unsigned Size)
const {
172 static const MCPhysReg Candidates[] = { X86::RBP, X86::RAX, X86::RBX,
173 X86::RCX, X86::RDX, X86::RDI,
175 for (
unsigned Reg : Candidates) {
177 return convReg(Reg, Size);
179 return X86::NoRegister;
183 unsigned convReg(
unsigned Reg,
unsigned Size)
const {
187 std::vector<unsigned> BusyRegs;
193 ~X86AddressSanitizer()
override =
default;
200 InstrumentMOVS(Inst, Operands, Ctx, MII, Out);
204 InstrumentMOV(Inst, Operands, Ctx, MII, Out);
206 RepPrefix = (Inst.
getOpcode() == X86::REP_PREFIX);
208 EmitInstruction(Out, Inst);
212 virtual void InstrumentMemOperandPrologue(
const RegisterContext &RegCtx,
217 virtual void InstrumentMemOperandEpilogue(
const RegisterContext &RegCtx,
221 virtual void InstrumentMemOperandSmall(
X86Operand &
Op,
unsigned AccessSize,
223 const RegisterContext &RegCtx,
225 virtual void InstrumentMemOperandLarge(
X86Operand &Op,
unsigned AccessSize,
227 const RegisterContext &RegCtx,
230 virtual void InstrumentMOVSImpl(
unsigned AccessSize,
MCContext &Ctx,
233 void InstrumentMemOperand(
X86Operand &Op,
unsigned AccessSize,
bool IsWrite,
234 const RegisterContext &RegCtx,
MCContext &Ctx,
236 void InstrumentMOVSBase(
unsigned DstReg,
unsigned SrcReg,
unsigned CntReg,
248 assert(Size == 32 || Size == 64);
250 Inst.
setOpcode(Size == 32 ? X86::LEA32r : X86::LEA64r);
253 EmitInstruction(Out, Inst);
256 void ComputeMemOperandAddress(
X86Operand &Op,
unsigned Size,
262 std::unique_ptr<X86Operand> AddDisplacement(
X86Operand &Op,
263 int64_t Displacement,
266 bool is64BitMode()
const {
270 bool is32BitMode()
const {
274 bool is16BitMode()
const {
278 unsigned getPointerWidth() {
279 if (is16BitMode())
return 16;
280 if (is32BitMode())
return 32;
281 if (is64BitMode())
return 64;
289 int64_t OrigSPOffset;
292 void X86AddressSanitizer::InstrumentMemOperand(
295 assert(Op.
isMem() &&
"Op should be a memory operand.");
296 assert((AccessSize & (AccessSize - 1)) == 0 && AccessSize <= 16 &&
297 "AccessSize should be a power of two, less or equal than 16.");
300 InstrumentMemOperandSmall(Op, AccessSize, IsWrite, RegCtx, Ctx, Out);
302 InstrumentMemOperandLarge(Op, AccessSize, IsWrite, RegCtx, Ctx, Out);
305 void X86AddressSanitizer::InstrumentMOVSBase(
unsigned DstReg,
unsigned SrcReg,
311 RegisterContext RegCtx(X86::RDX , X86::RAX ,
315 RegCtx.AddBusyReg(DstReg);
316 RegCtx.AddBusyReg(SrcReg);
317 RegCtx.AddBusyReg(CntReg);
319 InstrumentMemOperandPrologue(RegCtx, Ctx, Out);
325 getPointerWidth(), 0, Disp, SrcReg, 0, AccessSize,
SMLoc(),
SMLoc()));
326 InstrumentMemOperand(*Op, AccessSize,
false , RegCtx, Ctx,
334 getPointerWidth(), 0, Disp, SrcReg, CntReg, AccessSize,
SMLoc(),
336 InstrumentMemOperand(*Op, AccessSize,
false , RegCtx, Ctx,
344 getPointerWidth(), 0, Disp, DstReg, 0, AccessSize,
SMLoc(),
SMLoc()));
345 InstrumentMemOperand(*Op, AccessSize,
true , RegCtx, Ctx, Out);
352 getPointerWidth(), 0, Disp, DstReg, CntReg, AccessSize,
SMLoc(),
354 InstrumentMemOperand(*Op, AccessSize,
true , RegCtx, Ctx, Out);
357 InstrumentMemOperandEpilogue(RegCtx, Ctx, Out);
360 void X86AddressSanitizer::InstrumentMOVS(
const MCInst &Inst,
365 unsigned AccessSize = 0;
384 InstrumentMOVSImpl(AccessSize, Ctx, Out);
387 void X86AddressSanitizer::InstrumentMOV(
const MCInst &Inst,
392 unsigned AccessSize = 0;
425 const bool IsWrite = MII.
get(Inst.
getOpcode()).mayStore();
427 for (
unsigned Ix = 0; Ix < Operands.
size(); ++Ix) {
432 RegisterContext RegCtx(
433 X86::RDI , X86::RAX ,
436 RegCtx.AddBusyRegs(MemOp);
437 InstrumentMemOperandPrologue(RegCtx, Ctx, Out);
438 InstrumentMemOperand(MemOp, AccessSize, IsWrite, RegCtx, Ctx, Out);
439 InstrumentMemOperandEpilogue(RegCtx, Ctx, Out);
444 void X86AddressSanitizer::ComputeMemOperandAddress(
X86Operand &Op,
448 int64_t Displacement = 0;
450 Displacement -= OrigSPOffset;
454 assert(Displacement >= 0);
457 if (Displacement == 0) {
458 EmitLEA(Op, Size, Reg, Out);
463 std::unique_ptr<X86Operand> NewOp =
464 AddDisplacement(Op, Displacement, Ctx, &Residue);
465 EmitLEA(*NewOp, Size, Reg, Out);
467 while (Residue != 0) {
470 std::unique_ptr<X86Operand> DispOp =
473 EmitLEA(*DispOp, Size, Reg, Out);
478 std::unique_ptr<X86Operand>
479 X86AddressSanitizer::AddDisplacement(
X86Operand &Op, int64_t Displacement,
481 assert(Displacement >= 0);
483 if (Displacement == 0 ||
485 *Residue = Displacement;
492 int64_t OrigDisplacement =
495 Displacement += OrigDisplacement;
500 *Residue = Displacement - NewDisplacement;
507 class X86AddressSanitizer32 :
public X86AddressSanitizer {
509 static const long kShadowOffset = 0x20000000;
512 : X86AddressSanitizer(STI) {}
514 ~X86AddressSanitizer32()
override =
default;
517 unsigned FrameReg = GetFrameRegGeneric(Ctx, Out);
518 if (FrameReg == X86::NoRegister)
523 void SpillReg(
MCStreamer &Out,
unsigned Reg) {
524 EmitInstruction(Out,
MCInstBuilder(X86::PUSH32r).addReg(Reg));
528 void RestoreReg(
MCStreamer &Out,
unsigned Reg) {
529 EmitInstruction(Out,
MCInstBuilder(X86::POP32r).addReg(Reg));
543 void InstrumentMemOperandPrologue(
const RegisterContext &RegCtx,
546 unsigned LocalFrameReg = RegCtx.ChooseFrameReg(32);
547 assert(LocalFrameReg != X86::NoRegister);
550 unsigned FrameReg = GetFrameReg(Ctx, Out);
551 if (MRI && FrameReg != X86::NoRegister) {
552 SpillReg(Out, LocalFrameReg);
560 MCInstBuilder(X86::MOV32rr).addReg(LocalFrameReg).addReg(FrameReg));
566 SpillReg(Out, RegCtx.AddressReg(32));
567 SpillReg(Out, RegCtx.ShadowReg(32));
568 if (RegCtx.ScratchReg(32) != X86::NoRegister)
569 SpillReg(Out, RegCtx.ScratchReg(32));
573 void InstrumentMemOperandEpilogue(
const RegisterContext &RegCtx,
576 unsigned LocalFrameReg = RegCtx.ChooseFrameReg(32);
577 assert(LocalFrameReg != X86::NoRegister);
580 if (RegCtx.ScratchReg(32) != X86::NoRegister)
581 RestoreReg(Out, RegCtx.ScratchReg(32));
582 RestoreReg(Out, RegCtx.ShadowReg(32));
583 RestoreReg(Out, RegCtx.AddressReg(32));
585 unsigned FrameReg = GetFrameReg(Ctx, Out);
587 RestoreReg(Out, LocalFrameReg);
594 void InstrumentMemOperandSmall(
X86Operand &Op,
unsigned AccessSize,
596 const RegisterContext &RegCtx,
599 void InstrumentMemOperandLarge(
X86Operand &Op,
unsigned AccessSize,
601 const RegisterContext &RegCtx,
604 void InstrumentMOVSImpl(
unsigned AccessSize,
MCContext &Ctx,
608 void EmitCallAsanReport(
unsigned AccessSize,
bool IsWrite,
MCContext &Ctx,
609 MCStreamer &Out,
const RegisterContext &RegCtx) {
618 Out,
MCInstBuilder(X86::PUSH32r).addReg(RegCtx.AddressReg(32)));
621 (IsWrite ?
"store" :
"load") +
625 EmitInstruction(Out,
MCInstBuilder(X86::CALLpcrel32).addExpr(FnExpr));
629 void X86AddressSanitizer32::InstrumentMemOperandSmall(
630 X86Operand &Op,
unsigned AccessSize,
bool IsWrite,
632 unsigned AddressRegI32 = RegCtx.AddressReg(32);
633 unsigned ShadowRegI32 = RegCtx.ShadowReg(32);
634 unsigned ShadowRegI8 = RegCtx.ShadowReg(8);
636 assert(RegCtx.ScratchReg(32) != X86::NoRegister);
637 unsigned ScratchRegI32 = RegCtx.ScratchReg(32);
639 ComputeMemOperandAddress(Op, 32, AddressRegI32, Ctx, Out);
641 EmitInstruction(Out,
MCInstBuilder(X86::MOV32rr).addReg(ShadowRegI32).addReg(
644 .addReg(ShadowRegI32)
645 .addReg(ShadowRegI32)
653 std::unique_ptr<X86Operand>
Op(
656 Op->addMemOperands(Inst, 5);
657 EmitInstruction(Out, Inst);
661 Out,
MCInstBuilder(X86::TEST8rr).addReg(ShadowRegI8).addReg(ShadowRegI8));
664 EmitInstruction(Out,
MCInstBuilder(X86::JE_1).addExpr(DoneExpr));
666 EmitInstruction(Out,
MCInstBuilder(X86::MOV32rr).addReg(ScratchRegI32).addReg(
669 .addReg(ScratchRegI32)
670 .addReg(ScratchRegI32)
673 switch (AccessSize) {
679 std::unique_ptr<X86Operand>
Op(
682 EmitLEA(*Op, 32, ScratchRegI32, Out);
687 .addReg(ScratchRegI32)
688 .addReg(ScratchRegI32)
695 MCInstBuilder(X86::MOVSX32rr8).addReg(ShadowRegI32).addReg(ShadowRegI8));
696 EmitInstruction(Out,
MCInstBuilder(X86::CMP32rr).addReg(ScratchRegI32).addReg(
698 EmitInstruction(Out,
MCInstBuilder(X86::JL_1).addExpr(DoneExpr));
700 EmitCallAsanReport(AccessSize, IsWrite, Ctx, Out, RegCtx);
701 EmitLabel(Out, DoneSym);
704 void X86AddressSanitizer32::InstrumentMemOperandLarge(
705 X86Operand &Op,
unsigned AccessSize,
bool IsWrite,
707 unsigned AddressRegI32 = RegCtx.AddressReg(32);
708 unsigned ShadowRegI32 = RegCtx.ShadowReg(32);
710 ComputeMemOperandAddress(Op, 32, AddressRegI32, Ctx, Out);
712 EmitInstruction(Out,
MCInstBuilder(X86::MOV32rr).addReg(ShadowRegI32).addReg(
715 .addReg(ShadowRegI32)
716 .addReg(ShadowRegI32)
720 switch (AccessSize) {
730 std::unique_ptr<X86Operand>
Op(
733 Op->addMemOperands(Inst, 5);
735 EmitInstruction(Out, Inst);
739 EmitInstruction(Out,
MCInstBuilder(X86::JE_1).addExpr(DoneExpr));
741 EmitCallAsanReport(AccessSize, IsWrite, Ctx, Out, RegCtx);
742 EmitLabel(Out, DoneSym);
745 void X86AddressSanitizer32::InstrumentMOVSImpl(
unsigned AccessSize,
755 EmitInstruction(Out,
MCInstBuilder(X86::JE_1).addExpr(DoneExpr));
761 EmitLabel(Out, DoneSym);
765 class X86AddressSanitizer64 :
public X86AddressSanitizer {
767 static const long kShadowOffset = 0x7fff8000;
770 : X86AddressSanitizer(STI) {}
772 ~X86AddressSanitizer64()
override =
default;
775 unsigned FrameReg = GetFrameRegGeneric(Ctx, Out);
776 if (FrameReg == X86::NoRegister)
781 void SpillReg(
MCStreamer &Out,
unsigned Reg) {
782 EmitInstruction(Out,
MCInstBuilder(X86::PUSH64r).addReg(Reg));
786 void RestoreReg(
MCStreamer &Out,
unsigned Reg) {
787 EmitInstruction(Out,
MCInstBuilder(X86::POP64r).addReg(Reg));
801 void InstrumentMemOperandPrologue(
const RegisterContext &RegCtx,
804 unsigned LocalFrameReg = RegCtx.ChooseFrameReg(64);
805 assert(LocalFrameReg != X86::NoRegister);
808 unsigned FrameReg = GetFrameReg(Ctx, Out);
809 if (MRI && FrameReg != X86::NoRegister) {
810 SpillReg(Out, X86::RBP);
811 if (FrameReg == X86::RSP) {
818 MCInstBuilder(X86::MOV64rr).addReg(LocalFrameReg).addReg(FrameReg));
824 EmitAdjustRSP(Ctx, Out, -128);
825 SpillReg(Out, RegCtx.ShadowReg(64));
826 SpillReg(Out, RegCtx.AddressReg(64));
827 if (RegCtx.ScratchReg(64) != X86::NoRegister)
828 SpillReg(Out, RegCtx.ScratchReg(64));
832 void InstrumentMemOperandEpilogue(
const RegisterContext &RegCtx,
835 unsigned LocalFrameReg = RegCtx.ChooseFrameReg(64);
836 assert(LocalFrameReg != X86::NoRegister);
839 if (RegCtx.ScratchReg(64) != X86::NoRegister)
840 RestoreReg(Out, RegCtx.ScratchReg(64));
841 RestoreReg(Out, RegCtx.AddressReg(64));
842 RestoreReg(Out, RegCtx.ShadowReg(64));
843 EmitAdjustRSP(Ctx, Out, 128);
845 unsigned FrameReg = GetFrameReg(Ctx, Out);
847 RestoreReg(Out, LocalFrameReg);
849 if (FrameReg == X86::RSP)
854 void InstrumentMemOperandSmall(
X86Operand &Op,
unsigned AccessSize,
856 const RegisterContext &RegCtx,
859 void InstrumentMemOperandLarge(
X86Operand &Op,
unsigned AccessSize,
861 const RegisterContext &RegCtx,
864 void InstrumentMOVSImpl(
unsigned AccessSize,
MCContext &Ctx,
870 std::unique_ptr<X86Operand>
Op(
873 EmitLEA(*Op, 64, X86::RSP, Out);
877 void EmitCallAsanReport(
unsigned AccessSize,
bool IsWrite,
MCContext &Ctx,
878 MCStreamer &Out,
const RegisterContext &RegCtx) {
887 if (RegCtx.AddressReg(64) != X86::RDI) {
888 EmitInstruction(Out,
MCInstBuilder(X86::MOV64rr).addReg(X86::RDI).addReg(
889 RegCtx.AddressReg(64)));
892 (IsWrite ?
"store" :
"load") +
896 EmitInstruction(Out,
MCInstBuilder(X86::CALL64pcrel32).addExpr(FnExpr));
902 void X86AddressSanitizer64::InstrumentMemOperandSmall(
905 unsigned AddressRegI64 = RegCtx.AddressReg(64);
906 unsigned AddressRegI32 = RegCtx.AddressReg(32);
907 unsigned ShadowRegI64 = RegCtx.ShadowReg(64);
908 unsigned ShadowRegI32 = RegCtx.ShadowReg(32);
909 unsigned ShadowRegI8 = RegCtx.ShadowReg(8);
911 assert(RegCtx.ScratchReg(32) != X86::NoRegister);
912 unsigned ScratchRegI32 = RegCtx.ScratchReg(32);
914 ComputeMemOperandAddress(Op, 64, AddressRegI64, Ctx, Out);
916 EmitInstruction(Out,
MCInstBuilder(X86::MOV64rr).addReg(ShadowRegI64).addReg(
919 .addReg(ShadowRegI64)
920 .addReg(ShadowRegI64)
927 std::unique_ptr<X86Operand>
Op(
930 Op->addMemOperands(Inst, 5);
931 EmitInstruction(Out, Inst);
935 Out,
MCInstBuilder(X86::TEST8rr).addReg(ShadowRegI8).addReg(ShadowRegI8));
938 EmitInstruction(Out,
MCInstBuilder(X86::JE_1).addExpr(DoneExpr));
940 EmitInstruction(Out,
MCInstBuilder(X86::MOV32rr).addReg(ScratchRegI32).addReg(
943 .addReg(ScratchRegI32)
944 .addReg(ScratchRegI32)
947 switch (AccessSize) {
953 std::unique_ptr<X86Operand>
Op(
956 EmitLEA(*Op, 32, ScratchRegI32, Out);
961 .addReg(ScratchRegI32)
962 .addReg(ScratchRegI32)
969 MCInstBuilder(X86::MOVSX32rr8).addReg(ShadowRegI32).addReg(ShadowRegI8));
970 EmitInstruction(Out,
MCInstBuilder(X86::CMP32rr).addReg(ScratchRegI32).addReg(
972 EmitInstruction(Out,
MCInstBuilder(X86::JL_1).addExpr(DoneExpr));
974 EmitCallAsanReport(AccessSize, IsWrite, Ctx, Out, RegCtx);
975 EmitLabel(Out, DoneSym);
978 void X86AddressSanitizer64::InstrumentMemOperandLarge(
979 X86Operand &Op,
unsigned AccessSize,
bool IsWrite,
981 unsigned AddressRegI64 = RegCtx.AddressReg(64);
982 unsigned ShadowRegI64 = RegCtx.ShadowReg(64);
984 ComputeMemOperandAddress(Op, 64, AddressRegI64, Ctx, Out);
986 EmitInstruction(Out,
MCInstBuilder(X86::MOV64rr).addReg(ShadowRegI64).addReg(
989 .addReg(ShadowRegI64)
990 .addReg(ShadowRegI64)
994 switch (AccessSize) {
1004 std::unique_ptr<X86Operand>
Op(
1007 Op->addMemOperands(Inst, 5);
1009 EmitInstruction(Out, Inst);
1014 EmitInstruction(Out,
MCInstBuilder(X86::JE_1).addExpr(DoneExpr));
1016 EmitCallAsanReport(AccessSize, IsWrite, Ctx, Out, RegCtx);
1017 EmitLabel(Out, DoneSym);
1020 void X86AddressSanitizer64::InstrumentMOVSImpl(
unsigned AccessSize,
1029 Out,
MCInstBuilder(X86::TEST64rr).addReg(X86::RCX).addReg(X86::RCX));
1030 EmitInstruction(Out,
MCInstBuilder(X86::JE_1).addExpr(DoneExpr));
1033 InstrumentMOVSBase(X86::RDI , X86::RSI ,
1034 X86::RCX , AccessSize, Ctx, Out);
1036 EmitLabel(Out, DoneSym);
1052 bool PrintSchedInfoEnabled) {
1059 return X86::NoRegister;
1062 return X86::NoRegister;
1065 return X86::NoRegister;
1080 const bool hasCompilerRTSupport =
T.isOSLinux();
1084 return new X86AddressSanitizer32(STI);
1086 return new X86AddressSanitizer64(STI);
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
This class represents lattice values for constants.
static void CheckDisplacementBounds(int64_t Displacement)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
unsigned getMemModeSize() const
bool SanitizeAddress
Enables AddressSanitizer instrumentation at machine level.
unsigned CurrentCfaRegister
static std::unique_ptr< X86Operand > CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, unsigned Size=0, StringRef SymName=StringRef(), void *OpDecl=nullptr, unsigned FrontendSize=0)
Create an absolute memory operand.
virtual bool isMem() const =0
isMem - Is this a memory operand?
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, bool PrintSchedInfo=false)
Emit the given Instruction into the current section.
const Triple & getTargetTriple() const
virtual void EmitCFIRememberState()
virtual void InstrumentAndEmitInstruction(const MCInst &Inst, SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand >> &Operands, MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out, bool PrintSchedInfoEnabled)
static MCOperand createReg(unsigned Reg)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
const FeatureBitset & getFeatureBits() const
static const int64_t MinAllowedDisplacement
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Base class for the full range of assembler expressions which are needed for parsing.
Represent a reference to a symbol from inside an expression.
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
Context object for machine code objects.
virtual void EmitCFIRestoreState()
X86AsmInstrumentation(const MCSubtargetInfo *&STI)
Instances of this class represent a single low-level machine instruction.
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(adl_begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
initializer< Ty > init(const Ty &Val)
static int64_t ApplyDisplacementBounds(int64_t Displacement)
Streaming machine code generation interface.
MCSymbol * createTempSymbol(bool CanBeUnnamed=true)
Create and return a new assembler temporary symbol with a unique but unspecified name.
unsigned const MachineRegisterInfo * MRI
X86Operand - Instances of this class represent a parsed X86 machine instruction.
unsigned getMemBaseReg() const
Interface to description of machine instruction set.
virtual void EmitCFIDefCfaRegister(int64_t Register)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Triple - Helper class for working with autoconf configuration names.
unsigned GetFrameRegGeneric(const MCContext &Ctx, MCStreamer &Out)
X86AsmInstrumentation * CreateX86AsmInstrumentation(const MCTargetOptions &MCOptions, const MCContext &Ctx, const MCSubtargetInfo *&STI)
static bool IsStackReg(unsigned Reg)
void setOpcode(unsigned Op)
unsigned getMemScale() const
static cl::opt< bool > ClAsanInstrumentAssembly("asan-instrument-assembly", cl::desc("instrument assembly with AddressSanitizer checks"), cl::Hidden, cl::init(false))
void EmitInstruction(MCStreamer &Out, const MCInst &Inst, bool PrintSchedInfoEnabled=false)
unsigned getX86SubSuperRegister(unsigned, unsigned, bool High=false)
Returns the sub or super register of a specific X86 register.
static bool IsSmallMemAccess(unsigned AccessSize)
unsigned getNumFrameInfos()
unsigned getMemIndexReg() const
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset)
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Generic base class for all target subtargets.
static const int64_t MaxAllowedDisplacement
const MCSubtargetInfo *& STI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void addMemOperands(MCInst &Inst, unsigned N) const
const MCRegisterInfo * getRegisterInfo() const
const MCExpr * getMemDisp() const
ArrayRef< MCDwarfFrameInfo > getDwarfFrameInfos() const
virtual ~X86AsmInstrumentation()
virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
void addOperand(const MCOperand &Op)
unsigned getMemSegReg() const
Represents a location in source code.
unsigned getOpcode() const
static MCOperand createImm(int64_t Val)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment)
int getLLVMRegNum(unsigned RegNum, bool isEH) const
Map a dwarf register back to a target register.
bool isMem() const override
isMem - Is this a memory operand?