10b57cec5SDimitry Andric //===-- X86MCCodeEmitter.cpp - Convert X86 code to machine code -----------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the X86MCCodeEmitter class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "MCTargetDesc/X86BaseInfo.h"
140b57cec5SDimitry Andric #include "MCTargetDesc/X86FixupKinds.h"
150b57cec5SDimitry Andric #include "MCTargetDesc/X86MCTargetDesc.h"
160b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCCodeEmitter.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCFixup.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
230b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
240b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
250b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
260b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h"
2781ad6265SDimitry Andric #include "llvm/Support/Casting.h"
280b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
290b57cec5SDimitry Andric #include <cassert>
300b57cec5SDimitry Andric #include <cstdint>
310b57cec5SDimitry Andric #include <cstdlib>
320b57cec5SDimitry Andric
330b57cec5SDimitry Andric using namespace llvm;
340b57cec5SDimitry Andric
350b57cec5SDimitry Andric #define DEBUG_TYPE "mccodeemitter"
360b57cec5SDimitry Andric
370b57cec5SDimitry Andric namespace {
380b57cec5SDimitry Andric
395f757f3fSDimitry Andric enum PrefixKind { None, REX, REX2, XOP, VEX2, VEX3, EVEX };
4006c3fb27SDimitry Andric
emitByte(uint8_t C,SmallVectorImpl<char> & CB)4106c3fb27SDimitry Andric static void emitByte(uint8_t C, SmallVectorImpl<char> &CB) { CB.push_back(C); }
4206c3fb27SDimitry Andric
4306c3fb27SDimitry Andric class X86OpcodePrefixHelper {
4406c3fb27SDimitry Andric // REX (1 byte)
4506c3fb27SDimitry Andric // +-----+ +------+
4606c3fb27SDimitry Andric // | 40H | | WRXB |
4706c3fb27SDimitry Andric // +-----+ +------+
4806c3fb27SDimitry Andric
495f757f3fSDimitry Andric // REX2 (2 bytes)
505f757f3fSDimitry Andric // +-----+ +-------------------+
515f757f3fSDimitry Andric // | D5H | | M | R'X'B' | WRXB |
525f757f3fSDimitry Andric // +-----+ +-------------------+
535f757f3fSDimitry Andric
5406c3fb27SDimitry Andric // XOP (3-byte)
5506c3fb27SDimitry Andric // +-----+ +--------------+ +-------------------+
5606c3fb27SDimitry Andric // | 8Fh | | RXB | m-mmmm | | W | vvvv | L | pp |
5706c3fb27SDimitry Andric // +-----+ +--------------+ +-------------------+
5806c3fb27SDimitry Andric
5906c3fb27SDimitry Andric // VEX2 (2 bytes)
6006c3fb27SDimitry Andric // +-----+ +-------------------+
6106c3fb27SDimitry Andric // | C5h | | R | vvvv | L | pp |
6206c3fb27SDimitry Andric // +-----+ +-------------------+
6306c3fb27SDimitry Andric
6406c3fb27SDimitry Andric // VEX3 (3 bytes)
6506c3fb27SDimitry Andric // +-----+ +--------------+ +-------------------+
6606c3fb27SDimitry Andric // | C4h | | RXB | m-mmmm | | W | vvvv | L | pp |
6706c3fb27SDimitry Andric // +-----+ +--------------+ +-------------------+
6806c3fb27SDimitry Andric
6906c3fb27SDimitry Andric // VEX_R: opcode externsion equivalent to REX.R in
7006c3fb27SDimitry Andric // 1's complement (inverted) form
7106c3fb27SDimitry Andric //
7206c3fb27SDimitry Andric // 1: Same as REX_R=0 (must be 1 in 32-bit mode)
7306c3fb27SDimitry Andric // 0: Same as REX_R=1 (64 bit mode only)
7406c3fb27SDimitry Andric
7506c3fb27SDimitry Andric // VEX_X: equivalent to REX.X, only used when a
7606c3fb27SDimitry Andric // register is used for index in SIB Byte.
7706c3fb27SDimitry Andric //
7806c3fb27SDimitry Andric // 1: Same as REX.X=0 (must be 1 in 32-bit mode)
7906c3fb27SDimitry Andric // 0: Same as REX.X=1 (64-bit mode only)
8006c3fb27SDimitry Andric
8106c3fb27SDimitry Andric // VEX_B:
8206c3fb27SDimitry Andric // 1: Same as REX_B=0 (ignored in 32-bit mode)
8306c3fb27SDimitry Andric // 0: Same as REX_B=1 (64 bit mode only)
8406c3fb27SDimitry Andric
8506c3fb27SDimitry Andric // VEX_W: opcode specific (use like REX.W, or used for
8606c3fb27SDimitry Andric // opcode extension, or ignored, depending on the opcode byte)
8706c3fb27SDimitry Andric
8806c3fb27SDimitry Andric // VEX_5M (VEX m-mmmmm field):
8906c3fb27SDimitry Andric //
9006c3fb27SDimitry Andric // 0b00000: Reserved for future use
9106c3fb27SDimitry Andric // 0b00001: implied 0F leading opcode
9206c3fb27SDimitry Andric // 0b00010: implied 0F 38 leading opcode bytes
9306c3fb27SDimitry Andric // 0b00011: implied 0F 3A leading opcode bytes
9406c3fb27SDimitry Andric // 0b00100: Reserved for future use
9506c3fb27SDimitry Andric // 0b00101: VEX MAP5
9606c3fb27SDimitry Andric // 0b00110: VEX MAP6
975f757f3fSDimitry Andric // 0b00111: VEX MAP7
9806c3fb27SDimitry Andric // 0b00111-0b11111: Reserved for future use
9906c3fb27SDimitry Andric // 0b01000: XOP map select - 08h instructions with imm byte
10006c3fb27SDimitry Andric // 0b01001: XOP map select - 09h instructions with no imm byte
10106c3fb27SDimitry Andric // 0b01010: XOP map select - 0Ah instructions with imm dword
10206c3fb27SDimitry Andric
10306c3fb27SDimitry Andric // VEX_4V (VEX vvvv field): a register specifier
10406c3fb27SDimitry Andric // (in 1's complement form) or 1111 if unused.
10506c3fb27SDimitry Andric
10606c3fb27SDimitry Andric // VEX_PP: opcode extension providing equivalent
10706c3fb27SDimitry Andric // functionality of a SIMD prefix
10806c3fb27SDimitry Andric // 0b00: None
10906c3fb27SDimitry Andric // 0b01: 66
11006c3fb27SDimitry Andric // 0b10: F3
11106c3fb27SDimitry Andric // 0b11: F2
11206c3fb27SDimitry Andric
11306c3fb27SDimitry Andric // EVEX (4 bytes)
1145f757f3fSDimitry Andric // +-----+ +---------------+ +--------------------+ +------------------------+
1155f757f3fSDimitry Andric // | 62h | | RXBR' | B'mmm | | W | vvvv | X' | pp | | z | L'L | b | v' | aaa |
1165f757f3fSDimitry Andric // +-----+ +---------------+ +--------------------+ +------------------------+
11706c3fb27SDimitry Andric
11806c3fb27SDimitry Andric // EVEX_L2/VEX_L (Vector Length):
11906c3fb27SDimitry Andric // L2 L
12006c3fb27SDimitry Andric // 0 0: scalar or 128-bit vector
12106c3fb27SDimitry Andric // 0 1: 256-bit vector
12206c3fb27SDimitry Andric // 1 0: 512-bit vector
12306c3fb27SDimitry Andric
1245f757f3fSDimitry Andric // 32-Register Support in 64-bit Mode Using EVEX with Embedded REX/REX2 Bits:
1255f757f3fSDimitry Andric //
1265f757f3fSDimitry Andric // +----------+---------+--------+-----------+---------+--------------+
1275f757f3fSDimitry Andric // | | 4 | 3 | [2:0] | Type | Common Usage |
1285f757f3fSDimitry Andric // +----------+---------+--------+-----------+---------+--------------+
1295f757f3fSDimitry Andric // | REG | EVEX_R' | EVEX_R | modrm.reg | GPR, VR | Dest or Src |
1305f757f3fSDimitry Andric // | VVVV | EVEX_v' | EVEX.vvvv | GPR, VR | Dest or Src |
1315f757f3fSDimitry Andric // | RM (VR) | EVEX_X | EVEX_B | modrm.r/m | VR | Dest or Src |
1325f757f3fSDimitry Andric // | RM (GPR) | EVEX_B' | EVEX_B | modrm.r/m | GPR | Dest or Src |
1335f757f3fSDimitry Andric // | BASE | EVEX_B' | EVEX_B | modrm.r/m | GPR | MA |
1345f757f3fSDimitry Andric // | INDEX | EVEX_X' | EVEX_X | sib.index | GPR | MA |
1355f757f3fSDimitry Andric // | VIDX | EVEX_v' | EVEX_X | sib.index | VR | VSIB MA |
1365f757f3fSDimitry Andric // +----------+---------+--------+-----------+---------+--------------+
1375f757f3fSDimitry Andric //
1385f757f3fSDimitry Andric // * GPR - General-purpose register
1395f757f3fSDimitry Andric // * VR - Vector register
1405f757f3fSDimitry Andric // * VIDX - Vector index
1415f757f3fSDimitry Andric // * VSIB - Vector SIB
1425f757f3fSDimitry Andric // * MA - Memory addressing
1435f757f3fSDimitry Andric
14406c3fb27SDimitry Andric private:
14506c3fb27SDimitry Andric unsigned W : 1;
14606c3fb27SDimitry Andric unsigned R : 1;
14706c3fb27SDimitry Andric unsigned X : 1;
14806c3fb27SDimitry Andric unsigned B : 1;
1495f757f3fSDimitry Andric unsigned M : 1;
1505f757f3fSDimitry Andric unsigned R2 : 1;
1515f757f3fSDimitry Andric unsigned X2 : 1;
1525f757f3fSDimitry Andric unsigned B2 : 1;
15306c3fb27SDimitry Andric unsigned VEX_4V : 4;
15406c3fb27SDimitry Andric unsigned VEX_L : 1;
15506c3fb27SDimitry Andric unsigned VEX_PP : 2;
15606c3fb27SDimitry Andric unsigned VEX_5M : 5;
15706c3fb27SDimitry Andric unsigned EVEX_z : 1;
15806c3fb27SDimitry Andric unsigned EVEX_L2 : 1;
15906c3fb27SDimitry Andric unsigned EVEX_b : 1;
16006c3fb27SDimitry Andric unsigned EVEX_V2 : 1;
16106c3fb27SDimitry Andric unsigned EVEX_aaa : 3;
16206c3fb27SDimitry Andric PrefixKind Kind = None;
16306c3fb27SDimitry Andric const MCRegisterInfo &MRI;
16406c3fb27SDimitry Andric
getRegEncoding(const MCInst & MI,unsigned OpNum) const16506c3fb27SDimitry Andric unsigned getRegEncoding(const MCInst &MI, unsigned OpNum) const {
16606c3fb27SDimitry Andric return MRI.getEncodingValue(MI.getOperand(OpNum).getReg());
16706c3fb27SDimitry Andric }
16806c3fb27SDimitry Andric
setR(unsigned Encoding)16906c3fb27SDimitry Andric void setR(unsigned Encoding) { R = Encoding >> 3 & 1; }
setR2(unsigned Encoding)1705f757f3fSDimitry Andric void setR2(unsigned Encoding) {
1715f757f3fSDimitry Andric R2 = Encoding >> 4 & 1;
1725f757f3fSDimitry Andric assert((!R2 || (Kind <= REX2 || Kind == EVEX)) && "invalid setting");
1735f757f3fSDimitry Andric }
setX(unsigned Encoding)1745f757f3fSDimitry Andric void setX(unsigned Encoding) { X = Encoding >> 3 & 1; }
setX2(unsigned Encoding)1755f757f3fSDimitry Andric void setX2(unsigned Encoding) {
1765f757f3fSDimitry Andric assert((Kind <= REX2 || Kind == EVEX) && "invalid setting");
1775f757f3fSDimitry Andric X2 = Encoding >> 4 & 1;
1785f757f3fSDimitry Andric }
setB(unsigned Encoding)1795f757f3fSDimitry Andric void setB(unsigned Encoding) { B = Encoding >> 3 & 1; }
setB2(unsigned Encoding)1805f757f3fSDimitry Andric void setB2(unsigned Encoding) {
1815f757f3fSDimitry Andric assert((Kind <= REX2 || Kind == EVEX) && "invalid setting");
1825f757f3fSDimitry Andric B2 = Encoding >> 4 & 1;
1835f757f3fSDimitry Andric }
set4V(unsigned Encoding)18406c3fb27SDimitry Andric void set4V(unsigned Encoding) { VEX_4V = Encoding & 0xf; }
setV2(unsigned Encoding)18506c3fb27SDimitry Andric void setV2(unsigned Encoding) { EVEX_V2 = Encoding >> 4 & 1; }
18606c3fb27SDimitry Andric
18706c3fb27SDimitry Andric public:
setW(bool V)18806c3fb27SDimitry Andric void setW(bool V) { W = V; }
setR(const MCInst & MI,unsigned OpNum)18906c3fb27SDimitry Andric void setR(const MCInst &MI, unsigned OpNum) {
19006c3fb27SDimitry Andric setR(getRegEncoding(MI, OpNum));
19106c3fb27SDimitry Andric }
setX(const MCInst & MI,unsigned OpNum,unsigned Shift=3)19206c3fb27SDimitry Andric void setX(const MCInst &MI, unsigned OpNum, unsigned Shift = 3) {
1935f757f3fSDimitry Andric unsigned Reg = MI.getOperand(OpNum).getReg();
1945f757f3fSDimitry Andric // X is used to extend vector register only when shift is not 3.
1955f757f3fSDimitry Andric if (Shift != 3 && X86II::isApxExtendedReg(Reg))
1965f757f3fSDimitry Andric return;
1975f757f3fSDimitry Andric unsigned Encoding = MRI.getEncodingValue(Reg);
1985f757f3fSDimitry Andric X = Encoding >> Shift & 1;
19906c3fb27SDimitry Andric }
setB(const MCInst & MI,unsigned OpNum)20006c3fb27SDimitry Andric void setB(const MCInst &MI, unsigned OpNum) {
20106c3fb27SDimitry Andric B = getRegEncoding(MI, OpNum) >> 3 & 1;
20206c3fb27SDimitry Andric }
set4V(const MCInst & MI,unsigned OpNum,bool IsImm=false)203*0fca6ea1SDimitry Andric void set4V(const MCInst &MI, unsigned OpNum, bool IsImm = false) {
204*0fca6ea1SDimitry Andric // OF, SF, ZF and CF reuse VEX_4V bits but are not reversed
205*0fca6ea1SDimitry Andric if (IsImm)
206*0fca6ea1SDimitry Andric set4V(~(MI.getOperand(OpNum).getImm()));
207*0fca6ea1SDimitry Andric else
20806c3fb27SDimitry Andric set4V(getRegEncoding(MI, OpNum));
20906c3fb27SDimitry Andric }
setL(bool V)21006c3fb27SDimitry Andric void setL(bool V) { VEX_L = V; }
setPP(unsigned V)21106c3fb27SDimitry Andric void setPP(unsigned V) { VEX_PP = V; }
set5M(unsigned V)21206c3fb27SDimitry Andric void set5M(unsigned V) { VEX_5M = V; }
setR2(const MCInst & MI,unsigned OpNum)21306c3fb27SDimitry Andric void setR2(const MCInst &MI, unsigned OpNum) {
21406c3fb27SDimitry Andric setR2(getRegEncoding(MI, OpNum));
21506c3fb27SDimitry Andric }
setRR2(const MCInst & MI,unsigned OpNum)21606c3fb27SDimitry Andric void setRR2(const MCInst &MI, unsigned OpNum) {
21706c3fb27SDimitry Andric unsigned Encoding = getRegEncoding(MI, OpNum);
21806c3fb27SDimitry Andric setR(Encoding);
21906c3fb27SDimitry Andric setR2(Encoding);
22006c3fb27SDimitry Andric }
setM(bool V)2215f757f3fSDimitry Andric void setM(bool V) { M = V; }
setXX2(const MCInst & MI,unsigned OpNum)2225f757f3fSDimitry Andric void setXX2(const MCInst &MI, unsigned OpNum) {
2235f757f3fSDimitry Andric unsigned Reg = MI.getOperand(OpNum).getReg();
2245f757f3fSDimitry Andric unsigned Encoding = MRI.getEncodingValue(Reg);
2255f757f3fSDimitry Andric setX(Encoding);
2265f757f3fSDimitry Andric // Index can be a vector register while X2 is used to extend GPR only.
2275f757f3fSDimitry Andric if (Kind <= REX2 || X86II::isApxExtendedReg(Reg))
2285f757f3fSDimitry Andric setX2(Encoding);
2295f757f3fSDimitry Andric }
setBB2(const MCInst & MI,unsigned OpNum)2305f757f3fSDimitry Andric void setBB2(const MCInst &MI, unsigned OpNum) {
2315f757f3fSDimitry Andric unsigned Reg = MI.getOperand(OpNum).getReg();
2325f757f3fSDimitry Andric unsigned Encoding = MRI.getEncodingValue(Reg);
2335f757f3fSDimitry Andric setB(Encoding);
2345f757f3fSDimitry Andric // Base can be a vector register while B2 is used to extend GPR only
2355f757f3fSDimitry Andric if (Kind <= REX2 || X86II::isApxExtendedReg(Reg))
2365f757f3fSDimitry Andric setB2(Encoding);
2375f757f3fSDimitry Andric }
setZ(bool V)23806c3fb27SDimitry Andric void setZ(bool V) { EVEX_z = V; }
setL2(bool V)23906c3fb27SDimitry Andric void setL2(bool V) { EVEX_L2 = V; }
setEVEX_b(bool V)24006c3fb27SDimitry Andric void setEVEX_b(bool V) { EVEX_b = V; }
setV2(const MCInst & MI,unsigned OpNum,bool HasVEX_4V)2415f757f3fSDimitry Andric void setV2(const MCInst &MI, unsigned OpNum, bool HasVEX_4V) {
2425f757f3fSDimitry Andric // Only needed with VSIB which don't use VVVV.
2435f757f3fSDimitry Andric if (HasVEX_4V)
2445f757f3fSDimitry Andric return;
2455f757f3fSDimitry Andric unsigned Reg = MI.getOperand(OpNum).getReg();
2465f757f3fSDimitry Andric if (X86II::isApxExtendedReg(Reg))
2475f757f3fSDimitry Andric return;
2485f757f3fSDimitry Andric setV2(MRI.getEncodingValue(Reg));
24906c3fb27SDimitry Andric }
set4VV2(const MCInst & MI,unsigned OpNum)25006c3fb27SDimitry Andric void set4VV2(const MCInst &MI, unsigned OpNum) {
25106c3fb27SDimitry Andric unsigned Encoding = getRegEncoding(MI, OpNum);
25206c3fb27SDimitry Andric set4V(Encoding);
25306c3fb27SDimitry Andric setV2(Encoding);
25406c3fb27SDimitry Andric }
setAAA(const MCInst & MI,unsigned OpNum)25506c3fb27SDimitry Andric void setAAA(const MCInst &MI, unsigned OpNum) {
25606c3fb27SDimitry Andric EVEX_aaa = getRegEncoding(MI, OpNum);
25706c3fb27SDimitry Andric }
setNF(bool V)258647cbc5dSDimitry Andric void setNF(bool V) { EVEX_aaa |= V << 2; }
setSC(const MCInst & MI,unsigned OpNum)259*0fca6ea1SDimitry Andric void setSC(const MCInst &MI, unsigned OpNum) {
260*0fca6ea1SDimitry Andric unsigned Encoding = MI.getOperand(OpNum).getImm();
261*0fca6ea1SDimitry Andric EVEX_V2 = ~(Encoding >> 3) & 0x1;
262*0fca6ea1SDimitry Andric EVEX_aaa = Encoding & 0x7;
263*0fca6ea1SDimitry Andric }
26406c3fb27SDimitry Andric
X86OpcodePrefixHelper(const MCRegisterInfo & MRI)26506c3fb27SDimitry Andric X86OpcodePrefixHelper(const MCRegisterInfo &MRI)
2665f757f3fSDimitry Andric : W(0), R(0), X(0), B(0), M(0), R2(0), X2(0), B2(0), VEX_4V(0), VEX_L(0),
2675f757f3fSDimitry Andric VEX_PP(0), VEX_5M(0), EVEX_z(0), EVEX_L2(0), EVEX_b(0), EVEX_V2(0),
2685f757f3fSDimitry Andric EVEX_aaa(0), MRI(MRI) {}
26906c3fb27SDimitry Andric
setLowerBound(PrefixKind K)27006c3fb27SDimitry Andric void setLowerBound(PrefixKind K) { Kind = K; }
27106c3fb27SDimitry Andric
determineOptimalKind()27206c3fb27SDimitry Andric PrefixKind determineOptimalKind() {
27306c3fb27SDimitry Andric switch (Kind) {
27406c3fb27SDimitry Andric case None:
2755f757f3fSDimitry Andric // Not M bit here by intention b/c
2765f757f3fSDimitry Andric // 1. No guarantee that REX2 is supported by arch w/o explict EGPR
2775f757f3fSDimitry Andric // 2. REX2 is longer than 0FH
2785f757f3fSDimitry Andric Kind = (R2 | X2 | B2) ? REX2 : (W | R | X | B) ? REX : None;
27906c3fb27SDimitry Andric break;
28006c3fb27SDimitry Andric case REX:
2815f757f3fSDimitry Andric Kind = (R2 | X2 | B2) ? REX2 : REX;
2825f757f3fSDimitry Andric break;
2835f757f3fSDimitry Andric case REX2:
28406c3fb27SDimitry Andric case XOP:
28506c3fb27SDimitry Andric case VEX3:
28606c3fb27SDimitry Andric case EVEX:
28706c3fb27SDimitry Andric break;
28806c3fb27SDimitry Andric case VEX2:
28906c3fb27SDimitry Andric Kind = (W | X | B | (VEX_5M != 1)) ? VEX3 : VEX2;
29006c3fb27SDimitry Andric break;
29106c3fb27SDimitry Andric }
29206c3fb27SDimitry Andric return Kind;
29306c3fb27SDimitry Andric }
29406c3fb27SDimitry Andric
emit(SmallVectorImpl<char> & CB) const29506c3fb27SDimitry Andric void emit(SmallVectorImpl<char> &CB) const {
29606c3fb27SDimitry Andric uint8_t FirstPayload =
29706c3fb27SDimitry Andric ((~R) & 0x1) << 7 | ((~X) & 0x1) << 6 | ((~B) & 0x1) << 5;
29806c3fb27SDimitry Andric uint8_t LastPayload = ((~VEX_4V) & 0xf) << 3 | VEX_L << 2 | VEX_PP;
29906c3fb27SDimitry Andric switch (Kind) {
30006c3fb27SDimitry Andric case None:
30106c3fb27SDimitry Andric return;
30206c3fb27SDimitry Andric case REX:
30306c3fb27SDimitry Andric emitByte(0x40 | W << 3 | R << 2 | X << 1 | B, CB);
30406c3fb27SDimitry Andric return;
3055f757f3fSDimitry Andric case REX2:
3065f757f3fSDimitry Andric emitByte(0xD5, CB);
3075f757f3fSDimitry Andric emitByte(M << 7 | R2 << 6 | X2 << 5 | B2 << 4 | W << 3 | R << 2 | X << 1 |
3085f757f3fSDimitry Andric B,
3095f757f3fSDimitry Andric CB);
3105f757f3fSDimitry Andric return;
31106c3fb27SDimitry Andric case VEX2:
31206c3fb27SDimitry Andric emitByte(0xC5, CB);
31306c3fb27SDimitry Andric emitByte(((~R) & 1) << 7 | LastPayload, CB);
31406c3fb27SDimitry Andric return;
31506c3fb27SDimitry Andric case VEX3:
31606c3fb27SDimitry Andric case XOP:
31706c3fb27SDimitry Andric emitByte(Kind == VEX3 ? 0xC4 : 0x8F, CB);
31806c3fb27SDimitry Andric emitByte(FirstPayload | VEX_5M, CB);
31906c3fb27SDimitry Andric emitByte(W << 7 | LastPayload, CB);
32006c3fb27SDimitry Andric return;
32106c3fb27SDimitry Andric case EVEX:
32206c3fb27SDimitry Andric assert(VEX_5M && !(VEX_5M & 0x8) && "invalid mmm fields for EVEX!");
32306c3fb27SDimitry Andric emitByte(0x62, CB);
3245f757f3fSDimitry Andric emitByte(FirstPayload | ((~R2) & 0x1) << 4 | B2 << 3 | VEX_5M, CB);
3255f757f3fSDimitry Andric emitByte(W << 7 | ((~VEX_4V) & 0xf) << 3 | ((~X2) & 0x1) << 2 | VEX_PP,
3265f757f3fSDimitry Andric CB);
32706c3fb27SDimitry Andric emitByte(EVEX_z << 7 | EVEX_L2 << 6 | VEX_L << 5 | EVEX_b << 4 |
32806c3fb27SDimitry Andric ((~EVEX_V2) & 0x1) << 3 | EVEX_aaa,
32906c3fb27SDimitry Andric CB);
33006c3fb27SDimitry Andric return;
33106c3fb27SDimitry Andric }
33206c3fb27SDimitry Andric }
33306c3fb27SDimitry Andric };
33406c3fb27SDimitry Andric
3350b57cec5SDimitry Andric class X86MCCodeEmitter : public MCCodeEmitter {
3360b57cec5SDimitry Andric const MCInstrInfo &MCII;
3370b57cec5SDimitry Andric MCContext &Ctx;
3380b57cec5SDimitry Andric
3390b57cec5SDimitry Andric public:
X86MCCodeEmitter(const MCInstrInfo & mcii,MCContext & ctx)3400b57cec5SDimitry Andric X86MCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
341480093f4SDimitry Andric : MCII(mcii), Ctx(ctx) {}
3420b57cec5SDimitry Andric X86MCCodeEmitter(const X86MCCodeEmitter &) = delete;
3430b57cec5SDimitry Andric X86MCCodeEmitter &operator=(const X86MCCodeEmitter &) = delete;
3440b57cec5SDimitry Andric ~X86MCCodeEmitter() override = default;
3450b57cec5SDimitry Andric
34606c3fb27SDimitry Andric void emitPrefix(const MCInst &MI, SmallVectorImpl<char> &CB,
347*0fca6ea1SDimitry Andric const MCSubtargetInfo &STI) const;
3480b57cec5SDimitry Andric
34906c3fb27SDimitry Andric void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB,
350480093f4SDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
351480093f4SDimitry Andric const MCSubtargetInfo &STI) const override;
3520b57cec5SDimitry Andric
353480093f4SDimitry Andric private:
3545ffd83dbSDimitry Andric unsigned getX86RegNum(const MCOperand &MO) const;
3550b57cec5SDimitry Andric
3565ffd83dbSDimitry Andric unsigned getX86RegEncoding(const MCInst &MI, unsigned OpNum) const;
3570b57cec5SDimitry Andric
358480093f4SDimitry Andric void emitImmediate(const MCOperand &Disp, SMLoc Loc, unsigned ImmSize,
35906c3fb27SDimitry Andric MCFixupKind FixupKind, uint64_t StartByte,
36006c3fb27SDimitry Andric SmallVectorImpl<char> &CB,
361480093f4SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, int ImmOffset = 0) const;
3620b57cec5SDimitry Andric
3635ffd83dbSDimitry Andric void emitRegModRMByte(const MCOperand &ModRMReg, unsigned RegOpcodeFld,
36406c3fb27SDimitry Andric SmallVectorImpl<char> &CB) const;
3655ffd83dbSDimitry Andric
3665ffd83dbSDimitry Andric void emitSIBByte(unsigned SS, unsigned Index, unsigned Base,
36706c3fb27SDimitry Andric SmallVectorImpl<char> &CB) const;
3685ffd83dbSDimitry Andric
3695ffd83dbSDimitry Andric void emitMemModRMByte(const MCInst &MI, unsigned Op, unsigned RegOpcodeField,
37006c3fb27SDimitry Andric uint64_t TSFlags, PrefixKind Kind, uint64_t StartByte,
37106c3fb27SDimitry Andric SmallVectorImpl<char> &CB,
37206c3fb27SDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
3735ffd83dbSDimitry Andric const MCSubtargetInfo &STI,
3745ffd83dbSDimitry Andric bool ForceSIB = false) const;
3755ffd83dbSDimitry Andric
37606c3fb27SDimitry Andric PrefixKind emitPrefixImpl(unsigned &CurOp, const MCInst &MI,
37706c3fb27SDimitry Andric const MCSubtargetInfo &STI,
37806c3fb27SDimitry Andric SmallVectorImpl<char> &CB) const;
3795ffd83dbSDimitry Andric
38006c3fb27SDimitry Andric PrefixKind emitVEXOpcodePrefix(int MemOperand, const MCInst &MI,
3815f757f3fSDimitry Andric const MCSubtargetInfo &STI,
38206c3fb27SDimitry Andric SmallVectorImpl<char> &CB) const;
3835ffd83dbSDimitry Andric
3845ffd83dbSDimitry Andric void emitSegmentOverridePrefix(unsigned SegOperand, const MCInst &MI,
38506c3fb27SDimitry Andric SmallVectorImpl<char> &CB) const;
3865ffd83dbSDimitry Andric
38706c3fb27SDimitry Andric PrefixKind emitOpcodePrefix(int MemOperand, const MCInst &MI,
38806c3fb27SDimitry Andric const MCSubtargetInfo &STI,
38906c3fb27SDimitry Andric SmallVectorImpl<char> &CB) const;
3905ffd83dbSDimitry Andric
39106c3fb27SDimitry Andric PrefixKind emitREXPrefix(int MemOperand, const MCInst &MI,
39206c3fb27SDimitry Andric const MCSubtargetInfo &STI,
39306c3fb27SDimitry Andric SmallVectorImpl<char> &CB) const;
3945ffd83dbSDimitry Andric };
3955ffd83dbSDimitry Andric
3965ffd83dbSDimitry Andric } // end anonymous namespace
3975ffd83dbSDimitry Andric
modRMByte(unsigned Mod,unsigned RegOpcode,unsigned RM)398480093f4SDimitry Andric static uint8_t modRMByte(unsigned Mod, unsigned RegOpcode, unsigned RM) {
3990b57cec5SDimitry Andric assert(Mod < 4 && RegOpcode < 8 && RM < 8 && "ModRM Fields out of range!");
4000b57cec5SDimitry Andric return RM | (RegOpcode << 3) | (Mod << 6);
4010b57cec5SDimitry Andric }
4020b57cec5SDimitry Andric
emitConstant(uint64_t Val,unsigned Size,SmallVectorImpl<char> & CB)40306c3fb27SDimitry Andric static void emitConstant(uint64_t Val, unsigned Size,
40406c3fb27SDimitry Andric SmallVectorImpl<char> &CB) {
4055ffd83dbSDimitry Andric // Output the constant in little endian byte order.
4065ffd83dbSDimitry Andric for (unsigned i = 0; i != Size; ++i) {
40706c3fb27SDimitry Andric emitByte(Val & 255, CB);
4085ffd83dbSDimitry Andric Val >>= 8;
4090b57cec5SDimitry Andric }
4100b57cec5SDimitry Andric }
4110b57cec5SDimitry Andric
412e8d8bef9SDimitry Andric /// Determine if this immediate can fit in a disp8 or a compressed disp8 for
413e8d8bef9SDimitry Andric /// EVEX instructions. \p will be set to the value to pass to the ImmOffset
414e8d8bef9SDimitry Andric /// parameter of emitImmediate.
isDispOrCDisp8(uint64_t TSFlags,int Value,int & ImmOffset)415e8d8bef9SDimitry Andric static bool isDispOrCDisp8(uint64_t TSFlags, int Value, int &ImmOffset) {
416e8d8bef9SDimitry Andric bool HasEVEX = (TSFlags & X86II::EncodingMask) == X86II::EVEX;
4170b57cec5SDimitry Andric
41806c3fb27SDimitry Andric unsigned CD8_Scale =
4190b57cec5SDimitry Andric (TSFlags & X86II::CD8_Scale_Mask) >> X86II::CD8_Scale_Shift;
42006c3fb27SDimitry Andric CD8_Scale = CD8_Scale ? 1U << (CD8_Scale - 1) : 0U;
42106c3fb27SDimitry Andric if (!HasEVEX || !CD8_Scale)
422e8d8bef9SDimitry Andric return isInt<8>(Value);
4230b57cec5SDimitry Andric
424e8d8bef9SDimitry Andric assert(isPowerOf2_32(CD8_Scale) && "Unexpected CD8 scale!");
425e8d8bef9SDimitry Andric if (Value & (CD8_Scale - 1)) // Unaligned offset
4260b57cec5SDimitry Andric return false;
4270b57cec5SDimitry Andric
42806c3fb27SDimitry Andric int CDisp8 = Value / static_cast<int>(CD8_Scale);
429e8d8bef9SDimitry Andric if (!isInt<8>(CDisp8))
430e8d8bef9SDimitry Andric return false;
431e8d8bef9SDimitry Andric
432e8d8bef9SDimitry Andric // ImmOffset will be added to Value in emitImmediate leaving just CDisp8.
433e8d8bef9SDimitry Andric ImmOffset = CDisp8 - Value;
434e8d8bef9SDimitry Andric return true;
4350b57cec5SDimitry Andric }
4360b57cec5SDimitry Andric
437480093f4SDimitry Andric /// \returns the appropriate fixup kind to use for an immediate in an
438480093f4SDimitry Andric /// instruction with the specified TSFlags.
getImmFixupKind(uint64_t TSFlags)4390b57cec5SDimitry Andric static MCFixupKind getImmFixupKind(uint64_t TSFlags) {
4400b57cec5SDimitry Andric unsigned Size = X86II::getSizeOfImm(TSFlags);
4410b57cec5SDimitry Andric bool isPCRel = X86II::isImmPCRel(TSFlags);
4420b57cec5SDimitry Andric
4430b57cec5SDimitry Andric if (X86II::isImmSigned(TSFlags)) {
4440b57cec5SDimitry Andric switch (Size) {
445480093f4SDimitry Andric default:
446480093f4SDimitry Andric llvm_unreachable("Unsupported signed fixup size!");
447480093f4SDimitry Andric case 4:
448480093f4SDimitry Andric return MCFixupKind(X86::reloc_signed_4byte);
4490b57cec5SDimitry Andric }
4500b57cec5SDimitry Andric }
4510b57cec5SDimitry Andric return MCFixup::getKindForSize(Size, isPCRel);
4520b57cec5SDimitry Andric }
4530b57cec5SDimitry Andric
454480093f4SDimitry Andric enum GlobalOffsetTableExprKind { GOT_None, GOT_Normal, GOT_SymDiff };
455480093f4SDimitry Andric
456480093f4SDimitry Andric /// Check if this expression starts with _GLOBAL_OFFSET_TABLE_ and if it is
457480093f4SDimitry Andric /// of the form _GLOBAL_OFFSET_TABLE_-symbol. This is needed to support PIC on
458480093f4SDimitry Andric /// ELF i386 as _GLOBAL_OFFSET_TABLE_ is magical. We check only simple case that
459480093f4SDimitry Andric /// are know to be used: _GLOBAL_OFFSET_TABLE_ by itself or at the start of a
460480093f4SDimitry Andric /// binary expression.
4610b57cec5SDimitry Andric static GlobalOffsetTableExprKind
startsWithGlobalOffsetTable(const MCExpr * Expr)462480093f4SDimitry Andric startsWithGlobalOffsetTable(const MCExpr *Expr) {
4630b57cec5SDimitry Andric const MCExpr *RHS = nullptr;
4640b57cec5SDimitry Andric if (Expr->getKind() == MCExpr::Binary) {
4650b57cec5SDimitry Andric const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(Expr);
4660b57cec5SDimitry Andric Expr = BE->getLHS();
4670b57cec5SDimitry Andric RHS = BE->getRHS();
4680b57cec5SDimitry Andric }
4690b57cec5SDimitry Andric
4700b57cec5SDimitry Andric if (Expr->getKind() != MCExpr::SymbolRef)
4710b57cec5SDimitry Andric return GOT_None;
4720b57cec5SDimitry Andric
4730b57cec5SDimitry Andric const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4740b57cec5SDimitry Andric const MCSymbol &S = Ref->getSymbol();
4750b57cec5SDimitry Andric if (S.getName() != "_GLOBAL_OFFSET_TABLE_")
4760b57cec5SDimitry Andric return GOT_None;
4770b57cec5SDimitry Andric if (RHS && RHS->getKind() == MCExpr::SymbolRef)
4780b57cec5SDimitry Andric return GOT_SymDiff;
4790b57cec5SDimitry Andric return GOT_Normal;
4800b57cec5SDimitry Andric }
4810b57cec5SDimitry Andric
hasSecRelSymbolRef(const MCExpr * Expr)482480093f4SDimitry Andric static bool hasSecRelSymbolRef(const MCExpr *Expr) {
4830b57cec5SDimitry Andric if (Expr->getKind() == MCExpr::SymbolRef) {
4840b57cec5SDimitry Andric const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4850b57cec5SDimitry Andric return Ref->getKind() == MCSymbolRefExpr::VK_SECREL;
4860b57cec5SDimitry Andric }
4870b57cec5SDimitry Andric return false;
4880b57cec5SDimitry Andric }
4890b57cec5SDimitry Andric
isPCRel32Branch(const MCInst & MI,const MCInstrInfo & MCII)490480093f4SDimitry Andric static bool isPCRel32Branch(const MCInst &MI, const MCInstrInfo &MCII) {
4910b57cec5SDimitry Andric unsigned Opcode = MI.getOpcode();
4920b57cec5SDimitry Andric const MCInstrDesc &Desc = MCII.get(Opcode);
4935ffd83dbSDimitry Andric if ((Opcode != X86::CALL64pcrel32 && Opcode != X86::JMP_4 &&
4945ffd83dbSDimitry Andric Opcode != X86::JCC_4) ||
4950b57cec5SDimitry Andric getImmFixupKind(Desc.TSFlags) != FK_PCRel_4)
4960b57cec5SDimitry Andric return false;
4970b57cec5SDimitry Andric
4980b57cec5SDimitry Andric unsigned CurOp = X86II::getOperandBias(Desc);
4990b57cec5SDimitry Andric const MCOperand &Op = MI.getOperand(CurOp);
5000b57cec5SDimitry Andric if (!Op.isExpr())
5010b57cec5SDimitry Andric return false;
5020b57cec5SDimitry Andric
5030b57cec5SDimitry Andric const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Op.getExpr());
5040b57cec5SDimitry Andric return Ref && Ref->getKind() == MCSymbolRefExpr::VK_None;
5050b57cec5SDimitry Andric }
5060b57cec5SDimitry Andric
getX86RegNum(const MCOperand & MO) const5075ffd83dbSDimitry Andric unsigned X86MCCodeEmitter::getX86RegNum(const MCOperand &MO) const {
5085ffd83dbSDimitry Andric return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()) & 0x7;
5095ffd83dbSDimitry Andric }
5105ffd83dbSDimitry Andric
getX86RegEncoding(const MCInst & MI,unsigned OpNum) const5115ffd83dbSDimitry Andric unsigned X86MCCodeEmitter::getX86RegEncoding(const MCInst &MI,
5125ffd83dbSDimitry Andric unsigned OpNum) const {
5135ffd83dbSDimitry Andric return Ctx.getRegisterInfo()->getEncodingValue(MI.getOperand(OpNum).getReg());
5145ffd83dbSDimitry Andric }
5155ffd83dbSDimitry Andric
emitImmediate(const MCOperand & DispOp,SMLoc Loc,unsigned Size,MCFixupKind FixupKind,uint64_t StartByte,SmallVectorImpl<char> & CB,SmallVectorImpl<MCFixup> & Fixups,int ImmOffset) const516480093f4SDimitry Andric void X86MCCodeEmitter::emitImmediate(const MCOperand &DispOp, SMLoc Loc,
517480093f4SDimitry Andric unsigned Size, MCFixupKind FixupKind,
51806c3fb27SDimitry Andric uint64_t StartByte,
51906c3fb27SDimitry Andric SmallVectorImpl<char> &CB,
520480093f4SDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
521480093f4SDimitry Andric int ImmOffset) const {
5220b57cec5SDimitry Andric const MCExpr *Expr = nullptr;
5230b57cec5SDimitry Andric if (DispOp.isImm()) {
5240b57cec5SDimitry Andric // If this is a simple integer displacement that doesn't require a
5250b57cec5SDimitry Andric // relocation, emit it now.
526480093f4SDimitry Andric if (FixupKind != FK_PCRel_1 && FixupKind != FK_PCRel_2 &&
5270b57cec5SDimitry Andric FixupKind != FK_PCRel_4) {
52806c3fb27SDimitry Andric emitConstant(DispOp.getImm() + ImmOffset, Size, CB);
5290b57cec5SDimitry Andric return;
5300b57cec5SDimitry Andric }
5310b57cec5SDimitry Andric Expr = MCConstantExpr::create(DispOp.getImm(), Ctx);
5320b57cec5SDimitry Andric } else {
5330b57cec5SDimitry Andric Expr = DispOp.getExpr();
5340b57cec5SDimitry Andric }
5350b57cec5SDimitry Andric
5360b57cec5SDimitry Andric // If we have an immoffset, add it to the expression.
537480093f4SDimitry Andric if ((FixupKind == FK_Data_4 || FixupKind == FK_Data_8 ||
5380b57cec5SDimitry Andric FixupKind == MCFixupKind(X86::reloc_signed_4byte))) {
539480093f4SDimitry Andric GlobalOffsetTableExprKind Kind = startsWithGlobalOffsetTable(Expr);
5400b57cec5SDimitry Andric if (Kind != GOT_None) {
5410b57cec5SDimitry Andric assert(ImmOffset == 0);
5420b57cec5SDimitry Andric
5430b57cec5SDimitry Andric if (Size == 8) {
5440b57cec5SDimitry Andric FixupKind = MCFixupKind(X86::reloc_global_offset_table8);
5450b57cec5SDimitry Andric } else {
5460b57cec5SDimitry Andric assert(Size == 4);
5470b57cec5SDimitry Andric FixupKind = MCFixupKind(X86::reloc_global_offset_table);
5480b57cec5SDimitry Andric }
5490b57cec5SDimitry Andric
5500b57cec5SDimitry Andric if (Kind == GOT_Normal)
55106c3fb27SDimitry Andric ImmOffset = static_cast<int>(CB.size() - StartByte);
5520b57cec5SDimitry Andric } else if (Expr->getKind() == MCExpr::SymbolRef) {
553480093f4SDimitry Andric if (hasSecRelSymbolRef(Expr)) {
5540b57cec5SDimitry Andric FixupKind = MCFixupKind(FK_SecRel_4);
5550b57cec5SDimitry Andric }
5560b57cec5SDimitry Andric } else if (Expr->getKind() == MCExpr::Binary) {
5570b57cec5SDimitry Andric const MCBinaryExpr *Bin = static_cast<const MCBinaryExpr *>(Expr);
558480093f4SDimitry Andric if (hasSecRelSymbolRef(Bin->getLHS()) ||
559480093f4SDimitry Andric hasSecRelSymbolRef(Bin->getRHS())) {
5600b57cec5SDimitry Andric FixupKind = MCFixupKind(FK_SecRel_4);
5610b57cec5SDimitry Andric }
5620b57cec5SDimitry Andric }
5630b57cec5SDimitry Andric }
5640b57cec5SDimitry Andric
5650b57cec5SDimitry Andric // If the fixup is pc-relative, we need to bias the value to be relative to
5660b57cec5SDimitry Andric // the start of the field, not the end of the field.
5670b57cec5SDimitry Andric if (FixupKind == FK_PCRel_4 ||
5680b57cec5SDimitry Andric FixupKind == MCFixupKind(X86::reloc_riprel_4byte) ||
5690b57cec5SDimitry Andric FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load) ||
5700b57cec5SDimitry Andric FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax) ||
5710b57cec5SDimitry Andric FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_rex) ||
5720b57cec5SDimitry Andric FixupKind == MCFixupKind(X86::reloc_branch_4byte_pcrel)) {
5730b57cec5SDimitry Andric ImmOffset -= 4;
5740b57cec5SDimitry Andric // If this is a pc-relative load off _GLOBAL_OFFSET_TABLE_:
5750b57cec5SDimitry Andric // leaq _GLOBAL_OFFSET_TABLE_(%rip), %r15
5760b57cec5SDimitry Andric // this needs to be a GOTPC32 relocation.
577480093f4SDimitry Andric if (startsWithGlobalOffsetTable(Expr) != GOT_None)
5780b57cec5SDimitry Andric FixupKind = MCFixupKind(X86::reloc_global_offset_table);
5790b57cec5SDimitry Andric }
5800b57cec5SDimitry Andric if (FixupKind == FK_PCRel_2)
5810b57cec5SDimitry Andric ImmOffset -= 2;
5820b57cec5SDimitry Andric if (FixupKind == FK_PCRel_1)
5830b57cec5SDimitry Andric ImmOffset -= 1;
5840b57cec5SDimitry Andric
5850b57cec5SDimitry Andric if (ImmOffset)
5860b57cec5SDimitry Andric Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(ImmOffset, Ctx),
5870b57cec5SDimitry Andric Ctx);
5880b57cec5SDimitry Andric
5890b57cec5SDimitry Andric // Emit a symbolic constant as a fixup and 4 zeros.
59006c3fb27SDimitry Andric Fixups.push_back(MCFixup::create(static_cast<uint32_t>(CB.size() - StartByte),
5915ffd83dbSDimitry Andric Expr, FixupKind, Loc));
59206c3fb27SDimitry Andric emitConstant(0, Size, CB);
5935ffd83dbSDimitry Andric }
5945ffd83dbSDimitry Andric
emitRegModRMByte(const MCOperand & ModRMReg,unsigned RegOpcodeFld,SmallVectorImpl<char> & CB) const5955ffd83dbSDimitry Andric void X86MCCodeEmitter::emitRegModRMByte(const MCOperand &ModRMReg,
5965ffd83dbSDimitry Andric unsigned RegOpcodeFld,
59706c3fb27SDimitry Andric SmallVectorImpl<char> &CB) const {
59806c3fb27SDimitry Andric emitByte(modRMByte(3, RegOpcodeFld, getX86RegNum(ModRMReg)), CB);
5995ffd83dbSDimitry Andric }
6005ffd83dbSDimitry Andric
emitSIBByte(unsigned SS,unsigned Index,unsigned Base,SmallVectorImpl<char> & CB) const6015ffd83dbSDimitry Andric void X86MCCodeEmitter::emitSIBByte(unsigned SS, unsigned Index, unsigned Base,
60206c3fb27SDimitry Andric SmallVectorImpl<char> &CB) const {
6035ffd83dbSDimitry Andric // SIB byte is in the same format as the modRMByte.
60406c3fb27SDimitry Andric emitByte(modRMByte(SS, Index, Base), CB);
6050b57cec5SDimitry Andric }
6060b57cec5SDimitry Andric
emitMemModRMByte(const MCInst & MI,unsigned Op,unsigned RegOpcodeField,uint64_t TSFlags,PrefixKind Kind,uint64_t StartByte,SmallVectorImpl<char> & CB,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI,bool ForceSIB) const60706c3fb27SDimitry Andric void X86MCCodeEmitter::emitMemModRMByte(
60806c3fb27SDimitry Andric const MCInst &MI, unsigned Op, unsigned RegOpcodeField, uint64_t TSFlags,
60906c3fb27SDimitry Andric PrefixKind Kind, uint64_t StartByte, SmallVectorImpl<char> &CB,
61006c3fb27SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI,
6115ffd83dbSDimitry Andric bool ForceSIB) const {
6120b57cec5SDimitry Andric const MCOperand &Disp = MI.getOperand(Op + X86::AddrDisp);
6130b57cec5SDimitry Andric const MCOperand &Base = MI.getOperand(Op + X86::AddrBaseReg);
6140b57cec5SDimitry Andric const MCOperand &Scale = MI.getOperand(Op + X86::AddrScaleAmt);
6150b57cec5SDimitry Andric const MCOperand &IndexReg = MI.getOperand(Op + X86::AddrIndexReg);
6160b57cec5SDimitry Andric unsigned BaseReg = Base.getReg();
6170b57cec5SDimitry Andric
6180b57cec5SDimitry Andric // Handle %rip relative addressing.
6190b57cec5SDimitry Andric if (BaseReg == X86::RIP ||
6200b57cec5SDimitry Andric BaseReg == X86::EIP) { // [disp32+rIP] in X86-64 mode
62181ad6265SDimitry Andric assert(STI.hasFeature(X86::Is64Bit) &&
622480093f4SDimitry Andric "Rip-relative addressing requires 64-bit mode");
6235ffd83dbSDimitry Andric assert(IndexReg.getReg() == 0 && !ForceSIB &&
6245ffd83dbSDimitry Andric "Invalid rip-relative address");
62506c3fb27SDimitry Andric emitByte(modRMByte(0, RegOpcodeField, 5), CB);
6260b57cec5SDimitry Andric
6270b57cec5SDimitry Andric unsigned Opcode = MI.getOpcode();
628e8d8bef9SDimitry Andric unsigned FixupKind = [&]() {
629e8d8bef9SDimitry Andric // Enable relaxed relocation only for a MCSymbolRefExpr. We cannot use a
630e8d8bef9SDimitry Andric // relaxed relocation if an offset is present (e.g. x@GOTPCREL+4).
631e8d8bef9SDimitry Andric if (!(Disp.isExpr() && isa<MCSymbolRefExpr>(Disp.getExpr())))
632e8d8bef9SDimitry Andric return X86::reloc_riprel_4byte;
633e8d8bef9SDimitry Andric
634e8d8bef9SDimitry Andric // Certain loads for GOT references can be relocated against the symbol
635e8d8bef9SDimitry Andric // directly if the symbol ends up in the same linkage unit.
6360b57cec5SDimitry Andric switch (Opcode) {
6370b57cec5SDimitry Andric default:
6380b57cec5SDimitry Andric return X86::reloc_riprel_4byte;
6390b57cec5SDimitry Andric case X86::MOV64rm:
640e8d8bef9SDimitry Andric // movq loads is a subset of reloc_riprel_4byte_relax_rex. It is a
641e8d8bef9SDimitry Andric // special case because COFF and Mach-O don't support ELF's more
642e8d8bef9SDimitry Andric // flexible R_X86_64_REX_GOTPCRELX relaxation.
6435f757f3fSDimitry Andric // TODO: Support new relocation for REX2.
6445f757f3fSDimitry Andric assert(Kind == REX || Kind == REX2);
6450b57cec5SDimitry Andric return X86::reloc_riprel_4byte_movq_load;
646e8d8bef9SDimitry Andric case X86::ADC32rm:
647e8d8bef9SDimitry Andric case X86::ADD32rm:
648e8d8bef9SDimitry Andric case X86::AND32rm:
649e8d8bef9SDimitry Andric case X86::CMP32rm:
650e8d8bef9SDimitry Andric case X86::MOV32rm:
651e8d8bef9SDimitry Andric case X86::OR32rm:
652e8d8bef9SDimitry Andric case X86::SBB32rm:
653e8d8bef9SDimitry Andric case X86::SUB32rm:
654e8d8bef9SDimitry Andric case X86::TEST32mr:
655e8d8bef9SDimitry Andric case X86::XOR32rm:
6560b57cec5SDimitry Andric case X86::CALL64m:
6570b57cec5SDimitry Andric case X86::JMP64m:
6580b57cec5SDimitry Andric case X86::TAILJMPm64:
6590b57cec5SDimitry Andric case X86::TEST64mr:
6600b57cec5SDimitry Andric case X86::ADC64rm:
6610b57cec5SDimitry Andric case X86::ADD64rm:
6620b57cec5SDimitry Andric case X86::AND64rm:
6630b57cec5SDimitry Andric case X86::CMP64rm:
6640b57cec5SDimitry Andric case X86::OR64rm:
6650b57cec5SDimitry Andric case X86::SBB64rm:
6660b57cec5SDimitry Andric case X86::SUB64rm:
6670b57cec5SDimitry Andric case X86::XOR64rm:
6685f757f3fSDimitry Andric // We haven't support relocation for REX2 prefix, so temporarily use REX
6695f757f3fSDimitry Andric // relocation.
6705f757f3fSDimitry Andric // TODO: Support new relocation for REX2.
6715f757f3fSDimitry Andric return (Kind == REX || Kind == REX2) ? X86::reloc_riprel_4byte_relax_rex
6720b57cec5SDimitry Andric : X86::reloc_riprel_4byte_relax;
6730b57cec5SDimitry Andric }
6740b57cec5SDimitry Andric }();
6750b57cec5SDimitry Andric
6760b57cec5SDimitry Andric // rip-relative addressing is actually relative to the *next* instruction.
6770b57cec5SDimitry Andric // Since an immediate can follow the mod/rm byte for an instruction, this
6780b57cec5SDimitry Andric // means that we need to bias the displacement field of the instruction with
6790b57cec5SDimitry Andric // the size of the immediate field. If we have this case, add it into the
6800b57cec5SDimitry Andric // expression to emit.
6810b57cec5SDimitry Andric // Note: rip-relative addressing using immediate displacement values should
6820b57cec5SDimitry Andric // not be adjusted, assuming it was the user's intent.
6830b57cec5SDimitry Andric int ImmSize = !Disp.isImm() && X86II::hasImm(TSFlags)
6840b57cec5SDimitry Andric ? X86II::getSizeOfImm(TSFlags)
6850b57cec5SDimitry Andric : 0;
6860b57cec5SDimitry Andric
68706c3fb27SDimitry Andric emitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(FixupKind), StartByte, CB,
688480093f4SDimitry Andric Fixups, -ImmSize);
6890b57cec5SDimitry Andric return;
6900b57cec5SDimitry Andric }
6910b57cec5SDimitry Andric
692480093f4SDimitry Andric unsigned BaseRegNo = BaseReg ? getX86RegNum(Base) : -1U;
6930b57cec5SDimitry Andric
694*0fca6ea1SDimitry Andric bool IsAdSize16 = STI.hasFeature(X86::Is32Bit) &&
695*0fca6ea1SDimitry Andric (TSFlags & X86II::AdSizeMask) == X86II::AdSize16;
696*0fca6ea1SDimitry Andric
6970b57cec5SDimitry Andric // 16-bit addressing forms of the ModR/M byte have a different encoding for
6980b57cec5SDimitry Andric // the R/M field and are far more limited in which registers can be used.
699*0fca6ea1SDimitry Andric if (IsAdSize16 || X86_MC::is16BitMemOperand(MI, Op, STI)) {
7000b57cec5SDimitry Andric if (BaseReg) {
7010b57cec5SDimitry Andric // For 32-bit addressing, the row and column values in Table 2-2 are
7020b57cec5SDimitry Andric // basically the same. It's AX/CX/DX/BX/SP/BP/SI/DI in that order, with
703480093f4SDimitry Andric // some special cases. And getX86RegNum reflects that numbering.
7040b57cec5SDimitry Andric // For 16-bit addressing it's more fun, as shown in the SDM Vol 2A,
7050b57cec5SDimitry Andric // Table 2-1 "16-Bit Addressing Forms with the ModR/M byte". We can only
7060b57cec5SDimitry Andric // use SI/DI/BP/BX, which have "row" values 4-7 in no particular order,
7070b57cec5SDimitry Andric // while values 0-3 indicate the allowed combinations (base+index) of
7080b57cec5SDimitry Andric // those: 0 for BX+SI, 1 for BX+DI, 2 for BP+SI, 3 for BP+DI.
7090b57cec5SDimitry Andric //
7100b57cec5SDimitry Andric // R16Table[] is a lookup from the normal RegNo, to the row values from
7110b57cec5SDimitry Andric // Table 2-1 for 16-bit addressing modes. Where zero means disallowed.
7120b57cec5SDimitry Andric static const unsigned R16Table[] = {0, 0, 0, 7, 0, 6, 4, 5};
7130b57cec5SDimitry Andric unsigned RMfield = R16Table[BaseRegNo];
7140b57cec5SDimitry Andric
7150b57cec5SDimitry Andric assert(RMfield && "invalid 16-bit base register");
7160b57cec5SDimitry Andric
7170b57cec5SDimitry Andric if (IndexReg.getReg()) {
718480093f4SDimitry Andric unsigned IndexReg16 = R16Table[getX86RegNum(IndexReg)];
7190b57cec5SDimitry Andric
7200b57cec5SDimitry Andric assert(IndexReg16 && "invalid 16-bit index register");
7210b57cec5SDimitry Andric // We must have one of SI/DI (4,5), and one of BP/BX (6,7).
7220b57cec5SDimitry Andric assert(((IndexReg16 ^ RMfield) & 2) &&
7230b57cec5SDimitry Andric "invalid 16-bit base/index register combination");
7240b57cec5SDimitry Andric assert(Scale.getImm() == 1 &&
7250b57cec5SDimitry Andric "invalid scale for 16-bit memory reference");
7260b57cec5SDimitry Andric
7270b57cec5SDimitry Andric // Allow base/index to appear in either order (although GAS doesn't).
7280b57cec5SDimitry Andric if (IndexReg16 & 2)
7290b57cec5SDimitry Andric RMfield = (RMfield & 1) | ((7 - IndexReg16) << 1);
7300b57cec5SDimitry Andric else
7310b57cec5SDimitry Andric RMfield = (IndexReg16 & 1) | ((7 - RMfield) << 1);
7320b57cec5SDimitry Andric }
7330b57cec5SDimitry Andric
734e8d8bef9SDimitry Andric if (Disp.isImm() && isInt<8>(Disp.getImm())) {
7350b57cec5SDimitry Andric if (Disp.getImm() == 0 && RMfield != 6) {
7360b57cec5SDimitry Andric // There is no displacement; just the register.
73706c3fb27SDimitry Andric emitByte(modRMByte(0, RegOpcodeField, RMfield), CB);
7380b57cec5SDimitry Andric return;
7390b57cec5SDimitry Andric }
7400b57cec5SDimitry Andric // Use the [REG]+disp8 form, including for [BP] which cannot be encoded.
74106c3fb27SDimitry Andric emitByte(modRMByte(1, RegOpcodeField, RMfield), CB);
74206c3fb27SDimitry Andric emitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, StartByte, CB, Fixups);
7430b57cec5SDimitry Andric return;
7440b57cec5SDimitry Andric }
7450b57cec5SDimitry Andric // This is the [REG]+disp16 case.
74606c3fb27SDimitry Andric emitByte(modRMByte(2, RegOpcodeField, RMfield), CB);
7470b57cec5SDimitry Andric } else {
748e8d8bef9SDimitry Andric assert(IndexReg.getReg() == 0 && "Unexpected index register!");
7490b57cec5SDimitry Andric // There is no BaseReg; this is the plain [disp16] case.
75006c3fb27SDimitry Andric emitByte(modRMByte(0, RegOpcodeField, 6), CB);
7510b57cec5SDimitry Andric }
7520b57cec5SDimitry Andric
7530b57cec5SDimitry Andric // Emit 16-bit displacement for plain disp16 or [REG]+disp16 cases.
75406c3fb27SDimitry Andric emitImmediate(Disp, MI.getLoc(), 2, FK_Data_2, StartByte, CB, Fixups);
7550b57cec5SDimitry Andric return;
7560b57cec5SDimitry Andric }
7570b57cec5SDimitry Andric
758e8d8bef9SDimitry Andric // Check for presence of {disp8} or {disp32} pseudo prefixes.
759e8d8bef9SDimitry Andric bool UseDisp8 = MI.getFlags() & X86::IP_USE_DISP8;
760e8d8bef9SDimitry Andric bool UseDisp32 = MI.getFlags() & X86::IP_USE_DISP32;
7610b57cec5SDimitry Andric
762e8d8bef9SDimitry Andric // We only allow no displacement if no pseudo prefix is present.
763e8d8bef9SDimitry Andric bool AllowNoDisp = !UseDisp8 && !UseDisp32;
764e8d8bef9SDimitry Andric // Disp8 is allowed unless the {disp32} prefix is present.
765e8d8bef9SDimitry Andric bool AllowDisp8 = !UseDisp32;
766e8d8bef9SDimitry Andric
767e8d8bef9SDimitry Andric // Determine whether a SIB byte is needed.
768*0fca6ea1SDimitry Andric if (!ForceSIB && !X86II::needSIB(BaseReg, IndexReg.getReg(),
769*0fca6ea1SDimitry Andric STI.hasFeature(X86::Is64Bit))) {
7700b57cec5SDimitry Andric if (BaseReg == 0) { // [disp32] in X86-32 mode
77106c3fb27SDimitry Andric emitByte(modRMByte(0, RegOpcodeField, 5), CB);
77206c3fb27SDimitry Andric emitImmediate(Disp, MI.getLoc(), 4, FK_Data_4, StartByte, CB, Fixups);
7730b57cec5SDimitry Andric return;
7740b57cec5SDimitry Andric }
7750b57cec5SDimitry Andric
7765f757f3fSDimitry Andric // If the base is not EBP/ESP/R12/R13/R20/R21/R28/R29 and there is no
7775f757f3fSDimitry Andric // displacement, use simple indirect register encoding, this handles
7785f757f3fSDimitry Andric // addresses like [EAX]. The encoding for [EBP], [R13], [R20], [R21], [R28]
7795f757f3fSDimitry Andric // or [R29] with no displacement means [disp32] so we handle it by emitting
7805f757f3fSDimitry Andric // a displacement of 0 later.
7810b57cec5SDimitry Andric if (BaseRegNo != N86::EBP) {
782e8d8bef9SDimitry Andric if (Disp.isImm() && Disp.getImm() == 0 && AllowNoDisp) {
78306c3fb27SDimitry Andric emitByte(modRMByte(0, RegOpcodeField, BaseRegNo), CB);
7840b57cec5SDimitry Andric return;
7850b57cec5SDimitry Andric }
7860b57cec5SDimitry Andric
7870b57cec5SDimitry Andric // If the displacement is @tlscall, treat it as a zero.
7880b57cec5SDimitry Andric if (Disp.isExpr()) {
7890b57cec5SDimitry Andric auto *Sym = dyn_cast<MCSymbolRefExpr>(Disp.getExpr());
7900b57cec5SDimitry Andric if (Sym && Sym->getKind() == MCSymbolRefExpr::VK_TLSCALL) {
7910b57cec5SDimitry Andric // This is exclusively used by call *a@tlscall(base). The relocation
7920b57cec5SDimitry Andric // (R_386_TLSCALL or R_X86_64_TLSCALL) applies to the beginning.
7930b57cec5SDimitry Andric Fixups.push_back(MCFixup::create(0, Sym, FK_NONE, MI.getLoc()));
79406c3fb27SDimitry Andric emitByte(modRMByte(0, RegOpcodeField, BaseRegNo), CB);
7950b57cec5SDimitry Andric return;
7960b57cec5SDimitry Andric }
7970b57cec5SDimitry Andric }
7980b57cec5SDimitry Andric }
7990b57cec5SDimitry Andric
8000b57cec5SDimitry Andric // Otherwise, if the displacement fits in a byte, encode as [REG+disp8].
801e8d8bef9SDimitry Andric // Including a compressed disp8 for EVEX instructions that support it.
8025f757f3fSDimitry Andric // This also handles the 0 displacement for [EBP], [R13], [R21] or [R29]. We
8035f757f3fSDimitry Andric // can't use disp8 if the {disp32} pseudo prefix is present.
804e8d8bef9SDimitry Andric if (Disp.isImm() && AllowDisp8) {
805e8d8bef9SDimitry Andric int ImmOffset = 0;
806e8d8bef9SDimitry Andric if (isDispOrCDisp8(TSFlags, Disp.getImm(), ImmOffset)) {
80706c3fb27SDimitry Andric emitByte(modRMByte(1, RegOpcodeField, BaseRegNo), CB);
80806c3fb27SDimitry Andric emitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, StartByte, CB, Fixups,
809e8d8bef9SDimitry Andric ImmOffset);
8100b57cec5SDimitry Andric return;
8110b57cec5SDimitry Andric }
8120b57cec5SDimitry Andric }
8130b57cec5SDimitry Andric
814e8d8bef9SDimitry Andric // Otherwise, emit the most general non-SIB encoding: [REG+disp32].
8155f757f3fSDimitry Andric // Displacement may be 0 for [EBP], [R13], [R21], [R29] case if {disp32}
8165f757f3fSDimitry Andric // pseudo prefix prevented using disp8 above.
81706c3fb27SDimitry Andric emitByte(modRMByte(2, RegOpcodeField, BaseRegNo), CB);
8180b57cec5SDimitry Andric unsigned Opcode = MI.getOpcode();
8190b57cec5SDimitry Andric unsigned FixupKind = Opcode == X86::MOV32rm ? X86::reloc_signed_4byte_relax
8200b57cec5SDimitry Andric : X86::reloc_signed_4byte;
82106c3fb27SDimitry Andric emitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(FixupKind), StartByte, CB,
8220b57cec5SDimitry Andric Fixups);
8230b57cec5SDimitry Andric return;
8240b57cec5SDimitry Andric }
8250b57cec5SDimitry Andric
8260b57cec5SDimitry Andric // We need a SIB byte, so start by outputting the ModR/M byte first
827480093f4SDimitry Andric assert(IndexReg.getReg() != X86::ESP && IndexReg.getReg() != X86::RSP &&
828480093f4SDimitry Andric "Cannot use ESP as index reg!");
8290b57cec5SDimitry Andric
8300b57cec5SDimitry Andric bool ForceDisp32 = false;
8310b57cec5SDimitry Andric bool ForceDisp8 = false;
8320b57cec5SDimitry Andric int ImmOffset = 0;
8330b57cec5SDimitry Andric if (BaseReg == 0) {
8340b57cec5SDimitry Andric // If there is no base register, we emit the special case SIB byte with
8350b57cec5SDimitry Andric // MOD=0, BASE=5, to JUST get the index, scale, and displacement.
836e8d8bef9SDimitry Andric BaseRegNo = 5;
83706c3fb27SDimitry Andric emitByte(modRMByte(0, RegOpcodeField, 4), CB);
8380b57cec5SDimitry Andric ForceDisp32 = true;
839e8d8bef9SDimitry Andric } else if (Disp.isImm() && Disp.getImm() == 0 && AllowNoDisp &&
8405f757f3fSDimitry Andric // Base reg can't be EBP/RBP/R13/R21/R29 as that would end up with
8415f757f3fSDimitry Andric // '5' as the base field, but that is the magic [*] nomenclature
8425f757f3fSDimitry Andric // that indicates no base when mod=0. For these cases we'll emit a
8435f757f3fSDimitry Andric // 0 displacement instead.
8440b57cec5SDimitry Andric BaseRegNo != N86::EBP) {
8450b57cec5SDimitry Andric // Emit no displacement ModR/M byte
84606c3fb27SDimitry Andric emitByte(modRMByte(0, RegOpcodeField, 4), CB);
847e8d8bef9SDimitry Andric } else if (Disp.isImm() && AllowDisp8 &&
848e8d8bef9SDimitry Andric isDispOrCDisp8(TSFlags, Disp.getImm(), ImmOffset)) {
849e8d8bef9SDimitry Andric // Displacement fits in a byte or matches an EVEX compressed disp8, use
8505f757f3fSDimitry Andric // disp8 encoding. This also handles EBP/R13/R21/R29 base with 0
8515f757f3fSDimitry Andric // displacement unless {disp32} pseudo prefix was used.
85206c3fb27SDimitry Andric emitByte(modRMByte(1, RegOpcodeField, 4), CB);
853e8d8bef9SDimitry Andric ForceDisp8 = true;
8540b57cec5SDimitry Andric } else {
855e8d8bef9SDimitry Andric // Otherwise, emit the normal disp32 encoding.
85606c3fb27SDimitry Andric emitByte(modRMByte(2, RegOpcodeField, 4), CB);
857e8d8bef9SDimitry Andric ForceDisp32 = true;
8580b57cec5SDimitry Andric }
8590b57cec5SDimitry Andric
8600b57cec5SDimitry Andric // Calculate what the SS field value should be...
8610b57cec5SDimitry Andric static const unsigned SSTable[] = {~0U, 0, 1, ~0U, 2, ~0U, ~0U, ~0U, 3};
8620b57cec5SDimitry Andric unsigned SS = SSTable[Scale.getImm()];
8630b57cec5SDimitry Andric
864e8d8bef9SDimitry Andric unsigned IndexRegNo = IndexReg.getReg() ? getX86RegNum(IndexReg) : 4;
865e8d8bef9SDimitry Andric
86606c3fb27SDimitry Andric emitSIBByte(SS, IndexRegNo, BaseRegNo, CB);
8670b57cec5SDimitry Andric
8680b57cec5SDimitry Andric // Do we need to output a displacement?
8690b57cec5SDimitry Andric if (ForceDisp8)
87006c3fb27SDimitry Andric emitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, StartByte, CB, Fixups,
871480093f4SDimitry Andric ImmOffset);
872e8d8bef9SDimitry Andric else if (ForceDisp32)
873480093f4SDimitry Andric emitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(X86::reloc_signed_4byte),
87406c3fb27SDimitry Andric StartByte, CB, Fixups);
8750b57cec5SDimitry Andric }
8760b57cec5SDimitry Andric
8775ffd83dbSDimitry Andric /// Emit all instruction prefixes.
8785ffd83dbSDimitry Andric ///
87906c3fb27SDimitry Andric /// \returns one of the REX, XOP, VEX2, VEX3, EVEX if any of them is used,
88006c3fb27SDimitry Andric /// otherwise returns None.
emitPrefixImpl(unsigned & CurOp,const MCInst & MI,const MCSubtargetInfo & STI,SmallVectorImpl<char> & CB) const88106c3fb27SDimitry Andric PrefixKind X86MCCodeEmitter::emitPrefixImpl(unsigned &CurOp, const MCInst &MI,
882480093f4SDimitry Andric const MCSubtargetInfo &STI,
88306c3fb27SDimitry Andric SmallVectorImpl<char> &CB) const {
8845ffd83dbSDimitry Andric uint64_t TSFlags = MCII.get(MI.getOpcode()).TSFlags;
885480093f4SDimitry Andric // Determine where the memory operand starts, if present.
886480093f4SDimitry Andric int MemoryOperand = X86II::getMemoryOperandNo(TSFlags);
887480093f4SDimitry Andric // Emit segment override opcode prefix as needed.
8885ffd83dbSDimitry Andric if (MemoryOperand != -1) {
8895ffd83dbSDimitry Andric MemoryOperand += CurOp;
89006c3fb27SDimitry Andric emitSegmentOverridePrefix(MemoryOperand + X86::AddrSegmentReg, MI, CB);
8915ffd83dbSDimitry Andric }
892480093f4SDimitry Andric
893480093f4SDimitry Andric // Emit the repeat opcode prefix as needed.
894480093f4SDimitry Andric unsigned Flags = MI.getFlags();
895480093f4SDimitry Andric if (TSFlags & X86II::REP || Flags & X86::IP_HAS_REPEAT)
89606c3fb27SDimitry Andric emitByte(0xF3, CB);
897480093f4SDimitry Andric if (Flags & X86::IP_HAS_REPEAT_NE)
89806c3fb27SDimitry Andric emitByte(0xF2, CB);
899480093f4SDimitry Andric
900480093f4SDimitry Andric // Emit the address size opcode prefix as needed.
90181ad6265SDimitry Andric if (X86_MC::needsAddressSizeOverride(MI, STI, MemoryOperand, TSFlags) ||
90281ad6265SDimitry Andric Flags & X86::IP_HAS_AD_SIZE)
90306c3fb27SDimitry Andric emitByte(0x67, CB);
904480093f4SDimitry Andric
905480093f4SDimitry Andric uint64_t Form = TSFlags & X86II::FormMask;
906480093f4SDimitry Andric switch (Form) {
907480093f4SDimitry Andric default:
908480093f4SDimitry Andric break;
909480093f4SDimitry Andric case X86II::RawFrmDstSrc: {
910480093f4SDimitry Andric // Emit segment override opcode prefix as needed (not for %ds).
911480093f4SDimitry Andric if (MI.getOperand(2).getReg() != X86::DS)
91206c3fb27SDimitry Andric emitSegmentOverridePrefix(2, MI, CB);
913480093f4SDimitry Andric CurOp += 3; // Consume operands.
914480093f4SDimitry Andric break;
915480093f4SDimitry Andric }
916480093f4SDimitry Andric case X86II::RawFrmSrc: {
917480093f4SDimitry Andric // Emit segment override opcode prefix as needed (not for %ds).
918480093f4SDimitry Andric if (MI.getOperand(1).getReg() != X86::DS)
91906c3fb27SDimitry Andric emitSegmentOverridePrefix(1, MI, CB);
920480093f4SDimitry Andric CurOp += 2; // Consume operands.
921480093f4SDimitry Andric break;
922480093f4SDimitry Andric }
923480093f4SDimitry Andric case X86II::RawFrmDst: {
924480093f4SDimitry Andric ++CurOp; // Consume operand.
925480093f4SDimitry Andric break;
926480093f4SDimitry Andric }
927480093f4SDimitry Andric case X86II::RawFrmMemOffs: {
928480093f4SDimitry Andric // Emit segment override opcode prefix as needed.
92906c3fb27SDimitry Andric emitSegmentOverridePrefix(1, MI, CB);
930480093f4SDimitry Andric break;
931480093f4SDimitry Andric }
932480093f4SDimitry Andric }
9335ffd83dbSDimitry Andric
93481ad6265SDimitry Andric // REX prefix is optional, but if used must be immediately before the opcode
93581ad6265SDimitry Andric // Encoding type for this instruction.
93606c3fb27SDimitry Andric return (TSFlags & X86II::EncodingMask)
9375f757f3fSDimitry Andric ? emitVEXOpcodePrefix(MemoryOperand, MI, STI, CB)
93806c3fb27SDimitry Andric : emitOpcodePrefix(MemoryOperand, MI, STI, CB);
939480093f4SDimitry Andric }
940480093f4SDimitry Andric
94106c3fb27SDimitry Andric // AVX instructions are encoded using an encoding scheme that combines
94206c3fb27SDimitry Andric // prefix bytes, opcode extension field, operand encoding fields, and vector
94306c3fb27SDimitry Andric // length encoding capability into a new prefix, referred to as VEX.
94406c3fb27SDimitry Andric
94506c3fb27SDimitry Andric // The majority of the AVX-512 family of instructions (operating on
94606c3fb27SDimitry Andric // 512/256/128-bit vector register operands) are encoded using a new prefix
94706c3fb27SDimitry Andric // (called EVEX).
94806c3fb27SDimitry Andric
94906c3fb27SDimitry Andric // XOP is a revised subset of what was originally intended as SSE5. It was
95006c3fb27SDimitry Andric // changed to be similar but not overlapping with AVX.
95106c3fb27SDimitry Andric
95206c3fb27SDimitry Andric /// Emit XOP, VEX2, VEX3 or EVEX prefix.
95306c3fb27SDimitry Andric /// \returns the used prefix.
95406c3fb27SDimitry Andric PrefixKind
emitVEXOpcodePrefix(int MemOperand,const MCInst & MI,const MCSubtargetInfo & STI,SmallVectorImpl<char> & CB) const95506c3fb27SDimitry Andric X86MCCodeEmitter::emitVEXOpcodePrefix(int MemOperand, const MCInst &MI,
9565f757f3fSDimitry Andric const MCSubtargetInfo &STI,
95706c3fb27SDimitry Andric SmallVectorImpl<char> &CB) const {
9585ffd83dbSDimitry Andric const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
9595ffd83dbSDimitry Andric uint64_t TSFlags = Desc.TSFlags;
9605ffd83dbSDimitry Andric
9610b57cec5SDimitry Andric assert(!(TSFlags & X86II::LOCK) && "Can't have LOCK VEX.");
9620b57cec5SDimitry Andric
9635f757f3fSDimitry Andric #ifndef NDEBUG
9645f757f3fSDimitry Andric unsigned NumOps = MI.getNumOperands();
9655f757f3fSDimitry Andric for (unsigned I = NumOps ? X86II::getOperandBias(Desc) : 0; I != NumOps;
9665f757f3fSDimitry Andric ++I) {
9675f757f3fSDimitry Andric const MCOperand &MO = MI.getOperand(I);
9685f757f3fSDimitry Andric if (!MO.isReg())
9695f757f3fSDimitry Andric continue;
9705f757f3fSDimitry Andric unsigned Reg = MO.getReg();
9715f757f3fSDimitry Andric if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
9725f757f3fSDimitry Andric report_fatal_error(
9735f757f3fSDimitry Andric "Cannot encode high byte register in VEX/EVEX-prefixed instruction");
9745f757f3fSDimitry Andric }
9755f757f3fSDimitry Andric #endif
9765f757f3fSDimitry Andric
97706c3fb27SDimitry Andric X86OpcodePrefixHelper Prefix(*Ctx.getRegisterInfo());
97806c3fb27SDimitry Andric switch (TSFlags & X86II::EncodingMask) {
97906c3fb27SDimitry Andric default:
98006c3fb27SDimitry Andric break;
98106c3fb27SDimitry Andric case X86II::XOP:
98206c3fb27SDimitry Andric Prefix.setLowerBound(XOP);
98306c3fb27SDimitry Andric break;
98406c3fb27SDimitry Andric case X86II::VEX:
98506c3fb27SDimitry Andric // VEX can be 2 byte or 3 byte, not determined yet if not explicit
986*0fca6ea1SDimitry Andric Prefix.setLowerBound((MI.getFlags() & X86::IP_USE_VEX3) ? VEX3 : VEX2);
98706c3fb27SDimitry Andric break;
98806c3fb27SDimitry Andric case X86II::EVEX:
98906c3fb27SDimitry Andric Prefix.setLowerBound(EVEX);
99006c3fb27SDimitry Andric break;
99106c3fb27SDimitry Andric }
99206c3fb27SDimitry Andric
99306c3fb27SDimitry Andric Prefix.setW(TSFlags & X86II::REX_W);
994647cbc5dSDimitry Andric Prefix.setNF(TSFlags & X86II::EVEX_NF);
99506c3fb27SDimitry Andric
9960b57cec5SDimitry Andric bool HasEVEX_K = TSFlags & X86II::EVEX_K;
9970b57cec5SDimitry Andric bool HasVEX_4V = TSFlags & X86II::VEX_4V;
998647cbc5dSDimitry Andric bool IsND = X86II::hasNewDataDest(TSFlags); // IsND implies HasVEX_4V
9990b57cec5SDimitry Andric bool HasEVEX_RC = TSFlags & X86II::EVEX_RC;
10000b57cec5SDimitry Andric
10010b57cec5SDimitry Andric switch (TSFlags & X86II::OpMapMask) {
1002480093f4SDimitry Andric default:
1003480093f4SDimitry Andric llvm_unreachable("Invalid prefix!");
1004480093f4SDimitry Andric case X86II::TB:
100506c3fb27SDimitry Andric Prefix.set5M(0x1); // 0F
100606c3fb27SDimitry Andric break;
1007480093f4SDimitry Andric case X86II::T8:
100806c3fb27SDimitry Andric Prefix.set5M(0x2); // 0F 38
100906c3fb27SDimitry Andric break;
1010480093f4SDimitry Andric case X86II::TA:
101106c3fb27SDimitry Andric Prefix.set5M(0x3); // 0F 3A
101206c3fb27SDimitry Andric break;
1013480093f4SDimitry Andric case X86II::XOP8:
101406c3fb27SDimitry Andric Prefix.set5M(0x8);
1015480093f4SDimitry Andric break;
1016480093f4SDimitry Andric case X86II::XOP9:
101706c3fb27SDimitry Andric Prefix.set5M(0x9);
1018480093f4SDimitry Andric break;
1019480093f4SDimitry Andric case X86II::XOPA:
102006c3fb27SDimitry Andric Prefix.set5M(0xA);
1021480093f4SDimitry Andric break;
10225f757f3fSDimitry Andric case X86II::T_MAP4:
10235f757f3fSDimitry Andric Prefix.set5M(0x4);
10245f757f3fSDimitry Andric break;
1025349cc55cSDimitry Andric case X86II::T_MAP5:
102606c3fb27SDimitry Andric Prefix.set5M(0x5);
1027349cc55cSDimitry Andric break;
1028349cc55cSDimitry Andric case X86II::T_MAP6:
102906c3fb27SDimitry Andric Prefix.set5M(0x6);
1030349cc55cSDimitry Andric break;
10315f757f3fSDimitry Andric case X86II::T_MAP7:
10325f757f3fSDimitry Andric Prefix.set5M(0x7);
10335f757f3fSDimitry Andric break;
10340b57cec5SDimitry Andric }
10350b57cec5SDimitry Andric
103606c3fb27SDimitry Andric Prefix.setL(TSFlags & X86II::VEX_L);
103706c3fb27SDimitry Andric Prefix.setL2(TSFlags & X86II::EVEX_L2);
10385f757f3fSDimitry Andric if ((TSFlags & X86II::EVEX_L2) && STI.hasFeature(X86::FeatureAVX512) &&
10395f757f3fSDimitry Andric !STI.hasFeature(X86::FeatureEVEX512))
10405f757f3fSDimitry Andric report_fatal_error("ZMM registers are not supported without EVEX512");
10410b57cec5SDimitry Andric switch (TSFlags & X86II::OpPrefixMask) {
1042480093f4SDimitry Andric case X86II::PD:
104306c3fb27SDimitry Andric Prefix.setPP(0x1); // 66
104406c3fb27SDimitry Andric break;
1045480093f4SDimitry Andric case X86II::XS:
104606c3fb27SDimitry Andric Prefix.setPP(0x2); // F3
104706c3fb27SDimitry Andric break;
1048480093f4SDimitry Andric case X86II::XD:
104906c3fb27SDimitry Andric Prefix.setPP(0x3); // F2
105006c3fb27SDimitry Andric break;
10510b57cec5SDimitry Andric }
10520b57cec5SDimitry Andric
105306c3fb27SDimitry Andric Prefix.setZ(HasEVEX_K && (TSFlags & X86II::EVEX_Z));
105406c3fb27SDimitry Andric Prefix.setEVEX_b(TSFlags & X86II::EVEX_B);
10550b57cec5SDimitry Andric
10560b57cec5SDimitry Andric bool EncodeRC = false;
105706c3fb27SDimitry Andric uint8_t EVEX_rc = 0;
1058647cbc5dSDimitry Andric
10590b57cec5SDimitry Andric unsigned CurOp = X86II::getOperandBias(Desc);
1060*0fca6ea1SDimitry Andric bool HasTwoConditionalOps = TSFlags & X86II::TwoConditionalOps;
10610b57cec5SDimitry Andric
10620b57cec5SDimitry Andric switch (TSFlags & X86II::FormMask) {
1063480093f4SDimitry Andric default:
1064480093f4SDimitry Andric llvm_unreachable("Unexpected form in emitVEXOpcodePrefix!");
1065bdd1243dSDimitry Andric case X86II::MRMDestMem4VOp3CC: {
10665f757f3fSDimitry Andric // src1(ModR/M), MemAddr, src2(VEX_4V)
10675f757f3fSDimitry Andric Prefix.setRR2(MI, CurOp++);
10685f757f3fSDimitry Andric Prefix.setBB2(MI, MemOperand + X86::AddrBaseReg);
10695f757f3fSDimitry Andric Prefix.setXX2(MI, MemOperand + X86::AddrIndexReg);
1070bdd1243dSDimitry Andric CurOp += X86::AddrNumOperands;
1071cb14a3feSDimitry Andric Prefix.set4VV2(MI, CurOp++);
1072bdd1243dSDimitry Andric break;
1073bdd1243dSDimitry Andric }
10745ffd83dbSDimitry Andric case X86II::MRM_C0:
10750b57cec5SDimitry Andric case X86II::RawFrm:
10760b57cec5SDimitry Andric break;
1077*0fca6ea1SDimitry Andric case X86II::MRMDestMemCC:
10785ffd83dbSDimitry Andric case X86II::MRMDestMemFSIB:
10790b57cec5SDimitry Andric case X86II::MRMDestMem: {
10800b57cec5SDimitry Andric // MRMDestMem instructions forms:
10810b57cec5SDimitry Andric // MemAddr, src1(ModR/M)
10820b57cec5SDimitry Andric // MemAddr, src1(VEX_4V), src2(ModR/M)
10830b57cec5SDimitry Andric // MemAddr, src1(ModR/M), imm8
10840b57cec5SDimitry Andric //
1085647cbc5dSDimitry Andric // NDD:
1086647cbc5dSDimitry Andric // dst(VEX_4V), MemAddr, src1(ModR/M)
10875f757f3fSDimitry Andric Prefix.setBB2(MI, MemOperand + X86::AddrBaseReg);
10885f757f3fSDimitry Andric Prefix.setXX2(MI, MemOperand + X86::AddrIndexReg);
10895f757f3fSDimitry Andric Prefix.setV2(MI, MemOperand + X86::AddrIndexReg, HasVEX_4V);
10900b57cec5SDimitry Andric
1091647cbc5dSDimitry Andric if (IsND)
1092647cbc5dSDimitry Andric Prefix.set4VV2(MI, CurOp++);
1093647cbc5dSDimitry Andric
10940b57cec5SDimitry Andric CurOp += X86::AddrNumOperands;
10950b57cec5SDimitry Andric
10960b57cec5SDimitry Andric if (HasEVEX_K)
109706c3fb27SDimitry Andric Prefix.setAAA(MI, CurOp++);
10980b57cec5SDimitry Andric
1099647cbc5dSDimitry Andric if (!IsND && HasVEX_4V)
110006c3fb27SDimitry Andric Prefix.set4VV2(MI, CurOp++);
11010b57cec5SDimitry Andric
110206c3fb27SDimitry Andric Prefix.setRR2(MI, CurOp++);
1103*0fca6ea1SDimitry Andric if (HasTwoConditionalOps) {
1104*0fca6ea1SDimitry Andric Prefix.set4V(MI, CurOp++, /*IsImm=*/true);
1105*0fca6ea1SDimitry Andric Prefix.setSC(MI, CurOp++);
1106*0fca6ea1SDimitry Andric }
11070b57cec5SDimitry Andric break;
11080b57cec5SDimitry Andric }
1109*0fca6ea1SDimitry Andric case X86II::MRMSrcMemCC:
11105ffd83dbSDimitry Andric case X86II::MRMSrcMemFSIB:
11110b57cec5SDimitry Andric case X86II::MRMSrcMem: {
11120b57cec5SDimitry Andric // MRMSrcMem instructions forms:
11130b57cec5SDimitry Andric // src1(ModR/M), MemAddr
11140b57cec5SDimitry Andric // src1(ModR/M), src2(VEX_4V), MemAddr
11150b57cec5SDimitry Andric // src1(ModR/M), MemAddr, imm8
11160b57cec5SDimitry Andric // src1(ModR/M), MemAddr, src2(Imm[7:4])
11170b57cec5SDimitry Andric //
11180b57cec5SDimitry Andric // FMA4:
11190b57cec5SDimitry Andric // dst(ModR/M.reg), src1(VEX_4V), src2(ModR/M), src3(Imm[7:4])
1120647cbc5dSDimitry Andric //
1121647cbc5dSDimitry Andric // NDD:
1122647cbc5dSDimitry Andric // dst(VEX_4V), src1(ModR/M), MemAddr
1123647cbc5dSDimitry Andric if (IsND)
1124647cbc5dSDimitry Andric Prefix.set4VV2(MI, CurOp++);
1125647cbc5dSDimitry Andric
112606c3fb27SDimitry Andric Prefix.setRR2(MI, CurOp++);
11270b57cec5SDimitry Andric
11280b57cec5SDimitry Andric if (HasEVEX_K)
112906c3fb27SDimitry Andric Prefix.setAAA(MI, CurOp++);
11300b57cec5SDimitry Andric
1131647cbc5dSDimitry Andric if (!IsND && HasVEX_4V)
113206c3fb27SDimitry Andric Prefix.set4VV2(MI, CurOp++);
11330b57cec5SDimitry Andric
11345f757f3fSDimitry Andric Prefix.setBB2(MI, MemOperand + X86::AddrBaseReg);
11355f757f3fSDimitry Andric Prefix.setXX2(MI, MemOperand + X86::AddrIndexReg);
11365f757f3fSDimitry Andric Prefix.setV2(MI, MemOperand + X86::AddrIndexReg, HasVEX_4V);
1137*0fca6ea1SDimitry Andric CurOp += X86::AddrNumOperands;
1138*0fca6ea1SDimitry Andric if (HasTwoConditionalOps) {
1139*0fca6ea1SDimitry Andric Prefix.set4V(MI, CurOp++, /*IsImm=*/true);
1140*0fca6ea1SDimitry Andric Prefix.setSC(MI, CurOp++);
1141*0fca6ea1SDimitry Andric }
11420b57cec5SDimitry Andric break;
11430b57cec5SDimitry Andric }
11440b57cec5SDimitry Andric case X86II::MRMSrcMem4VOp3: {
11450b57cec5SDimitry Andric // Instruction format for 4VOp3:
11460b57cec5SDimitry Andric // src1(ModR/M), MemAddr, src3(VEX_4V)
11475f757f3fSDimitry Andric Prefix.setRR2(MI, CurOp++);
11485f757f3fSDimitry Andric Prefix.setBB2(MI, MemOperand + X86::AddrBaseReg);
11495f757f3fSDimitry Andric Prefix.setXX2(MI, MemOperand + X86::AddrIndexReg);
11505f757f3fSDimitry Andric Prefix.set4VV2(MI, CurOp + X86::AddrNumOperands);
11510b57cec5SDimitry Andric break;
11520b57cec5SDimitry Andric }
11530b57cec5SDimitry Andric case X86II::MRMSrcMemOp4: {
11540b57cec5SDimitry Andric // dst(ModR/M.reg), src1(VEX_4V), src2(Imm[7:4]), src3(ModR/M),
115506c3fb27SDimitry Andric Prefix.setR(MI, CurOp++);
115606c3fb27SDimitry Andric Prefix.set4V(MI, CurOp++);
11575f757f3fSDimitry Andric Prefix.setBB2(MI, MemOperand + X86::AddrBaseReg);
11585f757f3fSDimitry Andric Prefix.setXX2(MI, MemOperand + X86::AddrIndexReg);
11590b57cec5SDimitry Andric break;
11600b57cec5SDimitry Andric }
1161*0fca6ea1SDimitry Andric case X86II::MRMXmCC:
1162480093f4SDimitry Andric case X86II::MRM0m:
1163480093f4SDimitry Andric case X86II::MRM1m:
1164480093f4SDimitry Andric case X86II::MRM2m:
1165480093f4SDimitry Andric case X86II::MRM3m:
1166480093f4SDimitry Andric case X86II::MRM4m:
1167480093f4SDimitry Andric case X86II::MRM5m:
1168480093f4SDimitry Andric case X86II::MRM6m:
1169480093f4SDimitry Andric case X86II::MRM7m: {
11700b57cec5SDimitry Andric // MRM[0-9]m instructions forms:
11710b57cec5SDimitry Andric // MemAddr
11720b57cec5SDimitry Andric // src1(VEX_4V), MemAddr
117306c3fb27SDimitry Andric if (HasVEX_4V)
117406c3fb27SDimitry Andric Prefix.set4VV2(MI, CurOp++);
11750b57cec5SDimitry Andric
11760b57cec5SDimitry Andric if (HasEVEX_K)
117706c3fb27SDimitry Andric Prefix.setAAA(MI, CurOp++);
11780b57cec5SDimitry Andric
11795f757f3fSDimitry Andric Prefix.setBB2(MI, MemOperand + X86::AddrBaseReg);
11805f757f3fSDimitry Andric Prefix.setXX2(MI, MemOperand + X86::AddrIndexReg);
11815f757f3fSDimitry Andric Prefix.setV2(MI, MemOperand + X86::AddrIndexReg, HasVEX_4V);
1182*0fca6ea1SDimitry Andric CurOp += X86::AddrNumOperands + 1; // Skip first imm.
1183*0fca6ea1SDimitry Andric if (HasTwoConditionalOps) {
1184*0fca6ea1SDimitry Andric Prefix.set4V(MI, CurOp++, /*IsImm=*/true);
1185*0fca6ea1SDimitry Andric Prefix.setSC(MI, CurOp++);
1186*0fca6ea1SDimitry Andric }
11870b57cec5SDimitry Andric break;
11880b57cec5SDimitry Andric }
1189*0fca6ea1SDimitry Andric case X86II::MRMSrcRegCC:
11900b57cec5SDimitry Andric case X86II::MRMSrcReg: {
11910b57cec5SDimitry Andric // MRMSrcReg instructions forms:
11920b57cec5SDimitry Andric // dst(ModR/M), src1(VEX_4V), src2(ModR/M), src3(Imm[7:4])
11930b57cec5SDimitry Andric // dst(ModR/M), src1(ModR/M)
11940b57cec5SDimitry Andric // dst(ModR/M), src1(ModR/M), imm8
11950b57cec5SDimitry Andric //
11960b57cec5SDimitry Andric // FMA4:
11970b57cec5SDimitry Andric // dst(ModR/M.reg), src1(VEX_4V), src2(Imm[7:4]), src3(ModR/M),
1198647cbc5dSDimitry Andric //
1199647cbc5dSDimitry Andric // NDD:
1200647cbc5dSDimitry Andric // dst(VEX_4V), src1(ModR/M.reg), src2(ModR/M)
1201647cbc5dSDimitry Andric if (IsND)
1202647cbc5dSDimitry Andric Prefix.set4VV2(MI, CurOp++);
120306c3fb27SDimitry Andric Prefix.setRR2(MI, CurOp++);
12040b57cec5SDimitry Andric
12050b57cec5SDimitry Andric if (HasEVEX_K)
120606c3fb27SDimitry Andric Prefix.setAAA(MI, CurOp++);
12070b57cec5SDimitry Andric
1208647cbc5dSDimitry Andric if (!IsND && HasVEX_4V)
120906c3fb27SDimitry Andric Prefix.set4VV2(MI, CurOp++);
12100b57cec5SDimitry Andric
12115f757f3fSDimitry Andric Prefix.setBB2(MI, CurOp);
121206c3fb27SDimitry Andric Prefix.setX(MI, CurOp, 4);
121306c3fb27SDimitry Andric ++CurOp;
12140b57cec5SDimitry Andric
1215*0fca6ea1SDimitry Andric if (HasTwoConditionalOps) {
1216*0fca6ea1SDimitry Andric Prefix.set4V(MI, CurOp++, /*IsImm=*/true);
1217*0fca6ea1SDimitry Andric Prefix.setSC(MI, CurOp++);
1218*0fca6ea1SDimitry Andric }
1219*0fca6ea1SDimitry Andric
122006c3fb27SDimitry Andric if (TSFlags & X86II::EVEX_B) {
12210b57cec5SDimitry Andric if (HasEVEX_RC) {
122206c3fb27SDimitry Andric unsigned NumOps = Desc.getNumOperands();
12230b57cec5SDimitry Andric unsigned RcOperand = NumOps - 1;
12240b57cec5SDimitry Andric assert(RcOperand >= CurOp);
12250b57cec5SDimitry Andric EVEX_rc = MI.getOperand(RcOperand).getImm();
12260b57cec5SDimitry Andric assert(EVEX_rc <= 3 && "Invalid rounding control!");
12270b57cec5SDimitry Andric }
12280b57cec5SDimitry Andric EncodeRC = true;
12290b57cec5SDimitry Andric }
12300b57cec5SDimitry Andric break;
12310b57cec5SDimitry Andric }
12320b57cec5SDimitry Andric case X86II::MRMSrcReg4VOp3: {
12330b57cec5SDimitry Andric // Instruction format for 4VOp3:
12340b57cec5SDimitry Andric // src1(ModR/M), src2(ModR/M), src3(VEX_4V)
12355f757f3fSDimitry Andric Prefix.setRR2(MI, CurOp++);
12365f757f3fSDimitry Andric Prefix.setBB2(MI, CurOp++);
12375f757f3fSDimitry Andric Prefix.set4VV2(MI, CurOp++);
12380b57cec5SDimitry Andric break;
12390b57cec5SDimitry Andric }
12400b57cec5SDimitry Andric case X86II::MRMSrcRegOp4: {
12410b57cec5SDimitry Andric // dst(ModR/M.reg), src1(VEX_4V), src2(Imm[7:4]), src3(ModR/M),
124206c3fb27SDimitry Andric Prefix.setR(MI, CurOp++);
124306c3fb27SDimitry Andric Prefix.set4V(MI, CurOp++);
12440b57cec5SDimitry Andric // Skip second register source (encoded in Imm[7:4])
12450b57cec5SDimitry Andric ++CurOp;
12460b57cec5SDimitry Andric
124706c3fb27SDimitry Andric Prefix.setB(MI, CurOp);
124806c3fb27SDimitry Andric Prefix.setX(MI, CurOp, 4);
124906c3fb27SDimitry Andric ++CurOp;
12500b57cec5SDimitry Andric break;
12510b57cec5SDimitry Andric }
1252*0fca6ea1SDimitry Andric case X86II::MRMDestRegCC:
12530b57cec5SDimitry Andric case X86II::MRMDestReg: {
12540b57cec5SDimitry Andric // MRMDestReg instructions forms:
12550b57cec5SDimitry Andric // dst(ModR/M), src(ModR/M)
12560b57cec5SDimitry Andric // dst(ModR/M), src(ModR/M), imm8
12570b57cec5SDimitry Andric // dst(ModR/M), src1(VEX_4V), src2(ModR/M)
1258647cbc5dSDimitry Andric //
1259647cbc5dSDimitry Andric // NDD:
1260647cbc5dSDimitry Andric // dst(VEX_4V), src1(ModR/M), src2(ModR/M)
1261647cbc5dSDimitry Andric if (IsND)
1262647cbc5dSDimitry Andric Prefix.set4VV2(MI, CurOp++);
12635f757f3fSDimitry Andric Prefix.setBB2(MI, CurOp);
126406c3fb27SDimitry Andric Prefix.setX(MI, CurOp, 4);
126506c3fb27SDimitry Andric ++CurOp;
12660b57cec5SDimitry Andric
12670b57cec5SDimitry Andric if (HasEVEX_K)
126806c3fb27SDimitry Andric Prefix.setAAA(MI, CurOp++);
12690b57cec5SDimitry Andric
1270647cbc5dSDimitry Andric if (!IsND && HasVEX_4V)
127106c3fb27SDimitry Andric Prefix.set4VV2(MI, CurOp++);
12720b57cec5SDimitry Andric
127306c3fb27SDimitry Andric Prefix.setRR2(MI, CurOp++);
1274*0fca6ea1SDimitry Andric if (HasTwoConditionalOps) {
1275*0fca6ea1SDimitry Andric Prefix.set4V(MI, CurOp++, /*IsImm=*/true);
1276*0fca6ea1SDimitry Andric Prefix.setSC(MI, CurOp++);
1277*0fca6ea1SDimitry Andric }
127806c3fb27SDimitry Andric if (TSFlags & X86II::EVEX_B)
12790b57cec5SDimitry Andric EncodeRC = true;
12800b57cec5SDimitry Andric break;
12810b57cec5SDimitry Andric }
12825ffd83dbSDimitry Andric case X86II::MRMr0: {
12835ffd83dbSDimitry Andric // MRMr0 instructions forms:
12845ffd83dbSDimitry Andric // 11:rrr:000
12855ffd83dbSDimitry Andric // dst(ModR/M)
128606c3fb27SDimitry Andric Prefix.setRR2(MI, CurOp++);
12875ffd83dbSDimitry Andric break;
12885ffd83dbSDimitry Andric }
1289*0fca6ea1SDimitry Andric case X86II::MRMXrCC:
1290480093f4SDimitry Andric case X86II::MRM0r:
1291480093f4SDimitry Andric case X86II::MRM1r:
1292480093f4SDimitry Andric case X86II::MRM2r:
1293480093f4SDimitry Andric case X86II::MRM3r:
1294480093f4SDimitry Andric case X86II::MRM4r:
1295480093f4SDimitry Andric case X86II::MRM5r:
1296480093f4SDimitry Andric case X86II::MRM6r:
1297480093f4SDimitry Andric case X86II::MRM7r: {
12980b57cec5SDimitry Andric // MRM0r-MRM7r instructions forms:
12990b57cec5SDimitry Andric // dst(VEX_4V), src(ModR/M), imm8
130006c3fb27SDimitry Andric if (HasVEX_4V)
130106c3fb27SDimitry Andric Prefix.set4VV2(MI, CurOp++);
13020b57cec5SDimitry Andric
130306c3fb27SDimitry Andric if (HasEVEX_K)
130406c3fb27SDimitry Andric Prefix.setAAA(MI, CurOp++);
130506c3fb27SDimitry Andric
13065f757f3fSDimitry Andric Prefix.setBB2(MI, CurOp);
130706c3fb27SDimitry Andric Prefix.setX(MI, CurOp, 4);
130806c3fb27SDimitry Andric ++CurOp;
1309*0fca6ea1SDimitry Andric if (HasTwoConditionalOps) {
1310*0fca6ea1SDimitry Andric Prefix.set4V(MI, ++CurOp, /*IsImm=*/true);
1311*0fca6ea1SDimitry Andric Prefix.setSC(MI, ++CurOp);
1312*0fca6ea1SDimitry Andric }
13130b57cec5SDimitry Andric break;
13140b57cec5SDimitry Andric }
13150b57cec5SDimitry Andric }
131606c3fb27SDimitry Andric if (EncodeRC) {
131706c3fb27SDimitry Andric Prefix.setL(EVEX_rc & 0x1);
131806c3fb27SDimitry Andric Prefix.setL2(EVEX_rc & 0x2);
13190b57cec5SDimitry Andric }
132006c3fb27SDimitry Andric PrefixKind Kind = Prefix.determineOptimalKind();
132106c3fb27SDimitry Andric Prefix.emit(CB);
132206c3fb27SDimitry Andric return Kind;
13230b57cec5SDimitry Andric }
13240b57cec5SDimitry Andric
13255ffd83dbSDimitry Andric /// Emit REX prefix which specifies
13265ffd83dbSDimitry Andric /// 1) 64-bit instructions,
13275ffd83dbSDimitry Andric /// 2) non-default operand size, and
13285ffd83dbSDimitry Andric /// 3) use of X86-64 extended registers.
13295ffd83dbSDimitry Andric ///
133006c3fb27SDimitry Andric /// \returns the used prefix (REX or None).
emitREXPrefix(int MemOperand,const MCInst & MI,const MCSubtargetInfo & STI,SmallVectorImpl<char> & CB) const133106c3fb27SDimitry Andric PrefixKind X86MCCodeEmitter::emitREXPrefix(int MemOperand, const MCInst &MI,
1332e8d8bef9SDimitry Andric const MCSubtargetInfo &STI,
133306c3fb27SDimitry Andric SmallVectorImpl<char> &CB) const {
133406c3fb27SDimitry Andric if (!STI.hasFeature(X86::Is64Bit))
133506c3fb27SDimitry Andric return None;
133606c3fb27SDimitry Andric X86OpcodePrefixHelper Prefix(*Ctx.getRegisterInfo());
13375ffd83dbSDimitry Andric const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
13385ffd83dbSDimitry Andric uint64_t TSFlags = Desc.TSFlags;
133906c3fb27SDimitry Andric Prefix.setW(TSFlags & X86II::REX_W);
13400b57cec5SDimitry Andric unsigned NumOps = MI.getNumOperands();
134106c3fb27SDimitry Andric bool UsesHighByteReg = false;
134206c3fb27SDimitry Andric #ifndef NDEBUG
134306c3fb27SDimitry Andric bool HasRegOp = false;
134406c3fb27SDimitry Andric #endif
134506c3fb27SDimitry Andric unsigned CurOp = NumOps ? X86II::getOperandBias(Desc) : 0;
13460b57cec5SDimitry Andric for (unsigned i = CurOp; i != NumOps; ++i) {
13470b57cec5SDimitry Andric const MCOperand &MO = MI.getOperand(i);
1348e8d8bef9SDimitry Andric if (MO.isReg()) {
134906c3fb27SDimitry Andric #ifndef NDEBUG
135006c3fb27SDimitry Andric HasRegOp = true;
135106c3fb27SDimitry Andric #endif
13520b57cec5SDimitry Andric unsigned Reg = MO.getReg();
135306c3fb27SDimitry Andric if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
13540b57cec5SDimitry Andric UsesHighByteReg = true;
135506c3fb27SDimitry Andric // If it accesses SPL, BPL, SIL, or DIL, then it requires a REX prefix.
13560b57cec5SDimitry Andric if (X86II::isX86_64NonExtLowByteReg(Reg))
135706c3fb27SDimitry Andric Prefix.setLowerBound(REX);
1358fe6060f1SDimitry Andric } else if (MO.isExpr() && STI.getTargetTriple().isX32()) {
1359e8d8bef9SDimitry Andric // GOTTPOFF and TLSDESC relocations require a REX prefix to allow
1360e8d8bef9SDimitry Andric // linker optimizations: even if the instructions we see may not require
1361e8d8bef9SDimitry Andric // any prefix, they may be replaced by instructions that do. This is
1362e8d8bef9SDimitry Andric // handled as a special case here so that it also works for hand-written
1363e8d8bef9SDimitry Andric // assembly without the user needing to write REX, as with GNU as.
1364e8d8bef9SDimitry Andric const auto *Ref = dyn_cast<MCSymbolRefExpr>(MO.getExpr());
1365e8d8bef9SDimitry Andric if (Ref && (Ref->getKind() == MCSymbolRefExpr::VK_GOTTPOFF ||
1366e8d8bef9SDimitry Andric Ref->getKind() == MCSymbolRefExpr::VK_TLSDESC)) {
136706c3fb27SDimitry Andric Prefix.setLowerBound(REX);
1368e8d8bef9SDimitry Andric }
1369e8d8bef9SDimitry Andric }
13700b57cec5SDimitry Andric }
1371*0fca6ea1SDimitry Andric if (MI.getFlags() & X86::IP_USE_REX)
1372*0fca6ea1SDimitry Andric Prefix.setLowerBound(REX);
1373*0fca6ea1SDimitry Andric if ((TSFlags & X86II::ExplicitOpPrefixMask) == X86II::ExplicitREX2Prefix ||
1374*0fca6ea1SDimitry Andric MI.getFlags() & X86::IP_USE_REX2)
13755f757f3fSDimitry Andric Prefix.setLowerBound(REX2);
13760b57cec5SDimitry Andric switch (TSFlags & X86II::FormMask) {
137706c3fb27SDimitry Andric default:
137806c3fb27SDimitry Andric assert(!HasRegOp && "Unexpected form in emitREXPrefix!");
137906c3fb27SDimitry Andric break;
138006c3fb27SDimitry Andric case X86II::RawFrm:
138106c3fb27SDimitry Andric case X86II::RawFrmMemOffs:
138206c3fb27SDimitry Andric case X86II::RawFrmSrc:
138306c3fb27SDimitry Andric case X86II::RawFrmDst:
138406c3fb27SDimitry Andric case X86II::RawFrmDstSrc:
138506c3fb27SDimitry Andric break;
13860b57cec5SDimitry Andric case X86II::AddRegFrm:
13875f757f3fSDimitry Andric Prefix.setBB2(MI, CurOp++);
13880b57cec5SDimitry Andric break;
13890b57cec5SDimitry Andric case X86II::MRMSrcReg:
13900b57cec5SDimitry Andric case X86II::MRMSrcRegCC:
13915f757f3fSDimitry Andric Prefix.setRR2(MI, CurOp++);
13925f757f3fSDimitry Andric Prefix.setBB2(MI, CurOp++);
13930b57cec5SDimitry Andric break;
13940b57cec5SDimitry Andric case X86II::MRMSrcMem:
13950b57cec5SDimitry Andric case X86II::MRMSrcMemCC:
13965f757f3fSDimitry Andric Prefix.setRR2(MI, CurOp++);
13975f757f3fSDimitry Andric Prefix.setBB2(MI, MemOperand + X86::AddrBaseReg);
13985f757f3fSDimitry Andric Prefix.setXX2(MI, MemOperand + X86::AddrIndexReg);
13990b57cec5SDimitry Andric CurOp += X86::AddrNumOperands;
14000b57cec5SDimitry Andric break;
14010b57cec5SDimitry Andric case X86II::MRMDestReg:
14025f757f3fSDimitry Andric Prefix.setBB2(MI, CurOp++);
14035f757f3fSDimitry Andric Prefix.setRR2(MI, CurOp++);
14040b57cec5SDimitry Andric break;
14050b57cec5SDimitry Andric case X86II::MRMDestMem:
14065f757f3fSDimitry Andric Prefix.setBB2(MI, MemOperand + X86::AddrBaseReg);
14075f757f3fSDimitry Andric Prefix.setXX2(MI, MemOperand + X86::AddrIndexReg);
14080b57cec5SDimitry Andric CurOp += X86::AddrNumOperands;
14095f757f3fSDimitry Andric Prefix.setRR2(MI, CurOp++);
14100b57cec5SDimitry Andric break;
1411480093f4SDimitry Andric case X86II::MRMXmCC:
1412480093f4SDimitry Andric case X86II::MRMXm:
1413480093f4SDimitry Andric case X86II::MRM0m:
1414480093f4SDimitry Andric case X86II::MRM1m:
1415480093f4SDimitry Andric case X86II::MRM2m:
1416480093f4SDimitry Andric case X86II::MRM3m:
1417480093f4SDimitry Andric case X86II::MRM4m:
1418480093f4SDimitry Andric case X86II::MRM5m:
1419480093f4SDimitry Andric case X86II::MRM6m:
1420480093f4SDimitry Andric case X86II::MRM7m:
14215f757f3fSDimitry Andric Prefix.setBB2(MI, MemOperand + X86::AddrBaseReg);
14225f757f3fSDimitry Andric Prefix.setXX2(MI, MemOperand + X86::AddrIndexReg);
14230b57cec5SDimitry Andric break;
1424480093f4SDimitry Andric case X86II::MRMXrCC:
1425480093f4SDimitry Andric case X86II::MRMXr:
1426480093f4SDimitry Andric case X86II::MRM0r:
1427480093f4SDimitry Andric case X86II::MRM1r:
1428480093f4SDimitry Andric case X86II::MRM2r:
1429480093f4SDimitry Andric case X86II::MRM3r:
1430480093f4SDimitry Andric case X86II::MRM4r:
1431480093f4SDimitry Andric case X86II::MRM5r:
1432480093f4SDimitry Andric case X86II::MRM6r:
1433480093f4SDimitry Andric case X86II::MRM7r:
14345f757f3fSDimitry Andric Prefix.setBB2(MI, CurOp++);
14350b57cec5SDimitry Andric break;
14360b57cec5SDimitry Andric }
14375f757f3fSDimitry Andric Prefix.setM((TSFlags & X86II::OpMapMask) == X86II::TB);
143806c3fb27SDimitry Andric PrefixKind Kind = Prefix.determineOptimalKind();
143906c3fb27SDimitry Andric if (Kind && UsesHighByteReg)
1440480093f4SDimitry Andric report_fatal_error(
1441480093f4SDimitry Andric "Cannot encode high byte register in REX-prefixed instruction");
144206c3fb27SDimitry Andric Prefix.emit(CB);
144306c3fb27SDimitry Andric return Kind;
14440b57cec5SDimitry Andric }
14450b57cec5SDimitry Andric
1446480093f4SDimitry Andric /// Emit segment override opcode prefix as needed.
emitSegmentOverridePrefix(unsigned SegOperand,const MCInst & MI,SmallVectorImpl<char> & CB) const144706c3fb27SDimitry Andric void X86MCCodeEmitter::emitSegmentOverridePrefix(
144806c3fb27SDimitry Andric unsigned SegOperand, const MCInst &MI, SmallVectorImpl<char> &CB) const {
14490b57cec5SDimitry Andric // Check for explicit segment override on memory operand.
14505ffd83dbSDimitry Andric if (unsigned Reg = MI.getOperand(SegOperand).getReg())
145106c3fb27SDimitry Andric emitByte(X86::getSegmentOverridePrefixForReg(Reg), CB);
14520b57cec5SDimitry Andric }
14530b57cec5SDimitry Andric
14540b57cec5SDimitry Andric /// Emit all instruction prefixes prior to the opcode.
14550b57cec5SDimitry Andric ///
1456480093f4SDimitry Andric /// \param MemOperand the operand # of the start of a memory operand if present.
1457480093f4SDimitry Andric /// If not present, it is -1.
14580b57cec5SDimitry Andric ///
145906c3fb27SDimitry Andric /// \returns the used prefix (REX or None).
emitOpcodePrefix(int MemOperand,const MCInst & MI,const MCSubtargetInfo & STI,SmallVectorImpl<char> & CB) const146006c3fb27SDimitry Andric PrefixKind X86MCCodeEmitter::emitOpcodePrefix(int MemOperand, const MCInst &MI,
14610b57cec5SDimitry Andric const MCSubtargetInfo &STI,
146206c3fb27SDimitry Andric SmallVectorImpl<char> &CB) const {
14635ffd83dbSDimitry Andric const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
14645ffd83dbSDimitry Andric uint64_t TSFlags = Desc.TSFlags;
14655ffd83dbSDimitry Andric
14660b57cec5SDimitry Andric // Emit the operand size opcode prefix as needed.
1467480093f4SDimitry Andric if ((TSFlags & X86II::OpSizeMask) ==
146881ad6265SDimitry Andric (STI.hasFeature(X86::Is16Bit) ? X86II::OpSize32 : X86II::OpSize16))
146906c3fb27SDimitry Andric emitByte(0x66, CB);
14700b57cec5SDimitry Andric
14710b57cec5SDimitry Andric // Emit the LOCK opcode prefix.
14720b57cec5SDimitry Andric if (TSFlags & X86II::LOCK || MI.getFlags() & X86::IP_HAS_LOCK)
147306c3fb27SDimitry Andric emitByte(0xF0, CB);
14740b57cec5SDimitry Andric
14750b57cec5SDimitry Andric // Emit the NOTRACK opcode prefix.
14760b57cec5SDimitry Andric if (TSFlags & X86II::NOTRACK || MI.getFlags() & X86::IP_HAS_NOTRACK)
147706c3fb27SDimitry Andric emitByte(0x3E, CB);
14780b57cec5SDimitry Andric
14790b57cec5SDimitry Andric switch (TSFlags & X86II::OpPrefixMask) {
14800b57cec5SDimitry Andric case X86II::PD: // 66
148106c3fb27SDimitry Andric emitByte(0x66, CB);
14820b57cec5SDimitry Andric break;
14830b57cec5SDimitry Andric case X86II::XS: // F3
148406c3fb27SDimitry Andric emitByte(0xF3, CB);
14850b57cec5SDimitry Andric break;
14860b57cec5SDimitry Andric case X86II::XD: // F2
148706c3fb27SDimitry Andric emitByte(0xF2, CB);
14880b57cec5SDimitry Andric break;
14890b57cec5SDimitry Andric }
14900b57cec5SDimitry Andric
14910b57cec5SDimitry Andric // Handle REX prefix.
149281ad6265SDimitry Andric assert((STI.hasFeature(X86::Is64Bit) || !(TSFlags & X86II::REX_W)) &&
14935ffd83dbSDimitry Andric "REX.W requires 64bit mode.");
149406c3fb27SDimitry Andric PrefixKind Kind = emitREXPrefix(MemOperand, MI, STI, CB);
14950b57cec5SDimitry Andric
14960b57cec5SDimitry Andric // 0x0F escape code must be emitted just before the opcode.
14970b57cec5SDimitry Andric switch (TSFlags & X86II::OpMapMask) {
14980b57cec5SDimitry Andric case X86II::TB: // Two-byte opcode map
14995f757f3fSDimitry Andric // Encoded by M bit in REX2
15005f757f3fSDimitry Andric if (Kind == REX2)
15015f757f3fSDimitry Andric break;
15025f757f3fSDimitry Andric [[fallthrough]];
15030b57cec5SDimitry Andric case X86II::T8: // 0F 38
15040b57cec5SDimitry Andric case X86II::TA: // 0F 3A
15050b57cec5SDimitry Andric case X86II::ThreeDNow: // 0F 0F, second 0F emitted by caller.
150606c3fb27SDimitry Andric emitByte(0x0F, CB);
15070b57cec5SDimitry Andric break;
15080b57cec5SDimitry Andric }
15090b57cec5SDimitry Andric
15100b57cec5SDimitry Andric switch (TSFlags & X86II::OpMapMask) {
15110b57cec5SDimitry Andric case X86II::T8: // 0F 38
151206c3fb27SDimitry Andric emitByte(0x38, CB);
15130b57cec5SDimitry Andric break;
15140b57cec5SDimitry Andric case X86II::TA: // 0F 3A
151506c3fb27SDimitry Andric emitByte(0x3A, CB);
15160b57cec5SDimitry Andric break;
15170b57cec5SDimitry Andric }
15185ffd83dbSDimitry Andric
151906c3fb27SDimitry Andric return Kind;
15200b57cec5SDimitry Andric }
15210b57cec5SDimitry Andric
emitPrefix(const MCInst & MI,SmallVectorImpl<char> & CB,const MCSubtargetInfo & STI) const152206c3fb27SDimitry Andric void X86MCCodeEmitter::emitPrefix(const MCInst &MI, SmallVectorImpl<char> &CB,
1523480093f4SDimitry Andric const MCSubtargetInfo &STI) const {
1524480093f4SDimitry Andric unsigned Opcode = MI.getOpcode();
1525480093f4SDimitry Andric const MCInstrDesc &Desc = MCII.get(Opcode);
1526480093f4SDimitry Andric uint64_t TSFlags = Desc.TSFlags;
1527480093f4SDimitry Andric
1528480093f4SDimitry Andric // Pseudo instructions don't get encoded.
15295ffd83dbSDimitry Andric if (X86II::isPseudo(TSFlags))
1530480093f4SDimitry Andric return;
1531480093f4SDimitry Andric
1532480093f4SDimitry Andric unsigned CurOp = X86II::getOperandBias(Desc);
1533480093f4SDimitry Andric
153406c3fb27SDimitry Andric emitPrefixImpl(CurOp, MI, STI, CB);
1535480093f4SDimitry Andric }
1536480093f4SDimitry Andric
emitPrefix(MCCodeEmitter & MCE,const MCInst & MI,SmallVectorImpl<char> & CB,const MCSubtargetInfo & STI)1537*0fca6ea1SDimitry Andric void X86_MC::emitPrefix(MCCodeEmitter &MCE, const MCInst &MI,
1538*0fca6ea1SDimitry Andric SmallVectorImpl<char> &CB, const MCSubtargetInfo &STI) {
1539*0fca6ea1SDimitry Andric static_cast<X86MCCodeEmitter &>(MCE).emitPrefix(MI, CB, STI);
1540*0fca6ea1SDimitry Andric }
1541*0fca6ea1SDimitry Andric
encodeInstruction(const MCInst & MI,SmallVectorImpl<char> & CB,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const154206c3fb27SDimitry Andric void X86MCCodeEmitter::encodeInstruction(const MCInst &MI,
154306c3fb27SDimitry Andric SmallVectorImpl<char> &CB,
15440b57cec5SDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
15450b57cec5SDimitry Andric const MCSubtargetInfo &STI) const {
15460b57cec5SDimitry Andric unsigned Opcode = MI.getOpcode();
15470b57cec5SDimitry Andric const MCInstrDesc &Desc = MCII.get(Opcode);
15480b57cec5SDimitry Andric uint64_t TSFlags = Desc.TSFlags;
15490b57cec5SDimitry Andric
15500b57cec5SDimitry Andric // Pseudo instructions don't get encoded.
15515ffd83dbSDimitry Andric if (X86II::isPseudo(TSFlags))
15520b57cec5SDimitry Andric return;
15530b57cec5SDimitry Andric
15540b57cec5SDimitry Andric unsigned NumOps = Desc.getNumOperands();
15550b57cec5SDimitry Andric unsigned CurOp = X86II::getOperandBias(Desc);
15560b57cec5SDimitry Andric
155706c3fb27SDimitry Andric uint64_t StartByte = CB.size();
15580b57cec5SDimitry Andric
155906c3fb27SDimitry Andric PrefixKind Kind = emitPrefixImpl(CurOp, MI, STI, CB);
15600b57cec5SDimitry Andric
15610b57cec5SDimitry Andric // It uses the VEX.VVVV field?
15620b57cec5SDimitry Andric bool HasVEX_4V = TSFlags & X86II::VEX_4V;
15630b57cec5SDimitry Andric bool HasVEX_I8Reg = (TSFlags & X86II::ImmMask) == X86II::Imm8Reg;
15640b57cec5SDimitry Andric
15650b57cec5SDimitry Andric // It uses the EVEX.aaa field?
15660b57cec5SDimitry Andric bool HasEVEX_K = TSFlags & X86II::EVEX_K;
15670b57cec5SDimitry Andric bool HasEVEX_RC = TSFlags & X86II::EVEX_RC;
15680b57cec5SDimitry Andric
15690b57cec5SDimitry Andric // Used if a register is encoded in 7:4 of immediate.
15700b57cec5SDimitry Andric unsigned I8RegNum = 0;
15710b57cec5SDimitry Andric
15720b57cec5SDimitry Andric uint8_t BaseOpcode = X86II::getBaseOpcodeFor(TSFlags);
15730b57cec5SDimitry Andric
15740b57cec5SDimitry Andric if ((TSFlags & X86II::OpMapMask) == X86II::ThreeDNow)
15750b57cec5SDimitry Andric BaseOpcode = 0x0F; // Weird 3DNow! encoding.
15760b57cec5SDimitry Andric
15770b57cec5SDimitry Andric unsigned OpcodeOffset = 0;
15780b57cec5SDimitry Andric
1579647cbc5dSDimitry Andric bool IsND = X86II::hasNewDataDest(TSFlags);
1580*0fca6ea1SDimitry Andric bool HasTwoConditionalOps = TSFlags & X86II::TwoConditionalOps;
1581647cbc5dSDimitry Andric
15820b57cec5SDimitry Andric uint64_t Form = TSFlags & X86II::FormMask;
15830b57cec5SDimitry Andric switch (Form) {
1584480093f4SDimitry Andric default:
1585480093f4SDimitry Andric errs() << "FORM: " << Form << "\n";
15860b57cec5SDimitry Andric llvm_unreachable("Unknown FormMask value in X86MCCodeEmitter!");
15870b57cec5SDimitry Andric case X86II::Pseudo:
15880b57cec5SDimitry Andric llvm_unreachable("Pseudo instruction shouldn't be emitted");
1589480093f4SDimitry Andric case X86II::RawFrmDstSrc:
1590480093f4SDimitry Andric case X86II::RawFrmSrc:
1591480093f4SDimitry Andric case X86II::RawFrmDst:
15925ffd83dbSDimitry Andric case X86II::PrefixByte:
159306c3fb27SDimitry Andric emitByte(BaseOpcode, CB);
15940b57cec5SDimitry Andric break;
15950b57cec5SDimitry Andric case X86II::AddCCFrm: {
15960b57cec5SDimitry Andric // This will be added to the opcode in the fallthrough.
15970b57cec5SDimitry Andric OpcodeOffset = MI.getOperand(NumOps - 1).getImm();
15980b57cec5SDimitry Andric assert(OpcodeOffset < 16 && "Unexpected opcode offset!");
15990b57cec5SDimitry Andric --NumOps; // Drop the operand from the end.
1600bdd1243dSDimitry Andric [[fallthrough]];
16010b57cec5SDimitry Andric case X86II::RawFrm:
160206c3fb27SDimitry Andric emitByte(BaseOpcode + OpcodeOffset, CB);
16030b57cec5SDimitry Andric
160481ad6265SDimitry Andric if (!STI.hasFeature(X86::Is64Bit) || !isPCRel32Branch(MI, MCII))
16050b57cec5SDimitry Andric break;
16060b57cec5SDimitry Andric
16070b57cec5SDimitry Andric const MCOperand &Op = MI.getOperand(CurOp++);
1608480093f4SDimitry Andric emitImmediate(Op, MI.getLoc(), X86II::getSizeOfImm(TSFlags),
160906c3fb27SDimitry Andric MCFixupKind(X86::reloc_branch_4byte_pcrel), StartByte, CB,
16100b57cec5SDimitry Andric Fixups);
16110b57cec5SDimitry Andric break;
16120b57cec5SDimitry Andric }
16130b57cec5SDimitry Andric case X86II::RawFrmMemOffs:
161406c3fb27SDimitry Andric emitByte(BaseOpcode, CB);
1615480093f4SDimitry Andric emitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
16160b57cec5SDimitry Andric X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
161706c3fb27SDimitry Andric StartByte, CB, Fixups);
16180b57cec5SDimitry Andric ++CurOp; // skip segment operand
16190b57cec5SDimitry Andric break;
16200b57cec5SDimitry Andric case X86II::RawFrmImm8:
162106c3fb27SDimitry Andric emitByte(BaseOpcode, CB);
1622480093f4SDimitry Andric emitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
16230b57cec5SDimitry Andric X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
162406c3fb27SDimitry Andric StartByte, CB, Fixups);
16255ffd83dbSDimitry Andric emitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1, FK_Data_1, StartByte,
162606c3fb27SDimitry Andric CB, Fixups);
16270b57cec5SDimitry Andric break;
16280b57cec5SDimitry Andric case X86II::RawFrmImm16:
162906c3fb27SDimitry Andric emitByte(BaseOpcode, CB);
1630480093f4SDimitry Andric emitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
16310b57cec5SDimitry Andric X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
163206c3fb27SDimitry Andric StartByte, CB, Fixups);
16335ffd83dbSDimitry Andric emitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 2, FK_Data_2, StartByte,
163406c3fb27SDimitry Andric CB, Fixups);
16350b57cec5SDimitry Andric break;
16360b57cec5SDimitry Andric
16370b57cec5SDimitry Andric case X86II::AddRegFrm:
163806c3fb27SDimitry Andric emitByte(BaseOpcode + getX86RegNum(MI.getOperand(CurOp++)), CB);
16390b57cec5SDimitry Andric break;
16400b57cec5SDimitry Andric
16410b57cec5SDimitry Andric case X86II::MRMDestReg: {
164206c3fb27SDimitry Andric emitByte(BaseOpcode, CB);
16430b57cec5SDimitry Andric unsigned SrcRegNum = CurOp + 1;
16440b57cec5SDimitry Andric
16450b57cec5SDimitry Andric if (HasEVEX_K) // Skip writemask
16460b57cec5SDimitry Andric ++SrcRegNum;
16470b57cec5SDimitry Andric
16480b57cec5SDimitry Andric if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV)
16490b57cec5SDimitry Andric ++SrcRegNum;
1650647cbc5dSDimitry Andric if (IsND) // Skip the NDD operand encoded in EVEX_VVVV
1651647cbc5dSDimitry Andric ++CurOp;
16520b57cec5SDimitry Andric
1653480093f4SDimitry Andric emitRegModRMByte(MI.getOperand(CurOp),
165406c3fb27SDimitry Andric getX86RegNum(MI.getOperand(SrcRegNum)), CB);
16550b57cec5SDimitry Andric CurOp = SrcRegNum + 1;
16560b57cec5SDimitry Andric break;
16570b57cec5SDimitry Andric }
1658*0fca6ea1SDimitry Andric case X86II::MRMDestRegCC: {
1659*0fca6ea1SDimitry Andric unsigned FirstOp = CurOp++;
1660*0fca6ea1SDimitry Andric unsigned SecondOp = CurOp++;
1661*0fca6ea1SDimitry Andric unsigned CC = MI.getOperand(CurOp++).getImm();
1662*0fca6ea1SDimitry Andric emitByte(BaseOpcode + CC, CB);
1663*0fca6ea1SDimitry Andric emitRegModRMByte(MI.getOperand(FirstOp),
1664*0fca6ea1SDimitry Andric getX86RegNum(MI.getOperand(SecondOp)), CB);
1665*0fca6ea1SDimitry Andric break;
1666*0fca6ea1SDimitry Andric }
1667bdd1243dSDimitry Andric case X86II::MRMDestMem4VOp3CC: {
1668bdd1243dSDimitry Andric unsigned CC = MI.getOperand(8).getImm();
166906c3fb27SDimitry Andric emitByte(BaseOpcode + CC, CB);
1670bdd1243dSDimitry Andric unsigned SrcRegNum = CurOp + X86::AddrNumOperands;
1671bdd1243dSDimitry Andric emitMemModRMByte(MI, CurOp + 1, getX86RegNum(MI.getOperand(0)), TSFlags,
167206c3fb27SDimitry Andric Kind, StartByte, CB, Fixups, STI, false);
1673bdd1243dSDimitry Andric CurOp = SrcRegNum + 3; // skip reg, VEX_V4 and CC
1674bdd1243dSDimitry Andric break;
1675bdd1243dSDimitry Andric }
16765ffd83dbSDimitry Andric case X86II::MRMDestMemFSIB:
16770b57cec5SDimitry Andric case X86II::MRMDestMem: {
167806c3fb27SDimitry Andric emitByte(BaseOpcode, CB);
16790b57cec5SDimitry Andric unsigned SrcRegNum = CurOp + X86::AddrNumOperands;
16800b57cec5SDimitry Andric
16810b57cec5SDimitry Andric if (HasEVEX_K) // Skip writemask
16820b57cec5SDimitry Andric ++SrcRegNum;
16830b57cec5SDimitry Andric
16840b57cec5SDimitry Andric if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV)
16850b57cec5SDimitry Andric ++SrcRegNum;
16860b57cec5SDimitry Andric
1687647cbc5dSDimitry Andric if (IsND) // Skip new data destination
1688647cbc5dSDimitry Andric ++CurOp;
1689647cbc5dSDimitry Andric
16905ffd83dbSDimitry Andric bool ForceSIB = (Form == X86II::MRMDestMemFSIB);
1691480093f4SDimitry Andric emitMemModRMByte(MI, CurOp, getX86RegNum(MI.getOperand(SrcRegNum)), TSFlags,
169206c3fb27SDimitry Andric Kind, StartByte, CB, Fixups, STI, ForceSIB);
16930b57cec5SDimitry Andric CurOp = SrcRegNum + 1;
16940b57cec5SDimitry Andric break;
16950b57cec5SDimitry Andric }
1696*0fca6ea1SDimitry Andric case X86II::MRMDestMemCC: {
1697*0fca6ea1SDimitry Andric unsigned MemOp = CurOp;
1698*0fca6ea1SDimitry Andric CurOp = MemOp + X86::AddrNumOperands;
1699*0fca6ea1SDimitry Andric unsigned RegOp = CurOp++;
1700*0fca6ea1SDimitry Andric unsigned CC = MI.getOperand(CurOp++).getImm();
1701*0fca6ea1SDimitry Andric emitByte(BaseOpcode + CC, CB);
1702*0fca6ea1SDimitry Andric emitMemModRMByte(MI, MemOp, getX86RegNum(MI.getOperand(RegOp)), TSFlags,
1703*0fca6ea1SDimitry Andric Kind, StartByte, CB, Fixups, STI);
1704*0fca6ea1SDimitry Andric break;
1705*0fca6ea1SDimitry Andric }
17060b57cec5SDimitry Andric case X86II::MRMSrcReg: {
170706c3fb27SDimitry Andric emitByte(BaseOpcode, CB);
17080b57cec5SDimitry Andric unsigned SrcRegNum = CurOp + 1;
17090b57cec5SDimitry Andric
17100b57cec5SDimitry Andric if (HasEVEX_K) // Skip writemask
17110b57cec5SDimitry Andric ++SrcRegNum;
17120b57cec5SDimitry Andric
17130b57cec5SDimitry Andric if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV)
17140b57cec5SDimitry Andric ++SrcRegNum;
17150b57cec5SDimitry Andric
17161db9f3b2SDimitry Andric if (IsND) // Skip new data destination
17171db9f3b2SDimitry Andric ++CurOp;
17181db9f3b2SDimitry Andric
1719480093f4SDimitry Andric emitRegModRMByte(MI.getOperand(SrcRegNum),
172006c3fb27SDimitry Andric getX86RegNum(MI.getOperand(CurOp)), CB);
17210b57cec5SDimitry Andric CurOp = SrcRegNum + 1;
17220b57cec5SDimitry Andric if (HasVEX_I8Reg)
17230b57cec5SDimitry Andric I8RegNum = getX86RegEncoding(MI, CurOp++);
17240b57cec5SDimitry Andric // do not count the rounding control operand
17250b57cec5SDimitry Andric if (HasEVEX_RC)
17260b57cec5SDimitry Andric --NumOps;
17270b57cec5SDimitry Andric break;
17280b57cec5SDimitry Andric }
17290b57cec5SDimitry Andric case X86II::MRMSrcReg4VOp3: {
173006c3fb27SDimitry Andric emitByte(BaseOpcode, CB);
17310b57cec5SDimitry Andric unsigned SrcRegNum = CurOp + 1;
17320b57cec5SDimitry Andric
1733480093f4SDimitry Andric emitRegModRMByte(MI.getOperand(SrcRegNum),
173406c3fb27SDimitry Andric getX86RegNum(MI.getOperand(CurOp)), CB);
17350b57cec5SDimitry Andric CurOp = SrcRegNum + 1;
17360b57cec5SDimitry Andric ++CurOp; // Encoded in VEX.VVVV
17370b57cec5SDimitry Andric break;
17380b57cec5SDimitry Andric }
17390b57cec5SDimitry Andric case X86II::MRMSrcRegOp4: {
174006c3fb27SDimitry Andric emitByte(BaseOpcode, CB);
17410b57cec5SDimitry Andric unsigned SrcRegNum = CurOp + 1;
17420b57cec5SDimitry Andric
17430b57cec5SDimitry Andric // Skip 1st src (which is encoded in VEX_VVVV)
17440b57cec5SDimitry Andric ++SrcRegNum;
17450b57cec5SDimitry Andric
17460b57cec5SDimitry Andric // Capture 2nd src (which is encoded in Imm[7:4])
17470b57cec5SDimitry Andric assert(HasVEX_I8Reg && "MRMSrcRegOp4 should imply VEX_I8Reg");
17480b57cec5SDimitry Andric I8RegNum = getX86RegEncoding(MI, SrcRegNum++);
17490b57cec5SDimitry Andric
1750480093f4SDimitry Andric emitRegModRMByte(MI.getOperand(SrcRegNum),
175106c3fb27SDimitry Andric getX86RegNum(MI.getOperand(CurOp)), CB);
17520b57cec5SDimitry Andric CurOp = SrcRegNum + 1;
17530b57cec5SDimitry Andric break;
17540b57cec5SDimitry Andric }
17550b57cec5SDimitry Andric case X86II::MRMSrcRegCC: {
1756*0fca6ea1SDimitry Andric if (IsND) // Skip new data destination
1757*0fca6ea1SDimitry Andric ++CurOp;
17580b57cec5SDimitry Andric unsigned FirstOp = CurOp++;
17590b57cec5SDimitry Andric unsigned SecondOp = CurOp++;
17600b57cec5SDimitry Andric
17610b57cec5SDimitry Andric unsigned CC = MI.getOperand(CurOp++).getImm();
176206c3fb27SDimitry Andric emitByte(BaseOpcode + CC, CB);
17630b57cec5SDimitry Andric
1764480093f4SDimitry Andric emitRegModRMByte(MI.getOperand(SecondOp),
176506c3fb27SDimitry Andric getX86RegNum(MI.getOperand(FirstOp)), CB);
17660b57cec5SDimitry Andric break;
17670b57cec5SDimitry Andric }
17685ffd83dbSDimitry Andric case X86II::MRMSrcMemFSIB:
17690b57cec5SDimitry Andric case X86II::MRMSrcMem: {
17700b57cec5SDimitry Andric unsigned FirstMemOp = CurOp + 1;
17710b57cec5SDimitry Andric
1772647cbc5dSDimitry Andric if (IsND) // Skip new data destination
1773647cbc5dSDimitry Andric CurOp++;
1774647cbc5dSDimitry Andric
17750b57cec5SDimitry Andric if (HasEVEX_K) // Skip writemask
17760b57cec5SDimitry Andric ++FirstMemOp;
17770b57cec5SDimitry Andric
17780b57cec5SDimitry Andric if (HasVEX_4V)
17790b57cec5SDimitry Andric ++FirstMemOp; // Skip the register source (which is encoded in VEX_VVVV).
17800b57cec5SDimitry Andric
178106c3fb27SDimitry Andric emitByte(BaseOpcode, CB);
17820b57cec5SDimitry Andric
17835ffd83dbSDimitry Andric bool ForceSIB = (Form == X86II::MRMSrcMemFSIB);
1784480093f4SDimitry Andric emitMemModRMByte(MI, FirstMemOp, getX86RegNum(MI.getOperand(CurOp)),
178506c3fb27SDimitry Andric TSFlags, Kind, StartByte, CB, Fixups, STI, ForceSIB);
17860b57cec5SDimitry Andric CurOp = FirstMemOp + X86::AddrNumOperands;
17870b57cec5SDimitry Andric if (HasVEX_I8Reg)
17880b57cec5SDimitry Andric I8RegNum = getX86RegEncoding(MI, CurOp++);
17890b57cec5SDimitry Andric break;
17900b57cec5SDimitry Andric }
17910b57cec5SDimitry Andric case X86II::MRMSrcMem4VOp3: {
17920b57cec5SDimitry Andric unsigned FirstMemOp = CurOp + 1;
17930b57cec5SDimitry Andric
179406c3fb27SDimitry Andric emitByte(BaseOpcode, CB);
17950b57cec5SDimitry Andric
1796480093f4SDimitry Andric emitMemModRMByte(MI, FirstMemOp, getX86RegNum(MI.getOperand(CurOp)),
179706c3fb27SDimitry Andric TSFlags, Kind, StartByte, CB, Fixups, STI);
17980b57cec5SDimitry Andric CurOp = FirstMemOp + X86::AddrNumOperands;
17990b57cec5SDimitry Andric ++CurOp; // Encoded in VEX.VVVV.
18000b57cec5SDimitry Andric break;
18010b57cec5SDimitry Andric }
18020b57cec5SDimitry Andric case X86II::MRMSrcMemOp4: {
18030b57cec5SDimitry Andric unsigned FirstMemOp = CurOp + 1;
18040b57cec5SDimitry Andric
18050b57cec5SDimitry Andric ++FirstMemOp; // Skip the register source (which is encoded in VEX_VVVV).
18060b57cec5SDimitry Andric
18070b57cec5SDimitry Andric // Capture second register source (encoded in Imm[7:4])
18080b57cec5SDimitry Andric assert(HasVEX_I8Reg && "MRMSrcRegOp4 should imply VEX_I8Reg");
18090b57cec5SDimitry Andric I8RegNum = getX86RegEncoding(MI, FirstMemOp++);
18100b57cec5SDimitry Andric
181106c3fb27SDimitry Andric emitByte(BaseOpcode, CB);
18120b57cec5SDimitry Andric
1813480093f4SDimitry Andric emitMemModRMByte(MI, FirstMemOp, getX86RegNum(MI.getOperand(CurOp)),
181406c3fb27SDimitry Andric TSFlags, Kind, StartByte, CB, Fixups, STI);
18150b57cec5SDimitry Andric CurOp = FirstMemOp + X86::AddrNumOperands;
18160b57cec5SDimitry Andric break;
18170b57cec5SDimitry Andric }
18180b57cec5SDimitry Andric case X86II::MRMSrcMemCC: {
1819*0fca6ea1SDimitry Andric if (IsND) // Skip new data destination
1820*0fca6ea1SDimitry Andric ++CurOp;
18210b57cec5SDimitry Andric unsigned RegOp = CurOp++;
18220b57cec5SDimitry Andric unsigned FirstMemOp = CurOp;
18230b57cec5SDimitry Andric CurOp = FirstMemOp + X86::AddrNumOperands;
18240b57cec5SDimitry Andric
18250b57cec5SDimitry Andric unsigned CC = MI.getOperand(CurOp++).getImm();
182606c3fb27SDimitry Andric emitByte(BaseOpcode + CC, CB);
18270b57cec5SDimitry Andric
1828480093f4SDimitry Andric emitMemModRMByte(MI, FirstMemOp, getX86RegNum(MI.getOperand(RegOp)),
182906c3fb27SDimitry Andric TSFlags, Kind, StartByte, CB, Fixups, STI);
18300b57cec5SDimitry Andric break;
18310b57cec5SDimitry Andric }
18320b57cec5SDimitry Andric
18330b57cec5SDimitry Andric case X86II::MRMXrCC: {
18340b57cec5SDimitry Andric unsigned RegOp = CurOp++;
18350b57cec5SDimitry Andric
18360b57cec5SDimitry Andric unsigned CC = MI.getOperand(CurOp++).getImm();
183706c3fb27SDimitry Andric emitByte(BaseOpcode + CC, CB);
183806c3fb27SDimitry Andric emitRegModRMByte(MI.getOperand(RegOp), 0, CB);
18390b57cec5SDimitry Andric break;
18400b57cec5SDimitry Andric }
18410b57cec5SDimitry Andric
18420b57cec5SDimitry Andric case X86II::MRMXr:
1843480093f4SDimitry Andric case X86II::MRM0r:
1844480093f4SDimitry Andric case X86II::MRM1r:
1845480093f4SDimitry Andric case X86II::MRM2r:
1846480093f4SDimitry Andric case X86II::MRM3r:
1847480093f4SDimitry Andric case X86II::MRM4r:
1848480093f4SDimitry Andric case X86II::MRM5r:
1849480093f4SDimitry Andric case X86II::MRM6r:
1850480093f4SDimitry Andric case X86II::MRM7r:
18510b57cec5SDimitry Andric if (HasVEX_4V) // Skip the register dst (which is encoded in VEX_VVVV).
18520b57cec5SDimitry Andric ++CurOp;
18530b57cec5SDimitry Andric if (HasEVEX_K) // Skip writemask
18540b57cec5SDimitry Andric ++CurOp;
185506c3fb27SDimitry Andric emitByte(BaseOpcode, CB);
1856480093f4SDimitry Andric emitRegModRMByte(MI.getOperand(CurOp++),
185706c3fb27SDimitry Andric (Form == X86II::MRMXr) ? 0 : Form - X86II::MRM0r, CB);
18585ffd83dbSDimitry Andric break;
18595ffd83dbSDimitry Andric case X86II::MRMr0:
186006c3fb27SDimitry Andric emitByte(BaseOpcode, CB);
186106c3fb27SDimitry Andric emitByte(modRMByte(3, getX86RegNum(MI.getOperand(CurOp++)), 0), CB);
18620b57cec5SDimitry Andric break;
18630b57cec5SDimitry Andric
18640b57cec5SDimitry Andric case X86II::MRMXmCC: {
18650b57cec5SDimitry Andric unsigned FirstMemOp = CurOp;
18660b57cec5SDimitry Andric CurOp = FirstMemOp + X86::AddrNumOperands;
18670b57cec5SDimitry Andric
18680b57cec5SDimitry Andric unsigned CC = MI.getOperand(CurOp++).getImm();
186906c3fb27SDimitry Andric emitByte(BaseOpcode + CC, CB);
18700b57cec5SDimitry Andric
187106c3fb27SDimitry Andric emitMemModRMByte(MI, FirstMemOp, 0, TSFlags, Kind, StartByte, CB, Fixups,
18725ffd83dbSDimitry Andric STI);
18730b57cec5SDimitry Andric break;
18740b57cec5SDimitry Andric }
18750b57cec5SDimitry Andric
18760b57cec5SDimitry Andric case X86II::MRMXm:
1877480093f4SDimitry Andric case X86II::MRM0m:
1878480093f4SDimitry Andric case X86II::MRM1m:
1879480093f4SDimitry Andric case X86II::MRM2m:
1880480093f4SDimitry Andric case X86II::MRM3m:
1881480093f4SDimitry Andric case X86II::MRM4m:
1882480093f4SDimitry Andric case X86II::MRM5m:
1883480093f4SDimitry Andric case X86II::MRM6m:
1884480093f4SDimitry Andric case X86II::MRM7m:
18850b57cec5SDimitry Andric if (HasVEX_4V) // Skip the register dst (which is encoded in VEX_VVVV).
18860b57cec5SDimitry Andric ++CurOp;
18870b57cec5SDimitry Andric if (HasEVEX_K) // Skip writemask
18880b57cec5SDimitry Andric ++CurOp;
188906c3fb27SDimitry Andric emitByte(BaseOpcode, CB);
18900b57cec5SDimitry Andric emitMemModRMByte(MI, CurOp,
18910b57cec5SDimitry Andric (Form == X86II::MRMXm) ? 0 : Form - X86II::MRM0m, TSFlags,
189206c3fb27SDimitry Andric Kind, StartByte, CB, Fixups, STI);
18930b57cec5SDimitry Andric CurOp += X86::AddrNumOperands;
18940b57cec5SDimitry Andric break;
18950b57cec5SDimitry Andric
18965ffd83dbSDimitry Andric case X86II::MRM0X:
18975ffd83dbSDimitry Andric case X86II::MRM1X:
18985ffd83dbSDimitry Andric case X86II::MRM2X:
18995ffd83dbSDimitry Andric case X86II::MRM3X:
19005ffd83dbSDimitry Andric case X86II::MRM4X:
19015ffd83dbSDimitry Andric case X86II::MRM5X:
19025ffd83dbSDimitry Andric case X86II::MRM6X:
19035ffd83dbSDimitry Andric case X86II::MRM7X:
190406c3fb27SDimitry Andric emitByte(BaseOpcode, CB);
190506c3fb27SDimitry Andric emitByte(0xC0 + ((Form - X86II::MRM0X) << 3), CB);
19065ffd83dbSDimitry Andric break;
19075ffd83dbSDimitry Andric
1908480093f4SDimitry Andric case X86II::MRM_C0:
1909480093f4SDimitry Andric case X86II::MRM_C1:
1910480093f4SDimitry Andric case X86II::MRM_C2:
1911480093f4SDimitry Andric case X86II::MRM_C3:
1912480093f4SDimitry Andric case X86II::MRM_C4:
1913480093f4SDimitry Andric case X86II::MRM_C5:
1914480093f4SDimitry Andric case X86II::MRM_C6:
1915480093f4SDimitry Andric case X86II::MRM_C7:
1916480093f4SDimitry Andric case X86II::MRM_C8:
1917480093f4SDimitry Andric case X86II::MRM_C9:
1918480093f4SDimitry Andric case X86II::MRM_CA:
1919480093f4SDimitry Andric case X86II::MRM_CB:
1920480093f4SDimitry Andric case X86II::MRM_CC:
1921480093f4SDimitry Andric case X86II::MRM_CD:
1922480093f4SDimitry Andric case X86II::MRM_CE:
1923480093f4SDimitry Andric case X86II::MRM_CF:
1924480093f4SDimitry Andric case X86II::MRM_D0:
1925480093f4SDimitry Andric case X86II::MRM_D1:
1926480093f4SDimitry Andric case X86II::MRM_D2:
1927480093f4SDimitry Andric case X86II::MRM_D3:
1928480093f4SDimitry Andric case X86II::MRM_D4:
1929480093f4SDimitry Andric case X86II::MRM_D5:
1930480093f4SDimitry Andric case X86II::MRM_D6:
1931480093f4SDimitry Andric case X86II::MRM_D7:
1932480093f4SDimitry Andric case X86II::MRM_D8:
1933480093f4SDimitry Andric case X86II::MRM_D9:
1934480093f4SDimitry Andric case X86II::MRM_DA:
1935480093f4SDimitry Andric case X86II::MRM_DB:
1936480093f4SDimitry Andric case X86II::MRM_DC:
1937480093f4SDimitry Andric case X86II::MRM_DD:
1938480093f4SDimitry Andric case X86II::MRM_DE:
1939480093f4SDimitry Andric case X86II::MRM_DF:
1940480093f4SDimitry Andric case X86II::MRM_E0:
1941480093f4SDimitry Andric case X86II::MRM_E1:
1942480093f4SDimitry Andric case X86II::MRM_E2:
1943480093f4SDimitry Andric case X86II::MRM_E3:
1944480093f4SDimitry Andric case X86II::MRM_E4:
1945480093f4SDimitry Andric case X86II::MRM_E5:
1946480093f4SDimitry Andric case X86II::MRM_E6:
1947480093f4SDimitry Andric case X86II::MRM_E7:
1948480093f4SDimitry Andric case X86II::MRM_E8:
1949480093f4SDimitry Andric case X86II::MRM_E9:
1950480093f4SDimitry Andric case X86II::MRM_EA:
1951480093f4SDimitry Andric case X86II::MRM_EB:
1952480093f4SDimitry Andric case X86II::MRM_EC:
1953480093f4SDimitry Andric case X86II::MRM_ED:
1954480093f4SDimitry Andric case X86II::MRM_EE:
1955480093f4SDimitry Andric case X86II::MRM_EF:
1956480093f4SDimitry Andric case X86II::MRM_F0:
1957480093f4SDimitry Andric case X86II::MRM_F1:
1958480093f4SDimitry Andric case X86II::MRM_F2:
1959480093f4SDimitry Andric case X86II::MRM_F3:
1960480093f4SDimitry Andric case X86II::MRM_F4:
1961480093f4SDimitry Andric case X86II::MRM_F5:
1962480093f4SDimitry Andric case X86II::MRM_F6:
1963480093f4SDimitry Andric case X86II::MRM_F7:
1964480093f4SDimitry Andric case X86II::MRM_F8:
1965480093f4SDimitry Andric case X86II::MRM_F9:
1966480093f4SDimitry Andric case X86II::MRM_FA:
1967480093f4SDimitry Andric case X86II::MRM_FB:
1968480093f4SDimitry Andric case X86II::MRM_FC:
1969480093f4SDimitry Andric case X86II::MRM_FD:
1970480093f4SDimitry Andric case X86II::MRM_FE:
19710b57cec5SDimitry Andric case X86II::MRM_FF:
197206c3fb27SDimitry Andric emitByte(BaseOpcode, CB);
197306c3fb27SDimitry Andric emitByte(0xC0 + Form - X86II::MRM_C0, CB);
19740b57cec5SDimitry Andric break;
19750b57cec5SDimitry Andric }
19760b57cec5SDimitry Andric
19770b57cec5SDimitry Andric if (HasVEX_I8Reg) {
19780b57cec5SDimitry Andric // The last source register of a 4 operand instruction in AVX is encoded
19790b57cec5SDimitry Andric // in bits[7:4] of a immediate byte.
19800b57cec5SDimitry Andric assert(I8RegNum < 16 && "Register encoding out of range");
19810b57cec5SDimitry Andric I8RegNum <<= 4;
19820b57cec5SDimitry Andric if (CurOp != NumOps) {
19830b57cec5SDimitry Andric unsigned Val = MI.getOperand(CurOp++).getImm();
19840b57cec5SDimitry Andric assert(Val < 16 && "Immediate operand value out of range");
19850b57cec5SDimitry Andric I8RegNum |= Val;
19860b57cec5SDimitry Andric }
1987480093f4SDimitry Andric emitImmediate(MCOperand::createImm(I8RegNum), MI.getLoc(), 1, FK_Data_1,
198806c3fb27SDimitry Andric StartByte, CB, Fixups);
19890b57cec5SDimitry Andric } else {
19900b57cec5SDimitry Andric // If there is a remaining operand, it must be a trailing immediate. Emit it
19910b57cec5SDimitry Andric // according to the right size for the instruction. Some instructions
19920b57cec5SDimitry Andric // (SSE4a extrq and insertq) have two trailing immediates.
1993*0fca6ea1SDimitry Andric
1994*0fca6ea1SDimitry Andric // Skip two trainling conditional operands encoded in EVEX prefix
1995*0fca6ea1SDimitry Andric unsigned RemaningOps = NumOps - CurOp - 2 * HasTwoConditionalOps;
1996*0fca6ea1SDimitry Andric while (RemaningOps) {
1997480093f4SDimitry Andric emitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
19980b57cec5SDimitry Andric X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
199906c3fb27SDimitry Andric StartByte, CB, Fixups);
2000*0fca6ea1SDimitry Andric --RemaningOps;
20010b57cec5SDimitry Andric }
2002*0fca6ea1SDimitry Andric CurOp += 2 * HasTwoConditionalOps;
20030b57cec5SDimitry Andric }
20040b57cec5SDimitry Andric
20050b57cec5SDimitry Andric if ((TSFlags & X86II::OpMapMask) == X86II::ThreeDNow)
200606c3fb27SDimitry Andric emitByte(X86II::getBaseOpcodeFor(TSFlags), CB);
20070b57cec5SDimitry Andric
2008*0fca6ea1SDimitry Andric if (CB.size() - StartByte > 15)
2009*0fca6ea1SDimitry Andric Ctx.reportError(MI.getLoc(), "instruction length exceeds the limit of 15");
20100b57cec5SDimitry Andric #ifndef NDEBUG
20110b57cec5SDimitry Andric // FIXME: Verify.
20120b57cec5SDimitry Andric if (/*!Desc.isVariadic() &&*/ CurOp != NumOps) {
20130b57cec5SDimitry Andric errs() << "Cannot encode all operands of: ";
20140b57cec5SDimitry Andric MI.dump();
20150b57cec5SDimitry Andric errs() << '\n';
20160b57cec5SDimitry Andric abort();
20170b57cec5SDimitry Andric }
20180b57cec5SDimitry Andric #endif
20190b57cec5SDimitry Andric }
20200b57cec5SDimitry Andric
createX86MCCodeEmitter(const MCInstrInfo & MCII,MCContext & Ctx)20210b57cec5SDimitry Andric MCCodeEmitter *llvm::createX86MCCodeEmitter(const MCInstrInfo &MCII,
20220b57cec5SDimitry Andric MCContext &Ctx) {
20230b57cec5SDimitry Andric return new X86MCCodeEmitter(MCII, Ctx);
20240b57cec5SDimitry Andric }
2025