1 //===- bolt/Target/X86/X86MCPlusBuilder.cpp -------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file provides X86-specific MCPlus builder.
11 //===----------------------------------------------------------------------===//
13 #include "MCTargetDesc/X86BaseInfo.h"
14 #include "MCTargetDesc/X86InstrRelaxTables.h"
15 #include "MCTargetDesc/X86MCTargetDesc.h"
16 #include "X86MCSymbolizer.h"
17 #include "bolt/Core/MCPlus.h"
18 #include "bolt/Core/MCPlusBuilder.h"
19 #include "llvm/BinaryFormat/ELF.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCFixupKindInfo.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/MC/MCInstBuilder.h"
24 #include "llvm/MC/MCInstrInfo.h"
25 #include "llvm/MC/MCRegister.h"
26 #include "llvm/MC/MCRegisterInfo.h"
27 #include "llvm/Support/CommandLine.h"
28 #include "llvm/Support/DataExtractor.h"
29 #include "llvm/Support/Debug.h"
30 #include "llvm/Support/Errc.h"
31 #include "llvm/Support/ErrorHandling.h"
32 #include "llvm/Support/ErrorOr.h"
35 #define DEBUG_TYPE "mcplus"
42 extern cl::OptionCategory BoltOptCategory
;
44 static cl::opt
<bool> X86StripRedundantAddressSize(
45 "x86-strip-redundant-address-size",
46 cl::desc("Remove redundant Address-Size override prefix"), cl::init(true),
47 cl::cat(BoltOptCategory
));
53 unsigned getShortBranchOpcode(unsigned Opcode
) {
57 case X86::JMP_2
: return X86::JMP_1
;
58 case X86::JMP_4
: return X86::JMP_1
;
59 case X86::JCC_2
: return X86::JCC_1
;
60 case X86::JCC_4
: return X86::JCC_1
;
64 unsigned getShortArithOpcode(unsigned Opcode
) {
65 return X86::getShortOpcodeArith(Opcode
);
68 bool isMOVSX64rm32(const MCInst
&Inst
) {
69 return Inst
.getOpcode() == X86::MOVSX64rm32
;
72 bool isADD64rr(const MCInst
&Inst
) { return Inst
.getOpcode() == X86::ADD64rr
; }
74 bool isADDri(const MCInst
&Inst
) {
75 return Inst
.getOpcode() == X86::ADD64ri32
||
76 Inst
.getOpcode() == X86::ADD64ri8
;
79 #define GET_INSTRINFO_OPERAND_TYPES_ENUM
80 #define GET_INSTRINFO_OPERAND_TYPE
81 #define GET_INSTRINFO_MEM_OPERAND_SIZE
82 #include "X86GenInstrInfo.inc"
84 class X86MCPlusBuilder
: public MCPlusBuilder
{
86 X86MCPlusBuilder(const MCInstrAnalysis
*Analysis
, const MCInstrInfo
*Info
,
87 const MCRegisterInfo
*RegInfo
)
88 : MCPlusBuilder(Analysis
, Info
, RegInfo
) {}
90 std::unique_ptr
<MCSymbolizer
>
91 createTargetSymbolizer(BinaryFunction
&Function
) const override
{
92 return std::make_unique
<X86MCSymbolizer
>(Function
);
95 bool isBranch(const MCInst
&Inst
) const override
{
96 return Analysis
->isBranch(Inst
) && !isTailCall(Inst
);
99 bool isNoop(const MCInst
&Inst
) const override
{
100 return X86::isNOP(Inst
.getOpcode());
103 unsigned getCondCode(const MCInst
&Inst
) const override
{
104 unsigned Opcode
= Inst
.getOpcode();
105 if (X86::isJCC(Opcode
))
106 return Inst
.getOperand(Info
->get(Opcode
).NumOperands
- 1).getImm();
107 return X86::COND_INVALID
;
110 unsigned getInvertedCondCode(unsigned CC
) const override
{
112 default: return X86::COND_INVALID
;
113 case X86::COND_E
: return X86::COND_NE
;
114 case X86::COND_NE
: return X86::COND_E
;
115 case X86::COND_L
: return X86::COND_GE
;
116 case X86::COND_LE
: return X86::COND_G
;
117 case X86::COND_G
: return X86::COND_LE
;
118 case X86::COND_GE
: return X86::COND_L
;
119 case X86::COND_B
: return X86::COND_AE
;
120 case X86::COND_BE
: return X86::COND_A
;
121 case X86::COND_A
: return X86::COND_BE
;
122 case X86::COND_AE
: return X86::COND_B
;
123 case X86::COND_S
: return X86::COND_NS
;
124 case X86::COND_NS
: return X86::COND_S
;
125 case X86::COND_P
: return X86::COND_NP
;
126 case X86::COND_NP
: return X86::COND_P
;
127 case X86::COND_O
: return X86::COND_NO
;
128 case X86::COND_NO
: return X86::COND_O
;
132 unsigned getCondCodesLogicalOr(unsigned CC1
, unsigned CC2
) const override
{
133 enum DecodedCondCode
: uint8_t {
137 DCC_GREATER_OR_LESSER
= 0x6,
143 auto decodeCondCode
= [&](unsigned CC
) -> uint8_t {
145 default: return DCC_INVALID
;
146 case X86::COND_E
: return DCC_EQUAL
;
147 case X86::COND_NE
: return DCC_GREATER
| DCC_LESSER
;
148 case X86::COND_L
: return DCC_LESSER
| DCC_SIGNED
;
149 case X86::COND_LE
: return DCC_EQUAL
| DCC_LESSER
| DCC_SIGNED
;
150 case X86::COND_G
: return DCC_GREATER
| DCC_SIGNED
;
151 case X86::COND_GE
: return DCC_GREATER
| DCC_EQUAL
| DCC_SIGNED
;
152 case X86::COND_B
: return DCC_LESSER
| DCC_UNSIGNED
;
153 case X86::COND_BE
: return DCC_EQUAL
| DCC_LESSER
| DCC_UNSIGNED
;
154 case X86::COND_A
: return DCC_GREATER
| DCC_UNSIGNED
;
155 case X86::COND_AE
: return DCC_GREATER
| DCC_EQUAL
| DCC_UNSIGNED
;
159 uint8_t DCC
= decodeCondCode(CC1
) | decodeCondCode(CC2
);
161 if (DCC
& DCC_INVALID
)
162 return X86::COND_INVALID
;
164 if (DCC
& DCC_SIGNED
&& DCC
& DCC_UNSIGNED
)
165 return X86::COND_INVALID
;
168 default: return X86::COND_INVALID
;
169 case DCC_EQUAL
| DCC_LESSER
| DCC_SIGNED
: return X86::COND_LE
;
170 case DCC_EQUAL
| DCC_LESSER
| DCC_UNSIGNED
: return X86::COND_BE
;
171 case DCC_EQUAL
| DCC_GREATER
| DCC_SIGNED
: return X86::COND_GE
;
172 case DCC_EQUAL
| DCC_GREATER
| DCC_UNSIGNED
: return X86::COND_AE
;
173 case DCC_GREATER
| DCC_LESSER
| DCC_SIGNED
: return X86::COND_NE
;
174 case DCC_GREATER
| DCC_LESSER
| DCC_UNSIGNED
: return X86::COND_NE
;
175 case DCC_GREATER
| DCC_LESSER
: return X86::COND_NE
;
176 case DCC_EQUAL
| DCC_SIGNED
: return X86::COND_E
;
177 case DCC_EQUAL
| DCC_UNSIGNED
: return X86::COND_E
;
178 case DCC_EQUAL
: return X86::COND_E
;
179 case DCC_LESSER
| DCC_SIGNED
: return X86::COND_L
;
180 case DCC_LESSER
| DCC_UNSIGNED
: return X86::COND_B
;
181 case DCC_GREATER
| DCC_SIGNED
: return X86::COND_G
;
182 case DCC_GREATER
| DCC_UNSIGNED
: return X86::COND_A
;
186 bool isValidCondCode(unsigned CC
) const override
{
187 return (CC
!= X86::COND_INVALID
);
190 bool isBreakpoint(const MCInst
&Inst
) const override
{
191 return Inst
.getOpcode() == X86::INT3
;
194 bool isPrefix(const MCInst
&Inst
) const override
{
195 const MCInstrDesc
&Desc
= Info
->get(Inst
.getOpcode());
196 return X86II::isPrefix(Desc
.TSFlags
);
199 bool isRep(const MCInst
&Inst
) const override
{
200 return Inst
.getFlags() == X86::IP_HAS_REPEAT
;
203 bool deleteREPPrefix(MCInst
&Inst
) const override
{
204 if (Inst
.getFlags() == X86::IP_HAS_REPEAT
) {
211 // FIXME: For compatibility with old LLVM only!
212 bool isTerminator(const MCInst
&Inst
) const override
{
213 unsigned Opcode
= Inst
.getOpcode();
214 return Info
->get(Opcode
).isTerminator() || X86::isUD1(Opcode
) ||
218 bool isIndirectCall(const MCInst
&Inst
) const override
{
219 return isCall(Inst
) &&
220 ((getMemoryOperandNo(Inst
) != -1) || Inst
.getOperand(0).isReg());
223 bool isPop(const MCInst
&Inst
) const override
{
224 return getPopSize(Inst
) == 0 ? false : true;
227 bool isTerminateBranch(const MCInst
&Inst
) const override
{
228 return Inst
.getOpcode() == X86::ENDBR32
|| Inst
.getOpcode() == X86::ENDBR64
;
231 int getPopSize(const MCInst
&Inst
) const override
{
232 switch (Inst
.getOpcode()) {
266 bool isPush(const MCInst
&Inst
) const override
{
267 return getPushSize(Inst
) == 0 ? false : true;
270 int getPushSize(const MCInst
&Inst
) const override
{
271 switch (Inst
.getOpcode()) {
313 bool isSUB(const MCInst
&Inst
) const override
{
314 return X86::isSUB(Inst
.getOpcode());
317 bool isLEA64r(const MCInst
&Inst
) const override
{
318 return Inst
.getOpcode() == X86::LEA64r
;
321 bool isLeave(const MCInst
&Inst
) const override
{
322 return Inst
.getOpcode() == X86::LEAVE
|| Inst
.getOpcode() == X86::LEAVE64
;
325 bool isMoveMem2Reg(const MCInst
&Inst
) const override
{
326 switch (Inst
.getOpcode()) {
335 bool isUnsupportedBranch(unsigned Opcode
) const override
{
348 bool isLoad(const MCInst
&Inst
) const override
{
352 int MemOpNo
= getMemoryOperandNo(Inst
);
353 const MCInstrDesc
&MCII
= Info
->get(Inst
.getOpcode());
358 return MCII
.mayLoad();
361 bool isStore(const MCInst
&Inst
) const override
{
365 int MemOpNo
= getMemoryOperandNo(Inst
);
366 const MCInstrDesc
&MCII
= Info
->get(Inst
.getOpcode());
371 return MCII
.mayStore();
374 bool isCleanRegXOR(const MCInst
&Inst
) const override
{
375 switch (Inst
.getOpcode()) {
383 return (Inst
.getOperand(0).getReg() == Inst
.getOperand(2).getReg());
386 bool isPacked(const MCInst
&Inst
) const override
{
387 const MCInstrDesc
&Desc
= Info
->get(Inst
.getOpcode());
388 return (Desc
.TSFlags
& X86II::OpPrefixMask
) == X86II::PD
;
391 unsigned getTrapFillValue() const override
{ return 0xCC; }
393 struct IndJmpMatcherFrag1
: MCInstMatcher
{
394 std::unique_ptr
<MCInstMatcher
> Base
;
395 std::unique_ptr
<MCInstMatcher
> Scale
;
396 std::unique_ptr
<MCInstMatcher
> Index
;
397 std::unique_ptr
<MCInstMatcher
> Offset
;
399 IndJmpMatcherFrag1(std::unique_ptr
<MCInstMatcher
> Base
,
400 std::unique_ptr
<MCInstMatcher
> Scale
,
401 std::unique_ptr
<MCInstMatcher
> Index
,
402 std::unique_ptr
<MCInstMatcher
> Offset
)
403 : Base(std::move(Base
)), Scale(std::move(Scale
)),
404 Index(std::move(Index
)), Offset(std::move(Offset
)) {}
406 bool match(const MCRegisterInfo
&MRI
, MCPlusBuilder
&MIB
,
407 MutableArrayRef
<MCInst
> InInstrWindow
, int OpNum
) override
{
408 if (!MCInstMatcher::match(MRI
, MIB
, InInstrWindow
, OpNum
))
411 if (CurInst
->getOpcode() != X86::JMP64m
)
414 int MemOpNo
= MIB
.getMemoryOperandNo(*CurInst
);
418 if (!Base
->match(MRI
, MIB
, this->InstrWindow
, MemOpNo
+ X86::AddrBaseReg
))
420 if (!Scale
->match(MRI
, MIB
, this->InstrWindow
,
421 MemOpNo
+ X86::AddrScaleAmt
))
423 if (!Index
->match(MRI
, MIB
, this->InstrWindow
,
424 MemOpNo
+ X86::AddrIndexReg
))
426 if (!Offset
->match(MRI
, MIB
, this->InstrWindow
, MemOpNo
+ X86::AddrDisp
))
431 void annotate(MCPlusBuilder
&MIB
, StringRef Annotation
) override
{
432 MIB
.addAnnotation(*CurInst
, Annotation
, true);
433 Base
->annotate(MIB
, Annotation
);
434 Scale
->annotate(MIB
, Annotation
);
435 Index
->annotate(MIB
, Annotation
);
436 Offset
->annotate(MIB
, Annotation
);
440 std::unique_ptr
<MCInstMatcher
>
441 matchIndJmp(std::unique_ptr
<MCInstMatcher
> Base
,
442 std::unique_ptr
<MCInstMatcher
> Scale
,
443 std::unique_ptr
<MCInstMatcher
> Index
,
444 std::unique_ptr
<MCInstMatcher
> Offset
) const override
{
445 return std::unique_ptr
<MCInstMatcher
>(
446 new IndJmpMatcherFrag1(std::move(Base
), std::move(Scale
),
447 std::move(Index
), std::move(Offset
)));
450 struct IndJmpMatcherFrag2
: MCInstMatcher
{
451 std::unique_ptr
<MCInstMatcher
> Reg
;
453 IndJmpMatcherFrag2(std::unique_ptr
<MCInstMatcher
> Reg
)
454 : Reg(std::move(Reg
)) {}
456 bool match(const MCRegisterInfo
&MRI
, MCPlusBuilder
&MIB
,
457 MutableArrayRef
<MCInst
> InInstrWindow
, int OpNum
) override
{
458 if (!MCInstMatcher::match(MRI
, MIB
, InInstrWindow
, OpNum
))
461 if (CurInst
->getOpcode() != X86::JMP64r
)
464 return Reg
->match(MRI
, MIB
, this->InstrWindow
, 0);
467 void annotate(MCPlusBuilder
&MIB
, StringRef Annotation
) override
{
468 MIB
.addAnnotation(*CurInst
, Annotation
, true);
469 Reg
->annotate(MIB
, Annotation
);
473 std::unique_ptr
<MCInstMatcher
>
474 matchIndJmp(std::unique_ptr
<MCInstMatcher
> Target
) const override
{
475 return std::unique_ptr
<MCInstMatcher
>(
476 new IndJmpMatcherFrag2(std::move(Target
)));
479 struct LoadMatcherFrag1
: MCInstMatcher
{
480 std::unique_ptr
<MCInstMatcher
> Base
;
481 std::unique_ptr
<MCInstMatcher
> Scale
;
482 std::unique_ptr
<MCInstMatcher
> Index
;
483 std::unique_ptr
<MCInstMatcher
> Offset
;
485 LoadMatcherFrag1(std::unique_ptr
<MCInstMatcher
> Base
,
486 std::unique_ptr
<MCInstMatcher
> Scale
,
487 std::unique_ptr
<MCInstMatcher
> Index
,
488 std::unique_ptr
<MCInstMatcher
> Offset
)
489 : Base(std::move(Base
)), Scale(std::move(Scale
)),
490 Index(std::move(Index
)), Offset(std::move(Offset
)) {}
492 bool match(const MCRegisterInfo
&MRI
, MCPlusBuilder
&MIB
,
493 MutableArrayRef
<MCInst
> InInstrWindow
, int OpNum
) override
{
494 if (!MCInstMatcher::match(MRI
, MIB
, InInstrWindow
, OpNum
))
497 if (CurInst
->getOpcode() != X86::MOV64rm
&&
498 CurInst
->getOpcode() != X86::MOVSX64rm32
)
501 int MemOpNo
= MIB
.getMemoryOperandNo(*CurInst
);
505 if (!Base
->match(MRI
, MIB
, this->InstrWindow
, MemOpNo
+ X86::AddrBaseReg
))
507 if (!Scale
->match(MRI
, MIB
, this->InstrWindow
,
508 MemOpNo
+ X86::AddrScaleAmt
))
510 if (!Index
->match(MRI
, MIB
, this->InstrWindow
,
511 MemOpNo
+ X86::AddrIndexReg
))
513 if (!Offset
->match(MRI
, MIB
, this->InstrWindow
, MemOpNo
+ X86::AddrDisp
))
518 void annotate(MCPlusBuilder
&MIB
, StringRef Annotation
) override
{
519 MIB
.addAnnotation(*CurInst
, Annotation
, true);
520 Base
->annotate(MIB
, Annotation
);
521 Scale
->annotate(MIB
, Annotation
);
522 Index
->annotate(MIB
, Annotation
);
523 Offset
->annotate(MIB
, Annotation
);
527 std::unique_ptr
<MCInstMatcher
>
528 matchLoad(std::unique_ptr
<MCInstMatcher
> Base
,
529 std::unique_ptr
<MCInstMatcher
> Scale
,
530 std::unique_ptr
<MCInstMatcher
> Index
,
531 std::unique_ptr
<MCInstMatcher
> Offset
) const override
{
532 return std::unique_ptr
<MCInstMatcher
>(
533 new LoadMatcherFrag1(std::move(Base
), std::move(Scale
),
534 std::move(Index
), std::move(Offset
)));
537 struct AddMatcher
: MCInstMatcher
{
538 std::unique_ptr
<MCInstMatcher
> A
;
539 std::unique_ptr
<MCInstMatcher
> B
;
541 AddMatcher(std::unique_ptr
<MCInstMatcher
> A
,
542 std::unique_ptr
<MCInstMatcher
> B
)
543 : A(std::move(A
)), B(std::move(B
)) {}
545 bool match(const MCRegisterInfo
&MRI
, MCPlusBuilder
&MIB
,
546 MutableArrayRef
<MCInst
> InInstrWindow
, int OpNum
) override
{
547 if (!MCInstMatcher::match(MRI
, MIB
, InInstrWindow
, OpNum
))
550 if (CurInst
->getOpcode() == X86::ADD64rr
||
551 CurInst
->getOpcode() == X86::ADD64rr_DB
||
552 CurInst
->getOpcode() == X86::ADD64rr_REV
) {
553 if (!A
->match(MRI
, MIB
, this->InstrWindow
, 1)) {
554 if (!B
->match(MRI
, MIB
, this->InstrWindow
, 1))
556 return A
->match(MRI
, MIB
, this->InstrWindow
, 2);
559 if (B
->match(MRI
, MIB
, this->InstrWindow
, 2))
562 if (!B
->match(MRI
, MIB
, this->InstrWindow
, 1))
564 return A
->match(MRI
, MIB
, this->InstrWindow
, 2);
570 void annotate(MCPlusBuilder
&MIB
, StringRef Annotation
) override
{
571 MIB
.addAnnotation(*CurInst
, Annotation
, true);
572 A
->annotate(MIB
, Annotation
);
573 B
->annotate(MIB
, Annotation
);
577 std::unique_ptr
<MCInstMatcher
>
578 matchAdd(std::unique_ptr
<MCInstMatcher
> A
,
579 std::unique_ptr
<MCInstMatcher
> B
) const override
{
580 return std::unique_ptr
<MCInstMatcher
>(
581 new AddMatcher(std::move(A
), std::move(B
)));
584 struct LEAMatcher
: MCInstMatcher
{
585 std::unique_ptr
<MCInstMatcher
> Target
;
587 LEAMatcher(std::unique_ptr
<MCInstMatcher
> Target
)
588 : Target(std::move(Target
)) {}
590 bool match(const MCRegisterInfo
&MRI
, MCPlusBuilder
&MIB
,
591 MutableArrayRef
<MCInst
> InInstrWindow
, int OpNum
) override
{
592 if (!MCInstMatcher::match(MRI
, MIB
, InInstrWindow
, OpNum
))
595 if (CurInst
->getOpcode() != X86::LEA64r
)
598 if (CurInst
->getOperand(1 + X86::AddrScaleAmt
).getImm() != 1 ||
599 CurInst
->getOperand(1 + X86::AddrIndexReg
).getReg() !=
601 (CurInst
->getOperand(1 + X86::AddrBaseReg
).getReg() !=
603 CurInst
->getOperand(1 + X86::AddrBaseReg
).getReg() != X86::RIP
))
606 return Target
->match(MRI
, MIB
, this->InstrWindow
, 1 + X86::AddrDisp
);
609 void annotate(MCPlusBuilder
&MIB
, StringRef Annotation
) override
{
610 MIB
.addAnnotation(*CurInst
, Annotation
, true);
611 Target
->annotate(MIB
, Annotation
);
615 std::unique_ptr
<MCInstMatcher
>
616 matchLoadAddr(std::unique_ptr
<MCInstMatcher
> Target
) const override
{
617 return std::unique_ptr
<MCInstMatcher
>(new LEAMatcher(std::move(Target
)));
620 bool hasPCRelOperand(const MCInst
&Inst
) const override
{
621 for (const MCOperand
&Operand
: Inst
)
622 if (Operand
.isReg() && Operand
.getReg() == X86::RIP
)
627 int getMemoryOperandNo(const MCInst
&Inst
) const override
{
628 unsigned Opcode
= Inst
.getOpcode();
629 const MCInstrDesc
&Desc
= Info
->get(Opcode
);
630 int MemOpNo
= X86II::getMemoryOperandNo(Desc
.TSFlags
);
632 MemOpNo
+= X86II::getOperandBias(Desc
);
636 bool hasEVEXEncoding(const MCInst
&Inst
) const override
{
637 const MCInstrDesc
&Desc
= Info
->get(Inst
.getOpcode());
638 return (Desc
.TSFlags
& X86II::EncodingMask
) == X86II::EVEX
;
641 bool isMacroOpFusionPair(ArrayRef
<MCInst
> Insts
) const override
{
642 const auto *I
= Insts
.begin();
643 while (I
!= Insts
.end() && isPrefix(*I
))
645 if (I
== Insts
.end())
648 const MCInst
&FirstInst
= *I
;
650 while (I
!= Insts
.end() && isPrefix(*I
))
652 if (I
== Insts
.end())
654 const MCInst
&SecondInst
= *I
;
656 if (!isConditionalBranch(SecondInst
))
658 // Cannot fuse if the first instruction uses RIP-relative memory.
659 if (hasPCRelOperand(FirstInst
))
662 const X86::FirstMacroFusionInstKind CmpKind
=
663 X86::classifyFirstOpcodeInMacroFusion(FirstInst
.getOpcode());
664 if (CmpKind
== X86::FirstMacroFusionInstKind::Invalid
)
667 X86::CondCode CC
= static_cast<X86::CondCode
>(getCondCode(SecondInst
));
668 X86::SecondMacroFusionInstKind BranchKind
=
669 X86::classifySecondCondCodeInMacroFusion(CC
);
670 if (BranchKind
== X86::SecondMacroFusionInstKind::Invalid
)
672 return X86::isMacroFused(CmpKind
, BranchKind
);
676 evaluateX86MemoryOperand(const MCInst
&Inst
, unsigned *BaseRegNum
,
677 int64_t *ScaleImm
, unsigned *IndexRegNum
,
678 int64_t *DispImm
, unsigned *SegmentRegNum
,
679 const MCExpr
**DispExpr
= nullptr) const override
{
680 assert(BaseRegNum
&& ScaleImm
&& IndexRegNum
&& SegmentRegNum
&&
681 "one of the input pointers is null");
682 int MemOpNo
= getMemoryOperandNo(Inst
);
685 unsigned MemOpOffset
= static_cast<unsigned>(MemOpNo
);
687 if (MemOpOffset
+ X86::AddrSegmentReg
>= MCPlus::getNumPrimeOperands(Inst
))
690 const MCOperand
&Base
= Inst
.getOperand(MemOpOffset
+ X86::AddrBaseReg
);
691 const MCOperand
&Scale
= Inst
.getOperand(MemOpOffset
+ X86::AddrScaleAmt
);
692 const MCOperand
&Index
= Inst
.getOperand(MemOpOffset
+ X86::AddrIndexReg
);
693 const MCOperand
&Disp
= Inst
.getOperand(MemOpOffset
+ X86::AddrDisp
);
694 const MCOperand
&Segment
=
695 Inst
.getOperand(MemOpOffset
+ X86::AddrSegmentReg
);
697 // Make sure it is a well-formed memory operand.
698 if (!Base
.isReg() || !Scale
.isImm() || !Index
.isReg() ||
699 (!Disp
.isImm() && !Disp
.isExpr()) || !Segment
.isReg())
702 *BaseRegNum
= Base
.getReg();
703 *ScaleImm
= Scale
.getImm();
704 *IndexRegNum
= Index
.getReg();
706 assert(DispImm
&& "DispImm needs to be set");
707 *DispImm
= Disp
.getImm();
711 assert(DispExpr
&& "DispExpr needs to be set");
712 *DispExpr
= Disp
.getExpr();
716 *SegmentRegNum
= Segment
.getReg();
720 bool evaluateMemOperandTarget(const MCInst
&Inst
, uint64_t &Target
,
722 uint64_t Size
) const override
{
725 unsigned IndexRegNum
;
728 const MCExpr
*DispExpr
= nullptr;
729 if (!evaluateX86MemoryOperand(Inst
, &BaseRegNum
, &ScaleValue
, &IndexRegNum
,
730 &DispValue
, &SegRegNum
, &DispExpr
))
733 // Make sure it's a well-formed addressing we can statically evaluate.
734 if ((BaseRegNum
!= X86::RIP
&& BaseRegNum
!= X86::NoRegister
) ||
735 IndexRegNum
!= X86::NoRegister
|| SegRegNum
!= X86::NoRegister
||
740 if (BaseRegNum
== X86::RIP
) {
741 assert(Size
!= 0 && "instruction size required in order to statically "
742 "evaluate RIP-relative address");
743 Target
+= Address
+ Size
;
748 MCInst::iterator
getMemOperandDisp(MCInst
&Inst
) const override
{
749 int MemOpNo
= getMemoryOperandNo(Inst
);
752 return Inst
.begin() + (MemOpNo
+ X86::AddrDisp
);
755 bool replaceMemOperandDisp(MCInst
&Inst
, MCOperand Operand
) const override
{
756 MCOperand
*OI
= getMemOperandDisp(Inst
);
757 if (OI
== Inst
.end())
763 /// Get the registers used as function parameters.
764 /// This function is specific to the x86_64 abi on Linux.
765 BitVector
getRegsUsedAsParams() const override
{
766 BitVector Regs
= BitVector(RegInfo
->getNumRegs(), false);
767 Regs
|= getAliases(X86::RSI
);
768 Regs
|= getAliases(X86::RDI
);
769 Regs
|= getAliases(X86::RDX
);
770 Regs
|= getAliases(X86::RCX
);
771 Regs
|= getAliases(X86::R8
);
772 Regs
|= getAliases(X86::R9
);
776 void getCalleeSavedRegs(BitVector
&Regs
) const override
{
777 Regs
|= getAliases(X86::RBX
);
778 Regs
|= getAliases(X86::RBP
);
779 Regs
|= getAliases(X86::R12
);
780 Regs
|= getAliases(X86::R13
);
781 Regs
|= getAliases(X86::R14
);
782 Regs
|= getAliases(X86::R15
);
785 void getDefaultDefIn(BitVector
&Regs
) const override
{
786 assert(Regs
.size() >= RegInfo
->getNumRegs() &&
787 "The size of BitVector is less than RegInfo->getNumRegs().");
805 void getDefaultLiveOut(BitVector
&Regs
) const override
{
806 assert(Regs
.size() >= RegInfo
->getNumRegs() &&
807 "The size of BitVector is less than RegInfo->getNumRegs().");
808 Regs
|= getAliases(X86::RAX
);
809 Regs
|= getAliases(X86::RDX
);
810 Regs
|= getAliases(X86::RCX
);
811 Regs
|= getAliases(X86::XMM0
);
812 Regs
|= getAliases(X86::XMM1
);
815 void getGPRegs(BitVector
&Regs
, bool IncludeAlias
) const override
{
817 Regs
|= getAliases(X86::RAX
);
818 Regs
|= getAliases(X86::RBX
);
819 Regs
|= getAliases(X86::RBP
);
820 Regs
|= getAliases(X86::RSI
);
821 Regs
|= getAliases(X86::RDI
);
822 Regs
|= getAliases(X86::RDX
);
823 Regs
|= getAliases(X86::RCX
);
824 Regs
|= getAliases(X86::R8
);
825 Regs
|= getAliases(X86::R9
);
826 Regs
|= getAliases(X86::R10
);
827 Regs
|= getAliases(X86::R11
);
828 Regs
|= getAliases(X86::R12
);
829 Regs
|= getAliases(X86::R13
);
830 Regs
|= getAliases(X86::R14
);
831 Regs
|= getAliases(X86::R15
);
851 void getClassicGPRegs(BitVector
&Regs
) const override
{
852 Regs
|= getAliases(X86::RAX
);
853 Regs
|= getAliases(X86::RBX
);
854 Regs
|= getAliases(X86::RBP
);
855 Regs
|= getAliases(X86::RSI
);
856 Regs
|= getAliases(X86::RDI
);
857 Regs
|= getAliases(X86::RDX
);
858 Regs
|= getAliases(X86::RCX
);
861 void getRepRegs(BitVector
&Regs
) const override
{
862 Regs
|= getAliases(X86::RCX
);
865 MCPhysReg
getAliasSized(MCPhysReg Reg
, uint8_t Size
) const override
{
867 case X86::RAX
: case X86::EAX
: case X86::AX
: case X86::AL
: case X86::AH
:
869 case 8: return X86::RAX
; case 4: return X86::EAX
;
870 case 2: return X86::AX
; case 1: return X86::AL
;
871 default: llvm_unreachable("Unexpected size");
873 case X86::RBX
: case X86::EBX
: case X86::BX
: case X86::BL
: case X86::BH
:
875 case 8: return X86::RBX
; case 4: return X86::EBX
;
876 case 2: return X86::BX
; case 1: return X86::BL
;
877 default: llvm_unreachable("Unexpected size");
879 case X86::RDX
: case X86::EDX
: case X86::DX
: case X86::DL
: case X86::DH
:
881 case 8: return X86::RDX
; case 4: return X86::EDX
;
882 case 2: return X86::DX
; case 1: return X86::DL
;
883 default: llvm_unreachable("Unexpected size");
885 case X86::RDI
: case X86::EDI
: case X86::DI
: case X86::DIL
:
887 case 8: return X86::RDI
; case 4: return X86::EDI
;
888 case 2: return X86::DI
; case 1: return X86::DIL
;
889 default: llvm_unreachable("Unexpected size");
891 case X86::RSI
: case X86::ESI
: case X86::SI
: case X86::SIL
:
893 case 8: return X86::RSI
; case 4: return X86::ESI
;
894 case 2: return X86::SI
; case 1: return X86::SIL
;
895 default: llvm_unreachable("Unexpected size");
897 case X86::RCX
: case X86::ECX
: case X86::CX
: case X86::CL
: case X86::CH
:
899 case 8: return X86::RCX
; case 4: return X86::ECX
;
900 case 2: return X86::CX
; case 1: return X86::CL
;
901 default: llvm_unreachable("Unexpected size");
903 case X86::RSP
: case X86::ESP
: case X86::SP
: case X86::SPL
:
905 case 8: return X86::RSP
; case 4: return X86::ESP
;
906 case 2: return X86::SP
; case 1: return X86::SPL
;
907 default: llvm_unreachable("Unexpected size");
909 case X86::RBP
: case X86::EBP
: case X86::BP
: case X86::BPL
:
911 case 8: return X86::RBP
; case 4: return X86::EBP
;
912 case 2: return X86::BP
; case 1: return X86::BPL
;
913 default: llvm_unreachable("Unexpected size");
915 case X86::R8
: case X86::R8D
: case X86::R8W
: case X86::R8B
:
917 case 8: return X86::R8
; case 4: return X86::R8D
;
918 case 2: return X86::R8W
; case 1: return X86::R8B
;
919 default: llvm_unreachable("Unexpected size");
921 case X86::R9
: case X86::R9D
: case X86::R9W
: case X86::R9B
:
923 case 8: return X86::R9
; case 4: return X86::R9D
;
924 case 2: return X86::R9W
; case 1: return X86::R9B
;
925 default: llvm_unreachable("Unexpected size");
927 case X86::R10
: case X86::R10D
: case X86::R10W
: case X86::R10B
:
929 case 8: return X86::R10
; case 4: return X86::R10D
;
930 case 2: return X86::R10W
; case 1: return X86::R10B
;
931 default: llvm_unreachable("Unexpected size");
933 case X86::R11
: case X86::R11D
: case X86::R11W
: case X86::R11B
:
935 case 8: return X86::R11
; case 4: return X86::R11D
;
936 case 2: return X86::R11W
; case 1: return X86::R11B
;
937 default: llvm_unreachable("Unexpected size");
939 case X86::R12
: case X86::R12D
: case X86::R12W
: case X86::R12B
:
941 case 8: return X86::R12
; case 4: return X86::R12D
;
942 case 2: return X86::R12W
; case 1: return X86::R12B
;
943 default: llvm_unreachable("Unexpected size");
945 case X86::R13
: case X86::R13D
: case X86::R13W
: case X86::R13B
:
947 case 8: return X86::R13
; case 4: return X86::R13D
;
948 case 2: return X86::R13W
; case 1: return X86::R13B
;
949 default: llvm_unreachable("Unexpected size");
951 case X86::R14
: case X86::R14D
: case X86::R14W
: case X86::R14B
:
953 case 8: return X86::R14
; case 4: return X86::R14D
;
954 case 2: return X86::R14W
; case 1: return X86::R14B
;
955 default: llvm_unreachable("Unexpected size");
957 case X86::R15
: case X86::R15D
: case X86::R15W
: case X86::R15B
:
959 case 8: return X86::R15
; case 4: return X86::R15D
;
960 case 2: return X86::R15W
; case 1: return X86::R15B
;
961 default: llvm_unreachable("Unexpected size");
964 dbgs() << Reg
<< " (get alias sized)\n";
965 llvm_unreachable("Unexpected reg number");
970 bool isUpper8BitReg(MCPhysReg Reg
) const override
{
982 bool cannotUseREX(const MCInst
&Inst
) const override
{
983 switch (Inst
.getOpcode()) {
984 case X86::MOV8mr_NOREX
:
985 case X86::MOV8rm_NOREX
:
986 case X86::MOV8rr_NOREX
:
987 case X86::MOVSX32rm8_NOREX
:
988 case X86::MOVSX32rr8_NOREX
:
989 case X86::MOVZX32rm8_NOREX
:
990 case X86::MOVZX32rr8_NOREX
:
994 case X86::MOVSX32rm8
:
995 case X86::MOVSX32rr8
:
996 case X86::MOVZX32rm8
:
997 case X86::MOVZX32rr8
:
999 for (const MCOperand
&Operand
: MCPlus::primeOperands(Inst
)) {
1000 if (!Operand
.isReg())
1002 if (isUpper8BitReg(Operand
.getReg()))
1011 static uint8_t getMemDataSize(const MCInst
&Inst
, int MemOpNo
) {
1012 using namespace llvm::X86
;
1013 int OpType
= getOperandType(Inst
.getOpcode(), MemOpNo
);
1014 return getMemOperandSize(OpType
) / 8;
1017 /// Classifying a stack access as *not* "SIMPLE" here means we don't know how
1018 /// to change this instruction memory access. It will disable any changes to
1019 /// the stack layout, so we can't do the most aggressive form of shrink
1020 /// wrapping. We must do so in a way that keeps the original stack layout.
1021 /// Otherwise you need to adjust the offset of all instructions accessing the
1022 /// stack: we can't do that anymore because there is one instruction that is
1023 /// not simple. There are other implications as well. We have heuristics to
1024 /// detect when a register is callee-saved and thus eligible for shrink
1025 /// wrapping. If you are restoring a register using a non-simple stack access,
1026 /// then it is classified as NOT callee-saved, and it disables shrink wrapping
1027 /// for *that* register (but not for others).
1029 /// Classifying a stack access as "size 0" or detecting an indexed memory
1030 /// access (to address a vector, for example) here means we know there is a
1031 /// stack access, but we can't quite understand how wide is the access in
1032 /// bytes. This is very serious because we can't understand how memory
1033 /// accesses alias with each other for this function. This will essentially
1034 /// disable not only shrink wrapping but all frame analysis, it will fail it
1035 /// as "we don't understand this function and we give up on it".
1036 bool isStackAccess(const MCInst
&Inst
, bool &IsLoad
, bool &IsStore
,
1037 bool &IsStoreFromReg
, MCPhysReg
&Reg
, int32_t &SrcImm
,
1038 uint16_t &StackPtrReg
, int64_t &StackOffset
, uint8_t &Size
,
1039 bool &IsSimple
, bool &IsIndexed
) const override
{
1040 // Detect simple push/pop cases first
1041 if (int Sz
= getPushSize(Inst
)) {
1044 IsStoreFromReg
= true;
1045 StackPtrReg
= X86::RSP
;
1049 if (Inst
.getOperand(0).isImm())
1050 SrcImm
= Inst
.getOperand(0).getImm();
1051 else if (Inst
.getOperand(0).isReg())
1052 Reg
= Inst
.getOperand(0).getReg();
1058 if (int Sz
= getPopSize(Inst
)) {
1061 if (Inst
.getNumOperands() == 0 || !Inst
.getOperand(0).isReg()) {
1064 Reg
= Inst
.getOperand(0).getReg();
1067 StackPtrReg
= X86::RSP
;
1074 // Size in bytes that Inst loads from memory.
1083 int MemOpNo
= getMemoryOperandNo(Inst
);
1084 const MCInstrDesc
&MCII
= Info
->get(Inst
.getOpcode());
1085 // If it is not dealing with a memory operand, we discard it
1086 if (MemOpNo
== -1 || MCII
.isCall())
1089 switch (Inst
.getOpcode()) {
1091 bool IsLoad
= MCII
.mayLoad();
1092 bool IsStore
= MCII
.mayStore();
1093 // Is it LEA? (deals with memory but is not loading nor storing)
1094 if (!IsLoad
&& !IsStore
) {
1095 I
= {0, IsLoad
, IsStore
, false, false};
1098 uint8_t Sz
= getMemDataSize(Inst
, MemOpNo
);
1099 I
= {Sz
, IsLoad
, IsStore
, false, false};
1102 // Report simple stack accesses
1103 case X86::MOV8rm
: I
= {1, true, false, false, true}; break;
1104 case X86::MOV16rm
: I
= {2, true, false, false, true}; break;
1105 case X86::MOV32rm
: I
= {4, true, false, false, true}; break;
1106 case X86::MOV64rm
: I
= {8, true, false, false, true}; break;
1107 case X86::MOV8mr
: I
= {1, false, true, true, true}; break;
1108 case X86::MOV16mr
: I
= {2, false, true, true, true}; break;
1109 case X86::MOV32mr
: I
= {4, false, true, true, true}; break;
1110 case X86::MOV64mr
: I
= {8, false, true, true, true}; break;
1111 case X86::MOV8mi
: I
= {1, false, true, false, true}; break;
1112 case X86::MOV16mi
: I
= {2, false, true, false, true}; break;
1113 case X86::MOV32mi
: I
= {4, false, true, false, true}; break;
1114 } // end switch (Inst.getOpcode())
1116 unsigned BaseRegNum
;
1118 unsigned IndexRegNum
;
1121 const MCExpr
*DispExpr
;
1122 if (!evaluateX86MemoryOperand(Inst
, &BaseRegNum
, &ScaleValue
, &IndexRegNum
,
1123 &DispValue
, &SegRegNum
, &DispExpr
)) {
1124 LLVM_DEBUG(dbgs() << "Evaluate failed on ");
1125 LLVM_DEBUG(Inst
.dump());
1129 // Make sure it's a stack access
1130 if (BaseRegNum
!= X86::RBP
&& BaseRegNum
!= X86::RSP
)
1134 IsStore
= I
.IsStore
;
1135 IsStoreFromReg
= I
.StoreFromReg
;
1137 IsSimple
= I
.Simple
;
1138 StackPtrReg
= BaseRegNum
;
1139 StackOffset
= DispValue
;
1140 IsIndexed
= IndexRegNum
!= X86::NoRegister
|| SegRegNum
!= X86::NoRegister
;
1145 // Retrieve related register in simple MOV from/to stack operations.
1146 unsigned MemOpOffset
= static_cast<unsigned>(MemOpNo
);
1148 MCOperand RegOpnd
= Inst
.getOperand(0);
1149 assert(RegOpnd
.isReg() && "unexpected destination operand");
1150 Reg
= RegOpnd
.getReg();
1151 } else if (I
.IsStore
) {
1153 Inst
.getOperand(MemOpOffset
+ X86::AddrSegmentReg
+ 1);
1154 if (I
.StoreFromReg
) {
1155 assert(SrcOpnd
.isReg() && "unexpected source operand");
1156 Reg
= SrcOpnd
.getReg();
1158 assert(SrcOpnd
.isImm() && "unexpected source operand");
1159 SrcImm
= SrcOpnd
.getImm();
1166 void changeToPushOrPop(MCInst
&Inst
) const override
{
1167 assert(!isPush(Inst
) && !isPop(Inst
));
1170 // Size in bytes that Inst loads from memory.
1177 switch (Inst
.getOpcode()) {
1179 llvm_unreachable("Unhandled opcode");
1182 case X86::MOV16rm
: I
= {2, true, false}; break;
1183 case X86::MOV32rm
: I
= {4, true, false}; break;
1184 case X86::MOV64rm
: I
= {8, true, false}; break;
1185 case X86::MOV16mr
: I
= {2, false, true}; break;
1186 case X86::MOV32mr
: I
= {4, false, true}; break;
1187 case X86::MOV64mr
: I
= {8, false, true}; break;
1188 case X86::MOV16mi
: I
= {2, false, false}; break;
1189 case X86::MOV32mi
: I
= {4, false, false}; break;
1190 } // end switch (Inst.getOpcode())
1192 unsigned BaseRegNum
;
1194 unsigned IndexRegNum
;
1197 const MCExpr
*DispExpr
;
1198 if (!evaluateX86MemoryOperand(Inst
, &BaseRegNum
, &ScaleValue
, &IndexRegNum
,
1199 &DispValue
, &SegRegNum
, &DispExpr
)) {
1200 llvm_unreachable("Evaluate failed");
1203 // Make sure it's a stack access
1204 if (BaseRegNum
!= X86::RBP
&& BaseRegNum
!= X86::RSP
) {
1205 llvm_unreachable("Not a stack access");
1209 unsigned MemOpOffset
= getMemoryOperandNo(Inst
);
1210 unsigned NewOpcode
= 0;
1212 switch (I
.DataSize
) {
1213 case 2: NewOpcode
= X86::POP16r
; break;
1214 case 4: NewOpcode
= X86::POP32r
; break;
1215 case 8: NewOpcode
= X86::POP64r
; break;
1217 llvm_unreachable("Unexpected size");
1219 unsigned RegOpndNum
= Inst
.getOperand(0).getReg();
1221 Inst
.setOpcode(NewOpcode
);
1222 Inst
.addOperand(MCOperand::createReg(RegOpndNum
));
1225 Inst
.getOperand(MemOpOffset
+ X86::AddrSegmentReg
+ 1);
1226 if (I
.StoreFromReg
) {
1227 switch (I
.DataSize
) {
1228 case 2: NewOpcode
= X86::PUSH16r
; break;
1229 case 4: NewOpcode
= X86::PUSH32r
; break;
1230 case 8: NewOpcode
= X86::PUSH64r
; break;
1232 llvm_unreachable("Unexpected size");
1234 assert(SrcOpnd
.isReg() && "Unexpected source operand");
1235 unsigned RegOpndNum
= SrcOpnd
.getReg();
1237 Inst
.setOpcode(NewOpcode
);
1238 Inst
.addOperand(MCOperand::createReg(RegOpndNum
));
1240 switch (I
.DataSize
) {
1241 case 2: NewOpcode
= X86::PUSH16i8
; break;
1242 case 4: NewOpcode
= X86::PUSH32i8
; break;
1243 case 8: NewOpcode
= X86::PUSH64i32
; break;
1245 llvm_unreachable("Unexpected size");
1247 assert(SrcOpnd
.isImm() && "Unexpected source operand");
1248 int64_t SrcImm
= SrcOpnd
.getImm();
1250 Inst
.setOpcode(NewOpcode
);
1251 Inst
.addOperand(MCOperand::createImm(SrcImm
));
1256 bool isStackAdjustment(const MCInst
&Inst
) const override
{
1257 switch (Inst
.getOpcode()) {
1260 case X86::SUB64ri32
:
1262 case X86::ADD64ri32
:
1268 const MCInstrDesc
&MCII
= Info
->get(Inst
.getOpcode());
1269 for (int I
= 0, E
= MCII
.getNumDefs(); I
!= E
; ++I
) {
1270 const MCOperand
&Operand
= Inst
.getOperand(I
);
1271 if (Operand
.isReg() && Operand
.getReg() == X86::RSP
)
1278 evaluateStackOffsetExpr(const MCInst
&Inst
, int64_t &Output
,
1279 std::pair
<MCPhysReg
, int64_t> Input1
,
1280 std::pair
<MCPhysReg
, int64_t> Input2
) const override
{
1282 auto getOperandVal
= [&](MCPhysReg Reg
) -> ErrorOr
<int64_t> {
1283 if (Reg
== Input1
.first
)
1284 return Input1
.second
;
1285 if (Reg
== Input2
.first
)
1286 return Input2
.second
;
1287 return make_error_code(errc::result_out_of_range
);
1290 switch (Inst
.getOpcode()) {
1294 case X86::SUB64ri32
:
1296 if (!Inst
.getOperand(2).isImm())
1298 if (ErrorOr
<int64_t> InputVal
=
1299 getOperandVal(Inst
.getOperand(1).getReg()))
1300 Output
= *InputVal
- Inst
.getOperand(2).getImm();
1304 case X86::ADD64ri32
:
1306 if (!Inst
.getOperand(2).isImm())
1308 if (ErrorOr
<int64_t> InputVal
=
1309 getOperandVal(Inst
.getOperand(1).getReg()))
1310 Output
= *InputVal
+ Inst
.getOperand(2).getImm();
1315 if (!Inst
.getOperand(0).isImm())
1317 if (ErrorOr
<int64_t> InputVal
= getOperandVal(X86::RAX
))
1318 Output
= *InputVal
+ Inst
.getOperand(0).getImm();
1324 unsigned BaseRegNum
;
1326 unsigned IndexRegNum
;
1329 const MCExpr
*DispExpr
= nullptr;
1330 if (!evaluateX86MemoryOperand(Inst
, &BaseRegNum
, &ScaleValue
,
1331 &IndexRegNum
, &DispValue
, &SegRegNum
,
1335 if (BaseRegNum
== X86::NoRegister
|| IndexRegNum
!= X86::NoRegister
||
1336 SegRegNum
!= X86::NoRegister
|| DispExpr
)
1339 if (ErrorOr
<int64_t> InputVal
= getOperandVal(BaseRegNum
))
1340 Output
= *InputVal
+ DispValue
;
1350 bool isRegToRegMove(const MCInst
&Inst
, MCPhysReg
&From
,
1351 MCPhysReg
&To
) const override
{
1352 switch (Inst
.getOpcode()) {
1357 To
= getStackPointer();
1358 From
= getFramePointer();
1361 To
= Inst
.getOperand(0).getReg();
1362 From
= Inst
.getOperand(1).getReg();
1367 MCPhysReg
getStackPointer() const override
{ return X86::RSP
; }
1368 MCPhysReg
getFramePointer() const override
{ return X86::RBP
; }
1369 MCPhysReg
getFlagsReg() const override
{ return X86::EFLAGS
; }
1371 bool escapesVariable(const MCInst
&Inst
,
1372 bool HasFramePointer
) const override
{
1373 int MemOpNo
= getMemoryOperandNo(Inst
);
1374 const MCInstrDesc
&MCII
= Info
->get(Inst
.getOpcode());
1375 const unsigned NumDefs
= MCII
.getNumDefs();
1376 static BitVector
SPBPAliases(BitVector(getAliases(X86::RSP
)) |=
1377 getAliases(X86::RBP
));
1378 static BitVector
SPAliases(getAliases(X86::RSP
));
1380 // FIXME: PUSH can be technically a leak, but let's ignore this for now
1381 // because a lot of harmless prologue code will spill SP to the stack.
1382 // Unless push is clearly pushing an object address to the stack as
1383 // demonstrated by having a MemOp.
1384 bool IsPush
= isPush(Inst
);
1385 if (IsPush
&& MemOpNo
== -1)
1388 // We use this to detect LEA (has memop but does not access mem)
1389 bool AccessMem
= MCII
.mayLoad() || MCII
.mayStore();
1390 bool DoesLeak
= false;
1391 for (int I
= 0, E
= MCPlus::getNumPrimeOperands(Inst
); I
!= E
; ++I
) {
1392 // Ignore if SP/BP is used to dereference memory -- that's fine
1393 if (MemOpNo
!= -1 && !IsPush
&& AccessMem
&& I
>= MemOpNo
&&
1396 // Ignore if someone is writing to SP/BP
1397 if (I
< static_cast<int>(NumDefs
))
1400 const MCOperand
&Operand
= Inst
.getOperand(I
);
1401 if (HasFramePointer
&& Operand
.isReg() && SPBPAliases
[Operand
.getReg()]) {
1405 if (!HasFramePointer
&& Operand
.isReg() && SPAliases
[Operand
.getReg()]) {
1411 // If potential leak, check if it is not just writing to itself/sp/bp
1413 for (int I
= 0, E
= NumDefs
; I
!= E
; ++I
) {
1414 const MCOperand
&Operand
= Inst
.getOperand(I
);
1415 if (HasFramePointer
&& Operand
.isReg() &&
1416 SPBPAliases
[Operand
.getReg()]) {
1420 if (!HasFramePointer
&& Operand
.isReg() &&
1421 SPAliases
[Operand
.getReg()]) {
1430 bool addToImm(MCInst
&Inst
, int64_t &Amt
, MCContext
*Ctx
) const override
{
1431 unsigned ImmOpNo
= -1U;
1432 int MemOpNo
= getMemoryOperandNo(Inst
);
1434 ImmOpNo
= MemOpNo
+ X86::AddrDisp
;
1436 for (unsigned Index
= 0; Index
< MCPlus::getNumPrimeOperands(Inst
);
1438 if (Inst
.getOperand(Index
).isImm())
1443 MCOperand
&Operand
= Inst
.getOperand(ImmOpNo
);
1444 Amt
+= Operand
.getImm();
1445 Operand
.setImm(Amt
);
1446 // Check for the need for relaxation
1447 if (int64_t(Amt
) == int64_t(int8_t(Amt
)))
1450 // Relax instruction
1451 switch (Inst
.getOpcode()) {
1453 Inst
.setOpcode(X86::SUB64ri32
);
1456 Inst
.setOpcode(X86::ADD64ri32
);
1459 // No need for relaxation
1465 /// TODO: this implementation currently works for the most common opcodes that
1466 /// load from memory. It can be extended to work with memory store opcodes as
1467 /// well as more memory load opcodes.
1468 bool replaceMemOperandWithImm(MCInst
&Inst
, StringRef ConstantData
,
1469 uint64_t Offset
) const override
{
1470 enum CheckSignExt
: uint8_t {
1476 using CheckList
= std::vector
<std::pair
<CheckSignExt
, unsigned>>;
1478 // Size in bytes that Inst loads from memory.
1481 // True when the target operand has to be duplicated because the opcode
1482 // expects a LHS operand.
1485 // List of checks and corresponding opcodes to be used. We try to use the
1486 // smallest possible immediate value when various sizes are available,
1487 // hence we may need to check whether a larger constant fits in a smaller
1494 switch (Inst
.getOpcode()) {
1496 switch (getPopSize(Inst
)) {
1497 case 2: I
= {2, false, {{NOCHECK
, X86::MOV16ri
}}}; break;
1498 case 4: I
= {4, false, {{NOCHECK
, X86::MOV32ri
}}}; break;
1499 case 8: I
= {8, false, {{CHECK32
, X86::MOV64ri32
},
1500 {NOCHECK
, X86::MOV64rm
}}}; break;
1501 default: return false;
1507 case X86::MOV8rm
: I
= {1, false, {{NOCHECK
, X86::MOV8ri
}}}; break;
1508 case X86::MOV16rm
: I
= {2, false, {{NOCHECK
, X86::MOV16ri
}}}; break;
1509 case X86::MOV32rm
: I
= {4, false, {{NOCHECK
, X86::MOV32ri
}}}; break;
1510 case X86::MOV64rm
: I
= {8, false, {{CHECK32
, X86::MOV64ri32
},
1511 {NOCHECK
, X86::MOV64rm
}}}; break;
1514 case X86::MOVZX16rm8
: I
= {1, false, {{NOCHECK
, X86::MOV16ri
}}}; break;
1515 case X86::MOVZX32rm8
: I
= {1, false, {{NOCHECK
, X86::MOV32ri
}}}; break;
1516 case X86::MOVZX32rm16
: I
= {2, false, {{NOCHECK
, X86::MOV32ri
}}}; break;
1519 case X86::CMP8rm
: I
= {1, false, {{NOCHECK
, X86::CMP8ri
}}}; break;
1520 case X86::CMP16rm
: I
= {2, false, {{CHECK8
, X86::CMP16ri8
},
1521 {NOCHECK
, X86::CMP16ri
}}}; break;
1522 case X86::CMP32rm
: I
= {4, false, {{CHECK8
, X86::CMP32ri8
},
1523 {NOCHECK
, X86::CMP32ri
}}}; break;
1524 case X86::CMP64rm
: I
= {8, false, {{CHECK8
, X86::CMP64ri8
},
1525 {CHECK32
, X86::CMP64ri32
},
1526 {NOCHECK
, X86::CMP64rm
}}}; break;
1529 case X86::TEST8mr
: I
= {1, false, {{NOCHECK
, X86::TEST8ri
}}}; break;
1530 case X86::TEST16mr
: I
= {2, false, {{NOCHECK
, X86::TEST16ri
}}}; break;
1531 case X86::TEST32mr
: I
= {4, false, {{NOCHECK
, X86::TEST32ri
}}}; break;
1532 case X86::TEST64mr
: I
= {8, false, {{CHECK32
, X86::TEST64ri32
},
1533 {NOCHECK
, X86::TEST64mr
}}}; break;
1536 case X86::ADD8rm
: I
= {1, true, {{NOCHECK
, X86::ADD8ri
}}}; break;
1537 case X86::ADD16rm
: I
= {2, true, {{CHECK8
, X86::ADD16ri8
},
1538 {NOCHECK
, X86::ADD16ri
}}}; break;
1539 case X86::ADD32rm
: I
= {4, true, {{CHECK8
, X86::ADD32ri8
},
1540 {NOCHECK
, X86::ADD32ri
}}}; break;
1541 case X86::ADD64rm
: I
= {8, true, {{CHECK8
, X86::ADD64ri8
},
1542 {CHECK32
, X86::ADD64ri32
},
1543 {NOCHECK
, X86::ADD64rm
}}}; break;
1546 case X86::SUB8rm
: I
= {1, true, {{NOCHECK
, X86::SUB8ri
}}}; break;
1547 case X86::SUB16rm
: I
= {2, true, {{CHECK8
, X86::SUB16ri8
},
1548 {NOCHECK
, X86::SUB16ri
}}}; break;
1549 case X86::SUB32rm
: I
= {4, true, {{CHECK8
, X86::SUB32ri8
},
1550 {NOCHECK
, X86::SUB32ri
}}}; break;
1551 case X86::SUB64rm
: I
= {8, true, {{CHECK8
, X86::SUB64ri8
},
1552 {CHECK32
, X86::SUB64ri32
},
1553 {NOCHECK
, X86::SUB64rm
}}}; break;
1556 case X86::AND8rm
: I
= {1, true, {{NOCHECK
, X86::AND8ri
}}}; break;
1557 case X86::AND16rm
: I
= {2, true, {{CHECK8
, X86::AND16ri8
},
1558 {NOCHECK
, X86::AND16ri
}}}; break;
1559 case X86::AND32rm
: I
= {4, true, {{CHECK8
, X86::AND32ri8
},
1560 {NOCHECK
, X86::AND32ri
}}}; break;
1561 case X86::AND64rm
: I
= {8, true, {{CHECK8
, X86::AND64ri8
},
1562 {CHECK32
, X86::AND64ri32
},
1563 {NOCHECK
, X86::AND64rm
}}}; break;
1566 case X86::OR8rm
: I
= {1, true, {{NOCHECK
, X86::OR8ri
}}}; break;
1567 case X86::OR16rm
: I
= {2, true, {{CHECK8
, X86::OR16ri8
},
1568 {NOCHECK
, X86::OR16ri
}}}; break;
1569 case X86::OR32rm
: I
= {4, true, {{CHECK8
, X86::OR32ri8
},
1570 {NOCHECK
, X86::OR32ri
}}}; break;
1571 case X86::OR64rm
: I
= {8, true, {{CHECK8
, X86::OR64ri8
},
1572 {CHECK32
, X86::OR64ri32
},
1573 {NOCHECK
, X86::OR64rm
}}}; break;
1576 case X86::XOR8rm
: I
= {1, true, {{NOCHECK
, X86::XOR8ri
}}}; break;
1577 case X86::XOR16rm
: I
= {2, true, {{CHECK8
, X86::XOR16ri8
},
1578 {NOCHECK
, X86::XOR16ri
}}}; break;
1579 case X86::XOR32rm
: I
= {4, true, {{CHECK8
, X86::XOR32ri8
},
1580 {NOCHECK
, X86::XOR32ri
}}}; break;
1581 case X86::XOR64rm
: I
= {8, true, {{CHECK8
, X86::XOR64ri8
},
1582 {CHECK32
, X86::XOR64ri32
},
1583 {NOCHECK
, X86::XOR64rm
}}}; break;
1586 // Compute the immediate value.
1587 assert(Offset
+ I
.DataSize
<= ConstantData
.size() &&
1588 "invalid offset for given constant data");
1590 DataExtractor(ConstantData
, true, 8).getSigned(&Offset
, I
.DataSize
);
1592 // Compute the new opcode.
1593 unsigned NewOpcode
= 0;
1594 for (const std::pair
<CheckSignExt
, unsigned> &Check
: I
.Checks
) {
1595 NewOpcode
= Check
.second
;
1596 if (Check
.first
== NOCHECK
)
1598 if (Check
.first
== CHECK8
&& isInt
<8>(ImmVal
))
1600 if (Check
.first
== CHECK32
&& isInt
<32>(ImmVal
))
1603 if (NewOpcode
== Inst
.getOpcode())
1606 // Modify the instruction.
1607 MCOperand ImmOp
= MCOperand::createImm(ImmVal
);
1608 uint32_t TargetOpNum
= 0;
1609 // Test instruction does not follow the regular pattern of putting the
1610 // memory reference of a load (5 MCOperands) last in the list of operands.
1611 // Since it is not modifying the register operand, it is not treated as
1612 // a destination operand and it is not the first operand as it is in the
1613 // other instructions we treat here.
1614 if (NewOpcode
== X86::TEST8ri
|| NewOpcode
== X86::TEST16ri
||
1615 NewOpcode
== X86::TEST32ri
|| NewOpcode
== X86::TEST64ri32
)
1616 TargetOpNum
= getMemoryOperandNo(Inst
) + X86::AddrNumOperands
;
1618 MCOperand TargetOp
= Inst
.getOperand(TargetOpNum
);
1620 Inst
.setOpcode(NewOpcode
);
1621 Inst
.addOperand(TargetOp
);
1623 Inst
.addOperand(TargetOp
);
1624 Inst
.addOperand(ImmOp
);
1629 /// TODO: this implementation currently works for the most common opcodes that
1630 /// load from memory. It can be extended to work with memory store opcodes as
1631 /// well as more memory load opcodes.
1632 bool replaceMemOperandWithReg(MCInst
&Inst
, MCPhysReg RegNum
) const override
{
1635 switch (Inst
.getOpcode()) {
1637 switch (getPopSize(Inst
)) {
1638 case 2: NewOpcode
= X86::MOV16rr
; break;
1639 case 4: NewOpcode
= X86::MOV32rr
; break;
1640 case 8: NewOpcode
= X86::MOV64rr
; break;
1641 default: return false;
1647 case X86::MOV8rm
: NewOpcode
= X86::MOV8rr
; break;
1648 case X86::MOV16rm
: NewOpcode
= X86::MOV16rr
; break;
1649 case X86::MOV32rm
: NewOpcode
= X86::MOV32rr
; break;
1650 case X86::MOV64rm
: NewOpcode
= X86::MOV64rr
; break;
1653 // Modify the instruction.
1654 MCOperand RegOp
= MCOperand::createReg(RegNum
);
1655 MCOperand TargetOp
= Inst
.getOperand(0);
1657 Inst
.setOpcode(NewOpcode
);
1658 Inst
.addOperand(TargetOp
);
1659 Inst
.addOperand(RegOp
);
1664 bool isRedundantMove(const MCInst
&Inst
) const override
{
1665 switch (Inst
.getOpcode()) {
1677 assert(Inst
.getOperand(0).isReg() && Inst
.getOperand(1).isReg());
1678 return Inst
.getOperand(0).getReg() == Inst
.getOperand(1).getReg();
1681 bool requiresAlignedAddress(const MCInst
&Inst
) const override
{
1682 const MCInstrDesc
&Desc
= Info
->get(Inst
.getOpcode());
1683 for (unsigned int I
= 0; I
< Desc
.getNumOperands(); ++I
) {
1684 const MCOperandInfo
&Op
= Desc
.OpInfo
[I
];
1685 if (Op
.OperandType
!= MCOI::OPERAND_REGISTER
)
1687 if (Op
.RegClass
== X86::VR128RegClassID
)
1693 bool convertJmpToTailCall(MCInst
&Inst
) override
{
1694 if (isTailCall(Inst
))
1698 switch (Inst
.getOpcode()) {
1704 NewOpcode
= X86::JMP_4
;
1709 NewOpcode
= X86::JMP32m
;
1714 NewOpcode
= X86::JMP32r
;
1718 Inst
.setOpcode(NewOpcode
);
1723 bool convertTailCallToJmp(MCInst
&Inst
) override
{
1725 switch (Inst
.getOpcode()) {
1729 NewOpcode
= X86::JMP_1
;
1732 NewOpcode
= X86::JMP64m
;
1735 NewOpcode
= X86::JMP64r
;
1739 Inst
.setOpcode(NewOpcode
);
1740 removeAnnotation(Inst
, MCPlus::MCAnnotation::kTailCall
);
1745 bool convertTailCallToCall(MCInst
&Inst
) override
{
1747 switch (Inst
.getOpcode()) {
1751 NewOpcode
= X86::CALL64pcrel32
;
1754 NewOpcode
= X86::CALL64m
;
1757 NewOpcode
= X86::CALL64r
;
1761 Inst
.setOpcode(NewOpcode
);
1762 removeAnnotation(Inst
, MCPlus::MCAnnotation::kTailCall
);
1766 bool convertCallToIndirectCall(MCInst
&Inst
, const MCSymbol
*TargetLocation
,
1767 MCContext
*Ctx
) override
{
1768 assert((Inst
.getOpcode() == X86::CALL64pcrel32
||
1769 (Inst
.getOpcode() == X86::JMP_4
&& isTailCall(Inst
))) &&
1770 "64-bit direct (tail) call instruction expected");
1771 const auto NewOpcode
=
1772 (Inst
.getOpcode() == X86::CALL64pcrel32
) ? X86::CALL64m
: X86::JMP32m
;
1773 Inst
.setOpcode(NewOpcode
);
1775 // Replace the first operand and preserve auxiliary operands of
1777 Inst
.erase(Inst
.begin());
1778 Inst
.insert(Inst
.begin(),
1779 MCOperand::createReg(X86::NoRegister
)); // AddrSegmentReg
1780 Inst
.insert(Inst
.begin(),
1781 MCOperand::createExpr( // Displacement
1782 MCSymbolRefExpr::create(TargetLocation
,
1783 MCSymbolRefExpr::VK_None
, *Ctx
)));
1784 Inst
.insert(Inst
.begin(),
1785 MCOperand::createReg(X86::NoRegister
)); // IndexReg
1786 Inst
.insert(Inst
.begin(),
1787 MCOperand::createImm(1)); // ScaleAmt
1788 Inst
.insert(Inst
.begin(),
1789 MCOperand::createReg(X86::RIP
)); // BaseReg
1794 void convertIndirectCallToLoad(MCInst
&Inst
, MCPhysReg Reg
) override
{
1795 bool IsTailCall
= isTailCall(Inst
);
1797 removeAnnotation(Inst
, MCPlus::MCAnnotation::kTailCall
);
1798 if (Inst
.getOpcode() == X86::CALL64m
||
1799 (Inst
.getOpcode() == X86::JMP32m
&& IsTailCall
)) {
1800 Inst
.setOpcode(X86::MOV64rm
);
1801 Inst
.insert(Inst
.begin(), MCOperand::createReg(Reg
));
1804 if (Inst
.getOpcode() == X86::CALL64r
||
1805 (Inst
.getOpcode() == X86::JMP32r
&& IsTailCall
)) {
1806 Inst
.setOpcode(X86::MOV64rr
);
1807 Inst
.insert(Inst
.begin(), MCOperand::createReg(Reg
));
1810 LLVM_DEBUG(Inst
.dump());
1811 llvm_unreachable("not implemented");
1814 bool shortenInstruction(MCInst
&Inst
,
1815 const MCSubtargetInfo
&STI
) const override
{
1816 unsigned OldOpcode
= Inst
.getOpcode();
1817 unsigned NewOpcode
= OldOpcode
;
1819 int MemOpNo
= getMemoryOperandNo(Inst
);
1821 // Check and remove redundant Address-Size override prefix.
1822 if (opts::X86StripRedundantAddressSize
) {
1823 uint64_t TSFlags
= Info
->get(OldOpcode
).TSFlags
;
1824 unsigned Flags
= Inst
.getFlags();
1826 if (!X86_MC::needsAddressSizeOverride(Inst
, STI
, MemOpNo
, TSFlags
) &&
1827 Flags
& X86::IP_HAS_AD_SIZE
)
1828 Inst
.setFlags(Flags
^ X86::IP_HAS_AD_SIZE
);
1831 // Check and remove EIZ/RIZ. These cases represent ambiguous cases where
1832 // SIB byte is present, but no index is used and modrm alone should have
1833 // been enough. Converting to NoRegister effectively removes the SIB byte.
1835 MCOperand
&IndexOp
=
1836 Inst
.getOperand(static_cast<unsigned>(MemOpNo
) + X86::AddrIndexReg
);
1837 if (IndexOp
.getReg() == X86::EIZ
|| IndexOp
.getReg() == X86::RIZ
)
1838 IndexOp
= MCOperand::createReg(X86::NoRegister
);
1841 if (isBranch(Inst
)) {
1842 NewOpcode
= getShortBranchOpcode(OldOpcode
);
1843 } else if (OldOpcode
== X86::MOV64ri
) {
1844 if (Inst
.getOperand(MCPlus::getNumPrimeOperands(Inst
) - 1).isImm()) {
1846 Inst
.getOperand(MCPlus::getNumPrimeOperands(Inst
) - 1).getImm();
1847 if (int64_t(Imm
) == int64_t(int32_t(Imm
)))
1848 NewOpcode
= X86::MOV64ri32
;
1851 // If it's arithmetic instruction check if signed operand fits in 1 byte.
1852 const unsigned ShortOpcode
= getShortArithOpcode(OldOpcode
);
1853 if (ShortOpcode
!= OldOpcode
&&
1854 Inst
.getOperand(MCPlus::getNumPrimeOperands(Inst
) - 1).isImm()) {
1856 Inst
.getOperand(MCPlus::getNumPrimeOperands(Inst
) - 1).getImm();
1857 if (int64_t(Imm
) == int64_t(int8_t(Imm
)))
1858 NewOpcode
= ShortOpcode
;
1862 if (NewOpcode
== OldOpcode
)
1865 Inst
.setOpcode(NewOpcode
);
1870 convertMoveToConditionalMove(MCInst
&Inst
, unsigned CC
, bool AllowStackMemOp
,
1871 bool AllowBasePtrStackMemOp
) const override
{
1872 // - Register-register moves are OK
1873 // - Stores are filtered out by opcode (no store CMOV)
1874 // - Non-stack loads are prohibited (generally unsafe)
1875 // - Stack loads are OK if AllowStackMemOp is true
1876 // - Stack loads with RBP are OK if AllowBasePtrStackMemOp is true
1878 // If stack memory operands are not allowed, no loads are allowed
1879 if (!AllowStackMemOp
)
1882 // If stack memory operands are allowed, check if it's a load from stack
1883 bool IsLoad
, IsStore
, IsStoreFromReg
, IsSimple
, IsIndexed
;
1886 uint16_t StackPtrReg
;
1887 int64_t StackOffset
;
1889 bool IsStackAccess
=
1890 isStackAccess(Inst
, IsLoad
, IsStore
, IsStoreFromReg
, Reg
, SrcImm
,
1891 StackPtrReg
, StackOffset
, Size
, IsSimple
, IsIndexed
);
1892 // Prohibit non-stack-based loads
1895 // If stack memory operands are allowed, check if it's RBP-based
1896 if (!AllowBasePtrStackMemOp
&&
1897 RegInfo
->isSubRegisterEq(X86::RBP
, StackPtrReg
))
1901 unsigned NewOpcode
= 0;
1902 switch (Inst
.getOpcode()) {
1904 NewOpcode
= X86::CMOV16rr
;
1907 NewOpcode
= X86::CMOV16rm
;
1910 NewOpcode
= X86::CMOV32rr
;
1913 NewOpcode
= X86::CMOV32rm
;
1916 NewOpcode
= X86::CMOV64rr
;
1919 NewOpcode
= X86::CMOV64rm
;
1924 Inst
.setOpcode(NewOpcode
);
1925 // Insert CC at the end of prime operands, before annotations
1926 Inst
.insert(Inst
.begin() + MCPlus::getNumPrimeOperands(Inst
),
1927 MCOperand::createImm(CC
));
1928 // CMOV is a 3-operand MCInst, so duplicate the destination as src1
1929 Inst
.insert(Inst
.begin(), Inst
.getOperand(0));
1933 bool lowerTailCall(MCInst
&Inst
) override
{
1934 if (Inst
.getOpcode() == X86::JMP_4
&& isTailCall(Inst
)) {
1935 Inst
.setOpcode(X86::JMP_1
);
1936 removeAnnotation(Inst
, MCPlus::MCAnnotation::kTailCall
);
1942 const MCSymbol
*getTargetSymbol(const MCInst
&Inst
,
1943 unsigned OpNum
= 0) const override
{
1944 if (OpNum
>= MCPlus::getNumPrimeOperands(Inst
))
1947 const MCOperand
&Op
= Inst
.getOperand(OpNum
);
1951 auto *SymExpr
= dyn_cast
<MCSymbolRefExpr
>(Op
.getExpr());
1952 if (!SymExpr
|| SymExpr
->getKind() != MCSymbolRefExpr::VK_None
)
1955 return &SymExpr
->getSymbol();
1958 // This is the same as the base class, but since we are overriding one of
1959 // getTargetSymbol's signatures above, we need to override all of them.
1960 const MCSymbol
*getTargetSymbol(const MCExpr
*Expr
) const override
{
1961 return &cast
<const MCSymbolRefExpr
>(Expr
)->getSymbol();
1964 bool analyzeBranch(InstructionIterator Begin
, InstructionIterator End
,
1965 const MCSymbol
*&TBB
, const MCSymbol
*&FBB
,
1966 MCInst
*&CondBranch
,
1967 MCInst
*&UncondBranch
) const override
{
1970 // Bottom-up analysis
1971 while (I
!= Begin
) {
1974 // Ignore nops and CFIs
1978 // Stop when we find the first non-terminator
1979 if (!isTerminator(*I
))
1985 // Handle unconditional branches.
1986 if ((I
->getOpcode() == X86::JMP_1
|| I
->getOpcode() == X86::JMP_2
||
1987 I
->getOpcode() == X86::JMP_4
) &&
1989 // If any code was seen after this unconditional branch, we've seen
1990 // unreachable code. Ignore them.
1991 CondBranch
= nullptr;
1993 const MCSymbol
*Sym
= getTargetSymbol(*I
);
1994 assert(Sym
!= nullptr &&
1995 "Couldn't extract BB symbol from jump operand");
2000 // Handle conditional branches and ignore indirect branches
2001 if (!isUnsupportedBranch(I
->getOpcode()) &&
2002 getCondCode(*I
) == X86::COND_INVALID
) {
2007 if (CondBranch
== nullptr) {
2008 const MCSymbol
*TargetBB
= getTargetSymbol(*I
);
2009 if (TargetBB
== nullptr) {
2010 // Unrecognized branch target
2019 llvm_unreachable("multiple conditional branches in one BB");
2024 template <typename Itr
>
2025 std::pair
<IndirectBranchType
, MCInst
*>
2026 analyzePICJumpTable(Itr II
, Itr IE
, MCPhysReg R1
, MCPhysReg R2
) const {
2027 // Analyze PIC-style jump table code template:
2029 // lea PIC_JUMP_TABLE(%rip), {%r1|%r2} <- MemLocInstr
2030 // mov ({%r1|%r2}, %index, 4), {%r2|%r1}
2034 // (with any irrelevant instructions in-between)
2036 // When we call this helper we've already determined %r1 and %r2, and
2037 // reverse instruction iterator \p II is pointing to the ADD instruction.
2039 // PIC jump table looks like following:
2051 // Where L1, L2, ..., Ln represent labels in the function.
2053 // The actual relocations in the table will be of the form:
2056 // = (Ln - En) + (En - JT)
2057 // = R_X86_64_PC32(Ln) + En - JT
2058 // = R_X86_64_PC32(Ln + offsetof(En))
2060 LLVM_DEBUG(dbgs() << "Checking for PIC jump table\n");
2061 MCInst
*MemLocInstr
= nullptr;
2062 const MCInst
*MovInstr
= nullptr;
2063 while (++II
!= IE
) {
2064 MCInst
&Instr
= *II
;
2065 const MCInstrDesc
&InstrDesc
= Info
->get(Instr
.getOpcode());
2066 if (!InstrDesc
.hasDefOfPhysReg(Instr
, R1
, *RegInfo
) &&
2067 !InstrDesc
.hasDefOfPhysReg(Instr
, R2
, *RegInfo
)) {
2068 // Ignore instructions that don't affect R1, R2 registers.
2072 // Expect to see MOV instruction.
2073 if (!isMOVSX64rm32(Instr
)) {
2074 LLVM_DEBUG(dbgs() << "MOV instruction expected.\n");
2078 // Check if it's setting %r1 or %r2. In canonical form it sets %r2.
2079 // If it sets %r1 - rename the registers so we have to only check
2081 unsigned MovDestReg
= Instr
.getOperand(0).getReg();
2082 if (MovDestReg
!= R2
)
2084 if (MovDestReg
!= R2
) {
2085 LLVM_DEBUG(dbgs() << "MOV instruction expected to set %r2\n");
2089 // Verify operands for MOV.
2090 unsigned BaseRegNum
;
2092 unsigned IndexRegNum
;
2095 if (!evaluateX86MemoryOperand(Instr
, &BaseRegNum
, &ScaleValue
,
2096 &IndexRegNum
, &DispValue
, &SegRegNum
))
2098 if (BaseRegNum
!= R1
|| ScaleValue
!= 4 ||
2099 IndexRegNum
== X86::NoRegister
|| DispValue
!= 0 ||
2100 SegRegNum
!= X86::NoRegister
)
2104 if (!InstrDesc
.hasDefOfPhysReg(Instr
, R1
, *RegInfo
))
2106 if (!isLEA64r(Instr
)) {
2107 LLVM_DEBUG(dbgs() << "LEA instruction expected\n");
2110 if (Instr
.getOperand(0).getReg() != R1
) {
2111 LLVM_DEBUG(dbgs() << "LEA instruction expected to set %r1\n");
2115 // Verify operands for LEA.
2116 unsigned BaseRegNum
;
2118 unsigned IndexRegNum
;
2119 const MCExpr
*DispExpr
= nullptr;
2122 if (!evaluateX86MemoryOperand(Instr
, &BaseRegNum
, &ScaleValue
,
2123 &IndexRegNum
, &DispValue
, &SegRegNum
,
2126 if (BaseRegNum
!= RegInfo
->getProgramCounter() ||
2127 IndexRegNum
!= X86::NoRegister
|| SegRegNum
!= X86::NoRegister
||
2128 DispExpr
== nullptr)
2130 MemLocInstr
= &Instr
;
2136 return std::make_pair(IndirectBranchType::UNKNOWN
, nullptr);
2138 LLVM_DEBUG(dbgs() << "checking potential PIC jump table\n");
2139 return std::make_pair(IndirectBranchType::POSSIBLE_PIC_JUMP_TABLE
,
2143 IndirectBranchType
analyzeIndirectBranch(
2144 MCInst
&Instruction
, InstructionIterator Begin
, InstructionIterator End
,
2145 const unsigned PtrSize
, MCInst
*&MemLocInstrOut
, unsigned &BaseRegNumOut
,
2146 unsigned &IndexRegNumOut
, int64_t &DispValueOut
,
2147 const MCExpr
*&DispExprOut
, MCInst
*&PCRelBaseOut
) const override
{
2148 // Try to find a (base) memory location from where the address for
2149 // the indirect branch is loaded. For X86-64 the memory will be specified
2150 // in the following format:
2152 // {%rip}/{%basereg} + Imm + IndexReg * Scale
2154 // We are interested in the cases where Scale == sizeof(uintptr_t) and
2155 // the contents of the memory are presumably an array of pointers to code.
2157 // Normal jump table:
2159 // jmp *(JUMP_TABLE, %index, Scale) <- MemLocInstr
2163 // mov (JUMP_TABLE, %index, Scale), %r1 <- MemLocInstr
2167 // We handle PIC-style jump tables separately.
2169 MemLocInstrOut
= nullptr;
2170 BaseRegNumOut
= X86::NoRegister
;
2171 IndexRegNumOut
= X86::NoRegister
;
2173 DispExprOut
= nullptr;
2175 std::reverse_iterator
<InstructionIterator
> II(End
);
2176 std::reverse_iterator
<InstructionIterator
> IE(Begin
);
2178 IndirectBranchType Type
= IndirectBranchType::UNKNOWN
;
2180 // An instruction referencing memory used by jump instruction (directly or
2181 // via register). This location could be an array of function pointers
2182 // in case of indirect tail call, or a jump table.
2183 MCInst
*MemLocInstr
= nullptr;
2185 if (MCPlus::getNumPrimeOperands(Instruction
) == 1) {
2186 // If the indirect jump is on register - try to detect if the
2187 // register value is loaded from a memory location.
2188 assert(Instruction
.getOperand(0).isReg() && "register operand expected");
2189 const unsigned R1
= Instruction
.getOperand(0).getReg();
2190 // Check if one of the previous instructions defines the jump-on register.
2191 for (auto PrevII
= II
; PrevII
!= IE
; ++PrevII
) {
2192 MCInst
&PrevInstr
= *PrevII
;
2193 const MCInstrDesc
&PrevInstrDesc
= Info
->get(PrevInstr
.getOpcode());
2195 if (!PrevInstrDesc
.hasDefOfPhysReg(PrevInstr
, R1
, *RegInfo
))
2198 if (isMoveMem2Reg(PrevInstr
)) {
2199 MemLocInstr
= &PrevInstr
;
2202 if (isADD64rr(PrevInstr
)) {
2203 unsigned R2
= PrevInstr
.getOperand(2).getReg();
2205 return IndirectBranchType::UNKNOWN
;
2206 std::tie(Type
, MemLocInstr
) = analyzePICJumpTable(PrevII
, IE
, R1
, R2
);
2209 return IndirectBranchType::UNKNOWN
;
2212 // No definition seen for the register in this function so far. Could be
2213 // an input parameter - which means it is an external code reference.
2214 // It also could be that the definition happens to be in the code that
2215 // we haven't processed yet. Since we have to be conservative, return
2217 return IndirectBranchType::UNKNOWN
;
2220 MemLocInstr
= &Instruction
;
2223 const MCRegister RIPRegister
= RegInfo
->getProgramCounter();
2225 // Analyze the memory location.
2226 unsigned BaseRegNum
, IndexRegNum
, SegRegNum
;
2227 int64_t ScaleValue
, DispValue
;
2228 const MCExpr
*DispExpr
;
2230 if (!evaluateX86MemoryOperand(*MemLocInstr
, &BaseRegNum
, &ScaleValue
,
2231 &IndexRegNum
, &DispValue
, &SegRegNum
,
2233 return IndirectBranchType::UNKNOWN
;
2235 BaseRegNumOut
= BaseRegNum
;
2236 IndexRegNumOut
= IndexRegNum
;
2237 DispValueOut
= DispValue
;
2238 DispExprOut
= DispExpr
;
2240 if ((BaseRegNum
!= X86::NoRegister
&& BaseRegNum
!= RIPRegister
) ||
2241 SegRegNum
!= X86::NoRegister
)
2242 return IndirectBranchType::UNKNOWN
;
2244 if (MemLocInstr
== &Instruction
&&
2245 (!ScaleValue
|| IndexRegNum
== X86::NoRegister
)) {
2246 MemLocInstrOut
= MemLocInstr
;
2247 return IndirectBranchType::POSSIBLE_FIXED_BRANCH
;
2250 if (Type
== IndirectBranchType::POSSIBLE_PIC_JUMP_TABLE
&&
2251 (ScaleValue
!= 1 || BaseRegNum
!= RIPRegister
))
2252 return IndirectBranchType::UNKNOWN
;
2254 if (Type
!= IndirectBranchType::POSSIBLE_PIC_JUMP_TABLE
&&
2255 ScaleValue
!= PtrSize
)
2256 return IndirectBranchType::UNKNOWN
;
2258 MemLocInstrOut
= MemLocInstr
;
2263 /// Analyze a callsite to see if it could be a virtual method call. This only
2264 /// checks to see if the overall pattern is satisfied, it does not guarantee
2265 /// that the callsite is a true virtual method call.
2266 /// The format of virtual method calls that are recognized is one of the
2269 /// Form 1: (found in debug code)
2270 /// add METHOD_OFFSET, %VtableReg
2271 /// mov (%VtableReg), %MethodReg
2273 /// call or jmp *%MethodReg
2276 /// mov METHOD_OFFSET(%VtableReg), %MethodReg
2278 /// call or jmp *%MethodReg
2282 /// call or jmp *METHOD_OFFSET(%VtableReg)
2284 bool analyzeVirtualMethodCall(InstructionIterator ForwardBegin
,
2285 InstructionIterator ForwardEnd
,
2286 std::vector
<MCInst
*> &MethodFetchInsns
,
2287 unsigned &VtableRegNum
, unsigned &MethodRegNum
,
2288 uint64_t &MethodOffset
) const override
{
2289 VtableRegNum
= X86::NoRegister
;
2290 MethodRegNum
= X86::NoRegister
;
2293 std::reverse_iterator
<InstructionIterator
> Itr(ForwardEnd
);
2294 std::reverse_iterator
<InstructionIterator
> End(ForwardBegin
);
2296 MCInst
&CallInst
= *Itr
++;
2297 assert(isIndirectBranch(CallInst
) || isCall(CallInst
));
2299 unsigned BaseReg
, IndexReg
, SegmentReg
;
2300 int64_t Scale
, Disp
;
2301 const MCExpr
*DispExpr
;
2303 // The call can just be jmp offset(reg)
2304 if (evaluateX86MemoryOperand(CallInst
, &BaseReg
, &Scale
, &IndexReg
, &Disp
,
2305 &SegmentReg
, &DispExpr
)) {
2306 if (!DispExpr
&& BaseReg
!= X86::RIP
&& BaseReg
!= X86::RBP
&&
2307 BaseReg
!= X86::NoRegister
) {
2308 MethodRegNum
= BaseReg
;
2309 if (Scale
== 1 && IndexReg
== X86::NoRegister
&&
2310 SegmentReg
== X86::NoRegister
) {
2311 VtableRegNum
= MethodRegNum
;
2312 MethodOffset
= Disp
;
2313 MethodFetchInsns
.push_back(&CallInst
);
2319 if (CallInst
.getOperand(0).isReg())
2320 MethodRegNum
= CallInst
.getOperand(0).getReg();
2324 if (MethodRegNum
== X86::RIP
|| MethodRegNum
== X86::RBP
) {
2325 VtableRegNum
= X86::NoRegister
;
2326 MethodRegNum
= X86::NoRegister
;
2330 // find load from vtable, this may or may not include the method offset
2331 while (Itr
!= End
) {
2332 MCInst
&CurInst
= *Itr
++;
2333 const MCInstrDesc
&Desc
= Info
->get(CurInst
.getOpcode());
2334 if (Desc
.hasDefOfPhysReg(CurInst
, MethodRegNum
, *RegInfo
)) {
2335 if (isLoad(CurInst
) &&
2336 evaluateX86MemoryOperand(CurInst
, &BaseReg
, &Scale
, &IndexReg
,
2337 &Disp
, &SegmentReg
, &DispExpr
)) {
2338 if (!DispExpr
&& Scale
== 1 && BaseReg
!= X86::RIP
&&
2339 BaseReg
!= X86::RBP
&& BaseReg
!= X86::NoRegister
&&
2340 IndexReg
== X86::NoRegister
&& SegmentReg
== X86::NoRegister
&&
2341 BaseReg
!= X86::RIP
) {
2342 VtableRegNum
= BaseReg
;
2343 MethodOffset
= Disp
;
2344 MethodFetchInsns
.push_back(&CurInst
);
2345 if (MethodOffset
!= 0)
2357 // look for any adds affecting the method register.
2358 while (Itr
!= End
) {
2359 MCInst
&CurInst
= *Itr
++;
2360 const MCInstrDesc
&Desc
= Info
->get(CurInst
.getOpcode());
2361 if (Desc
.hasDefOfPhysReg(CurInst
, VtableRegNum
, *RegInfo
)) {
2362 if (isADDri(CurInst
)) {
2363 assert(!MethodOffset
);
2364 MethodOffset
= CurInst
.getOperand(2).getImm();
2365 MethodFetchInsns
.insert(MethodFetchInsns
.begin(), &CurInst
);
2374 bool createStackPointerIncrement(MCInst
&Inst
, int Size
,
2375 bool NoFlagsClobber
) const override
{
2376 if (NoFlagsClobber
) {
2377 Inst
.setOpcode(X86::LEA64r
);
2379 Inst
.addOperand(MCOperand::createReg(X86::RSP
));
2380 Inst
.addOperand(MCOperand::createReg(X86::RSP
)); // BaseReg
2381 Inst
.addOperand(MCOperand::createImm(1)); // ScaleAmt
2382 Inst
.addOperand(MCOperand::createReg(X86::NoRegister
)); // IndexReg
2383 Inst
.addOperand(MCOperand::createImm(-Size
)); // Displacement
2384 Inst
.addOperand(MCOperand::createReg(X86::NoRegister
)); // AddrSegmentReg
2387 Inst
.setOpcode(X86::SUB64ri8
);
2389 Inst
.addOperand(MCOperand::createReg(X86::RSP
));
2390 Inst
.addOperand(MCOperand::createReg(X86::RSP
));
2391 Inst
.addOperand(MCOperand::createImm(Size
));
2395 bool createStackPointerDecrement(MCInst
&Inst
, int Size
,
2396 bool NoFlagsClobber
) const override
{
2397 if (NoFlagsClobber
) {
2398 Inst
.setOpcode(X86::LEA64r
);
2400 Inst
.addOperand(MCOperand::createReg(X86::RSP
));
2401 Inst
.addOperand(MCOperand::createReg(X86::RSP
)); // BaseReg
2402 Inst
.addOperand(MCOperand::createImm(1)); // ScaleAmt
2403 Inst
.addOperand(MCOperand::createReg(X86::NoRegister
)); // IndexReg
2404 Inst
.addOperand(MCOperand::createImm(Size
)); // Displacement
2405 Inst
.addOperand(MCOperand::createReg(X86::NoRegister
)); // AddrSegmentReg
2408 Inst
.setOpcode(X86::ADD64ri8
);
2410 Inst
.addOperand(MCOperand::createReg(X86::RSP
));
2411 Inst
.addOperand(MCOperand::createReg(X86::RSP
));
2412 Inst
.addOperand(MCOperand::createImm(Size
));
2416 bool createSaveToStack(MCInst
&Inst
, const MCPhysReg
&StackReg
, int Offset
,
2417 const MCPhysReg
&SrcReg
, int Size
) const override
{
2422 case 2: NewOpcode
= X86::MOV16mr
; break;
2423 case 4: NewOpcode
= X86::MOV32mr
; break;
2424 case 8: NewOpcode
= X86::MOV64mr
; break;
2426 Inst
.setOpcode(NewOpcode
);
2428 Inst
.addOperand(MCOperand::createReg(StackReg
)); // BaseReg
2429 Inst
.addOperand(MCOperand::createImm(1)); // ScaleAmt
2430 Inst
.addOperand(MCOperand::createReg(X86::NoRegister
)); // IndexReg
2431 Inst
.addOperand(MCOperand::createImm(Offset
)); // Displacement
2432 Inst
.addOperand(MCOperand::createReg(X86::NoRegister
)); // AddrSegmentReg
2433 Inst
.addOperand(MCOperand::createReg(SrcReg
));
2437 bool createRestoreFromStack(MCInst
&Inst
, const MCPhysReg
&StackReg
,
2438 int Offset
, const MCPhysReg
&DstReg
,
2439 int Size
) const override
{
2440 return createLoad(Inst
, StackReg
, /*Scale=*/1, /*IndexReg=*/X86::NoRegister
,
2441 Offset
, nullptr, /*AddrSegmentReg=*/X86::NoRegister
,
2445 bool createLoad(MCInst
&Inst
, const MCPhysReg
&BaseReg
, int64_t Scale
,
2446 const MCPhysReg
&IndexReg
, int64_t Offset
,
2447 const MCExpr
*OffsetExpr
, const MCPhysReg
&AddrSegmentReg
,
2448 const MCPhysReg
&DstReg
, int Size
) const override
{
2453 case 2: NewOpcode
= X86::MOV16rm
; break;
2454 case 4: NewOpcode
= X86::MOV32rm
; break;
2455 case 8: NewOpcode
= X86::MOV64rm
; break;
2457 Inst
.setOpcode(NewOpcode
);
2459 Inst
.addOperand(MCOperand::createReg(DstReg
));
2460 Inst
.addOperand(MCOperand::createReg(BaseReg
));
2461 Inst
.addOperand(MCOperand::createImm(Scale
));
2462 Inst
.addOperand(MCOperand::createReg(IndexReg
));
2464 Inst
.addOperand(MCOperand::createExpr(OffsetExpr
)); // Displacement
2466 Inst
.addOperand(MCOperand::createImm(Offset
)); // Displacement
2467 Inst
.addOperand(MCOperand::createReg(AddrSegmentReg
)); // AddrSegmentReg
2471 void createLoadImmediate(MCInst
&Inst
, const MCPhysReg Dest
,
2472 uint32_t Imm
) const override
{
2473 Inst
.setOpcode(X86::MOV64ri32
);
2475 Inst
.addOperand(MCOperand::createReg(Dest
));
2476 Inst
.addOperand(MCOperand::createImm(Imm
));
2479 bool createIncMemory(MCInst
&Inst
, const MCSymbol
*Target
,
2480 MCContext
*Ctx
) const override
{
2482 Inst
.setOpcode(X86::LOCK_INC64m
);
2484 Inst
.addOperand(MCOperand::createReg(X86::RIP
)); // BaseReg
2485 Inst
.addOperand(MCOperand::createImm(1)); // ScaleAmt
2486 Inst
.addOperand(MCOperand::createReg(X86::NoRegister
)); // IndexReg
2488 Inst
.addOperand(MCOperand::createExpr(
2489 MCSymbolRefExpr::create(Target
, MCSymbolRefExpr::VK_None
,
2490 *Ctx
))); // Displacement
2491 Inst
.addOperand(MCOperand::createReg(X86::NoRegister
)); // AddrSegmentReg
2495 bool createIJmp32Frag(SmallVectorImpl
<MCInst
> &Insts
,
2496 const MCOperand
&BaseReg
, const MCOperand
&Scale
,
2497 const MCOperand
&IndexReg
, const MCOperand
&Offset
,
2498 const MCOperand
&TmpReg
) const override
{
2499 // The code fragment we emit here is:
2501 // mov32 (%base, %index, scale), %tmpreg
2505 IJmp
.setOpcode(X86::JMP64r
);
2506 IJmp
.addOperand(TmpReg
);
2509 Load
.setOpcode(X86::MOV32rm
);
2510 Load
.addOperand(TmpReg
);
2511 Load
.addOperand(BaseReg
);
2512 Load
.addOperand(Scale
);
2513 Load
.addOperand(IndexReg
);
2514 Load
.addOperand(Offset
);
2515 Load
.addOperand(MCOperand::createReg(X86::NoRegister
));
2517 Insts
.push_back(Load
);
2518 Insts
.push_back(IJmp
);
2522 bool createNoop(MCInst
&Inst
) const override
{
2523 Inst
.setOpcode(X86::NOOP
);
2527 bool createReturn(MCInst
&Inst
) const override
{
2528 Inst
.setOpcode(X86::RET64
);
2532 InstructionListType
createInlineMemcpy(bool ReturnEnd
) const override
{
2533 InstructionListType Code
;
2535 Code
.emplace_back(MCInstBuilder(X86::LEA64r
)
2541 .addReg(X86::NoRegister
));
2543 Code
.emplace_back(MCInstBuilder(X86::MOV64rr
)
2547 Code
.emplace_back(MCInstBuilder(X86::MOV32rr
)
2550 Code
.emplace_back(MCInstBuilder(X86::REP_MOVSB_64
));
2555 InstructionListType
createOneByteMemcpy() const override
{
2556 InstructionListType Code
;
2557 Code
.emplace_back(MCInstBuilder(X86::MOV8rm
)
2561 .addReg(X86::NoRegister
)
2563 .addReg(X86::NoRegister
));
2564 Code
.emplace_back(MCInstBuilder(X86::MOV8mr
)
2567 .addReg(X86::NoRegister
)
2569 .addReg(X86::NoRegister
)
2571 Code
.emplace_back(MCInstBuilder(X86::MOV64rr
)
2577 InstructionListType
createCmpJE(MCPhysReg RegNo
, int64_t Imm
,
2578 const MCSymbol
*Target
,
2579 MCContext
*Ctx
) const override
{
2580 InstructionListType Code
;
2581 Code
.emplace_back(MCInstBuilder(X86::CMP64ri8
)
2584 Code
.emplace_back(MCInstBuilder(X86::JCC_1
)
2585 .addExpr(MCSymbolRefExpr::create(
2586 Target
, MCSymbolRefExpr::VK_None
, *Ctx
))
2587 .addImm(X86::COND_E
));
2591 Optional
<Relocation
>
2592 createRelocation(const MCFixup
&Fixup
,
2593 const MCAsmBackend
&MAB
) const override
{
2594 const MCFixupKindInfo
&FKI
= MAB
.getFixupKindInfo(Fixup
.getKind());
2596 assert(FKI
.TargetOffset
== 0 && "0-bit relocation offset expected");
2597 const uint64_t RelOffset
= Fixup
.getOffset();
2600 if (FKI
.Flags
& MCFixupKindInfo::FKF_IsPCRel
) {
2601 switch (FKI
.TargetSize
) {
2604 case 8: RelType
= ELF::R_X86_64_PC8
; break;
2605 case 16: RelType
= ELF::R_X86_64_PC16
; break;
2606 case 32: RelType
= ELF::R_X86_64_PC32
; break;
2607 case 64: RelType
= ELF::R_X86_64_PC64
; break;
2610 switch (FKI
.TargetSize
) {
2613 case 8: RelType
= ELF::R_X86_64_8
; break;
2614 case 16: RelType
= ELF::R_X86_64_16
; break;
2615 case 32: RelType
= ELF::R_X86_64_32
; break;
2616 case 64: RelType
= ELF::R_X86_64_64
; break;
2620 // Extract a symbol and an addend out of the fixup value expression.
2622 // Only the following limited expression types are supported:
2625 uint64_t Addend
= 0;
2626 MCSymbol
*Symbol
= nullptr;
2627 const MCExpr
*ValueExpr
= Fixup
.getValue();
2628 if (ValueExpr
->getKind() == MCExpr::Binary
) {
2629 const auto *BinaryExpr
= cast
<MCBinaryExpr
>(ValueExpr
);
2630 assert(BinaryExpr
->getOpcode() == MCBinaryExpr::Add
&&
2631 "unexpected binary expression");
2632 const MCExpr
*LHS
= BinaryExpr
->getLHS();
2633 assert(LHS
->getKind() == MCExpr::SymbolRef
&& "unexpected LHS");
2634 Symbol
= const_cast<MCSymbol
*>(this->getTargetSymbol(LHS
));
2635 const MCExpr
*RHS
= BinaryExpr
->getRHS();
2636 assert(RHS
->getKind() == MCExpr::Constant
&& "unexpected RHS");
2637 Addend
= cast
<MCConstantExpr
>(RHS
)->getValue();
2639 assert(ValueExpr
->getKind() == MCExpr::SymbolRef
&& "unexpected value");
2640 Symbol
= const_cast<MCSymbol
*>(this->getTargetSymbol(ValueExpr
));
2643 return Relocation({RelOffset
, Symbol
, RelType
, Addend
, 0});
2646 bool replaceImmWithSymbolRef(MCInst
&Inst
, const MCSymbol
*Symbol
,
2647 int64_t Addend
, MCContext
*Ctx
, int64_t &Value
,
2648 uint64_t RelType
) const override
{
2649 unsigned ImmOpNo
= -1U;
2651 for (unsigned Index
= 0; Index
< MCPlus::getNumPrimeOperands(Inst
);
2653 if (Inst
.getOperand(Index
).isImm()) {
2655 // TODO: this is a bit hacky. It finds the correct operand by
2656 // searching for a specific immediate value. If no value is
2657 // provided it defaults to the last immediate operand found.
2658 // This could lead to unexpected results if the instruction
2659 // has more than one immediate with the same value.
2660 if (Inst
.getOperand(ImmOpNo
).getImm() == Value
)
2668 Value
= Inst
.getOperand(ImmOpNo
).getImm();
2670 setOperandToSymbolRef(Inst
, ImmOpNo
, Symbol
, Addend
, Ctx
, RelType
);
2675 bool replaceRegWithImm(MCInst
&Inst
, unsigned Register
,
2676 int64_t Imm
) const override
{
2678 enum CheckSignExt
: uint8_t {
2684 using CheckList
= std::vector
<std::pair
<CheckSignExt
, unsigned>>;
2686 // Size in bytes that Inst loads from memory.
2689 // True when the target operand has to be duplicated because the opcode
2690 // expects a LHS operand.
2693 // List of checks and corresponding opcodes to be used. We try to use the
2694 // smallest possible immediate value when various sizes are available,
2695 // hence we may need to check whether a larger constant fits in a smaller
2702 switch (Inst
.getOpcode()) {
2704 switch (getPushSize(Inst
)) {
2706 case 2: I
= {2, false, {{CHECK8
, X86::PUSH16i8
}, {NOCHECK
, X86::PUSHi16
}}}; break;
2707 case 4: I
= {4, false, {{CHECK8
, X86::PUSH32i8
}, {NOCHECK
, X86::PUSHi32
}}}; break;
2708 case 8: I
= {8, false, {{CHECK8
, X86::PUSH64i8
},
2709 {CHECK32
, X86::PUSH64i32
},
2710 {NOCHECK
, Inst
.getOpcode()}}}; break;
2711 default: return false;
2717 case X86::MOV8rr
: I
= {1, false, {{NOCHECK
, X86::MOV8ri
}}}; break;
2718 case X86::MOV16rr
: I
= {2, false, {{NOCHECK
, X86::MOV16ri
}}}; break;
2719 case X86::MOV32rr
: I
= {4, false, {{NOCHECK
, X86::MOV32ri
}}}; break;
2720 case X86::MOV64rr
: I
= {8, false, {{CHECK32
, X86::MOV64ri32
},
2721 {NOCHECK
, X86::MOV64ri
}}}; break;
2723 case X86::MOV8mr
: I
= {1, false, {{NOCHECK
, X86::MOV8mi
}}}; break;
2724 case X86::MOV16mr
: I
= {2, false, {{NOCHECK
, X86::MOV16mi
}}}; break;
2725 case X86::MOV32mr
: I
= {4, false, {{NOCHECK
, X86::MOV32mi
}}}; break;
2726 case X86::MOV64mr
: I
= {8, false, {{CHECK32
, X86::MOV64mi32
},
2727 {NOCHECK
, X86::MOV64mr
}}}; break;
2730 case X86::MOVZX16rr8
: I
= {1, false, {{NOCHECK
, X86::MOV16ri
}}}; break;
2731 case X86::MOVZX32rr8
: I
= {1, false, {{NOCHECK
, X86::MOV32ri
}}}; break;
2732 case X86::MOVZX32rr16
: I
= {2, false, {{NOCHECK
, X86::MOV32ri
}}}; break;
2735 case X86::CMP8rr
: I
= {1, false, {{NOCHECK
, X86::CMP8ri
}}}; break;
2736 case X86::CMP16rr
: I
= {2, false, {{CHECK8
, X86::CMP16ri8
},
2737 {NOCHECK
, X86::CMP16ri
}}}; break;
2738 case X86::CMP32rr
: I
= {4, false, {{CHECK8
, X86::CMP32ri8
},
2739 {NOCHECK
, X86::CMP32ri
}}}; break;
2740 case X86::CMP64rr
: I
= {8, false, {{CHECK8
, X86::CMP64ri8
},
2741 {CHECK32
, X86::CMP64ri32
},
2742 {NOCHECK
, X86::CMP64rr
}}}; break;
2745 case X86::TEST8rr
: I
= {1, false, {{NOCHECK
, X86::TEST8ri
}}}; break;
2746 case X86::TEST16rr
: I
= {2, false, {{NOCHECK
, X86::TEST16ri
}}}; break;
2747 case X86::TEST32rr
: I
= {4, false, {{NOCHECK
, X86::TEST32ri
}}}; break;
2748 case X86::TEST64rr
: I
= {8, false, {{CHECK32
, X86::TEST64ri32
},
2749 {NOCHECK
, X86::TEST64rr
}}}; break;
2752 case X86::ADD8rr
: I
= {1, true, {{NOCHECK
, X86::ADD8ri
}}}; break;
2753 case X86::ADD16rr
: I
= {2, true, {{CHECK8
, X86::ADD16ri8
},
2754 {NOCHECK
, X86::ADD16ri
}}}; break;
2755 case X86::ADD32rr
: I
= {4, true, {{CHECK8
, X86::ADD32ri8
},
2756 {NOCHECK
, X86::ADD32ri
}}}; break;
2757 case X86::ADD64rr
: I
= {8, true, {{CHECK8
, X86::ADD64ri8
},
2758 {CHECK32
, X86::ADD64ri32
},
2759 {NOCHECK
, X86::ADD64rr
}}}; break;
2762 case X86::SUB8rr
: I
= {1, true, {{NOCHECK
, X86::SUB8ri
}}}; break;
2763 case X86::SUB16rr
: I
= {2, true, {{CHECK8
, X86::SUB16ri8
},
2764 {NOCHECK
, X86::SUB16ri
}}}; break;
2765 case X86::SUB32rr
: I
= {4, true, {{CHECK8
, X86::SUB32ri8
},
2766 {NOCHECK
, X86::SUB32ri
}}}; break;
2767 case X86::SUB64rr
: I
= {8, true, {{CHECK8
, X86::SUB64ri8
},
2768 {CHECK32
, X86::SUB64ri32
},
2769 {NOCHECK
, X86::SUB64rr
}}}; break;
2772 case X86::AND8rr
: I
= {1, true, {{NOCHECK
, X86::AND8ri
}}}; break;
2773 case X86::AND16rr
: I
= {2, true, {{CHECK8
, X86::AND16ri8
},
2774 {NOCHECK
, X86::AND16ri
}}}; break;
2775 case X86::AND32rr
: I
= {4, true, {{CHECK8
, X86::AND32ri8
},
2776 {NOCHECK
, X86::AND32ri
}}}; break;
2777 case X86::AND64rr
: I
= {8, true, {{CHECK8
, X86::AND64ri8
},
2778 {CHECK32
, X86::AND64ri32
},
2779 {NOCHECK
, X86::AND64rr
}}}; break;
2782 case X86::OR8rr
: I
= {1, true, {{NOCHECK
, X86::OR8ri
}}}; break;
2783 case X86::OR16rr
: I
= {2, true, {{CHECK8
, X86::OR16ri8
},
2784 {NOCHECK
, X86::OR16ri
}}}; break;
2785 case X86::OR32rr
: I
= {4, true, {{CHECK8
, X86::OR32ri8
},
2786 {NOCHECK
, X86::OR32ri
}}}; break;
2787 case X86::OR64rr
: I
= {8, true, {{CHECK8
, X86::OR64ri8
},
2788 {CHECK32
, X86::OR64ri32
},
2789 {NOCHECK
, X86::OR64rr
}}}; break;
2792 case X86::XOR8rr
: I
= {1, true, {{NOCHECK
, X86::XOR8ri
}}}; break;
2793 case X86::XOR16rr
: I
= {2, true, {{CHECK8
, X86::XOR16ri8
},
2794 {NOCHECK
, X86::XOR16ri
}}}; break;
2795 case X86::XOR32rr
: I
= {4, true, {{CHECK8
, X86::XOR32ri8
},
2796 {NOCHECK
, X86::XOR32ri
}}}; break;
2797 case X86::XOR64rr
: I
= {8, true, {{CHECK8
, X86::XOR64ri8
},
2798 {CHECK32
, X86::XOR64ri32
},
2799 {NOCHECK
, X86::XOR64rr
}}}; break;
2802 // Compute the new opcode.
2803 unsigned NewOpcode
= 0;
2804 for (const std::pair
<CheckSignExt
, unsigned> &Check
: I
.Checks
) {
2805 NewOpcode
= Check
.second
;
2806 if (Check
.first
== NOCHECK
)
2808 if (Check
.first
== CHECK8
&& isInt
<8>(Imm
))
2810 if (Check
.first
== CHECK32
&& isInt
<32>(Imm
))
2813 if (NewOpcode
== Inst
.getOpcode())
2816 const MCInstrDesc
&InstDesc
= Info
->get(Inst
.getOpcode());
2818 unsigned NumFound
= 0;
2819 for (unsigned Index
= InstDesc
.getNumDefs() + (I
.HasLHS
? 1 : 0),
2820 E
= InstDesc
.getNumOperands();
2821 Index
!= E
; ++Index
)
2822 if (Inst
.getOperand(Index
).isReg() &&
2823 Inst
.getOperand(Index
).getReg() == Register
)
2829 MCOperand TargetOp
= Inst
.getOperand(0);
2831 Inst
.setOpcode(NewOpcode
);
2832 Inst
.addOperand(TargetOp
);
2834 Inst
.addOperand(TargetOp
);
2835 Inst
.addOperand(MCOperand::createImm(Imm
));
2840 bool replaceRegWithReg(MCInst
&Inst
, unsigned ToReplace
,
2841 unsigned ReplaceWith
) const override
{
2843 // Get the HasLHS value so that iteration can be done
2845 if (X86::isAND(Inst
.getOpcode()) || X86::isADD(Inst
.getOpcode()) ||
2846 X86::isSUB(Inst
.getOpcode())) {
2848 } else if (isPop(Inst
) || isPush(Inst
) || X86::isCMP(Inst
.getOpcode()) ||
2849 X86::isTEST(Inst
.getOpcode())) {
2852 switch (Inst
.getOpcode()) {
2869 case X86::MOVZX16rr8
:
2870 case X86::MOVZX32rr8
:
2871 case X86::MOVZX32rr16
:
2872 case X86::MOVSX32rm8
:
2873 case X86::MOVSX32rr8
:
2874 case X86::MOVSX64rm32
:
2883 const MCInstrDesc
&InstDesc
= Info
->get(Inst
.getOpcode());
2885 bool FoundOne
= false;
2887 // Iterate only through src operands that arent also dest operands
2888 for (unsigned Index
= InstDesc
.getNumDefs() + (HasLHS
? 1 : 0),
2889 E
= InstDesc
.getNumOperands();
2890 Index
!= E
; ++Index
) {
2891 BitVector RegAliases
= getAliases(ToReplace
, true);
2892 if (!Inst
.getOperand(Index
).isReg() ||
2893 !RegAliases
.test(Inst
.getOperand(Index
).getReg()))
2895 // Resize register if needed
2896 unsigned SizedReplaceWith
= getAliasSized(
2897 ReplaceWith
, getRegSize(Inst
.getOperand(Index
).getReg()));
2898 MCOperand NewOperand
= MCOperand::createReg(SizedReplaceWith
);
2899 Inst
.getOperand(Index
) = NewOperand
;
2903 // Return true if at least one operand was replaced
2907 bool createUncondBranch(MCInst
&Inst
, const MCSymbol
*TBB
,
2908 MCContext
*Ctx
) const override
{
2909 Inst
.setOpcode(X86::JMP_1
);
2910 Inst
.addOperand(MCOperand::createExpr(
2911 MCSymbolRefExpr::create(TBB
, MCSymbolRefExpr::VK_None
, *Ctx
)));
2915 bool createCall(MCInst
&Inst
, const MCSymbol
*Target
,
2916 MCContext
*Ctx
) override
{
2917 Inst
.setOpcode(X86::CALL64pcrel32
);
2918 Inst
.addOperand(MCOperand::createExpr(
2919 MCSymbolRefExpr::create(Target
, MCSymbolRefExpr::VK_None
, *Ctx
)));
2923 bool createTailCall(MCInst
&Inst
, const MCSymbol
*Target
,
2924 MCContext
*Ctx
) override
{
2925 return createDirectCall(Inst
, Target
, Ctx
, /*IsTailCall*/ true);
2928 void createLongTailCall(InstructionListType
&Seq
, const MCSymbol
*Target
,
2929 MCContext
*Ctx
) override
{
2932 createDirectCall(Seq
.back(), Target
, Ctx
, /*IsTailCall*/ true);
2935 bool createTrap(MCInst
&Inst
) const override
{
2937 Inst
.setOpcode(X86::TRAP
);
2941 bool reverseBranchCondition(MCInst
&Inst
, const MCSymbol
*TBB
,
2942 MCContext
*Ctx
) const override
{
2943 unsigned InvCC
= getInvertedCondCode(getCondCode(Inst
));
2944 assert(InvCC
!= X86::COND_INVALID
&& "invalid branch instruction");
2945 Inst
.getOperand(Info
->get(Inst
.getOpcode()).NumOperands
- 1).setImm(InvCC
);
2946 Inst
.getOperand(0) = MCOperand::createExpr(
2947 MCSymbolRefExpr::create(TBB
, MCSymbolRefExpr::VK_None
, *Ctx
));
2951 bool replaceBranchCondition(MCInst
&Inst
, const MCSymbol
*TBB
, MCContext
*Ctx
,
2952 unsigned CC
) const override
{
2953 if (CC
== X86::COND_INVALID
)
2955 Inst
.getOperand(Info
->get(Inst
.getOpcode()).NumOperands
- 1).setImm(CC
);
2956 Inst
.getOperand(0) = MCOperand::createExpr(
2957 MCSymbolRefExpr::create(TBB
, MCSymbolRefExpr::VK_None
, *Ctx
));
2961 unsigned getCanonicalBranchCondCode(unsigned CC
) const override
{
2963 default: return X86::COND_INVALID
;
2965 case X86::COND_E
: return X86::COND_E
;
2966 case X86::COND_NE
: return X86::COND_E
;
2968 case X86::COND_L
: return X86::COND_L
;
2969 case X86::COND_GE
: return X86::COND_L
;
2971 case X86::COND_LE
: return X86::COND_G
;
2972 case X86::COND_G
: return X86::COND_G
;
2974 case X86::COND_B
: return X86::COND_B
;
2975 case X86::COND_AE
: return X86::COND_B
;
2977 case X86::COND_BE
: return X86::COND_A
;
2978 case X86::COND_A
: return X86::COND_A
;
2980 case X86::COND_S
: return X86::COND_S
;
2981 case X86::COND_NS
: return X86::COND_S
;
2983 case X86::COND_P
: return X86::COND_P
;
2984 case X86::COND_NP
: return X86::COND_P
;
2986 case X86::COND_O
: return X86::COND_O
;
2987 case X86::COND_NO
: return X86::COND_O
;
2991 bool replaceBranchTarget(MCInst
&Inst
, const MCSymbol
*TBB
,
2992 MCContext
*Ctx
) const override
{
2993 assert((isCall(Inst
) || isBranch(Inst
)) && !isIndirectBranch(Inst
) &&
2994 "Invalid instruction");
2995 Inst
.getOperand(0) = MCOperand::createExpr(
2996 MCSymbolRefExpr::create(TBB
, MCSymbolRefExpr::VK_None
, *Ctx
));
3000 MCPhysReg
getX86R11() const override
{ return X86::R11
; }
3002 MCPhysReg
getIntArgRegister(unsigned ArgNo
) const override
{
3003 // FIXME: this should depend on the calling convention.
3005 case 0: return X86::RDI
;
3006 case 1: return X86::RSI
;
3007 case 2: return X86::RDX
;
3008 case 3: return X86::RCX
;
3009 case 4: return X86::R8
;
3010 case 5: return X86::R9
;
3011 default: return getNoRegister();
3015 void createPause(MCInst
&Inst
) const override
{
3017 Inst
.setOpcode(X86::PAUSE
);
3020 void createLfence(MCInst
&Inst
) const override
{
3022 Inst
.setOpcode(X86::LFENCE
);
3025 bool createDirectCall(MCInst
&Inst
, const MCSymbol
*Target
, MCContext
*Ctx
,
3026 bool IsTailCall
) override
{
3028 Inst
.setOpcode(IsTailCall
? X86::JMP_4
: X86::CALL64pcrel32
);
3029 Inst
.addOperand(MCOperand::createExpr(
3030 MCSymbolRefExpr::create(Target
, MCSymbolRefExpr::VK_None
, *Ctx
)));
3036 void createShortJmp(InstructionListType
&Seq
, const MCSymbol
*Target
,
3037 MCContext
*Ctx
, bool IsTailCall
) override
{
3040 Inst
.setOpcode(X86::JMP_1
);
3041 Inst
.addOperand(MCOperand::createExpr(
3042 MCSymbolRefExpr::create(Target
, MCSymbolRefExpr::VK_None
, *Ctx
)));
3045 Seq
.emplace_back(Inst
);
3048 bool isConditionalMove(const MCInst
&Inst
) const override
{
3049 unsigned OpCode
= Inst
.getOpcode();
3050 return (OpCode
== X86::CMOV16rr
|| OpCode
== X86::CMOV32rr
||
3051 OpCode
== X86::CMOV64rr
);
3054 bool isBranchOnMem(const MCInst
&Inst
) const override
{
3055 unsigned OpCode
= Inst
.getOpcode();
3056 if (OpCode
== X86::CALL64m
|| (OpCode
== X86::JMP32m
&& isTailCall(Inst
)) ||
3057 OpCode
== X86::JMP64m
)
3063 bool isBranchOnReg(const MCInst
&Inst
) const override
{
3064 unsigned OpCode
= Inst
.getOpcode();
3065 if (OpCode
== X86::CALL64r
|| (OpCode
== X86::JMP32r
&& isTailCall(Inst
)) ||
3066 OpCode
== X86::JMP64r
)
3072 void createPushRegister(MCInst
&Inst
, MCPhysReg Reg
,
3073 unsigned Size
) const override
{
3075 unsigned NewOpcode
= 0;
3076 if (Reg
== X86::EFLAGS
) {
3078 case 2: NewOpcode
= X86::PUSHF16
; break;
3079 case 4: NewOpcode
= X86::PUSHF32
; break;
3080 case 8: NewOpcode
= X86::PUSHF64
; break;
3082 llvm_unreachable("Unexpected size");
3084 Inst
.setOpcode(NewOpcode
);
3088 case 2: NewOpcode
= X86::PUSH16r
; break;
3089 case 4: NewOpcode
= X86::PUSH32r
; break;
3090 case 8: NewOpcode
= X86::PUSH64r
; break;
3092 llvm_unreachable("Unexpected size");
3094 Inst
.setOpcode(NewOpcode
);
3095 Inst
.addOperand(MCOperand::createReg(Reg
));
3098 void createPopRegister(MCInst
&Inst
, MCPhysReg Reg
,
3099 unsigned Size
) const override
{
3101 unsigned NewOpcode
= 0;
3102 if (Reg
== X86::EFLAGS
) {
3104 case 2: NewOpcode
= X86::POPF16
; break;
3105 case 4: NewOpcode
= X86::POPF32
; break;
3106 case 8: NewOpcode
= X86::POPF64
; break;
3108 llvm_unreachable("Unexpected size");
3110 Inst
.setOpcode(NewOpcode
);
3114 case 2: NewOpcode
= X86::POP16r
; break;
3115 case 4: NewOpcode
= X86::POP32r
; break;
3116 case 8: NewOpcode
= X86::POP64r
; break;
3118 llvm_unreachable("Unexpected size");
3120 Inst
.setOpcode(NewOpcode
);
3121 Inst
.addOperand(MCOperand::createReg(Reg
));
3124 void createPushFlags(MCInst
&Inst
, unsigned Size
) const override
{
3125 return createPushRegister(Inst
, X86::EFLAGS
, Size
);
3128 void createPopFlags(MCInst
&Inst
, unsigned Size
) const override
{
3129 return createPopRegister(Inst
, X86::EFLAGS
, Size
);
3132 void createAddRegImm(MCInst
&Inst
, MCPhysReg Reg
, int64_t Value
,
3133 unsigned Size
) const {
3134 unsigned int Opcode
;
3136 case 1: Opcode
= X86::ADD8ri
; break;
3137 case 2: Opcode
= X86::ADD16ri
; break;
3138 case 4: Opcode
= X86::ADD32ri
; break;
3140 llvm_unreachable("Unexpected size");
3142 Inst
.setOpcode(Opcode
);
3144 Inst
.addOperand(MCOperand::createReg(Reg
));
3145 Inst
.addOperand(MCOperand::createReg(Reg
));
3146 Inst
.addOperand(MCOperand::createImm(Value
));
3149 void createClearRegWithNoEFlagsUpdate(MCInst
&Inst
, MCPhysReg Reg
,
3150 unsigned Size
) const {
3151 unsigned int Opcode
;
3153 case 1: Opcode
= X86::MOV8ri
; break;
3154 case 2: Opcode
= X86::MOV16ri
; break;
3155 case 4: Opcode
= X86::MOV32ri
; break;
3156 // Writing to a 32-bit register always zeros the upper 32 bits of the
3157 // full-width register
3159 Opcode
= X86::MOV32ri
;
3160 Reg
= getAliasSized(Reg
, 4);
3163 llvm_unreachable("Unexpected size");
3165 Inst
.setOpcode(Opcode
);
3167 Inst
.addOperand(MCOperand::createReg(Reg
));
3168 Inst
.addOperand(MCOperand::createImm(0));
3171 void createX86SaveOVFlagToRegister(MCInst
&Inst
, MCPhysReg Reg
) const {
3172 Inst
.setOpcode(X86::SETCCr
);
3174 Inst
.addOperand(MCOperand::createReg(Reg
));
3175 Inst
.addOperand(MCOperand::createImm(X86::COND_O
));
3178 void createX86Lahf(MCInst
&Inst
) const {
3179 Inst
.setOpcode(X86::LAHF
);
3183 void createX86Sahf(MCInst
&Inst
) const {
3184 Inst
.setOpcode(X86::SAHF
);
3188 void createInstrIncMemory(InstructionListType
&Instrs
, const MCSymbol
*Target
,
3189 MCContext
*Ctx
, bool IsLeaf
) const override
{
3192 Instrs
.resize(IsLeaf
? 13 : 11);
3193 // Don't clobber application red zone (ABI dependent)
3195 createStackPointerIncrement(Instrs
[I
++], 128,
3196 /*NoFlagsClobber=*/true);
3198 // Performance improvements based on the optimization discussed at
3199 // https://reviews.llvm.org/D6629
3200 // LAHF/SAHF are used instead of PUSHF/POPF
3202 createPushRegister(Instrs
[I
++], X86::RAX
, 8);
3203 createClearRegWithNoEFlagsUpdate(Instrs
[I
++], X86::RAX
, 8);
3204 createX86Lahf(Instrs
[I
++]);
3205 createPushRegister(Instrs
[I
++], X86::RAX
, 8);
3206 createClearRegWithNoEFlagsUpdate(Instrs
[I
++], X86::RAX
, 8);
3207 createX86SaveOVFlagToRegister(Instrs
[I
++], X86::AL
);
3209 createIncMemory(Instrs
[I
++], Target
, Ctx
);
3211 createAddRegImm(Instrs
[I
++], X86::AL
, 127, 1);
3212 createPopRegister(Instrs
[I
++], X86::RAX
, 8);
3213 createX86Sahf(Instrs
[I
++]);
3214 createPopRegister(Instrs
[I
++], X86::RAX
, 8);
3217 createStackPointerDecrement(Instrs
[I
], 128,
3218 /*NoFlagsClobber=*/true);
3221 void createSwap(MCInst
&Inst
, MCPhysReg Source
, MCPhysReg MemBaseReg
,
3222 int64_t Disp
) const {
3223 Inst
.setOpcode(X86::XCHG64rm
);
3224 Inst
.addOperand(MCOperand::createReg(Source
));
3225 Inst
.addOperand(MCOperand::createReg(Source
));
3226 Inst
.addOperand(MCOperand::createReg(MemBaseReg
)); // BaseReg
3227 Inst
.addOperand(MCOperand::createImm(1)); // ScaleAmt
3228 Inst
.addOperand(MCOperand::createReg(X86::NoRegister
)); // IndexReg
3229 Inst
.addOperand(MCOperand::createImm(Disp
)); // Displacement
3230 Inst
.addOperand(MCOperand::createReg(X86::NoRegister
)); // AddrSegmentReg
3233 void createIndirectBranch(MCInst
&Inst
, MCPhysReg MemBaseReg
,
3234 int64_t Disp
) const {
3235 Inst
.setOpcode(X86::JMP64m
);
3236 Inst
.addOperand(MCOperand::createReg(MemBaseReg
)); // BaseReg
3237 Inst
.addOperand(MCOperand::createImm(1)); // ScaleAmt
3238 Inst
.addOperand(MCOperand::createReg(X86::NoRegister
)); // IndexReg
3239 Inst
.addOperand(MCOperand::createImm(Disp
)); // Displacement
3240 Inst
.addOperand(MCOperand::createReg(X86::NoRegister
)); // AddrSegmentReg
3243 InstructionListType
createInstrumentedIndirectCall(const MCInst
&CallInst
,
3245 MCSymbol
*HandlerFuncAddr
,
3247 MCContext
*Ctx
) override
{
3248 // Check if the target address expression used in the original indirect call
3249 // uses the stack pointer, which we are going to clobber.
3250 static BitVector
SPAliases(getAliases(X86::RSP
));
3251 bool UsesSP
= false;
3253 for (unsigned I
= Info
->get(CallInst
.getOpcode()).getNumDefs(),
3254 E
= MCPlus::getNumPrimeOperands(CallInst
);
3256 const MCOperand
&Operand
= CallInst
.getOperand(I
);
3257 if (Operand
.isReg() && SPAliases
[Operand
.getReg()]) {
3263 InstructionListType Insts
;
3264 MCPhysReg TempReg
= getIntArgRegister(0);
3265 // Code sequence used to enter indirect call instrumentation helper:
3267 // add $8, %rsp ;; $rsp may be used in target, so fix it to prev val
3268 // movq target, %rdi ;; via convertIndirectCallTargetToLoad
3269 // sub $8, %rsp ;; restore correct stack value
3271 // movq $CallSiteID, %rdi
3273 // callq/jmp HandlerFuncAddr
3274 Insts
.emplace_back();
3275 createPushRegister(Insts
.back(), TempReg
, 8);
3276 if (UsesSP
) { // Only adjust SP if we really need to
3277 Insts
.emplace_back();
3278 createStackPointerDecrement(Insts
.back(), 8, /*NoFlagsClobber=*/false);
3280 Insts
.emplace_back(CallInst
);
3281 // Insts.back() and CallInst now share the same annotation instruction.
3282 // Strip it from Insts.back(), only preserving tail call annotation.
3283 stripAnnotations(Insts
.back(), /*KeepTC=*/true);
3284 convertIndirectCallToLoad(Insts
.back(), TempReg
);
3286 Insts
.emplace_back();
3287 createStackPointerIncrement(Insts
.back(), 8, /*NoFlagsClobber=*/false);
3289 Insts
.emplace_back();
3290 createPushRegister(Insts
.back(), TempReg
, 8);
3291 Insts
.emplace_back();
3292 createLoadImmediate(Insts
.back(), TempReg
, CallSiteID
);
3293 Insts
.emplace_back();
3294 createPushRegister(Insts
.back(), TempReg
, 8);
3295 Insts
.emplace_back();
3296 createDirectCall(Insts
.back(), HandlerFuncAddr
, Ctx
,
3297 /*TailCall=*/TailCall
);
3298 // Carry over metadata
3299 for (int I
= MCPlus::getNumPrimeOperands(CallInst
),
3300 E
= CallInst
.getNumOperands();
3302 Insts
.back().addOperand(CallInst
.getOperand(I
));
3307 InstructionListType
createInstrumentedIndCallHandlerExitBB() const override
{
3308 const MCPhysReg TempReg
= getIntArgRegister(0);
3309 // We just need to undo the sequence created for every ind call in
3310 // instrumentIndirectTarget(), which can be accomplished minimally with:
3314 // xchg (%rsp), %rdi
3316 InstructionListType
Insts(5);
3317 createPopFlags(Insts
[0], 8);
3318 createPopRegister(Insts
[1], TempReg
, 8);
3319 createStackPointerDecrement(Insts
[2], 16, /*NoFlagsClobber=*/false);
3320 createSwap(Insts
[3], TempReg
, X86::RSP
, 0);
3321 createIndirectBranch(Insts
[4], X86::RSP
, -8);
3326 createInstrumentedIndTailCallHandlerExitBB() const override
{
3327 const MCPhysReg TempReg
= getIntArgRegister(0);
3328 // Same thing as above, but for tail calls
3333 InstructionListType
Insts(4);
3334 createPopFlags(Insts
[0], 8);
3335 createStackPointerDecrement(Insts
[1], 16, /*NoFlagsClobber=*/false);
3336 createPopRegister(Insts
[2], TempReg
, 8);
3337 createIndirectBranch(Insts
[3], X86::RSP
, -16);
3342 createInstrumentedIndCallHandlerEntryBB(const MCSymbol
*InstrTrampoline
,
3343 const MCSymbol
*IndCallHandler
,
3344 MCContext
*Ctx
) override
{
3345 const MCPhysReg TempReg
= getIntArgRegister(0);
3346 // Code sequence used to check whether InstrTampoline was initialized
3347 // and call it if so, returns via IndCallHandler.
3349 // mov InstrTrampoline,%rdi
3351 // je IndCallHandler
3353 // jmpq IndCallHandler
3354 InstructionListType Insts
;
3355 Insts
.emplace_back();
3356 createPushFlags(Insts
.back(), 8);
3357 Insts
.emplace_back();
3358 createMove(Insts
.back(), InstrTrampoline
, TempReg
, Ctx
);
3359 InstructionListType cmpJmp
= createCmpJE(TempReg
, 0, IndCallHandler
, Ctx
);
3360 Insts
.insert(Insts
.end(), cmpJmp
.begin(), cmpJmp
.end());
3361 Insts
.emplace_back();
3362 Insts
.back().setOpcode(X86::CALL64r
);
3363 Insts
.back().addOperand(MCOperand::createReg(TempReg
));
3364 Insts
.emplace_back();
3365 createDirectCall(Insts
.back(), IndCallHandler
, Ctx
, /*IsTailCall*/ true);
3369 InstructionListType
createNumCountersGetter(MCContext
*Ctx
) const override
{
3370 InstructionListType
Insts(2);
3371 MCSymbol
*NumLocs
= Ctx
->getOrCreateSymbol("__bolt_num_counters");
3372 createMove(Insts
[0], NumLocs
, X86::EAX
, Ctx
);
3373 createReturn(Insts
[1]);
3378 createInstrLocationsGetter(MCContext
*Ctx
) const override
{
3379 InstructionListType
Insts(2);
3380 MCSymbol
*Locs
= Ctx
->getOrCreateSymbol("__bolt_instr_locations");
3381 createLea(Insts
[0], Locs
, X86::EAX
, Ctx
);
3382 createReturn(Insts
[1]);
3386 InstructionListType
createInstrTablesGetter(MCContext
*Ctx
) const override
{
3387 InstructionListType
Insts(2);
3388 MCSymbol
*Locs
= Ctx
->getOrCreateSymbol("__bolt_instr_tables");
3389 createLea(Insts
[0], Locs
, X86::EAX
, Ctx
);
3390 createReturn(Insts
[1]);
3394 InstructionListType
createInstrNumFuncsGetter(MCContext
*Ctx
) const override
{
3395 InstructionListType
Insts(2);
3396 MCSymbol
*NumFuncs
= Ctx
->getOrCreateSymbol("__bolt_instr_num_funcs");
3397 createMove(Insts
[0], NumFuncs
, X86::EAX
, Ctx
);
3398 createReturn(Insts
[1]);
3402 InstructionListType
createSymbolTrampoline(const MCSymbol
*TgtSym
,
3403 MCContext
*Ctx
) const override
{
3404 InstructionListType
Insts(1);
3405 createUncondBranch(Insts
[0], TgtSym
, Ctx
);
3409 InstructionListType
createDummyReturnFunction(MCContext
*Ctx
) const override
{
3410 InstructionListType
Insts(1);
3411 createReturn(Insts
[0]);
3415 BlocksVectorTy
indirectCallPromotion(
3416 const MCInst
&CallInst
,
3417 const std::vector
<std::pair
<MCSymbol
*, uint64_t>> &Targets
,
3418 const std::vector
<std::pair
<MCSymbol
*, uint64_t>> &VtableSyms
,
3419 const std::vector
<MCInst
*> &MethodFetchInsns
,
3420 const bool MinimizeCodeSize
, MCContext
*Ctx
) override
{
3421 const bool IsTailCall
= isTailCall(CallInst
);
3422 const bool IsJumpTable
= getJumpTable(CallInst
) != 0;
3423 BlocksVectorTy Results
;
3425 // Label for the current code block.
3426 MCSymbol
*NextTarget
= nullptr;
3428 // The join block which contains all the instructions following CallInst.
3429 // MergeBlock remains null if CallInst is a tail call.
3430 MCSymbol
*MergeBlock
= nullptr;
3432 unsigned FuncAddrReg
= X86::R10
;
3434 const bool LoadElim
= !VtableSyms
.empty();
3435 assert((!LoadElim
|| VtableSyms
.size() == Targets
.size()) &&
3436 "There must be a vtable entry for every method "
3437 "in the targets vector.");
3439 if (MinimizeCodeSize
&& !LoadElim
) {
3440 std::set
<unsigned> UsedRegs
;
3442 for (unsigned int I
= 0; I
< MCPlus::getNumPrimeOperands(CallInst
); ++I
) {
3443 const MCOperand
&Op
= CallInst
.getOperand(I
);
3445 UsedRegs
.insert(Op
.getReg());
3448 if (UsedRegs
.count(X86::R10
) == 0)
3449 FuncAddrReg
= X86::R10
;
3450 else if (UsedRegs
.count(X86::R11
) == 0)
3451 FuncAddrReg
= X86::R11
;
3456 const auto jumpToMergeBlock
= [&](InstructionListType
&NewCall
) {
3458 NewCall
.push_back(CallInst
);
3459 MCInst
&Merge
= NewCall
.back();
3461 createUncondBranch(Merge
, MergeBlock
, Ctx
);
3464 for (unsigned int i
= 0; i
< Targets
.size(); ++i
) {
3465 Results
.emplace_back(NextTarget
, InstructionListType());
3466 InstructionListType
*NewCall
= &Results
.back().second
;
3468 if (MinimizeCodeSize
&& !LoadElim
) {
3469 // Load the call target into FuncAddrReg.
3470 NewCall
->push_back(CallInst
); // Copy CallInst in order to get SMLoc
3471 MCInst
&Target
= NewCall
->back();
3473 Target
.setOpcode(X86::MOV64ri32
);
3474 Target
.addOperand(MCOperand::createReg(FuncAddrReg
));
3475 if (Targets
[i
].first
) {
3477 Target
.addOperand(MCOperand::createExpr(MCSymbolRefExpr::create(
3478 Targets
[i
].first
, MCSymbolRefExpr::VK_None
, *Ctx
)));
3480 const uint64_t Addr
= Targets
[i
].second
;
3481 // Immediate address is out of sign extended 32 bit range.
3482 if (int64_t(Addr
) != int64_t(int32_t(Addr
)))
3483 return BlocksVectorTy();
3485 Target
.addOperand(MCOperand::createImm(Addr
));
3488 // Compare current call target to a specific address.
3489 NewCall
->push_back(CallInst
);
3490 MCInst
&Compare
= NewCall
->back();
3492 if (isBranchOnReg(CallInst
))
3493 Compare
.setOpcode(X86::CMP64rr
);
3494 else if (CallInst
.getOpcode() == X86::CALL64pcrel32
)
3495 Compare
.setOpcode(X86::CMP64ri32
);
3497 Compare
.setOpcode(X86::CMP64rm
);
3499 Compare
.addOperand(MCOperand::createReg(FuncAddrReg
));
3501 // TODO: Would be preferable to only load this value once.
3502 for (unsigned i
= 0;
3503 i
< Info
->get(CallInst
.getOpcode()).getNumOperands(); ++i
)
3504 if (!CallInst
.getOperand(i
).isInst())
3505 Compare
.addOperand(CallInst
.getOperand(i
));
3507 // Compare current call target to a specific address.
3508 NewCall
->push_back(CallInst
);
3509 MCInst
&Compare
= NewCall
->back();
3511 if (isBranchOnReg(CallInst
))
3512 Compare
.setOpcode(X86::CMP64ri32
);
3514 Compare
.setOpcode(X86::CMP64mi32
);
3516 // Original call address.
3517 for (unsigned i
= 0;
3518 i
< Info
->get(CallInst
.getOpcode()).getNumOperands(); ++i
)
3519 if (!CallInst
.getOperand(i
).isInst())
3520 Compare
.addOperand(CallInst
.getOperand(i
));
3523 if (Targets
[i
].first
|| LoadElim
) {
3524 const MCSymbol
*Sym
=
3525 LoadElim
? VtableSyms
[i
].first
: Targets
[i
].first
;
3526 const uint64_t Addend
= LoadElim
? VtableSyms
[i
].second
: 0;
3527 const MCExpr
*Expr
= MCSymbolRefExpr::create(Sym
, *Ctx
);
3529 Expr
= MCBinaryExpr::createAdd(
3530 Expr
, MCConstantExpr::create(Addend
, *Ctx
), *Ctx
);
3531 Compare
.addOperand(MCOperand::createExpr(Expr
));
3533 const uint64_t Addr
= Targets
[i
].second
;
3534 // Immediate address is out of sign extended 32 bit range.
3535 if (int64_t(Addr
) != int64_t(int32_t(Addr
)))
3536 return BlocksVectorTy();
3538 Compare
.addOperand(MCOperand::createImm(Addr
));
3542 // jump to next target compare.
3544 Ctx
->createNamedTempSymbol(); // generate label for the next block
3545 NewCall
->push_back(CallInst
);
3548 MCInst
&Je
= NewCall
->back();
3550 // Jump to next compare if target addresses don't match.
3552 Je
.setOpcode(X86::JCC_1
);
3553 if (Targets
[i
].first
)
3554 Je
.addOperand(MCOperand::createExpr(MCSymbolRefExpr::create(
3555 Targets
[i
].first
, MCSymbolRefExpr::VK_None
, *Ctx
)));
3557 Je
.addOperand(MCOperand::createImm(Targets
[i
].second
));
3559 Je
.addOperand(MCOperand::createImm(X86::COND_E
));
3560 assert(!isInvoke(CallInst
));
3562 MCInst
&Jne
= NewCall
->back();
3564 // Jump to next compare if target addresses don't match.
3566 Jne
.setOpcode(X86::JCC_1
);
3567 Jne
.addOperand(MCOperand::createExpr(MCSymbolRefExpr::create(
3568 NextTarget
, MCSymbolRefExpr::VK_None
, *Ctx
)));
3569 Jne
.addOperand(MCOperand::createImm(X86::COND_NE
));
3571 // Call specific target directly.
3572 Results
.emplace_back(Ctx
->createNamedTempSymbol(),
3573 InstructionListType());
3574 NewCall
= &Results
.back().second
;
3575 NewCall
->push_back(CallInst
);
3576 MCInst
&CallOrJmp
= NewCall
->back();
3580 if (MinimizeCodeSize
&& !LoadElim
) {
3581 CallOrJmp
.setOpcode(IsTailCall
? X86::JMP32r
: X86::CALL64r
);
3582 CallOrJmp
.addOperand(MCOperand::createReg(FuncAddrReg
));
3584 CallOrJmp
.setOpcode(IsTailCall
? X86::JMP_4
: X86::CALL64pcrel32
);
3586 if (Targets
[i
].first
)
3587 CallOrJmp
.addOperand(MCOperand::createExpr(MCSymbolRefExpr::create(
3588 Targets
[i
].first
, MCSymbolRefExpr::VK_None
, *Ctx
)));
3590 CallOrJmp
.addOperand(MCOperand::createImm(Targets
[i
].second
));
3593 setTailCall(CallOrJmp
);
3595 if (CallOrJmp
.getOpcode() == X86::CALL64r
||
3596 CallOrJmp
.getOpcode() == X86::CALL64pcrel32
) {
3597 if (Optional
<uint32_t> Offset
= getOffset(CallInst
))
3598 // Annotated as duplicated call
3599 setOffset(CallOrJmp
, *Offset
);
3602 if (isInvoke(CallInst
) && !isInvoke(CallOrJmp
)) {
3603 // Copy over any EH or GNU args size information from the original
3605 Optional
<MCPlus::MCLandingPad
> EHInfo
= getEHInfo(CallInst
);
3607 addEHInfo(CallOrJmp
, *EHInfo
);
3608 int64_t GnuArgsSize
= getGnuArgsSize(CallInst
);
3609 if (GnuArgsSize
>= 0)
3610 addGnuArgsSize(CallOrJmp
, GnuArgsSize
);
3614 // The fallthrough block for the most common target should be
3617 // Fallthrough to merge block.
3618 MergeBlock
= Ctx
->createNamedTempSymbol();
3620 // Insert jump to the merge block if we are not doing a fallthrough.
3621 jumpToMergeBlock(*NewCall
);
3628 Results
.emplace_back(NextTarget
, InstructionListType());
3629 InstructionListType
&NewCall
= Results
.back().second
;
3630 for (const MCInst
*Inst
: MethodFetchInsns
)
3631 if (Inst
!= &CallInst
)
3632 NewCall
.push_back(*Inst
);
3633 NewCall
.push_back(CallInst
);
3635 // Jump to merge block from cold call block
3636 if (!IsTailCall
&& !IsJumpTable
) {
3637 jumpToMergeBlock(NewCall
);
3639 // Record merge block
3640 Results
.emplace_back(MergeBlock
, InstructionListType());
3646 BlocksVectorTy
jumpTablePromotion(
3647 const MCInst
&IJmpInst
,
3648 const std::vector
<std::pair
<MCSymbol
*, uint64_t>> &Targets
,
3649 const std::vector
<MCInst
*> &TargetFetchInsns
,
3650 MCContext
*Ctx
) const override
{
3651 assert(getJumpTable(IJmpInst
) != 0);
3652 uint16_t IndexReg
= getAnnotationAs
<uint16_t>(IJmpInst
, "JTIndexReg");
3654 return BlocksVectorTy();
3656 BlocksVectorTy Results
;
3658 // Label for the current code block.
3659 MCSymbol
*NextTarget
= nullptr;
3661 for (unsigned int i
= 0; i
< Targets
.size(); ++i
) {
3662 Results
.emplace_back(NextTarget
, InstructionListType());
3663 InstructionListType
*CurBB
= &Results
.back().second
;
3665 // Compare current index to a specific index.
3666 CurBB
->emplace_back(MCInst());
3667 MCInst
&CompareInst
= CurBB
->back();
3668 CompareInst
.setLoc(IJmpInst
.getLoc());
3669 CompareInst
.setOpcode(X86::CMP64ri32
);
3670 CompareInst
.addOperand(MCOperand::createReg(IndexReg
));
3672 const uint64_t CaseIdx
= Targets
[i
].second
;
3673 // Immediate address is out of sign extended 32 bit range.
3674 if (int64_t(CaseIdx
) != int64_t(int32_t(CaseIdx
)))
3675 return BlocksVectorTy();
3677 CompareInst
.addOperand(MCOperand::createImm(CaseIdx
));
3678 shortenInstruction(CompareInst
, *Ctx
->getSubtargetInfo());
3680 // jump to next target compare.
3682 Ctx
->createNamedTempSymbol(); // generate label for the next block
3683 CurBB
->push_back(MCInst());
3685 MCInst
&JEInst
= CurBB
->back();
3686 JEInst
.setLoc(IJmpInst
.getLoc());
3688 // Jump to target if indices match
3689 JEInst
.setOpcode(X86::JCC_1
);
3690 JEInst
.addOperand(MCOperand::createExpr(MCSymbolRefExpr::create(
3691 Targets
[i
].first
, MCSymbolRefExpr::VK_None
, *Ctx
)));
3692 JEInst
.addOperand(MCOperand::createImm(X86::COND_E
));
3696 Results
.emplace_back(NextTarget
, InstructionListType());
3697 InstructionListType
&CurBB
= Results
.back().second
;
3698 for (const MCInst
*Inst
: TargetFetchInsns
)
3699 if (Inst
!= &IJmpInst
)
3700 CurBB
.push_back(*Inst
);
3702 CurBB
.push_back(IJmpInst
);
3708 bool createMove(MCInst
&Inst
, const MCSymbol
*Src
, unsigned Reg
,
3709 MCContext
*Ctx
) const {
3710 Inst
.setOpcode(X86::MOV64rm
);
3711 Inst
.addOperand(MCOperand::createReg(Reg
));
3712 Inst
.addOperand(MCOperand::createReg(X86::RIP
)); // BaseReg
3713 Inst
.addOperand(MCOperand::createImm(1)); // ScaleAmt
3714 Inst
.addOperand(MCOperand::createReg(X86::NoRegister
)); // IndexReg
3715 Inst
.addOperand(MCOperand::createExpr(
3716 MCSymbolRefExpr::create(Src
, MCSymbolRefExpr::VK_None
,
3717 *Ctx
))); // Displacement
3718 Inst
.addOperand(MCOperand::createReg(X86::NoRegister
)); // AddrSegmentReg
3723 bool createLea(MCInst
&Inst
, const MCSymbol
*Src
, unsigned Reg
,
3724 MCContext
*Ctx
) const {
3725 Inst
.setOpcode(X86::LEA64r
);
3726 Inst
.addOperand(MCOperand::createReg(Reg
));
3727 Inst
.addOperand(MCOperand::createReg(X86::RIP
)); // BaseReg
3728 Inst
.addOperand(MCOperand::createImm(1)); // ScaleAmt
3729 Inst
.addOperand(MCOperand::createReg(X86::NoRegister
)); // IndexReg
3730 Inst
.addOperand(MCOperand::createExpr(
3731 MCSymbolRefExpr::create(Src
, MCSymbolRefExpr::VK_None
,
3732 *Ctx
))); // Displacement
3733 Inst
.addOperand(MCOperand::createReg(X86::NoRegister
)); // AddrSegmentReg
3743 MCPlusBuilder
*createX86MCPlusBuilder(const MCInstrAnalysis
*Analysis
,
3744 const MCInstrInfo
*Info
,
3745 const MCRegisterInfo
*RegInfo
) {
3746 return new X86MCPlusBuilder(Analysis
, Info
, RegInfo
);