[release] Use threaded compression with xz
[llvm-project.git] / bolt / lib / Target / X86 / X86MCPlusBuilder.cpp
blobc210c71abe0c1010478b2bde76e910ee2926f08b
1 //===- bolt/Target/X86/X86MCPlusBuilder.cpp -------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
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"
33 #include <set>
35 #define DEBUG_TYPE "mcplus"
37 using namespace llvm;
38 using namespace bolt;
40 namespace opts {
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));
49 } // namespace opts
51 namespace {
53 unsigned getShortBranchOpcode(unsigned Opcode) {
54 switch (Opcode) {
55 default:
56 return 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 {
85 public:
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 {
111 switch (CC) {
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 {
134 DCC_EQUAL = 0x1,
135 DCC_GREATER = 0x2,
136 DCC_LESSER = 0x4,
137 DCC_GREATER_OR_LESSER = 0x6,
138 DCC_UNSIGNED = 0x8,
139 DCC_SIGNED = 0x10,
140 DCC_INVALID = 0x20,
143 auto decodeCondCode = [&](unsigned CC) -> uint8_t {
144 switch (CC) {
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;
167 switch (DCC) {
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) {
205 Inst.setFlags(0);
206 return true;
208 return false;
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) ||
215 X86::isUD2(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()) {
233 case X86::POP16r:
234 case X86::POP16rmm:
235 case X86::POP16rmr:
236 case X86::POPF16:
237 case X86::POPA16:
238 case X86::POPDS16:
239 case X86::POPES16:
240 case X86::POPFS16:
241 case X86::POPGS16:
242 case X86::POPSS16:
243 return 2;
244 case X86::POP32r:
245 case X86::POP32rmm:
246 case X86::POP32rmr:
247 case X86::POPA32:
248 case X86::POPDS32:
249 case X86::POPES32:
250 case X86::POPF32:
251 case X86::POPFS32:
252 case X86::POPGS32:
253 case X86::POPSS32:
254 return 4;
255 case X86::POP64r:
256 case X86::POP64rmm:
257 case X86::POP64rmr:
258 case X86::POPF64:
259 case X86::POPFS64:
260 case X86::POPGS64:
261 return 8;
263 return 0;
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()) {
272 case X86::PUSH16i8:
273 case X86::PUSH16r:
274 case X86::PUSH16rmm:
275 case X86::PUSH16rmr:
276 case X86::PUSHA16:
277 case X86::PUSHCS16:
278 case X86::PUSHDS16:
279 case X86::PUSHES16:
280 case X86::PUSHF16:
281 case X86::PUSHFS16:
282 case X86::PUSHGS16:
283 case X86::PUSHSS16:
284 case X86::PUSHi16:
285 return 2;
286 case X86::PUSH32i8:
287 case X86::PUSH32r:
288 case X86::PUSH32rmm:
289 case X86::PUSH32rmr:
290 case X86::PUSHA32:
291 case X86::PUSHCS32:
292 case X86::PUSHDS32:
293 case X86::PUSHES32:
294 case X86::PUSHF32:
295 case X86::PUSHFS32:
296 case X86::PUSHGS32:
297 case X86::PUSHSS32:
298 case X86::PUSHi32:
299 return 4;
300 case X86::PUSH64i32:
301 case X86::PUSH64i8:
302 case X86::PUSH64r:
303 case X86::PUSH64rmm:
304 case X86::PUSH64rmr:
305 case X86::PUSHF64:
306 case X86::PUSHFS64:
307 case X86::PUSHGS64:
308 return 8;
310 return 0;
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()) {
327 case X86::MOV16rm:
328 case X86::MOV32rm:
329 case X86::MOV64rm:
330 return true;
332 return false;
335 bool isUnsupportedBranch(unsigned Opcode) const override {
336 switch (Opcode) {
337 default:
338 return false;
339 case X86::LOOP:
340 case X86::LOOPE:
341 case X86::LOOPNE:
342 case X86::JECXZ:
343 case X86::JRCXZ:
344 return true;
348 bool isLoad(const MCInst &Inst) const override {
349 if (isPop(Inst))
350 return true;
352 int MemOpNo = getMemoryOperandNo(Inst);
353 const MCInstrDesc &MCII = Info->get(Inst.getOpcode());
355 if (MemOpNo == -1)
356 return false;
358 return MCII.mayLoad();
361 bool isStore(const MCInst &Inst) const override {
362 if (isPush(Inst))
363 return true;
365 int MemOpNo = getMemoryOperandNo(Inst);
366 const MCInstrDesc &MCII = Info->get(Inst.getOpcode());
368 if (MemOpNo == -1)
369 return false;
371 return MCII.mayStore();
374 bool isCleanRegXOR(const MCInst &Inst) const override {
375 switch (Inst.getOpcode()) {
376 case X86::XOR16rr:
377 case X86::XOR32rr:
378 case X86::XOR64rr:
379 break;
380 default:
381 return false;
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))
409 return false;
411 if (CurInst->getOpcode() != X86::JMP64m)
412 return false;
414 int MemOpNo = MIB.getMemoryOperandNo(*CurInst);
415 if (MemOpNo == -1)
416 return false;
418 if (!Base->match(MRI, MIB, this->InstrWindow, MemOpNo + X86::AddrBaseReg))
419 return false;
420 if (!Scale->match(MRI, MIB, this->InstrWindow,
421 MemOpNo + X86::AddrScaleAmt))
422 return false;
423 if (!Index->match(MRI, MIB, this->InstrWindow,
424 MemOpNo + X86::AddrIndexReg))
425 return false;
426 if (!Offset->match(MRI, MIB, this->InstrWindow, MemOpNo + X86::AddrDisp))
427 return false;
428 return true;
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))
459 return false;
461 if (CurInst->getOpcode() != X86::JMP64r)
462 return false;
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))
495 return false;
497 if (CurInst->getOpcode() != X86::MOV64rm &&
498 CurInst->getOpcode() != X86::MOVSX64rm32)
499 return false;
501 int MemOpNo = MIB.getMemoryOperandNo(*CurInst);
502 if (MemOpNo == -1)
503 return false;
505 if (!Base->match(MRI, MIB, this->InstrWindow, MemOpNo + X86::AddrBaseReg))
506 return false;
507 if (!Scale->match(MRI, MIB, this->InstrWindow,
508 MemOpNo + X86::AddrScaleAmt))
509 return false;
510 if (!Index->match(MRI, MIB, this->InstrWindow,
511 MemOpNo + X86::AddrIndexReg))
512 return false;
513 if (!Offset->match(MRI, MIB, this->InstrWindow, MemOpNo + X86::AddrDisp))
514 return false;
515 return true;
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))
548 return false;
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))
555 return false;
556 return A->match(MRI, MIB, this->InstrWindow, 2);
559 if (B->match(MRI, MIB, this->InstrWindow, 2))
560 return true;
562 if (!B->match(MRI, MIB, this->InstrWindow, 1))
563 return false;
564 return A->match(MRI, MIB, this->InstrWindow, 2);
567 return false;
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))
593 return false;
595 if (CurInst->getOpcode() != X86::LEA64r)
596 return false;
598 if (CurInst->getOperand(1 + X86::AddrScaleAmt).getImm() != 1 ||
599 CurInst->getOperand(1 + X86::AddrIndexReg).getReg() !=
600 X86::NoRegister ||
601 (CurInst->getOperand(1 + X86::AddrBaseReg).getReg() !=
602 X86::NoRegister &&
603 CurInst->getOperand(1 + X86::AddrBaseReg).getReg() != X86::RIP))
604 return false;
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)
623 return true;
624 return false;
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);
631 if (MemOpNo >= 0)
632 MemOpNo += X86II::getOperandBias(Desc);
633 return MemOpNo;
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))
644 ++I;
645 if (I == Insts.end())
646 return false;
648 const MCInst &FirstInst = *I;
649 ++I;
650 while (I != Insts.end() && isPrefix(*I))
651 ++I;
652 if (I == Insts.end())
653 return false;
654 const MCInst &SecondInst = *I;
656 if (!isConditionalBranch(SecondInst))
657 return false;
658 // Cannot fuse if the first instruction uses RIP-relative memory.
659 if (hasPCRelOperand(FirstInst))
660 return false;
662 const X86::FirstMacroFusionInstKind CmpKind =
663 X86::classifyFirstOpcodeInMacroFusion(FirstInst.getOpcode());
664 if (CmpKind == X86::FirstMacroFusionInstKind::Invalid)
665 return false;
667 X86::CondCode CC = static_cast<X86::CondCode>(getCondCode(SecondInst));
668 X86::SecondMacroFusionInstKind BranchKind =
669 X86::classifySecondCondCodeInMacroFusion(CC);
670 if (BranchKind == X86::SecondMacroFusionInstKind::Invalid)
671 return false;
672 return X86::isMacroFused(CmpKind, BranchKind);
675 bool
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);
683 if (MemOpNo < 0)
684 return false;
685 unsigned MemOpOffset = static_cast<unsigned>(MemOpNo);
687 if (MemOpOffset + X86::AddrSegmentReg >= MCPlus::getNumPrimeOperands(Inst))
688 return false;
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())
700 return false;
702 *BaseRegNum = Base.getReg();
703 *ScaleImm = Scale.getImm();
704 *IndexRegNum = Index.getReg();
705 if (Disp.isImm()) {
706 assert(DispImm && "DispImm needs to be set");
707 *DispImm = Disp.getImm();
708 if (DispExpr)
709 *DispExpr = nullptr;
710 } else {
711 assert(DispExpr && "DispExpr needs to be set");
712 *DispExpr = Disp.getExpr();
713 if (DispImm)
714 *DispImm = 0;
716 *SegmentRegNum = Segment.getReg();
717 return true;
720 bool evaluateMemOperandTarget(const MCInst &Inst, uint64_t &Target,
721 uint64_t Address,
722 uint64_t Size) const override {
723 unsigned BaseRegNum;
724 int64_t ScaleValue;
725 unsigned IndexRegNum;
726 int64_t DispValue;
727 unsigned SegRegNum;
728 const MCExpr *DispExpr = nullptr;
729 if (!evaluateX86MemoryOperand(Inst, &BaseRegNum, &ScaleValue, &IndexRegNum,
730 &DispValue, &SegRegNum, &DispExpr))
731 return false;
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 ||
736 DispExpr)
737 return false;
739 Target = DispValue;
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;
745 return true;
748 MCInst::iterator getMemOperandDisp(MCInst &Inst) const override {
749 int MemOpNo = getMemoryOperandNo(Inst);
750 if (MemOpNo < 0)
751 return Inst.end();
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())
758 return false;
759 *OI = Operand;
760 return true;
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);
773 return Regs;
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().");
788 Regs.set(X86::RAX);
789 Regs.set(X86::RCX);
790 Regs.set(X86::RDX);
791 Regs.set(X86::RSI);
792 Regs.set(X86::RDI);
793 Regs.set(X86::R8);
794 Regs.set(X86::R9);
795 Regs.set(X86::XMM0);
796 Regs.set(X86::XMM1);
797 Regs.set(X86::XMM2);
798 Regs.set(X86::XMM3);
799 Regs.set(X86::XMM4);
800 Regs.set(X86::XMM5);
801 Regs.set(X86::XMM6);
802 Regs.set(X86::XMM7);
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 {
816 if (IncludeAlias) {
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);
832 return;
834 Regs.set(X86::RAX);
835 Regs.set(X86::RBX);
836 Regs.set(X86::RBP);
837 Regs.set(X86::RSI);
838 Regs.set(X86::RDI);
839 Regs.set(X86::RDX);
840 Regs.set(X86::RCX);
841 Regs.set(X86::R8);
842 Regs.set(X86::R9);
843 Regs.set(X86::R10);
844 Regs.set(X86::R11);
845 Regs.set(X86::R12);
846 Regs.set(X86::R13);
847 Regs.set(X86::R14);
848 Regs.set(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 {
866 switch (Reg) {
867 case X86::RAX: case X86::EAX: case X86::AX: case X86::AL: case X86::AH:
868 switch (Size) {
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:
874 switch (Size) {
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:
880 switch (Size) {
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:
886 switch (Size) {
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:
892 switch (Size) {
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:
898 switch (Size) {
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:
904 switch (Size) {
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:
910 switch (Size) {
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:
916 switch (Size) {
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:
922 switch (Size) {
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:
928 switch (Size) {
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:
934 switch (Size) {
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:
940 switch (Size) {
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:
946 switch (Size) {
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:
952 switch (Size) {
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:
958 switch (Size) {
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");
963 default:
964 dbgs() << Reg << " (get alias sized)\n";
965 llvm_unreachable("Unexpected reg number");
966 break;
970 bool isUpper8BitReg(MCPhysReg Reg) const override {
971 switch (Reg) {
972 case X86::AH:
973 case X86::BH:
974 case X86::CH:
975 case X86::DH:
976 return true;
977 default:
978 return false;
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:
991 case X86::MOV8mr:
992 case X86::MOV8rm:
993 case X86::MOV8rr:
994 case X86::MOVSX32rm8:
995 case X86::MOVSX32rr8:
996 case X86::MOVZX32rm8:
997 case X86::MOVZX32rr8:
998 case X86::TEST8ri:
999 for (const MCOperand &Operand : MCPlus::primeOperands(Inst)) {
1000 if (!Operand.isReg())
1001 continue;
1002 if (isUpper8BitReg(Operand.getReg()))
1003 return true;
1005 [[fallthrough]];
1006 default:
1007 return false;
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)) {
1042 IsLoad = false;
1043 IsStore = true;
1044 IsStoreFromReg = true;
1045 StackPtrReg = X86::RSP;
1046 StackOffset = -Sz;
1047 Size = Sz;
1048 IsSimple = true;
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();
1053 else
1054 IsSimple = false;
1056 return true;
1058 if (int Sz = getPopSize(Inst)) {
1059 IsLoad = true;
1060 IsStore = false;
1061 if (Inst.getNumOperands() == 0 || !Inst.getOperand(0).isReg()) {
1062 IsSimple = false;
1063 } else {
1064 Reg = Inst.getOperand(0).getReg();
1065 IsSimple = true;
1067 StackPtrReg = X86::RSP;
1068 StackOffset = 0;
1069 Size = Sz;
1070 return true;
1073 struct InstInfo {
1074 // Size in bytes that Inst loads from memory.
1075 uint8_t DataSize;
1076 bool IsLoad;
1077 bool IsStore;
1078 bool StoreFromReg;
1079 bool Simple;
1082 InstInfo I;
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())
1087 return false;
1089 switch (Inst.getOpcode()) {
1090 default: {
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};
1096 break;
1098 uint8_t Sz = getMemDataSize(Inst, MemOpNo);
1099 I = {Sz, IsLoad, IsStore, false, false};
1100 break;
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;
1117 int64_t ScaleValue;
1118 unsigned IndexRegNum;
1119 int64_t DispValue;
1120 unsigned SegRegNum;
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());
1126 return false;
1129 // Make sure it's a stack access
1130 if (BaseRegNum != X86::RBP && BaseRegNum != X86::RSP)
1131 return false;
1133 IsLoad = I.IsLoad;
1134 IsStore = I.IsStore;
1135 IsStoreFromReg = I.StoreFromReg;
1136 Size = I.DataSize;
1137 IsSimple = I.Simple;
1138 StackPtrReg = BaseRegNum;
1139 StackOffset = DispValue;
1140 IsIndexed = IndexRegNum != X86::NoRegister || SegRegNum != X86::NoRegister;
1142 if (!I.Simple)
1143 return true;
1145 // Retrieve related register in simple MOV from/to stack operations.
1146 unsigned MemOpOffset = static_cast<unsigned>(MemOpNo);
1147 if (I.IsLoad) {
1148 MCOperand RegOpnd = Inst.getOperand(0);
1149 assert(RegOpnd.isReg() && "unexpected destination operand");
1150 Reg = RegOpnd.getReg();
1151 } else if (I.IsStore) {
1152 MCOperand SrcOpnd =
1153 Inst.getOperand(MemOpOffset + X86::AddrSegmentReg + 1);
1154 if (I.StoreFromReg) {
1155 assert(SrcOpnd.isReg() && "unexpected source operand");
1156 Reg = SrcOpnd.getReg();
1157 } else {
1158 assert(SrcOpnd.isImm() && "unexpected source operand");
1159 SrcImm = SrcOpnd.getImm();
1163 return true;
1166 void changeToPushOrPop(MCInst &Inst) const override {
1167 assert(!isPush(Inst) && !isPop(Inst));
1169 struct InstInfo {
1170 // Size in bytes that Inst loads from memory.
1171 uint8_t DataSize;
1172 bool IsLoad;
1173 bool StoreFromReg;
1176 InstInfo I;
1177 switch (Inst.getOpcode()) {
1178 default: {
1179 llvm_unreachable("Unhandled opcode");
1180 return;
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;
1193 int64_t ScaleValue;
1194 unsigned IndexRegNum;
1195 int64_t DispValue;
1196 unsigned SegRegNum;
1197 const MCExpr *DispExpr;
1198 if (!evaluateX86MemoryOperand(Inst, &BaseRegNum, &ScaleValue, &IndexRegNum,
1199 &DispValue, &SegRegNum, &DispExpr)) {
1200 llvm_unreachable("Evaluate failed");
1201 return;
1203 // Make sure it's a stack access
1204 if (BaseRegNum != X86::RBP && BaseRegNum != X86::RSP) {
1205 llvm_unreachable("Not a stack access");
1206 return;
1209 unsigned MemOpOffset = getMemoryOperandNo(Inst);
1210 unsigned NewOpcode = 0;
1211 if (I.IsLoad) {
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;
1216 default:
1217 llvm_unreachable("Unexpected size");
1219 unsigned RegOpndNum = Inst.getOperand(0).getReg();
1220 Inst.clear();
1221 Inst.setOpcode(NewOpcode);
1222 Inst.addOperand(MCOperand::createReg(RegOpndNum));
1223 } else {
1224 MCOperand SrcOpnd =
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;
1231 default:
1232 llvm_unreachable("Unexpected size");
1234 assert(SrcOpnd.isReg() && "Unexpected source operand");
1235 unsigned RegOpndNum = SrcOpnd.getReg();
1236 Inst.clear();
1237 Inst.setOpcode(NewOpcode);
1238 Inst.addOperand(MCOperand::createReg(RegOpndNum));
1239 } else {
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;
1244 default:
1245 llvm_unreachable("Unexpected size");
1247 assert(SrcOpnd.isImm() && "Unexpected source operand");
1248 int64_t SrcImm = SrcOpnd.getImm();
1249 Inst.clear();
1250 Inst.setOpcode(NewOpcode);
1251 Inst.addOperand(MCOperand::createImm(SrcImm));
1256 bool isStackAdjustment(const MCInst &Inst) const override {
1257 switch (Inst.getOpcode()) {
1258 default:
1259 return false;
1260 case X86::SUB64ri32:
1261 case X86::SUB64ri8:
1262 case X86::ADD64ri32:
1263 case X86::ADD64ri8:
1264 case X86::LEA64r:
1265 break;
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)
1272 return true;
1274 return false;
1277 bool
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()) {
1291 default:
1292 return false;
1294 case X86::SUB64ri32:
1295 case X86::SUB64ri8:
1296 if (!Inst.getOperand(2).isImm())
1297 return false;
1298 if (ErrorOr<int64_t> InputVal =
1299 getOperandVal(Inst.getOperand(1).getReg()))
1300 Output = *InputVal - Inst.getOperand(2).getImm();
1301 else
1302 return false;
1303 break;
1304 case X86::ADD64ri32:
1305 case X86::ADD64ri8:
1306 if (!Inst.getOperand(2).isImm())
1307 return false;
1308 if (ErrorOr<int64_t> InputVal =
1309 getOperandVal(Inst.getOperand(1).getReg()))
1310 Output = *InputVal + Inst.getOperand(2).getImm();
1311 else
1312 return false;
1313 break;
1314 case X86::ADD64i32:
1315 if (!Inst.getOperand(0).isImm())
1316 return false;
1317 if (ErrorOr<int64_t> InputVal = getOperandVal(X86::RAX))
1318 Output = *InputVal + Inst.getOperand(0).getImm();
1319 else
1320 return false;
1321 break;
1323 case X86::LEA64r: {
1324 unsigned BaseRegNum;
1325 int64_t ScaleValue;
1326 unsigned IndexRegNum;
1327 int64_t DispValue;
1328 unsigned SegRegNum;
1329 const MCExpr *DispExpr = nullptr;
1330 if (!evaluateX86MemoryOperand(Inst, &BaseRegNum, &ScaleValue,
1331 &IndexRegNum, &DispValue, &SegRegNum,
1332 &DispExpr))
1333 return false;
1335 if (BaseRegNum == X86::NoRegister || IndexRegNum != X86::NoRegister ||
1336 SegRegNum != X86::NoRegister || DispExpr)
1337 return false;
1339 if (ErrorOr<int64_t> InputVal = getOperandVal(BaseRegNum))
1340 Output = *InputVal + DispValue;
1341 else
1342 return false;
1344 break;
1347 return true;
1350 bool isRegToRegMove(const MCInst &Inst, MCPhysReg &From,
1351 MCPhysReg &To) const override {
1352 switch (Inst.getOpcode()) {
1353 default:
1354 return false;
1355 case X86::LEAVE:
1356 case X86::LEAVE64:
1357 To = getStackPointer();
1358 From = getFramePointer();
1359 return true;
1360 case X86::MOV64rr:
1361 To = Inst.getOperand(0).getReg();
1362 From = Inst.getOperand(1).getReg();
1363 return true;
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)
1386 return false;
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 &&
1394 I <= MemOpNo + 5)
1395 continue;
1396 // Ignore if someone is writing to SP/BP
1397 if (I < static_cast<int>(NumDefs))
1398 continue;
1400 const MCOperand &Operand = Inst.getOperand(I);
1401 if (HasFramePointer && Operand.isReg() && SPBPAliases[Operand.getReg()]) {
1402 DoesLeak = true;
1403 break;
1405 if (!HasFramePointer && Operand.isReg() && SPAliases[Operand.getReg()]) {
1406 DoesLeak = true;
1407 break;
1411 // If potential leak, check if it is not just writing to itself/sp/bp
1412 if (DoesLeak) {
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()]) {
1417 DoesLeak = false;
1418 break;
1420 if (!HasFramePointer && Operand.isReg() &&
1421 SPAliases[Operand.getReg()]) {
1422 DoesLeak = false;
1423 break;
1427 return DoesLeak;
1430 bool addToImm(MCInst &Inst, int64_t &Amt, MCContext *Ctx) const override {
1431 unsigned ImmOpNo = -1U;
1432 int MemOpNo = getMemoryOperandNo(Inst);
1433 if (MemOpNo != -1)
1434 ImmOpNo = MemOpNo + X86::AddrDisp;
1435 else
1436 for (unsigned Index = 0; Index < MCPlus::getNumPrimeOperands(Inst);
1437 ++Index)
1438 if (Inst.getOperand(Index).isImm())
1439 ImmOpNo = Index;
1440 if (ImmOpNo == -1U)
1441 return false;
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)))
1448 return true;
1450 // Relax instruction
1451 switch (Inst.getOpcode()) {
1452 case X86::SUB64ri8:
1453 Inst.setOpcode(X86::SUB64ri32);
1454 break;
1455 case X86::ADD64ri8:
1456 Inst.setOpcode(X86::ADD64ri32);
1457 break;
1458 default:
1459 // No need for relaxation
1460 break;
1462 return true;
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 {
1471 NOCHECK = 0,
1472 CHECK8,
1473 CHECK32,
1476 using CheckList = std::vector<std::pair<CheckSignExt, unsigned>>;
1477 struct InstInfo {
1478 // Size in bytes that Inst loads from memory.
1479 uint8_t DataSize;
1481 // True when the target operand has to be duplicated because the opcode
1482 // expects a LHS operand.
1483 bool HasLHS;
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
1488 // immediate.
1489 CheckList Checks;
1492 InstInfo I;
1494 switch (Inst.getOpcode()) {
1495 default: {
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;
1503 break;
1506 // MOV
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;
1513 // MOVZX
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;
1518 // CMP
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;
1528 // TEST
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;
1535 // ADD
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;
1545 // SUB
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;
1555 // AND
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;
1565 // OR
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;
1575 // XOR
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");
1589 int64_t ImmVal =
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)
1597 break;
1598 if (Check.first == CHECK8 && isInt<8>(ImmVal))
1599 break;
1600 if (Check.first == CHECK32 && isInt<32>(ImmVal))
1601 break;
1603 if (NewOpcode == Inst.getOpcode())
1604 return false;
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);
1619 Inst.clear();
1620 Inst.setOpcode(NewOpcode);
1621 Inst.addOperand(TargetOp);
1622 if (I.HasLHS)
1623 Inst.addOperand(TargetOp);
1624 Inst.addOperand(ImmOp);
1626 return true;
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 {
1633 unsigned NewOpcode;
1635 switch (Inst.getOpcode()) {
1636 default: {
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;
1643 break;
1646 // MOV
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);
1656 Inst.clear();
1657 Inst.setOpcode(NewOpcode);
1658 Inst.addOperand(TargetOp);
1659 Inst.addOperand(RegOp);
1661 return true;
1664 bool isRedundantMove(const MCInst &Inst) const override {
1665 switch (Inst.getOpcode()) {
1666 default:
1667 return false;
1669 // MOV
1670 case X86::MOV8rr:
1671 case X86::MOV16rr:
1672 case X86::MOV32rr:
1673 case X86::MOV64rr:
1674 break;
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)
1686 continue;
1687 if (Op.RegClass == X86::VR128RegClassID)
1688 return true;
1690 return false;
1693 bool convertJmpToTailCall(MCInst &Inst) override {
1694 if (isTailCall(Inst))
1695 return false;
1697 int NewOpcode;
1698 switch (Inst.getOpcode()) {
1699 default:
1700 return false;
1701 case X86::JMP_1:
1702 case X86::JMP_2:
1703 case X86::JMP_4:
1704 NewOpcode = X86::JMP_4;
1705 break;
1706 case X86::JMP16m:
1707 case X86::JMP32m:
1708 case X86::JMP64m:
1709 NewOpcode = X86::JMP32m;
1710 break;
1711 case X86::JMP16r:
1712 case X86::JMP32r:
1713 case X86::JMP64r:
1714 NewOpcode = X86::JMP32r;
1715 break;
1718 Inst.setOpcode(NewOpcode);
1719 setTailCall(Inst);
1720 return true;
1723 bool convertTailCallToJmp(MCInst &Inst) override {
1724 int NewOpcode;
1725 switch (Inst.getOpcode()) {
1726 default:
1727 return false;
1728 case X86::JMP_4:
1729 NewOpcode = X86::JMP_1;
1730 break;
1731 case X86::JMP32m:
1732 NewOpcode = X86::JMP64m;
1733 break;
1734 case X86::JMP32r:
1735 NewOpcode = X86::JMP64r;
1736 break;
1739 Inst.setOpcode(NewOpcode);
1740 removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);
1741 clearOffset(Inst);
1742 return true;
1745 bool convertTailCallToCall(MCInst &Inst) override {
1746 int NewOpcode;
1747 switch (Inst.getOpcode()) {
1748 default:
1749 return false;
1750 case X86::JMP_4:
1751 NewOpcode = X86::CALL64pcrel32;
1752 break;
1753 case X86::JMP32m:
1754 NewOpcode = X86::CALL64m;
1755 break;
1756 case X86::JMP32r:
1757 NewOpcode = X86::CALL64r;
1758 break;
1761 Inst.setOpcode(NewOpcode);
1762 removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);
1763 return true;
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
1776 // the instruction.
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
1791 return true;
1794 void convertIndirectCallToLoad(MCInst &Inst, MCPhysReg Reg) override {
1795 bool IsTailCall = isTailCall(Inst);
1796 if (IsTailCall)
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));
1802 return;
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));
1808 return;
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.
1834 if (MemOpNo >= 0) {
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()) {
1845 const int64_t Imm =
1846 Inst.getOperand(MCPlus::getNumPrimeOperands(Inst) - 1).getImm();
1847 if (int64_t(Imm) == int64_t(int32_t(Imm)))
1848 NewOpcode = X86::MOV64ri32;
1850 } else {
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()) {
1855 int64_t Imm =
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)
1863 return false;
1865 Inst.setOpcode(NewOpcode);
1866 return true;
1869 bool
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
1877 if (isLoad(Inst)) {
1878 // If stack memory operands are not allowed, no loads are allowed
1879 if (!AllowStackMemOp)
1880 return false;
1882 // If stack memory operands are allowed, check if it's a load from stack
1883 bool IsLoad, IsStore, IsStoreFromReg, IsSimple, IsIndexed;
1884 MCPhysReg Reg;
1885 int32_t SrcImm;
1886 uint16_t StackPtrReg;
1887 int64_t StackOffset;
1888 uint8_t Size;
1889 bool IsStackAccess =
1890 isStackAccess(Inst, IsLoad, IsStore, IsStoreFromReg, Reg, SrcImm,
1891 StackPtrReg, StackOffset, Size, IsSimple, IsIndexed);
1892 // Prohibit non-stack-based loads
1893 if (!IsStackAccess)
1894 return false;
1895 // If stack memory operands are allowed, check if it's RBP-based
1896 if (!AllowBasePtrStackMemOp &&
1897 RegInfo->isSubRegisterEq(X86::RBP, StackPtrReg))
1898 return false;
1901 unsigned NewOpcode = 0;
1902 switch (Inst.getOpcode()) {
1903 case X86::MOV16rr:
1904 NewOpcode = X86::CMOV16rr;
1905 break;
1906 case X86::MOV16rm:
1907 NewOpcode = X86::CMOV16rm;
1908 break;
1909 case X86::MOV32rr:
1910 NewOpcode = X86::CMOV32rr;
1911 break;
1912 case X86::MOV32rm:
1913 NewOpcode = X86::CMOV32rm;
1914 break;
1915 case X86::MOV64rr:
1916 NewOpcode = X86::CMOV64rr;
1917 break;
1918 case X86::MOV64rm:
1919 NewOpcode = X86::CMOV64rm;
1920 break;
1921 default:
1922 return false;
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));
1930 return true;
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);
1937 return true;
1939 return false;
1942 const MCSymbol *getTargetSymbol(const MCInst &Inst,
1943 unsigned OpNum = 0) const override {
1944 if (OpNum >= MCPlus::getNumPrimeOperands(Inst))
1945 return nullptr;
1947 const MCOperand &Op = Inst.getOperand(OpNum);
1948 if (!Op.isExpr())
1949 return nullptr;
1951 auto *SymExpr = dyn_cast<MCSymbolRefExpr>(Op.getExpr());
1952 if (!SymExpr || SymExpr->getKind() != MCSymbolRefExpr::VK_None)
1953 return nullptr;
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 {
1968 auto I = End;
1970 // Bottom-up analysis
1971 while (I != Begin) {
1972 --I;
1974 // Ignore nops and CFIs
1975 if (isPseudo(*I))
1976 continue;
1978 // Stop when we find the first non-terminator
1979 if (!isTerminator(*I))
1980 break;
1982 if (!isBranch(*I))
1983 break;
1985 // Handle unconditional branches.
1986 if ((I->getOpcode() == X86::JMP_1 || I->getOpcode() == X86::JMP_2 ||
1987 I->getOpcode() == X86::JMP_4) &&
1988 !isTailCall(*I)) {
1989 // If any code was seen after this unconditional branch, we've seen
1990 // unreachable code. Ignore them.
1991 CondBranch = nullptr;
1992 UncondBranch = &*I;
1993 const MCSymbol *Sym = getTargetSymbol(*I);
1994 assert(Sym != nullptr &&
1995 "Couldn't extract BB symbol from jump operand");
1996 TBB = Sym;
1997 continue;
2000 // Handle conditional branches and ignore indirect branches
2001 if (!isUnsupportedBranch(I->getOpcode()) &&
2002 getCondCode(*I) == X86::COND_INVALID) {
2003 // Indirect branch
2004 return false;
2007 if (CondBranch == nullptr) {
2008 const MCSymbol *TargetBB = getTargetSymbol(*I);
2009 if (TargetBB == nullptr) {
2010 // Unrecognized branch target
2011 return false;
2013 FBB = TBB;
2014 TBB = TargetBB;
2015 CondBranch = &*I;
2016 continue;
2019 llvm_unreachable("multiple conditional branches in one BB");
2021 return true;
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}
2031 // add %r2, %r1
2032 // jmp *%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:
2041 // JT: ----------
2042 // E1:| L1 - JT |
2043 // |----------|
2044 // E2:| L2 - JT |
2045 // |----------|
2046 // | |
2047 // ......
2048 // En:| Ln - JT |
2049 // ----------
2051 // Where L1, L2, ..., Ln represent labels in the function.
2053 // The actual relocations in the table will be of the form:
2055 // Ln - JT
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.
2069 continue;
2071 if (!MovInstr) {
2072 // Expect to see MOV instruction.
2073 if (!isMOVSX64rm32(Instr)) {
2074 LLVM_DEBUG(dbgs() << "MOV instruction expected.\n");
2075 break;
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
2080 // a single form.
2081 unsigned MovDestReg = Instr.getOperand(0).getReg();
2082 if (MovDestReg != R2)
2083 std::swap(R1, R2);
2084 if (MovDestReg != R2) {
2085 LLVM_DEBUG(dbgs() << "MOV instruction expected to set %r2\n");
2086 break;
2089 // Verify operands for MOV.
2090 unsigned BaseRegNum;
2091 int64_t ScaleValue;
2092 unsigned IndexRegNum;
2093 int64_t DispValue;
2094 unsigned SegRegNum;
2095 if (!evaluateX86MemoryOperand(Instr, &BaseRegNum, &ScaleValue,
2096 &IndexRegNum, &DispValue, &SegRegNum))
2097 break;
2098 if (BaseRegNum != R1 || ScaleValue != 4 ||
2099 IndexRegNum == X86::NoRegister || DispValue != 0 ||
2100 SegRegNum != X86::NoRegister)
2101 break;
2102 MovInstr = &Instr;
2103 } else {
2104 if (!InstrDesc.hasDefOfPhysReg(Instr, R1, *RegInfo))
2105 continue;
2106 if (!isLEA64r(Instr)) {
2107 LLVM_DEBUG(dbgs() << "LEA instruction expected\n");
2108 break;
2110 if (Instr.getOperand(0).getReg() != R1) {
2111 LLVM_DEBUG(dbgs() << "LEA instruction expected to set %r1\n");
2112 break;
2115 // Verify operands for LEA.
2116 unsigned BaseRegNum;
2117 int64_t ScaleValue;
2118 unsigned IndexRegNum;
2119 const MCExpr *DispExpr = nullptr;
2120 int64_t DispValue;
2121 unsigned SegRegNum;
2122 if (!evaluateX86MemoryOperand(Instr, &BaseRegNum, &ScaleValue,
2123 &IndexRegNum, &DispValue, &SegRegNum,
2124 &DispExpr))
2125 break;
2126 if (BaseRegNum != RegInfo->getProgramCounter() ||
2127 IndexRegNum != X86::NoRegister || SegRegNum != X86::NoRegister ||
2128 DispExpr == nullptr)
2129 break;
2130 MemLocInstr = &Instr;
2131 break;
2135 if (!MemLocInstr)
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,
2140 MemLocInstr);
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
2161 // or
2163 // mov (JUMP_TABLE, %index, Scale), %r1 <- MemLocInstr
2164 // ...
2165 // jmp %r1
2167 // We handle PIC-style jump tables separately.
2169 MemLocInstrOut = nullptr;
2170 BaseRegNumOut = X86::NoRegister;
2171 IndexRegNumOut = X86::NoRegister;
2172 DispValueOut = 0;
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))
2196 continue;
2198 if (isMoveMem2Reg(PrevInstr)) {
2199 MemLocInstr = &PrevInstr;
2200 break;
2202 if (isADD64rr(PrevInstr)) {
2203 unsigned R2 = PrevInstr.getOperand(2).getReg();
2204 if (R1 == R2)
2205 return IndirectBranchType::UNKNOWN;
2206 std::tie(Type, MemLocInstr) = analyzePICJumpTable(PrevII, IE, R1, R2);
2207 break;
2209 return IndirectBranchType::UNKNOWN;
2211 if (!MemLocInstr) {
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
2216 // as UNKNOWN case.
2217 return IndirectBranchType::UNKNOWN;
2219 } else {
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,
2232 &DispExpr))
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;
2260 return Type;
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
2267 /// following:
2269 /// Form 1: (found in debug code)
2270 /// add METHOD_OFFSET, %VtableReg
2271 /// mov (%VtableReg), %MethodReg
2272 /// ...
2273 /// call or jmp *%MethodReg
2275 /// Form 2:
2276 /// mov METHOD_OFFSET(%VtableReg), %MethodReg
2277 /// ...
2278 /// call or jmp *%MethodReg
2280 /// Form 3:
2281 /// ...
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;
2291 MethodOffset = 0;
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);
2314 return true;
2317 return false;
2319 if (CallInst.getOperand(0).isReg())
2320 MethodRegNum = CallInst.getOperand(0).getReg();
2321 else
2322 return false;
2324 if (MethodRegNum == X86::RIP || MethodRegNum == X86::RBP) {
2325 VtableRegNum = X86::NoRegister;
2326 MethodRegNum = X86::NoRegister;
2327 return false;
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)
2346 return true;
2347 break;
2350 return false;
2354 if (!VtableRegNum)
2355 return false;
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);
2366 break;
2371 return true;
2374 bool createStackPointerIncrement(MCInst &Inst, int Size,
2375 bool NoFlagsClobber) const override {
2376 if (NoFlagsClobber) {
2377 Inst.setOpcode(X86::LEA64r);
2378 Inst.clear();
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
2385 return true;
2387 Inst.setOpcode(X86::SUB64ri8);
2388 Inst.clear();
2389 Inst.addOperand(MCOperand::createReg(X86::RSP));
2390 Inst.addOperand(MCOperand::createReg(X86::RSP));
2391 Inst.addOperand(MCOperand::createImm(Size));
2392 return true;
2395 bool createStackPointerDecrement(MCInst &Inst, int Size,
2396 bool NoFlagsClobber) const override {
2397 if (NoFlagsClobber) {
2398 Inst.setOpcode(X86::LEA64r);
2399 Inst.clear();
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
2406 return true;
2408 Inst.setOpcode(X86::ADD64ri8);
2409 Inst.clear();
2410 Inst.addOperand(MCOperand::createReg(X86::RSP));
2411 Inst.addOperand(MCOperand::createReg(X86::RSP));
2412 Inst.addOperand(MCOperand::createImm(Size));
2413 return true;
2416 bool createSaveToStack(MCInst &Inst, const MCPhysReg &StackReg, int Offset,
2417 const MCPhysReg &SrcReg, int Size) const override {
2418 unsigned NewOpcode;
2419 switch (Size) {
2420 default:
2421 return false;
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);
2427 Inst.clear();
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));
2434 return true;
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,
2442 DstReg, Size);
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 {
2449 unsigned NewOpcode;
2450 switch (Size) {
2451 default:
2452 return false;
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);
2458 Inst.clear();
2459 Inst.addOperand(MCOperand::createReg(DstReg));
2460 Inst.addOperand(MCOperand::createReg(BaseReg));
2461 Inst.addOperand(MCOperand::createImm(Scale));
2462 Inst.addOperand(MCOperand::createReg(IndexReg));
2463 if (OffsetExpr)
2464 Inst.addOperand(MCOperand::createExpr(OffsetExpr)); // Displacement
2465 else
2466 Inst.addOperand(MCOperand::createImm(Offset)); // Displacement
2467 Inst.addOperand(MCOperand::createReg(AddrSegmentReg)); // AddrSegmentReg
2468 return true;
2471 void createLoadImmediate(MCInst &Inst, const MCPhysReg Dest,
2472 uint32_t Imm) const override {
2473 Inst.setOpcode(X86::MOV64ri32);
2474 Inst.clear();
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);
2483 Inst.clear();
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
2492 return true;
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
2502 // ijmp *(%tmpreg)
2504 MCInst IJmp;
2505 IJmp.setOpcode(X86::JMP64r);
2506 IJmp.addOperand(TmpReg);
2508 MCInst Load;
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);
2519 return true;
2522 bool createNoop(MCInst &Inst) const override {
2523 Inst.setOpcode(X86::NOOP);
2524 return true;
2527 bool createReturn(MCInst &Inst) const override {
2528 Inst.setOpcode(X86::RET64);
2529 return true;
2532 InstructionListType createInlineMemcpy(bool ReturnEnd) const override {
2533 InstructionListType Code;
2534 if (ReturnEnd)
2535 Code.emplace_back(MCInstBuilder(X86::LEA64r)
2536 .addReg(X86::RAX)
2537 .addReg(X86::RDI)
2538 .addImm(1)
2539 .addReg(X86::RDX)
2540 .addImm(0)
2541 .addReg(X86::NoRegister));
2542 else
2543 Code.emplace_back(MCInstBuilder(X86::MOV64rr)
2544 .addReg(X86::RAX)
2545 .addReg(X86::RDI));
2547 Code.emplace_back(MCInstBuilder(X86::MOV32rr)
2548 .addReg(X86::ECX)
2549 .addReg(X86::EDX));
2550 Code.emplace_back(MCInstBuilder(X86::REP_MOVSB_64));
2552 return Code;
2555 InstructionListType createOneByteMemcpy() const override {
2556 InstructionListType Code;
2557 Code.emplace_back(MCInstBuilder(X86::MOV8rm)
2558 .addReg(X86::CL)
2559 .addReg(X86::RSI)
2560 .addImm(0)
2561 .addReg(X86::NoRegister)
2562 .addImm(0)
2563 .addReg(X86::NoRegister));
2564 Code.emplace_back(MCInstBuilder(X86::MOV8mr)
2565 .addReg(X86::RDI)
2566 .addImm(0)
2567 .addReg(X86::NoRegister)
2568 .addImm(0)
2569 .addReg(X86::NoRegister)
2570 .addReg(X86::CL));
2571 Code.emplace_back(MCInstBuilder(X86::MOV64rr)
2572 .addReg(X86::RAX)
2573 .addReg(X86::RDI));
2574 return Code;
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)
2582 .addReg(RegNo)
2583 .addImm(Imm));
2584 Code.emplace_back(MCInstBuilder(X86::JCC_1)
2585 .addExpr(MCSymbolRefExpr::create(
2586 Target, MCSymbolRefExpr::VK_None, *Ctx))
2587 .addImm(X86::COND_E));
2588 return Code;
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();
2599 uint64_t RelType;
2600 if (FKI.Flags & MCFixupKindInfo::FKF_IsPCRel) {
2601 switch (FKI.TargetSize) {
2602 default:
2603 return NoneType();
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;
2609 } else {
2610 switch (FKI.TargetSize) {
2611 default:
2612 return NoneType();
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:
2623 // Symbol + Addend
2624 // Symbol
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();
2638 } else {
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);
2652 ++Index) {
2653 if (Inst.getOperand(Index).isImm()) {
2654 ImmOpNo = Index;
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)
2661 break;
2665 if (ImmOpNo == -1U)
2666 return false;
2668 Value = Inst.getOperand(ImmOpNo).getImm();
2670 setOperandToSymbolRef(Inst, ImmOpNo, Symbol, Addend, Ctx, RelType);
2672 return true;
2675 bool replaceRegWithImm(MCInst &Inst, unsigned Register,
2676 int64_t Imm) const override {
2678 enum CheckSignExt : uint8_t {
2679 NOCHECK = 0,
2680 CHECK8,
2681 CHECK32,
2684 using CheckList = std::vector<std::pair<CheckSignExt, unsigned>>;
2685 struct InstInfo {
2686 // Size in bytes that Inst loads from memory.
2687 uint8_t DataSize;
2689 // True when the target operand has to be duplicated because the opcode
2690 // expects a LHS operand.
2691 bool HasLHS;
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
2696 // immediate.
2697 CheckList Checks;
2700 InstInfo I;
2702 switch (Inst.getOpcode()) {
2703 default: {
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;
2713 break;
2716 // MOV
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;
2729 // MOVZX
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;
2734 // CMP
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;
2744 // TEST
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;
2751 // ADD
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;
2761 // SUB
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;
2771 // AND
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;
2781 // OR
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;
2791 // XOR
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)
2807 break;
2808 if (Check.first == CHECK8 && isInt<8>(Imm))
2809 break;
2810 if (Check.first == CHECK32 && isInt<32>(Imm))
2811 break;
2813 if (NewOpcode == Inst.getOpcode())
2814 return false;
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)
2824 NumFound++;
2826 if (NumFound != 1)
2827 return false;
2829 MCOperand TargetOp = Inst.getOperand(0);
2830 Inst.clear();
2831 Inst.setOpcode(NewOpcode);
2832 Inst.addOperand(TargetOp);
2833 if (I.HasLHS)
2834 Inst.addOperand(TargetOp);
2835 Inst.addOperand(MCOperand::createImm(Imm));
2837 return true;
2840 bool replaceRegWithReg(MCInst &Inst, unsigned ToReplace,
2841 unsigned ReplaceWith) const override {
2843 // Get the HasLHS value so that iteration can be done
2844 bool HasLHS;
2845 if (X86::isAND(Inst.getOpcode()) || X86::isADD(Inst.getOpcode()) ||
2846 X86::isSUB(Inst.getOpcode())) {
2847 HasLHS = true;
2848 } else if (isPop(Inst) || isPush(Inst) || X86::isCMP(Inst.getOpcode()) ||
2849 X86::isTEST(Inst.getOpcode())) {
2850 HasLHS = false;
2851 } else {
2852 switch (Inst.getOpcode()) {
2853 case X86::MOV8rr:
2854 case X86::MOV8rm:
2855 case X86::MOV8mr:
2856 case X86::MOV8ri:
2857 case X86::MOV16rr:
2858 case X86::MOV16rm:
2859 case X86::MOV16mr:
2860 case X86::MOV16ri:
2861 case X86::MOV32rr:
2862 case X86::MOV32rm:
2863 case X86::MOV32mr:
2864 case X86::MOV32ri:
2865 case X86::MOV64rr:
2866 case X86::MOV64rm:
2867 case X86::MOV64mr:
2868 case X86::MOV64ri:
2869 case X86::MOVZX16rr8:
2870 case X86::MOVZX32rr8:
2871 case X86::MOVZX32rr16:
2872 case X86::MOVSX32rm8:
2873 case X86::MOVSX32rr8:
2874 case X86::MOVSX64rm32:
2875 case X86::LEA64r:
2876 HasLHS = false;
2877 break;
2878 default:
2879 return false;
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()))
2894 continue;
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;
2900 FoundOne = true;
2903 // Return true if at least one operand was replaced
2904 return FoundOne;
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)));
2912 return true;
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)));
2920 return true;
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 {
2930 Seq.clear();
2931 Seq.emplace_back();
2932 createDirectCall(Seq.back(), Target, Ctx, /*IsTailCall*/ true);
2935 bool createTrap(MCInst &Inst) const override {
2936 Inst.clear();
2937 Inst.setOpcode(X86::TRAP);
2938 return true;
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));
2948 return true;
2951 bool replaceBranchCondition(MCInst &Inst, const MCSymbol *TBB, MCContext *Ctx,
2952 unsigned CC) const override {
2953 if (CC == X86::COND_INVALID)
2954 return false;
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));
2958 return true;
2961 unsigned getCanonicalBranchCondCode(unsigned CC) const override {
2962 switch (CC) {
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));
2997 return true;
3000 MCPhysReg getX86R11() const override { return X86::R11; }
3002 MCPhysReg getIntArgRegister(unsigned ArgNo) const override {
3003 // FIXME: this should depend on the calling convention.
3004 switch (ArgNo) {
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 {
3016 Inst.clear();
3017 Inst.setOpcode(X86::PAUSE);
3020 void createLfence(MCInst &Inst) const override {
3021 Inst.clear();
3022 Inst.setOpcode(X86::LFENCE);
3025 bool createDirectCall(MCInst &Inst, const MCSymbol *Target, MCContext *Ctx,
3026 bool IsTailCall) override {
3027 Inst.clear();
3028 Inst.setOpcode(IsTailCall ? X86::JMP_4 : X86::CALL64pcrel32);
3029 Inst.addOperand(MCOperand::createExpr(
3030 MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx)));
3031 if (IsTailCall)
3032 setTailCall(Inst);
3033 return true;
3036 void createShortJmp(InstructionListType &Seq, const MCSymbol *Target,
3037 MCContext *Ctx, bool IsTailCall) override {
3038 Seq.clear();
3039 MCInst Inst;
3040 Inst.setOpcode(X86::JMP_1);
3041 Inst.addOperand(MCOperand::createExpr(
3042 MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx)));
3043 if (IsTailCall)
3044 setTailCall(Inst);
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)
3058 return true;
3060 return false;
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)
3067 return true;
3069 return false;
3072 void createPushRegister(MCInst &Inst, MCPhysReg Reg,
3073 unsigned Size) const override {
3074 Inst.clear();
3075 unsigned NewOpcode = 0;
3076 if (Reg == X86::EFLAGS) {
3077 switch (Size) {
3078 case 2: NewOpcode = X86::PUSHF16; break;
3079 case 4: NewOpcode = X86::PUSHF32; break;
3080 case 8: NewOpcode = X86::PUSHF64; break;
3081 default:
3082 llvm_unreachable("Unexpected size");
3084 Inst.setOpcode(NewOpcode);
3085 return;
3087 switch (Size) {
3088 case 2: NewOpcode = X86::PUSH16r; break;
3089 case 4: NewOpcode = X86::PUSH32r; break;
3090 case 8: NewOpcode = X86::PUSH64r; break;
3091 default:
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 {
3100 Inst.clear();
3101 unsigned NewOpcode = 0;
3102 if (Reg == X86::EFLAGS) {
3103 switch (Size) {
3104 case 2: NewOpcode = X86::POPF16; break;
3105 case 4: NewOpcode = X86::POPF32; break;
3106 case 8: NewOpcode = X86::POPF64; break;
3107 default:
3108 llvm_unreachable("Unexpected size");
3110 Inst.setOpcode(NewOpcode);
3111 return;
3113 switch (Size) {
3114 case 2: NewOpcode = X86::POP16r; break;
3115 case 4: NewOpcode = X86::POP32r; break;
3116 case 8: NewOpcode = X86::POP64r; break;
3117 default:
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;
3135 switch (Size) {
3136 case 1: Opcode = X86::ADD8ri; break;
3137 case 2: Opcode = X86::ADD16ri; break;
3138 case 4: Opcode = X86::ADD32ri; break;
3139 default:
3140 llvm_unreachable("Unexpected size");
3142 Inst.setOpcode(Opcode);
3143 Inst.clear();
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;
3152 switch (Size) {
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
3158 case 8:
3159 Opcode = X86::MOV32ri;
3160 Reg = getAliasSized(Reg, 4);
3161 break;
3162 default:
3163 llvm_unreachable("Unexpected size");
3165 Inst.setOpcode(Opcode);
3166 Inst.clear();
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);
3173 Inst.clear();
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);
3180 Inst.clear();
3183 void createX86Sahf(MCInst &Inst) const {
3184 Inst.setOpcode(X86::SAHF);
3185 Inst.clear();
3188 void createInstrIncMemory(InstructionListType &Instrs, const MCSymbol *Target,
3189 MCContext *Ctx, bool IsLeaf) const override {
3190 unsigned int I = 0;
3192 Instrs.resize(IsLeaf ? 13 : 11);
3193 // Don't clobber application red zone (ABI dependent)
3194 if (IsLeaf)
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
3201 // PUSHF
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);
3208 // LOCK INC
3209 createIncMemory(Instrs[I++], Target, Ctx);
3210 // POPF
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);
3216 if (IsLeaf)
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,
3244 bool TailCall,
3245 MCSymbol *HandlerFuncAddr,
3246 int CallSiteID,
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;
3252 // Skip defs.
3253 for (unsigned I = Info->get(CallInst.getOpcode()).getNumDefs(),
3254 E = MCPlus::getNumPrimeOperands(CallInst);
3255 I != E; ++I) {
3256 const MCOperand &Operand = CallInst.getOperand(I);
3257 if (Operand.isReg() && SPAliases[Operand.getReg()]) {
3258 UsesSP = true;
3259 break;
3263 InstructionListType Insts;
3264 MCPhysReg TempReg = getIntArgRegister(0);
3265 // Code sequence used to enter indirect call instrumentation helper:
3266 // push %rdi
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
3270 // push %rdi
3271 // movq $CallSiteID, %rdi
3272 // push %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);
3285 if (UsesSP) {
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();
3301 I != E; ++I)
3302 Insts.back().addOperand(CallInst.getOperand(I));
3304 return Insts;
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:
3311 // popfq
3312 // pop %rdi
3313 // add $16, %rsp
3314 // xchg (%rsp), %rdi
3315 // jmp *-8(%rsp)
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);
3322 return Insts;
3325 InstructionListType
3326 createInstrumentedIndTailCallHandlerExitBB() const override {
3327 const MCPhysReg TempReg = getIntArgRegister(0);
3328 // Same thing as above, but for tail calls
3329 // popfq
3330 // add $16, %rsp
3331 // pop %rdi
3332 // jmp *-16(%rsp)
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);
3338 return Insts;
3341 InstructionListType
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.
3348 // pushfq
3349 // mov InstrTrampoline,%rdi
3350 // cmp $0x0,%rdi
3351 // je IndCallHandler
3352 // callq *%rdi
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);
3366 return Insts;
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]);
3374 return Insts;
3377 InstructionListType
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]);
3383 return Insts;
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]);
3391 return Insts;
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]);
3399 return Insts;
3402 InstructionListType createSymbolTrampoline(const MCSymbol *TgtSym,
3403 MCContext *Ctx) const override {
3404 InstructionListType Insts(1);
3405 createUncondBranch(Insts[0], TgtSym, Ctx);
3406 return Insts;
3409 InstructionListType createDummyReturnFunction(MCContext *Ctx) const override {
3410 InstructionListType Insts(1);
3411 createReturn(Insts[0]);
3412 return Insts;
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);
3444 if (Op.isReg())
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;
3452 else
3453 return Results;
3456 const auto jumpToMergeBlock = [&](InstructionListType &NewCall) {
3457 assert(MergeBlock);
3458 NewCall.push_back(CallInst);
3459 MCInst &Merge = NewCall.back();
3460 Merge.clear();
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();
3472 Target.clear();
3473 Target.setOpcode(X86::MOV64ri32);
3474 Target.addOperand(MCOperand::createReg(FuncAddrReg));
3475 if (Targets[i].first) {
3476 // Is this OK?
3477 Target.addOperand(MCOperand::createExpr(MCSymbolRefExpr::create(
3478 Targets[i].first, MCSymbolRefExpr::VK_None, *Ctx)));
3479 } else {
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();
3491 Compare.clear();
3492 if (isBranchOnReg(CallInst))
3493 Compare.setOpcode(X86::CMP64rr);
3494 else if (CallInst.getOpcode() == X86::CALL64pcrel32)
3495 Compare.setOpcode(X86::CMP64ri32);
3496 else
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));
3506 } else {
3507 // Compare current call target to a specific address.
3508 NewCall->push_back(CallInst);
3509 MCInst &Compare = NewCall->back();
3510 Compare.clear();
3511 if (isBranchOnReg(CallInst))
3512 Compare.setOpcode(X86::CMP64ri32);
3513 else
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));
3522 // Target address.
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);
3528 if (Addend)
3529 Expr = MCBinaryExpr::createAdd(
3530 Expr, MCConstantExpr::create(Addend, *Ctx), *Ctx);
3531 Compare.addOperand(MCOperand::createExpr(Expr));
3532 } else {
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.
3543 NextTarget =
3544 Ctx->createNamedTempSymbol(); // generate label for the next block
3545 NewCall->push_back(CallInst);
3547 if (IsJumpTable) {
3548 MCInst &Je = NewCall->back();
3550 // Jump to next compare if target addresses don't match.
3551 Je.clear();
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)));
3556 else
3557 Je.addOperand(MCOperand::createImm(Targets[i].second));
3559 Je.addOperand(MCOperand::createImm(X86::COND_E));
3560 assert(!isInvoke(CallInst));
3561 } else {
3562 MCInst &Jne = NewCall->back();
3564 // Jump to next compare if target addresses don't match.
3565 Jne.clear();
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();
3578 CallOrJmp.clear();
3580 if (MinimizeCodeSize && !LoadElim) {
3581 CallOrJmp.setOpcode(IsTailCall ? X86::JMP32r : X86::CALL64r);
3582 CallOrJmp.addOperand(MCOperand::createReg(FuncAddrReg));
3583 } else {
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)));
3589 else
3590 CallOrJmp.addOperand(MCOperand::createImm(Targets[i].second));
3592 if (IsTailCall)
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
3604 // call.
3605 Optional<MCPlus::MCLandingPad> EHInfo = getEHInfo(CallInst);
3606 if (EHInfo)
3607 addEHInfo(CallOrJmp, *EHInfo);
3608 int64_t GnuArgsSize = getGnuArgsSize(CallInst);
3609 if (GnuArgsSize >= 0)
3610 addGnuArgsSize(CallOrJmp, GnuArgsSize);
3613 if (!IsTailCall) {
3614 // The fallthrough block for the most common target should be
3615 // the merge block.
3616 if (i == 0) {
3617 // Fallthrough to merge block.
3618 MergeBlock = Ctx->createNamedTempSymbol();
3619 } else {
3620 // Insert jump to the merge block if we are not doing a fallthrough.
3621 jumpToMergeBlock(*NewCall);
3627 // Cold call block.
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());
3643 return Results;
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");
3653 if (IndexReg == 0)
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.
3681 NextTarget =
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));
3695 // Cold call block.
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);
3704 return Results;
3707 private:
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
3720 return true;
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
3734 return true;
3738 } // namespace
3740 namespace llvm {
3741 namespace bolt {
3743 MCPlusBuilder *createX86MCPlusBuilder(const MCInstrAnalysis *Analysis,
3744 const MCInstrInfo *Info,
3745 const MCRegisterInfo *RegInfo) {
3746 return new X86MCPlusBuilder(Analysis, Info, RegInfo);
3749 } // namespace bolt
3750 } // namespace llvm