0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1 //===-- X86MCCodeEmitter.cpp - Convert X86 code to machine code -----------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
2 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
3 // The LLVM Compiler Infrastructure
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
4 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
5 // This file is distributed under the University of Illinois Open Source
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
6 // License. See LICENSE.TXT for details.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
7 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
8 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
9 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
10 // This file implements the X86MCCodeEmitter class.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
11 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
12 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
13
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
14 #include "MCTargetDesc/X86BaseInfo.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
15 #include "MCTargetDesc/X86FixupKinds.h"
|
121
|
16 #include "MCTargetDesc/X86MCTargetDesc.h"
|
|
17 #include "llvm/ADT/SmallVector.h"
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
18 #include "llvm/MC/MCCodeEmitter.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
19 #include "llvm/MC/MCContext.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
20 #include "llvm/MC/MCExpr.h"
|
121
|
21 #include "llvm/MC/MCFixup.h"
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
22 #include "llvm/MC/MCInst.h"
|
121
|
23 #include "llvm/MC/MCInstrDesc.h"
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
24 #include "llvm/MC/MCInstrInfo.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
25 #include "llvm/MC/MCRegisterInfo.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
26 #include "llvm/MC/MCSubtargetInfo.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
27 #include "llvm/MC/MCSymbol.h"
|
121
|
28 #include "llvm/Support/ErrorHandling.h"
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
29 #include "llvm/Support/raw_ostream.h"
|
121
|
30 #include <cassert>
|
|
31 #include <cstdint>
|
|
32 #include <cstdlib>
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
33
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
34 using namespace llvm;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
35
|
77
|
36 #define DEBUG_TYPE "mccodeemitter"
|
|
37
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
38 namespace {
|
121
|
39
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
40 class X86MCCodeEmitter : public MCCodeEmitter {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
41 const MCInstrInfo &MCII;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
42 MCContext &Ctx;
|
121
|
43
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
44 public:
|
77
|
45 X86MCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
|
|
46 : MCII(mcii), Ctx(ctx) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
47 }
|
121
|
48 X86MCCodeEmitter(const X86MCCodeEmitter &) = delete;
|
|
49 X86MCCodeEmitter &operator=(const X86MCCodeEmitter &) = delete;
|
|
50 ~X86MCCodeEmitter() override = default;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
51
|
77
|
52 bool is64BitMode(const MCSubtargetInfo &STI) const {
|
95
|
53 return STI.getFeatureBits()[X86::Mode64Bit];
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
54 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
55
|
77
|
56 bool is32BitMode(const MCSubtargetInfo &STI) const {
|
95
|
57 return STI.getFeatureBits()[X86::Mode32Bit];
|
77
|
58 }
|
|
59
|
|
60 bool is16BitMode(const MCSubtargetInfo &STI) const {
|
95
|
61 return STI.getFeatureBits()[X86::Mode16Bit];
|
77
|
62 }
|
|
63
|
|
64 /// Is16BitMemOperand - Return true if the specified instruction has
|
|
65 /// a 16-bit memory operand. Op specifies the operand # of the memoperand.
|
|
66 bool Is16BitMemOperand(const MCInst &MI, unsigned Op,
|
|
67 const MCSubtargetInfo &STI) const {
|
|
68 const MCOperand &BaseReg = MI.getOperand(Op+X86::AddrBaseReg);
|
|
69 const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg);
|
|
70 const MCOperand &Disp = MI.getOperand(Op+X86::AddrDisp);
|
|
71
|
|
72 if (is16BitMode(STI) && BaseReg.getReg() == 0 &&
|
|
73 Disp.isImm() && Disp.getImm() < 0x10000)
|
|
74 return true;
|
|
75 if ((BaseReg.getReg() != 0 &&
|
|
76 X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg.getReg())) ||
|
|
77 (IndexReg.getReg() != 0 &&
|
|
78 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg.getReg())))
|
|
79 return true;
|
|
80 return false;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
81 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
82
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
83 unsigned GetX86RegNum(const MCOperand &MO) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
84 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()) & 0x7;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
85 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
86
|
120
|
87 unsigned getX86RegEncoding(const MCInst &MI, unsigned OpNum) const {
|
|
88 return Ctx.getRegisterInfo()->getEncodingValue(
|
|
89 MI.getOperand(OpNum).getReg());
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
90 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
91
|
120
|
92 // Does this register require a bit to be set in REX prefix.
|
|
93 bool isREXExtendedReg(const MCInst &MI, unsigned OpNum) const {
|
|
94 return (getX86RegEncoding(MI, OpNum) >> 3) & 1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
95 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
96
|
120
|
97 void EmitByte(uint8_t C, unsigned &CurByte, raw_ostream &OS) const {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
98 OS << (char)C;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
99 ++CurByte;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
100 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
101
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
102 void EmitConstant(uint64_t Val, unsigned Size, unsigned &CurByte,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
103 raw_ostream &OS) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
104 // Output the constant in little endian byte order.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
105 for (unsigned i = 0; i != Size; ++i) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
106 EmitByte(Val & 255, CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
107 Val >>= 8;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
108 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
109 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
110
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
111 void EmitImmediate(const MCOperand &Disp, SMLoc Loc,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
112 unsigned ImmSize, MCFixupKind FixupKind,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
113 unsigned &CurByte, raw_ostream &OS,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
114 SmallVectorImpl<MCFixup> &Fixups,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
115 int ImmOffset = 0) const;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
116
|
121
|
117 static uint8_t ModRMByte(unsigned Mod, unsigned RegOpcode, unsigned RM) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
118 assert(Mod < 4 && RegOpcode < 8 && RM < 8 && "ModRM Fields out of range!");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
119 return RM | (RegOpcode << 3) | (Mod << 6);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
120 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
121
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
122 void EmitRegModRMByte(const MCOperand &ModRMReg, unsigned RegOpcodeFld,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
123 unsigned &CurByte, raw_ostream &OS) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
124 EmitByte(ModRMByte(3, RegOpcodeFld, GetX86RegNum(ModRMReg)), CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
125 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
126
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
127 void EmitSIBByte(unsigned SS, unsigned Index, unsigned Base,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
128 unsigned &CurByte, raw_ostream &OS) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
129 // SIB byte is in the same format as the ModRMByte.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
130 EmitByte(ModRMByte(SS, Index, Base), CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
131 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
132
|
120
|
133 void emitMemModRMByte(const MCInst &MI, unsigned Op, unsigned RegOpcodeField,
|
|
134 uint64_t TSFlags, bool Rex, unsigned &CurByte,
|
|
135 raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups,
|
77
|
136 const MCSubtargetInfo &STI) const;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
137
|
95
|
138 void encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
77
|
139 SmallVectorImpl<MCFixup> &Fixups,
|
|
140 const MCSubtargetInfo &STI) const override;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
141
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
142 void EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
143 const MCInst &MI, const MCInstrDesc &Desc,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
144 raw_ostream &OS) const;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
145
|
77
|
146 void EmitSegmentOverridePrefix(unsigned &CurByte, unsigned SegOperand,
|
|
147 const MCInst &MI, raw_ostream &OS) const;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
148
|
120
|
149 bool emitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand,
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
150 const MCInst &MI, const MCInstrDesc &Desc,
|
120
|
151 const MCSubtargetInfo &STI, raw_ostream &OS) const;
|
|
152
|
|
153 uint8_t DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags,
|
|
154 int MemOperand, const MCInstrDesc &Desc) const;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
155 };
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
156
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
157 } // end anonymous namespace
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
158
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
159 /// isDisp8 - Return true if this signed displacement fits in a 8-bit
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
160 /// sign-extended field.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
161 static bool isDisp8(int Value) {
|
120
|
162 return Value == (int8_t)Value;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
163 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
164
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
165 /// isCDisp8 - Return true if this signed displacement fits in a 8-bit
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
166 /// compressed dispacement field.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
167 static bool isCDisp8(uint64_t TSFlags, int Value, int& CValue) {
|
83
|
168 assert(((TSFlags & X86II::EncodingMask) == X86II::EVEX) &&
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
169 "Compressed 8-bit displacement is only valid for EVEX inst.");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
170
|
77
|
171 unsigned CD8_Scale =
|
83
|
172 (TSFlags & X86II::CD8_Scale_Mask) >> X86II::CD8_Scale_Shift;
|
77
|
173 if (CD8_Scale == 0) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
174 CValue = Value;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
175 return isDisp8(Value);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
176 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
177
|
77
|
178 unsigned Mask = CD8_Scale - 1;
|
|
179 assert((CD8_Scale & Mask) == 0 && "Invalid memory object size.");
|
|
180 if (Value & Mask) // Unaligned offset
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
181 return false;
|
77
|
182 Value /= (int)CD8_Scale;
|
120
|
183 bool Ret = (Value == (int8_t)Value);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
184
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
185 if (Ret)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
186 CValue = Value;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
187 return Ret;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
188 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
189
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
190 /// getImmFixupKind - Return the appropriate fixup kind to use for an immediate
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
191 /// in an instruction with the specified TSFlags.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
192 static MCFixupKind getImmFixupKind(uint64_t TSFlags) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
193 unsigned Size = X86II::getSizeOfImm(TSFlags);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
194 bool isPCRel = X86II::isImmPCRel(TSFlags);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
195
|
77
|
196 if (X86II::isImmSigned(TSFlags)) {
|
|
197 switch (Size) {
|
|
198 default: llvm_unreachable("Unsupported signed fixup size!");
|
|
199 case 4: return MCFixupKind(X86::reloc_signed_4byte);
|
|
200 }
|
|
201 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
202 return MCFixup::getKindForSize(Size, isPCRel);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
203 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
204
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
205 /// Is32BitMemOperand - Return true if the specified instruction has
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
206 /// a 32-bit memory operand. Op specifies the operand # of the memoperand.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
207 static bool Is32BitMemOperand(const MCInst &MI, unsigned Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
208 const MCOperand &BaseReg = MI.getOperand(Op+X86::AddrBaseReg);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
209 const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
210
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
211 if ((BaseReg.getReg() != 0 &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
212 X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg.getReg())) ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
213 (IndexReg.getReg() != 0 &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
214 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg.getReg())))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
215 return true;
|
120
|
216 if (BaseReg.getReg() == X86::EIP) {
|
|
217 assert(IndexReg.getReg() == 0 && "Invalid eip-based address.");
|
|
218 return true;
|
|
219 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
220 return false;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
221 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
222
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
223 /// Is64BitMemOperand - Return true if the specified instruction has
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
224 /// a 64-bit memory operand. Op specifies the operand # of the memoperand.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
225 #ifndef NDEBUG
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
226 static bool Is64BitMemOperand(const MCInst &MI, unsigned Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
227 const MCOperand &BaseReg = MI.getOperand(Op+X86::AddrBaseReg);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
228 const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
229
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
230 if ((BaseReg.getReg() != 0 &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
231 X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg.getReg())) ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
232 (IndexReg.getReg() != 0 &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
233 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg.getReg())))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
234 return true;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
235 return false;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
236 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
237 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
238
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
239 /// StartsWithGlobalOffsetTable - Check if this expression starts with
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
240 /// _GLOBAL_OFFSET_TABLE_ and if it is of the form
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
241 /// _GLOBAL_OFFSET_TABLE_-symbol. This is needed to support PIC on ELF
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
242 /// i386 as _GLOBAL_OFFSET_TABLE_ is magical. We check only simple case that
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
243 /// are know to be used: _GLOBAL_OFFSET_TABLE_ by itself or at the start
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
244 /// of a binary expression.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
245 enum GlobalOffsetTableExprKind {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
246 GOT_None,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
247 GOT_Normal,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
248 GOT_SymDiff
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
249 };
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
250 static GlobalOffsetTableExprKind
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
251 StartsWithGlobalOffsetTable(const MCExpr *Expr) {
|
77
|
252 const MCExpr *RHS = nullptr;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
253 if (Expr->getKind() == MCExpr::Binary) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
254 const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(Expr);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
255 Expr = BE->getLHS();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
256 RHS = BE->getRHS();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
257 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
258
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
259 if (Expr->getKind() != MCExpr::SymbolRef)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
260 return GOT_None;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
261
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
262 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
263 const MCSymbol &S = Ref->getSymbol();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
264 if (S.getName() != "_GLOBAL_OFFSET_TABLE_")
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
265 return GOT_None;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
266 if (RHS && RHS->getKind() == MCExpr::SymbolRef)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
267 return GOT_SymDiff;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
268 return GOT_Normal;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
269 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
270
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
271 static bool HasSecRelSymbolRef(const MCExpr *Expr) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
272 if (Expr->getKind() == MCExpr::SymbolRef) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
273 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
274 return Ref->getKind() == MCSymbolRefExpr::VK_SECREL;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
275 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
276 return false;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
277 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
278
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
279 void X86MCCodeEmitter::
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
280 EmitImmediate(const MCOperand &DispOp, SMLoc Loc, unsigned Size,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
281 MCFixupKind FixupKind, unsigned &CurByte, raw_ostream &OS,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
282 SmallVectorImpl<MCFixup> &Fixups, int ImmOffset) const {
|
77
|
283 const MCExpr *Expr = nullptr;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
284 if (DispOp.isImm()) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
285 // If this is a simple integer displacement that doesn't require a
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
286 // relocation, emit it now.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
287 if (FixupKind != FK_PCRel_1 &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
288 FixupKind != FK_PCRel_2 &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
289 FixupKind != FK_PCRel_4) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
290 EmitConstant(DispOp.getImm()+ImmOffset, Size, CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
291 return;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
292 }
|
95
|
293 Expr = MCConstantExpr::create(DispOp.getImm(), Ctx);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
294 } else {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
295 Expr = DispOp.getExpr();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
296 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
297
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
298 // If we have an immoffset, add it to the expression.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
299 if ((FixupKind == FK_Data_4 ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
300 FixupKind == FK_Data_8 ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
301 FixupKind == MCFixupKind(X86::reloc_signed_4byte))) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
302 GlobalOffsetTableExprKind Kind = StartsWithGlobalOffsetTable(Expr);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
303 if (Kind != GOT_None) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
304 assert(ImmOffset == 0);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
305
|
77
|
306 if (Size == 8) {
|
|
307 FixupKind = MCFixupKind(X86::reloc_global_offset_table8);
|
|
308 } else {
|
|
309 assert(Size == 4);
|
|
310 FixupKind = MCFixupKind(X86::reloc_global_offset_table);
|
|
311 }
|
|
312
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
313 if (Kind == GOT_Normal)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
314 ImmOffset = CurByte;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
315 } else if (Expr->getKind() == MCExpr::SymbolRef) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
316 if (HasSecRelSymbolRef(Expr)) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
317 FixupKind = MCFixupKind(FK_SecRel_4);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
318 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
319 } else if (Expr->getKind() == MCExpr::Binary) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
320 const MCBinaryExpr *Bin = static_cast<const MCBinaryExpr*>(Expr);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
321 if (HasSecRelSymbolRef(Bin->getLHS())
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
322 || HasSecRelSymbolRef(Bin->getRHS())) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
323 FixupKind = MCFixupKind(FK_SecRel_4);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
324 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
325 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
326 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
327
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
328 // If the fixup is pc-relative, we need to bias the value to be relative to
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
329 // the start of the field, not the end of the field.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
330 if (FixupKind == FK_PCRel_4 ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
331 FixupKind == MCFixupKind(X86::reloc_riprel_4byte) ||
|
120
|
332 FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load) ||
|
|
333 FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax) ||
|
|
334 FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_rex))
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
335 ImmOffset -= 4;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
336 if (FixupKind == FK_PCRel_2)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
337 ImmOffset -= 2;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
338 if (FixupKind == FK_PCRel_1)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
339 ImmOffset -= 1;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
340
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
341 if (ImmOffset)
|
95
|
342 Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(ImmOffset, Ctx),
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
343 Ctx);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
344
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
345 // Emit a symbolic constant as a fixup and 4 zeros.
|
95
|
346 Fixups.push_back(MCFixup::create(CurByte, Expr, FixupKind, Loc));
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
347 EmitConstant(0, Size, CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
348 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
349
|
120
|
350 void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
351 unsigned RegOpcodeField,
|
120
|
352 uint64_t TSFlags, bool Rex,
|
|
353 unsigned &CurByte, raw_ostream &OS,
|
77
|
354 SmallVectorImpl<MCFixup> &Fixups,
|
120
|
355 const MCSubtargetInfo &STI) const {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
356 const MCOperand &Disp = MI.getOperand(Op+X86::AddrDisp);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
357 const MCOperand &Base = MI.getOperand(Op+X86::AddrBaseReg);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
358 const MCOperand &Scale = MI.getOperand(Op+X86::AddrScaleAmt);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
359 const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
360 unsigned BaseReg = Base.getReg();
|
83
|
361 bool HasEVEX = (TSFlags & X86II::EncodingMask) == X86II::EVEX;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
362
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
363 // Handle %rip relative addressing.
|
120
|
364 if (BaseReg == X86::RIP ||
|
|
365 BaseReg == X86::EIP) { // [disp32+rIP] in X86-64 mode
|
77
|
366 assert(is64BitMode(STI) && "Rip-relative addressing requires 64-bit mode");
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
367 assert(IndexReg.getReg() == 0 && "Invalid rip-relative address");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
368 EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
369
|
120
|
370 unsigned Opcode = MI.getOpcode();
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
371 // movq loads are handled with a special relocation form which allows the
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
372 // linker to eliminate some loads for GOT references which end up in the
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
373 // same linkage unit.
|
120
|
374 unsigned FixupKind = [=]() {
|
|
375 switch (Opcode) {
|
|
376 default:
|
|
377 return X86::reloc_riprel_4byte;
|
|
378 case X86::MOV64rm:
|
|
379 assert(Rex);
|
|
380 return X86::reloc_riprel_4byte_movq_load;
|
|
381 case X86::CALL64m:
|
|
382 case X86::JMP64m:
|
121
|
383 case X86::TEST64mr:
|
120
|
384 case X86::ADC64rm:
|
|
385 case X86::ADD64rm:
|
|
386 case X86::AND64rm:
|
|
387 case X86::CMP64rm:
|
|
388 case X86::OR64rm:
|
|
389 case X86::SBB64rm:
|
|
390 case X86::SUB64rm:
|
|
391 case X86::XOR64rm:
|
|
392 return Rex ? X86::reloc_riprel_4byte_relax_rex
|
|
393 : X86::reloc_riprel_4byte_relax;
|
|
394 }
|
|
395 }();
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
396
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
397 // rip-relative addressing is actually relative to the *next* instruction.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
398 // Since an immediate can follow the mod/rm byte for an instruction, this
|
134
|
399 // means that we need to bias the displacement field of the instruction with
|
|
400 // the size of the immediate field. If we have this case, add it into the
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
401 // expression to emit.
|
134
|
402 // Note: rip-relative addressing using immediate displacement values should
|
|
403 // not be adjusted, assuming it was the user's intent.
|
|
404 int ImmSize = !Disp.isImm() && X86II::hasImm(TSFlags)
|
|
405 ? X86II::getSizeOfImm(TSFlags)
|
|
406 : 0;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
407
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
408 EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(FixupKind),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
409 CurByte, OS, Fixups, -ImmSize);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
410 return;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
411 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
412
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
413 unsigned BaseRegNo = BaseReg ? GetX86RegNum(Base) : -1U;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
414
|
77
|
415 // 16-bit addressing forms of the ModR/M byte have a different encoding for
|
|
416 // the R/M field and are far more limited in which registers can be used.
|
|
417 if (Is16BitMemOperand(MI, Op, STI)) {
|
|
418 if (BaseReg) {
|
|
419 // For 32-bit addressing, the row and column values in Table 2-2 are
|
|
420 // basically the same. It's AX/CX/DX/BX/SP/BP/SI/DI in that order, with
|
|
421 // some special cases. And GetX86RegNum reflects that numbering.
|
|
422 // For 16-bit addressing it's more fun, as shown in the SDM Vol 2A,
|
|
423 // Table 2-1 "16-Bit Addressing Forms with the ModR/M byte". We can only
|
|
424 // use SI/DI/BP/BX, which have "row" values 4-7 in no particular order,
|
|
425 // while values 0-3 indicate the allowed combinations (base+index) of
|
|
426 // those: 0 for BX+SI, 1 for BX+DI, 2 for BP+SI, 3 for BP+DI.
|
|
427 //
|
|
428 // R16Table[] is a lookup from the normal RegNo, to the row values from
|
|
429 // Table 2-1 for 16-bit addressing modes. Where zero means disallowed.
|
|
430 static const unsigned R16Table[] = { 0, 0, 0, 7, 0, 6, 4, 5 };
|
|
431 unsigned RMfield = R16Table[BaseRegNo];
|
|
432
|
|
433 assert(RMfield && "invalid 16-bit base register");
|
|
434
|
|
435 if (IndexReg.getReg()) {
|
|
436 unsigned IndexReg16 = R16Table[GetX86RegNum(IndexReg)];
|
|
437
|
|
438 assert(IndexReg16 && "invalid 16-bit index register");
|
|
439 // We must have one of SI/DI (4,5), and one of BP/BX (6,7).
|
|
440 assert(((IndexReg16 ^ RMfield) & 2) &&
|
|
441 "invalid 16-bit base/index register combination");
|
|
442 assert(Scale.getImm() == 1 &&
|
|
443 "invalid scale for 16-bit memory reference");
|
|
444
|
|
445 // Allow base/index to appear in either order (although GAS doesn't).
|
|
446 if (IndexReg16 & 2)
|
|
447 RMfield = (RMfield & 1) | ((7 - IndexReg16) << 1);
|
|
448 else
|
|
449 RMfield = (IndexReg16 & 1) | ((7 - RMfield) << 1);
|
|
450 }
|
|
451
|
|
452 if (Disp.isImm() && isDisp8(Disp.getImm())) {
|
|
453 if (Disp.getImm() == 0 && BaseRegNo != N86::EBP) {
|
|
454 // There is no displacement; just the register.
|
|
455 EmitByte(ModRMByte(0, RegOpcodeField, RMfield), CurByte, OS);
|
|
456 return;
|
|
457 }
|
|
458 // Use the [REG]+disp8 form, including for [BP] which cannot be encoded.
|
|
459 EmitByte(ModRMByte(1, RegOpcodeField, RMfield), CurByte, OS);
|
|
460 EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups);
|
|
461 return;
|
|
462 }
|
|
463 // This is the [REG]+disp16 case.
|
|
464 EmitByte(ModRMByte(2, RegOpcodeField, RMfield), CurByte, OS);
|
|
465 } else {
|
|
466 // There is no BaseReg; this is the plain [disp16] case.
|
|
467 EmitByte(ModRMByte(0, RegOpcodeField, 6), CurByte, OS);
|
|
468 }
|
|
469
|
|
470 // Emit 16-bit displacement for plain disp16 or [REG]+disp16 cases.
|
|
471 EmitImmediate(Disp, MI.getLoc(), 2, FK_Data_2, CurByte, OS, Fixups);
|
|
472 return;
|
|
473 }
|
|
474
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
475 // Determine whether a SIB byte is needed.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
476 // If no BaseReg, issue a RIP relative instruction only if the MCE can
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
477 // resolve addresses on-the-fly, otherwise use SIB (Intel Manual 2A, table
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
478 // 2-7) and absolute references.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
479
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
480 if (// The SIB byte must be used if there is an index register.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
481 IndexReg.getReg() == 0 &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
482 // The SIB byte must be used if the base is ESP/RSP/R12, all of which
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
483 // encode to an R/M value of 4, which indicates that a SIB byte is
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
484 // present.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
485 BaseRegNo != N86::ESP &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
486 // If there is no base register and we're in 64-bit mode, we need a SIB
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
487 // byte to emit an addr that is just 'disp32' (the non-RIP relative form).
|
77
|
488 (!is64BitMode(STI) || BaseReg != 0)) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
489
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
490 if (BaseReg == 0) { // [disp32] in X86-32 mode
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
491 EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
492 EmitImmediate(Disp, MI.getLoc(), 4, FK_Data_4, CurByte, OS, Fixups);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
493 return;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
494 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
495
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
496 // If the base is not EBP/ESP and there is no displacement, use simple
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
497 // indirect register encoding, this handles addresses like [EAX]. The
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
498 // encoding for [EBP] with no displacement means [disp32] so we handle it
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
499 // by emitting a displacement of 0 below.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
500 if (Disp.isImm() && Disp.getImm() == 0 && BaseRegNo != N86::EBP) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
501 EmitByte(ModRMByte(0, RegOpcodeField, BaseRegNo), CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
502 return;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
503 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
504
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
505 // Otherwise, if the displacement fits in a byte, encode as [REG+disp8].
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
506 if (Disp.isImm()) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
507 if (!HasEVEX && isDisp8(Disp.getImm())) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
508 EmitByte(ModRMByte(1, RegOpcodeField, BaseRegNo), CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
509 EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
510 return;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
511 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
512 // Try EVEX compressed 8-bit displacement first; if failed, fall back to
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
513 // 32-bit displacement.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
514 int CDisp8 = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
515 if (HasEVEX && isCDisp8(TSFlags, Disp.getImm(), CDisp8)) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
516 EmitByte(ModRMByte(1, RegOpcodeField, BaseRegNo), CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
517 EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
518 CDisp8 - Disp.getImm());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
519 return;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
520 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
521 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
522
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
523 // Otherwise, emit the most general non-SIB encoding: [REG+disp32]
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
524 EmitByte(ModRMByte(2, RegOpcodeField, BaseRegNo), CurByte, OS);
|
120
|
525 unsigned Opcode = MI.getOpcode();
|
|
526 unsigned FixupKind = Opcode == X86::MOV32rm ? X86::reloc_signed_4byte_relax
|
|
527 : X86::reloc_signed_4byte;
|
|
528 EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(FixupKind), CurByte, OS,
|
|
529 Fixups);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
530 return;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
531 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
532
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
533 // We need a SIB byte, so start by outputting the ModR/M byte first
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
534 assert(IndexReg.getReg() != X86::ESP &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
535 IndexReg.getReg() != X86::RSP && "Cannot use ESP as index reg!");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
536
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
537 bool ForceDisp32 = false;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
538 bool ForceDisp8 = false;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
539 int CDisp8 = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
540 int ImmOffset = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
541 if (BaseReg == 0) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
542 // If there is no base register, we emit the special case SIB byte with
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
543 // MOD=0, BASE=5, to JUST get the index, scale, and displacement.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
544 EmitByte(ModRMByte(0, RegOpcodeField, 4), CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
545 ForceDisp32 = true;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
546 } else if (!Disp.isImm()) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
547 // Emit the normal disp32 encoding.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
548 EmitByte(ModRMByte(2, RegOpcodeField, 4), CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
549 ForceDisp32 = true;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
550 } else if (Disp.getImm() == 0 &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
551 // Base reg can't be anything that ends up with '5' as the base
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
552 // reg, it is the magic [*] nomenclature that indicates no base.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
553 BaseRegNo != N86::EBP) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
554 // Emit no displacement ModR/M byte
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
555 EmitByte(ModRMByte(0, RegOpcodeField, 4), CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
556 } else if (!HasEVEX && isDisp8(Disp.getImm())) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
557 // Emit the disp8 encoding.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
558 EmitByte(ModRMByte(1, RegOpcodeField, 4), CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
559 ForceDisp8 = true; // Make sure to force 8 bit disp if Base=EBP
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
560 } else if (HasEVEX && isCDisp8(TSFlags, Disp.getImm(), CDisp8)) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
561 // Emit the disp8 encoding.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
562 EmitByte(ModRMByte(1, RegOpcodeField, 4), CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
563 ForceDisp8 = true; // Make sure to force 8 bit disp if Base=EBP
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
564 ImmOffset = CDisp8 - Disp.getImm();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
565 } else {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
566 // Emit the normal disp32 encoding.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
567 EmitByte(ModRMByte(2, RegOpcodeField, 4), CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
568 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
569
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
570 // Calculate what the SS field value should be...
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
571 static const unsigned SSTable[] = { ~0U, 0, 1, ~0U, 2, ~0U, ~0U, ~0U, 3 };
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
572 unsigned SS = SSTable[Scale.getImm()];
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
573
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
574 if (BaseReg == 0) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
575 // Handle the SIB byte for the case where there is no base, see Intel
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
576 // Manual 2A, table 2-7. The displacement has already been output.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
577 unsigned IndexRegNo;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
578 if (IndexReg.getReg())
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
579 IndexRegNo = GetX86RegNum(IndexReg);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
580 else // Examples: [ESP+1*<noreg>+4] or [scaled idx]+disp32 (MOD=0,BASE=5)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
581 IndexRegNo = 4;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
582 EmitSIBByte(SS, IndexRegNo, 5, CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
583 } else {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
584 unsigned IndexRegNo;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
585 if (IndexReg.getReg())
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
586 IndexRegNo = GetX86RegNum(IndexReg);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
587 else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
588 IndexRegNo = 4; // For example [ESP+1*<noreg>+4]
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
589 EmitSIBByte(SS, IndexRegNo, GetX86RegNum(Base), CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
590 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
591
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
592 // Do we need to output a displacement?
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
593 if (ForceDisp8)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
594 EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups, ImmOffset);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
595 else if (ForceDisp32 || Disp.getImm() != 0)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
596 EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(X86::reloc_signed_4byte),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
597 CurByte, OS, Fixups);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
598 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
599
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
600 /// EmitVEXOpcodePrefix - AVX instructions are encoded using a opcode prefix
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
601 /// called VEX.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
602 void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
603 int MemOperand, const MCInst &MI,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
604 const MCInstrDesc &Desc,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
605 raw_ostream &OS) const {
|
83
|
606 assert(!(TSFlags & X86II::LOCK) && "Can't have LOCK VEX.");
|
|
607
|
|
608 uint64_t Encoding = TSFlags & X86II::EncodingMask;
|
|
609 bool HasEVEX_K = TSFlags & X86II::EVEX_K;
|
|
610 bool HasVEX_4V = TSFlags & X86II::VEX_4V;
|
|
611 bool HasEVEX_RC = TSFlags & X86II::EVEX_RC;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
612
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
613 // VEX_R: opcode externsion equivalent to REX.R in
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
614 // 1's complement (inverted) form
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
615 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
616 // 1: Same as REX_R=0 (must be 1 in 32-bit mode)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
617 // 0: Same as REX_R=1 (64 bit mode only)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
618 //
|
120
|
619 uint8_t VEX_R = 0x1;
|
|
620 uint8_t EVEX_R2 = 0x1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
621
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
622 // VEX_X: equivalent to REX.X, only used when a
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
623 // register is used for index in SIB Byte.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
624 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
625 // 1: Same as REX.X=0 (must be 1 in 32-bit mode)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
626 // 0: Same as REX.X=1 (64-bit mode only)
|
120
|
627 uint8_t VEX_X = 0x1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
628
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
629 // VEX_B:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
630 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
631 // 1: Same as REX_B=0 (ignored in 32-bit mode)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
632 // 0: Same as REX_B=1 (64 bit mode only)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
633 //
|
120
|
634 uint8_t VEX_B = 0x1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
635
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
636 // VEX_W: opcode specific (use like REX.W, or used for
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
637 // opcode extension, or ignored, depending on the opcode byte)
|
120
|
638 uint8_t VEX_W = (TSFlags & X86II::VEX_W) ? 1 : 0;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
639
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
640 // VEX_5M (VEX m-mmmmm field):
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
641 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
642 // 0b00000: Reserved for future use
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
643 // 0b00001: implied 0F leading opcode
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
644 // 0b00010: implied 0F 38 leading opcode bytes
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
645 // 0b00011: implied 0F 3A leading opcode bytes
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
646 // 0b00100-0b11111: Reserved for future use
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
647 // 0b01000: XOP map select - 08h instructions with imm byte
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
648 // 0b01001: XOP map select - 09h instructions with no imm byte
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
649 // 0b01010: XOP map select - 0Ah instructions with imm dword
|
120
|
650 uint8_t VEX_5M;
|
|
651 switch (TSFlags & X86II::OpMapMask) {
|
|
652 default: llvm_unreachable("Invalid prefix!");
|
|
653 case X86II::TB: VEX_5M = 0x1; break; // 0F
|
|
654 case X86II::T8: VEX_5M = 0x2; break; // 0F 38
|
|
655 case X86II::TA: VEX_5M = 0x3; break; // 0F 3A
|
|
656 case X86II::XOP8: VEX_5M = 0x8; break;
|
|
657 case X86II::XOP9: VEX_5M = 0x9; break;
|
|
658 case X86II::XOPA: VEX_5M = 0xA; break;
|
|
659 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
660
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
661 // VEX_4V (VEX vvvv field): a register specifier
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
662 // (in 1's complement form) or 1111 if unused.
|
120
|
663 uint8_t VEX_4V = 0xf;
|
|
664 uint8_t EVEX_V2 = 0x1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
665
|
120
|
666 // EVEX_L2/VEX_L (Vector Length):
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
667 //
|
120
|
668 // L2 L
|
|
669 // 0 0: scalar or 128-bit vector
|
|
670 // 0 1: 256-bit vector
|
|
671 // 1 0: 512-bit vector
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
672 //
|
120
|
673 uint8_t VEX_L = (TSFlags & X86II::VEX_L) ? 1 : 0;
|
|
674 uint8_t EVEX_L2 = (TSFlags & X86II::EVEX_L2) ? 1 : 0;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
675
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
676 // VEX_PP: opcode extension providing equivalent
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
677 // functionality of a SIMD prefix
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
678 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
679 // 0b00: None
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
680 // 0b01: 66
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
681 // 0b10: F3
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
682 // 0b11: F2
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
683 //
|
120
|
684 uint8_t VEX_PP;
|
77
|
685 switch (TSFlags & X86II::OpPrefixMask) {
|
120
|
686 default: llvm_unreachable("Invalid op prefix!");
|
|
687 case X86II::PS: VEX_PP = 0x0; break; // none
|
77
|
688 case X86II::PD: VEX_PP = 0x1; break; // 66
|
|
689 case X86II::XS: VEX_PP = 0x2; break; // F3
|
|
690 case X86II::XD: VEX_PP = 0x3; break; // F2
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
691 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
692
|
120
|
693 // EVEX_U
|
|
694 uint8_t EVEX_U = 1; // Always '1' so far
|
|
695
|
|
696 // EVEX_z
|
|
697 uint8_t EVEX_z = (HasEVEX_K && (TSFlags & X86II::EVEX_Z)) ? 1 : 0;
|
|
698
|
|
699 // EVEX_b
|
|
700 uint8_t EVEX_b = (TSFlags & X86II::EVEX_B) ? 1 : 0;
|
|
701
|
|
702 // EVEX_rc
|
|
703 uint8_t EVEX_rc = 0;
|
|
704
|
|
705 // EVEX_aaa
|
|
706 uint8_t EVEX_aaa = 0;
|
|
707
|
|
708 bool EncodeRC = false;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
709
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
710 // Classify VEX_B, VEX_4V, VEX_R, VEX_X
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
711 unsigned NumOps = Desc.getNumOperands();
|
77
|
712 unsigned CurOp = X86II::getOperandBias(Desc);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
713
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
714 switch (TSFlags & X86II::FormMask) {
|
77
|
715 default: llvm_unreachable("Unexpected form in EmitVEXOpcodePrefix!");
|
|
716 case X86II::RawFrm:
|
|
717 break;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
718 case X86II::MRMDestMem: {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
719 // MRMDestMem instructions forms:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
720 // MemAddr, src1(ModR/M)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
721 // MemAddr, src1(VEX_4V), src2(ModR/M)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
722 // MemAddr, src1(ModR/M), imm8
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
723 //
|
120
|
724 unsigned BaseRegEnc = getX86RegEncoding(MI, MemOperand + X86::AddrBaseReg);
|
|
725 VEX_B = ~(BaseRegEnc >> 3) & 1;
|
|
726 unsigned IndexRegEnc = getX86RegEncoding(MI, MemOperand+X86::AddrIndexReg);
|
|
727 VEX_X = ~(IndexRegEnc >> 3) & 1;
|
|
728 if (!HasVEX_4V) // Only needed with VSIB which don't use VVVV.
|
|
729 EVEX_V2 = ~(IndexRegEnc >> 4) & 1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
730
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
731 CurOp += X86::AddrNumOperands;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
732
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
733 if (HasEVEX_K)
|
120
|
734 EVEX_aaa = getX86RegEncoding(MI, CurOp++);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
735
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
736 if (HasVEX_4V) {
|
120
|
737 unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
|
|
738 VEX_4V = ~VRegEnc & 0xf;
|
|
739 EVEX_V2 = ~(VRegEnc >> 4) & 1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
740 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
741
|
120
|
742 unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
|
|
743 VEX_R = ~(RegEnc >> 3) & 1;
|
|
744 EVEX_R2 = ~(RegEnc >> 4) & 1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
745 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
746 }
|
120
|
747 case X86II::MRMSrcMem: {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
748 // MRMSrcMem instructions forms:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
749 // src1(ModR/M), MemAddr
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
750 // src1(ModR/M), src2(VEX_4V), MemAddr
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
751 // src1(ModR/M), MemAddr, imm8
|
120
|
752 // src1(ModR/M), MemAddr, src2(Imm[7:4])
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
753 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
754 // FMA4:
|
120
|
755 // dst(ModR/M.reg), src1(VEX_4V), src2(ModR/M), src3(Imm[7:4])
|
|
756 unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
|
|
757 VEX_R = ~(RegEnc >> 3) & 1;
|
|
758 EVEX_R2 = ~(RegEnc >> 4) & 1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
759
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
760 if (HasEVEX_K)
|
120
|
761 EVEX_aaa = getX86RegEncoding(MI, CurOp++);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
762
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
763 if (HasVEX_4V) {
|
120
|
764 unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
|
|
765 VEX_4V = ~VRegEnc & 0xf;
|
|
766 EVEX_V2 = ~(VRegEnc >> 4) & 1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
767 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
768
|
120
|
769 unsigned BaseRegEnc = getX86RegEncoding(MI, MemOperand + X86::AddrBaseReg);
|
|
770 VEX_B = ~(BaseRegEnc >> 3) & 1;
|
|
771 unsigned IndexRegEnc = getX86RegEncoding(MI, MemOperand+X86::AddrIndexReg);
|
|
772 VEX_X = ~(IndexRegEnc >> 3) & 1;
|
|
773 if (!HasVEX_4V) // Only needed with VSIB which don't use VVVV.
|
|
774 EVEX_V2 = ~(IndexRegEnc >> 4) & 1;
|
|
775
|
|
776 break;
|
|
777 }
|
|
778 case X86II::MRMSrcMem4VOp3: {
|
|
779 // Instruction format for 4VOp3:
|
|
780 // src1(ModR/M), MemAddr, src3(VEX_4V)
|
|
781 unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
|
|
782 VEX_R = ~(RegEnc >> 3) & 1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
783
|
120
|
784 unsigned BaseRegEnc = getX86RegEncoding(MI, MemOperand + X86::AddrBaseReg);
|
|
785 VEX_B = ~(BaseRegEnc >> 3) & 1;
|
|
786 unsigned IndexRegEnc = getX86RegEncoding(MI, MemOperand+X86::AddrIndexReg);
|
|
787 VEX_X = ~(IndexRegEnc >> 3) & 1;
|
|
788
|
|
789 VEX_4V = ~getX86RegEncoding(MI, CurOp + X86::AddrNumOperands) & 0xf;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
790 break;
|
120
|
791 }
|
|
792 case X86II::MRMSrcMemOp4: {
|
|
793 // dst(ModR/M.reg), src1(VEX_4V), src2(Imm[7:4]), src3(ModR/M),
|
|
794 unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
|
|
795 VEX_R = ~(RegEnc >> 3) & 1;
|
|
796
|
|
797 unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
|
|
798 VEX_4V = ~VRegEnc & 0xf;
|
|
799
|
|
800 unsigned BaseRegEnc = getX86RegEncoding(MI, MemOperand + X86::AddrBaseReg);
|
|
801 VEX_B = ~(BaseRegEnc >> 3) & 1;
|
|
802 unsigned IndexRegEnc = getX86RegEncoding(MI, MemOperand+X86::AddrIndexReg);
|
|
803 VEX_X = ~(IndexRegEnc >> 3) & 1;
|
|
804 break;
|
|
805 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
806 case X86II::MRM0m: case X86II::MRM1m:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
807 case X86II::MRM2m: case X86II::MRM3m:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
808 case X86II::MRM4m: case X86II::MRM5m:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
809 case X86II::MRM6m: case X86II::MRM7m: {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
810 // MRM[0-9]m instructions forms:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
811 // MemAddr
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
812 // src1(VEX_4V), MemAddr
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
813 if (HasVEX_4V) {
|
120
|
814 unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
|
|
815 VEX_4V = ~VRegEnc & 0xf;
|
|
816 EVEX_V2 = ~(VRegEnc >> 4) & 1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
817 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
818
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
819 if (HasEVEX_K)
|
120
|
820 EVEX_aaa = getX86RegEncoding(MI, CurOp++);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
821
|
120
|
822 unsigned BaseRegEnc = getX86RegEncoding(MI, MemOperand + X86::AddrBaseReg);
|
|
823 VEX_B = ~(BaseRegEnc >> 3) & 1;
|
|
824 unsigned IndexRegEnc = getX86RegEncoding(MI, MemOperand+X86::AddrIndexReg);
|
|
825 VEX_X = ~(IndexRegEnc >> 3) & 1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
826 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
827 }
|
120
|
828 case X86II::MRMSrcReg: {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
829 // MRMSrcReg instructions forms:
|
120
|
830 // dst(ModR/M), src1(VEX_4V), src2(ModR/M), src3(Imm[7:4])
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
831 // dst(ModR/M), src1(ModR/M)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
832 // dst(ModR/M), src1(ModR/M), imm8
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
833 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
834 // FMA4:
|
120
|
835 // dst(ModR/M.reg), src1(VEX_4V), src2(Imm[7:4]), src3(ModR/M),
|
|
836 unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
|
|
837 VEX_R = ~(RegEnc >> 3) & 1;
|
|
838 EVEX_R2 = ~(RegEnc >> 4) & 1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
839
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
840 if (HasEVEX_K)
|
120
|
841 EVEX_aaa = getX86RegEncoding(MI, CurOp++);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
842
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
843 if (HasVEX_4V) {
|
120
|
844 unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
|
|
845 VEX_4V = ~VRegEnc & 0xf;
|
|
846 EVEX_V2 = ~(VRegEnc >> 4) & 1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
847 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
848
|
120
|
849 RegEnc = getX86RegEncoding(MI, CurOp++);
|
|
850 VEX_B = ~(RegEnc >> 3) & 1;
|
|
851 VEX_X = ~(RegEnc >> 4) & 1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
852
|
77
|
853 if (EVEX_b) {
|
|
854 if (HasEVEX_RC) {
|
|
855 unsigned RcOperand = NumOps-1;
|
|
856 assert(RcOperand >= CurOp);
|
|
857 EVEX_rc = MI.getOperand(RcOperand).getImm() & 0x3;
|
|
858 }
|
|
859 EncodeRC = true;
|
83
|
860 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
861 break;
|
120
|
862 }
|
|
863 case X86II::MRMSrcReg4VOp3: {
|
|
864 // Instruction format for 4VOp3:
|
|
865 // src1(ModR/M), src2(ModR/M), src3(VEX_4V)
|
|
866 unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
|
|
867 VEX_R = ~(RegEnc >> 3) & 1;
|
|
868
|
|
869 RegEnc = getX86RegEncoding(MI, CurOp++);
|
|
870 VEX_B = ~(RegEnc >> 3) & 1;
|
|
871
|
|
872 VEX_4V = ~getX86RegEncoding(MI, CurOp++) & 0xf;
|
|
873 break;
|
|
874 }
|
|
875 case X86II::MRMSrcRegOp4: {
|
|
876 // dst(ModR/M.reg), src1(VEX_4V), src2(Imm[7:4]), src3(ModR/M),
|
|
877 unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
|
|
878 VEX_R = ~(RegEnc >> 3) & 1;
|
|
879
|
|
880 unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
|
|
881 VEX_4V = ~VRegEnc & 0xf;
|
|
882
|
|
883 // Skip second register source (encoded in Imm[7:4])
|
|
884 ++CurOp;
|
|
885
|
|
886 RegEnc = getX86RegEncoding(MI, CurOp++);
|
|
887 VEX_B = ~(RegEnc >> 3) & 1;
|
|
888 VEX_X = ~(RegEnc >> 4) & 1;
|
|
889 break;
|
|
890 }
|
|
891 case X86II::MRMDestReg: {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
892 // MRMDestReg instructions forms:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
893 // dst(ModR/M), src(ModR/M)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
894 // dst(ModR/M), src(ModR/M), imm8
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
895 // dst(ModR/M), src1(VEX_4V), src2(ModR/M)
|
120
|
896 unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
|
|
897 VEX_B = ~(RegEnc >> 3) & 1;
|
|
898 VEX_X = ~(RegEnc >> 4) & 1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
899
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
900 if (HasEVEX_K)
|
120
|
901 EVEX_aaa = getX86RegEncoding(MI, CurOp++);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
902
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
903 if (HasVEX_4V) {
|
120
|
904 unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
|
|
905 VEX_4V = ~VRegEnc & 0xf;
|
|
906 EVEX_V2 = ~(VRegEnc >> 4) & 1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
907 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
908
|
120
|
909 RegEnc = getX86RegEncoding(MI, CurOp++);
|
|
910 VEX_R = ~(RegEnc >> 3) & 1;
|
|
911 EVEX_R2 = ~(RegEnc >> 4) & 1;
|
77
|
912 if (EVEX_b)
|
|
913 EncodeRC = true;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
914 break;
|
120
|
915 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
916 case X86II::MRM0r: case X86II::MRM1r:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
917 case X86II::MRM2r: case X86II::MRM3r:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
918 case X86II::MRM4r: case X86II::MRM5r:
|
120
|
919 case X86II::MRM6r: case X86II::MRM7r: {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
920 // MRM0r-MRM7r instructions forms:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
921 // dst(VEX_4V), src(ModR/M), imm8
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
922 if (HasVEX_4V) {
|
120
|
923 unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
|
|
924 VEX_4V = ~VRegEnc & 0xf;
|
|
925 EVEX_V2 = ~(VRegEnc >> 4) & 1;
|
77
|
926 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
927 if (HasEVEX_K)
|
120
|
928 EVEX_aaa = getX86RegEncoding(MI, CurOp++);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
929
|
120
|
930 unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
|
|
931 VEX_B = ~(RegEnc >> 3) & 1;
|
|
932 VEX_X = ~(RegEnc >> 4) & 1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
933 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
934 }
|
120
|
935 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
936
|
77
|
937 if (Encoding == X86II::VEX || Encoding == X86II::XOP) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
938 // VEX opcode prefix can have 2 or 3 bytes
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
939 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
940 // 3 bytes:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
941 // +-----+ +--------------+ +-------------------+
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
942 // | C4h | | RXB | m-mmmm | | W | vvvv | L | pp |
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
943 // +-----+ +--------------+ +-------------------+
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
944 // 2 bytes:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
945 // +-----+ +-------------------+
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
946 // | C5h | | R | vvvv | L | pp |
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
947 // +-----+ +-------------------+
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
948 //
|
77
|
949 // XOP uses a similar prefix:
|
|
950 // +-----+ +--------------+ +-------------------+
|
|
951 // | 8Fh | | RXB | m-mmmm | | W | vvvv | L | pp |
|
|
952 // +-----+ +--------------+ +-------------------+
|
120
|
953 uint8_t LastByte = VEX_PP | (VEX_L << 2) | (VEX_4V << 3);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
954
|
77
|
955 // Can we use the 2 byte VEX prefix?
|
|
956 if (Encoding == X86II::VEX && VEX_B && VEX_X && !VEX_W && (VEX_5M == 1)) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
957 EmitByte(0xC5, CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
958 EmitByte(LastByte | (VEX_R << 7), CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
959 return;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
960 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
961
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
962 // 3 byte VEX prefix
|
77
|
963 EmitByte(Encoding == X86II::XOP ? 0x8F : 0xC4, CurByte, OS);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
964 EmitByte(VEX_R << 7 | VEX_X << 6 | VEX_B << 5 | VEX_5M, CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
965 EmitByte(LastByte | (VEX_W << 7), CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
966 } else {
|
77
|
967 assert(Encoding == X86II::EVEX && "unknown encoding!");
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
968 // EVEX opcode prefix can have 4 bytes
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
969 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
970 // +-----+ +--------------+ +-------------------+ +------------------------+
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
971 // | 62h | | RXBR' | 00mm | | W | vvvv | U | pp | | z | L'L | b | v' | aaa |
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
972 // +-----+ +--------------+ +-------------------+ +------------------------+
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
973 assert((VEX_5M & 0x3) == VEX_5M
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
974 && "More than 2 significant bits in VEX.m-mmmm fields for EVEX!");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
975
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
976 EmitByte(0x62, CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
977 EmitByte((VEX_R << 7) |
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
978 (VEX_X << 6) |
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
979 (VEX_B << 5) |
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
980 (EVEX_R2 << 4) |
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
981 VEX_5M, CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
982 EmitByte((VEX_W << 7) |
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
983 (VEX_4V << 3) |
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
984 (EVEX_U << 2) |
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
985 VEX_PP, CurByte, OS);
|
77
|
986 if (EncodeRC)
|
|
987 EmitByte((EVEX_z << 7) |
|
120
|
988 (EVEX_rc << 5) |
|
|
989 (EVEX_b << 4) |
|
|
990 (EVEX_V2 << 3) |
|
|
991 EVEX_aaa, CurByte, OS);
|
77
|
992 else
|
|
993 EmitByte((EVEX_z << 7) |
|
120
|
994 (EVEX_L2 << 6) |
|
|
995 (VEX_L << 5) |
|
|
996 (EVEX_b << 4) |
|
|
997 (EVEX_V2 << 3) |
|
|
998 EVEX_aaa, CurByte, OS);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
999 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1000 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1001
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1002 /// DetermineREXPrefix - Determine if the MCInst has to be encoded with a X86-64
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1003 /// REX prefix which specifies 1) 64-bit instructions, 2) non-default operand
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1004 /// size, and 3) use of X86-64 extended registers.
|
120
|
1005 uint8_t X86MCCodeEmitter::DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags,
|
|
1006 int MemOperand,
|
|
1007 const MCInstrDesc &Desc) const {
|
|
1008 uint8_t REX = 0;
|
100
|
1009 bool UsesHighByteReg = false;
|
|
1010
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1011 if (TSFlags & X86II::REX_W)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1012 REX |= 1 << 3; // set REX.W
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1013
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1014 if (MI.getNumOperands() == 0) return REX;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1015
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1016 unsigned NumOps = MI.getNumOperands();
|
120
|
1017 unsigned CurOp = X86II::getOperandBias(Desc);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1018
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1019 // If it accesses SPL, BPL, SIL, or DIL, then it requires a 0x40 REX prefix.
|
120
|
1020 for (unsigned i = CurOp; i != NumOps; ++i) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1021 const MCOperand &MO = MI.getOperand(i);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1022 if (!MO.isReg()) continue;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1023 unsigned Reg = MO.getReg();
|
100
|
1024 if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
|
|
1025 UsesHighByteReg = true;
|
120
|
1026 if (X86II::isX86_64NonExtLowByteReg(Reg))
|
|
1027 // FIXME: The caller of DetermineREXPrefix slaps this prefix onto anything
|
|
1028 // that returns non-zero.
|
|
1029 REX |= 0x40; // REX fixed encoding prefix
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1030 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1031
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1032 switch (TSFlags & X86II::FormMask) {
|
120
|
1033 case X86II::AddRegFrm:
|
|
1034 REX |= isREXExtendedReg(MI, CurOp++) << 0; // REX.B
|
|
1035 break;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1036 case X86II::MRMSrcReg:
|
120
|
1037 REX |= isREXExtendedReg(MI, CurOp++) << 2; // REX.R
|
|
1038 REX |= isREXExtendedReg(MI, CurOp++) << 0; // REX.B
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1039 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1040 case X86II::MRMSrcMem: {
|
120
|
1041 REX |= isREXExtendedReg(MI, CurOp++) << 2; // REX.R
|
|
1042 REX |= isREXExtendedReg(MI, MemOperand+X86::AddrBaseReg) << 0; // REX.B
|
|
1043 REX |= isREXExtendedReg(MI, MemOperand+X86::AddrIndexReg) << 1; // REX.X
|
|
1044 CurOp += X86::AddrNumOperands;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1045 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1046 }
|
120
|
1047 case X86II::MRMDestReg:
|
|
1048 REX |= isREXExtendedReg(MI, CurOp++) << 0; // REX.B
|
|
1049 REX |= isREXExtendedReg(MI, CurOp++) << 2; // REX.R
|
|
1050 break;
|
|
1051 case X86II::MRMDestMem:
|
|
1052 REX |= isREXExtendedReg(MI, MemOperand+X86::AddrBaseReg) << 0; // REX.B
|
|
1053 REX |= isREXExtendedReg(MI, MemOperand+X86::AddrIndexReg) << 1; // REX.X
|
|
1054 CurOp += X86::AddrNumOperands;
|
|
1055 REX |= isREXExtendedReg(MI, CurOp++) << 2; // REX.R
|
|
1056 break;
|
77
|
1057 case X86II::MRMXm:
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1058 case X86II::MRM0m: case X86II::MRM1m:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1059 case X86II::MRM2m: case X86II::MRM3m:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1060 case X86II::MRM4m: case X86II::MRM5m:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1061 case X86II::MRM6m: case X86II::MRM7m:
|
120
|
1062 REX |= isREXExtendedReg(MI, MemOperand+X86::AddrBaseReg) << 0; // REX.B
|
|
1063 REX |= isREXExtendedReg(MI, MemOperand+X86::AddrIndexReg) << 1; // REX.X
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1064 break;
|
120
|
1065 case X86II::MRMXr:
|
|
1066 case X86II::MRM0r: case X86II::MRM1r:
|
|
1067 case X86II::MRM2r: case X86II::MRM3r:
|
|
1068 case X86II::MRM4r: case X86II::MRM5r:
|
|
1069 case X86II::MRM6r: case X86II::MRM7r:
|
|
1070 REX |= isREXExtendedReg(MI, CurOp++) << 0; // REX.B
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1071 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1072 }
|
100
|
1073 if (REX && UsesHighByteReg)
|
|
1074 report_fatal_error("Cannot encode high byte register in REX-prefixed instruction");
|
|
1075
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1076 return REX;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1077 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1078
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1079 /// EmitSegmentOverridePrefix - Emit segment override opcode prefix as needed
|
77
|
1080 void X86MCCodeEmitter::EmitSegmentOverridePrefix(unsigned &CurByte,
|
|
1081 unsigned SegOperand,
|
|
1082 const MCInst &MI,
|
|
1083 raw_ostream &OS) const {
|
|
1084 // Check for explicit segment override on memory operand.
|
|
1085 switch (MI.getOperand(SegOperand).getReg()) {
|
|
1086 default: llvm_unreachable("Unknown segment register!");
|
|
1087 case 0: break;
|
|
1088 case X86::CS: EmitByte(0x2E, CurByte, OS); break;
|
|
1089 case X86::SS: EmitByte(0x36, CurByte, OS); break;
|
|
1090 case X86::DS: EmitByte(0x3E, CurByte, OS); break;
|
|
1091 case X86::ES: EmitByte(0x26, CurByte, OS); break;
|
|
1092 case X86::FS: EmitByte(0x64, CurByte, OS); break;
|
|
1093 case X86::GS: EmitByte(0x65, CurByte, OS); break;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1094 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1095 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1096
|
120
|
1097 /// Emit all instruction prefixes prior to the opcode.
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1098 ///
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1099 /// MemOperand is the operand # of the start of a memory operand if present. If
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1100 /// Not present, it is -1.
|
120
|
1101 ///
|
|
1102 /// Returns true if a REX prefix was used.
|
|
1103 bool X86MCCodeEmitter::emitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1104 int MemOperand, const MCInst &MI,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1105 const MCInstrDesc &Desc,
|
77
|
1106 const MCSubtargetInfo &STI,
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1107 raw_ostream &OS) const {
|
120
|
1108 bool Ret = false;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1109 // Emit the operand size opcode prefix as needed.
|
83
|
1110 if ((TSFlags & X86II::OpSizeMask) == (is16BitMode(STI) ? X86II::OpSize32
|
|
1111 : X86II::OpSize16))
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1112 EmitByte(0x66, CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1113
|
83
|
1114 // Emit the LOCK opcode prefix.
|
121
|
1115 if (TSFlags & X86II::LOCK || MI.getFlags() & X86::IP_HAS_LOCK)
|
83
|
1116 EmitByte(0xF0, CurByte, OS);
|
|
1117
|
77
|
1118 switch (TSFlags & X86II::OpPrefixMask) {
|
|
1119 case X86II::PD: // 66
|
|
1120 EmitByte(0x66, CurByte, OS);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1121 break;
|
77
|
1122 case X86II::XS: // F3
|
|
1123 EmitByte(0xF3, CurByte, OS);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1124 break;
|
77
|
1125 case X86II::XD: // F2
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1126 EmitByte(0xF2, CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1127 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1128 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1129
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1130 // Handle REX prefix.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1131 // FIXME: Can this come before F2 etc to simplify emission?
|
77
|
1132 if (is64BitMode(STI)) {
|
120
|
1133 if (uint8_t REX = DetermineREXPrefix(MI, TSFlags, MemOperand, Desc)) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1134 EmitByte(0x40 | REX, CurByte, OS);
|
120
|
1135 Ret = true;
|
|
1136 }
|
134
|
1137 } else {
|
|
1138 assert(!(TSFlags & X86II::REX_W) && "REX.W requires 64bit mode.");
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1139 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1140
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1141 // 0x0F escape code must be emitted just before the opcode.
|
77
|
1142 switch (TSFlags & X86II::OpMapMask) {
|
|
1143 case X86II::TB: // Two-byte opcode map
|
|
1144 case X86II::T8: // 0F 38
|
|
1145 case X86II::TA: // 0F 3A
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1146 EmitByte(0x0F, CurByte, OS);
|
77
|
1147 break;
|
|
1148 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1149
|
77
|
1150 switch (TSFlags & X86II::OpMapMask) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1151 case X86II::T8: // 0F 38
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1152 EmitByte(0x38, CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1153 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1154 case X86II::TA: // 0F 3A
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1155 EmitByte(0x3A, CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1156 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1157 }
|
120
|
1158 return Ret;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1159 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1160
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1161 void X86MCCodeEmitter::
|
95
|
1162 encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
77
|
1163 SmallVectorImpl<MCFixup> &Fixups,
|
|
1164 const MCSubtargetInfo &STI) const {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1165 unsigned Opcode = MI.getOpcode();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1166 const MCInstrDesc &Desc = MCII.get(Opcode);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1167 uint64_t TSFlags = Desc.TSFlags;
|
121
|
1168 unsigned Flags = MI.getFlags();
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1169
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1170 // Pseudo instructions don't get encoded.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1171 if ((TSFlags & X86II::FormMask) == X86II::Pseudo)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1172 return;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1173
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1174 unsigned NumOps = Desc.getNumOperands();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1175 unsigned CurOp = X86II::getOperandBias(Desc);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1176
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1177 // Keep track of the current byte being emitted.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1178 unsigned CurByte = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1179
|
77
|
1180 // Encoding type for this instruction.
|
83
|
1181 uint64_t Encoding = TSFlags & X86II::EncodingMask;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1182
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1183 // It uses the VEX.VVVV field?
|
83
|
1184 bool HasVEX_4V = TSFlags & X86II::VEX_4V;
|
120
|
1185 bool HasVEX_I8Reg = (TSFlags & X86II::ImmMask) == X86II::Imm8Reg;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1186
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1187 // It uses the EVEX.aaa field?
|
83
|
1188 bool HasEVEX_K = TSFlags & X86II::EVEX_K;
|
|
1189 bool HasEVEX_RC = TSFlags & X86II::EVEX_RC;
|
|
1190
|
120
|
1191 // Used if a register is encoded in 7:4 of immediate.
|
|
1192 unsigned I8RegNum = 0;
|
|
1193
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1194 // Determine where the memory operand starts, if present.
|
120
|
1195 int MemoryOperand = X86II::getMemoryOperandNo(TSFlags);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1196 if (MemoryOperand != -1) MemoryOperand += CurOp;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1197
|
77
|
1198 // Emit segment override opcode prefix as needed.
|
|
1199 if (MemoryOperand >= 0)
|
|
1200 EmitSegmentOverridePrefix(CurByte, MemoryOperand+X86::AddrSegmentReg,
|
|
1201 MI, OS);
|
|
1202
|
|
1203 // Emit the repeat opcode prefix as needed.
|
121
|
1204 if (TSFlags & X86II::REP || Flags & X86::IP_HAS_REPEAT)
|
77
|
1205 EmitByte(0xF3, CurByte, OS);
|
121
|
1206 if (Flags & X86::IP_HAS_REPEAT_NE)
|
|
1207 EmitByte(0xF2, CurByte, OS);
|
77
|
1208
|
|
1209 // Emit the address size opcode prefix as needed.
|
|
1210 bool need_address_override;
|
83
|
1211 uint64_t AdSize = TSFlags & X86II::AdSizeMask;
|
|
1212 if ((is16BitMode(STI) && AdSize == X86II::AdSize32) ||
|
|
1213 (is32BitMode(STI) && AdSize == X86II::AdSize16) ||
|
|
1214 (is64BitMode(STI) && AdSize == X86II::AdSize32)) {
|
77
|
1215 need_address_override = true;
|
|
1216 } else if (MemoryOperand < 0) {
|
|
1217 need_address_override = false;
|
|
1218 } else if (is64BitMode(STI)) {
|
|
1219 assert(!Is16BitMemOperand(MI, MemoryOperand, STI));
|
|
1220 need_address_override = Is32BitMemOperand(MI, MemoryOperand);
|
|
1221 } else if (is32BitMode(STI)) {
|
|
1222 assert(!Is64BitMemOperand(MI, MemoryOperand));
|
|
1223 need_address_override = Is16BitMemOperand(MI, MemoryOperand, STI);
|
|
1224 } else {
|
|
1225 assert(is16BitMode(STI));
|
|
1226 assert(!Is64BitMemOperand(MI, MemoryOperand));
|
|
1227 need_address_override = !Is16BitMemOperand(MI, MemoryOperand, STI);
|
|
1228 }
|
|
1229
|
|
1230 if (need_address_override)
|
|
1231 EmitByte(0x67, CurByte, OS);
|
|
1232
|
120
|
1233 bool Rex = false;
|
77
|
1234 if (Encoding == 0)
|
120
|
1235 Rex = emitOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, STI, OS);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1236 else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1237 EmitVEXOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1238
|
120
|
1239 uint8_t BaseOpcode = X86II::getBaseOpcodeFor(TSFlags);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1240
|
83
|
1241 if (TSFlags & X86II::Has3DNow0F0FOpcode)
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1242 BaseOpcode = 0x0F; // Weird 3DNow! encoding.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1243
|
120
|
1244 uint64_t Form = TSFlags & X86II::FormMask;
|
|
1245 switch (Form) {
|
|
1246 default: errs() << "FORM: " << Form << "\n";
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1247 llvm_unreachable("Unknown FormMask value in X86MCCodeEmitter!");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1248 case X86II::Pseudo:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1249 llvm_unreachable("Pseudo instruction shouldn't be emitted");
|
77
|
1250 case X86II::RawFrmDstSrc: {
|
|
1251 unsigned siReg = MI.getOperand(1).getReg();
|
|
1252 assert(((siReg == X86::SI && MI.getOperand(0).getReg() == X86::DI) ||
|
|
1253 (siReg == X86::ESI && MI.getOperand(0).getReg() == X86::EDI) ||
|
|
1254 (siReg == X86::RSI && MI.getOperand(0).getReg() == X86::RDI)) &&
|
|
1255 "SI and DI register sizes do not match");
|
|
1256 // Emit segment override opcode prefix as needed (not for %ds).
|
|
1257 if (MI.getOperand(2).getReg() != X86::DS)
|
|
1258 EmitSegmentOverridePrefix(CurByte, 2, MI, OS);
|
|
1259 // Emit AdSize prefix as needed.
|
|
1260 if ((!is32BitMode(STI) && siReg == X86::ESI) ||
|
|
1261 (is32BitMode(STI) && siReg == X86::SI))
|
|
1262 EmitByte(0x67, CurByte, OS);
|
|
1263 CurOp += 3; // Consume operands.
|
|
1264 EmitByte(BaseOpcode, CurByte, OS);
|
|
1265 break;
|
|
1266 }
|
|
1267 case X86II::RawFrmSrc: {
|
|
1268 unsigned siReg = MI.getOperand(0).getReg();
|
|
1269 // Emit segment override opcode prefix as needed (not for %ds).
|
|
1270 if (MI.getOperand(1).getReg() != X86::DS)
|
|
1271 EmitSegmentOverridePrefix(CurByte, 1, MI, OS);
|
|
1272 // Emit AdSize prefix as needed.
|
|
1273 if ((!is32BitMode(STI) && siReg == X86::ESI) ||
|
|
1274 (is32BitMode(STI) && siReg == X86::SI))
|
|
1275 EmitByte(0x67, CurByte, OS);
|
|
1276 CurOp += 2; // Consume operands.
|
|
1277 EmitByte(BaseOpcode, CurByte, OS);
|
|
1278 break;
|
|
1279 }
|
|
1280 case X86II::RawFrmDst: {
|
|
1281 unsigned siReg = MI.getOperand(0).getReg();
|
|
1282 // Emit AdSize prefix as needed.
|
|
1283 if ((!is32BitMode(STI) && siReg == X86::EDI) ||
|
|
1284 (is32BitMode(STI) && siReg == X86::DI))
|
|
1285 EmitByte(0x67, CurByte, OS);
|
|
1286 ++CurOp; // Consume operand.
|
|
1287 EmitByte(BaseOpcode, CurByte, OS);
|
|
1288 break;
|
|
1289 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1290 case X86II::RawFrm:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1291 EmitByte(BaseOpcode, CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1292 break;
|
77
|
1293 case X86II::RawFrmMemOffs:
|
|
1294 // Emit segment override opcode prefix as needed.
|
|
1295 EmitSegmentOverridePrefix(CurByte, 1, MI, OS);
|
|
1296 EmitByte(BaseOpcode, CurByte, OS);
|
|
1297 EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
|
|
1298 X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
|
|
1299 CurByte, OS, Fixups);
|
|
1300 ++CurOp; // skip segment operand
|
|
1301 break;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1302 case X86II::RawFrmImm8:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1303 EmitByte(BaseOpcode, CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1304 EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1305 X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1306 CurByte, OS, Fixups);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1307 EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1, FK_Data_1, CurByte,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1308 OS, Fixups);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1309 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1310 case X86II::RawFrmImm16:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1311 EmitByte(BaseOpcode, CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1312 EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1313 X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1314 CurByte, OS, Fixups);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1315 EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 2, FK_Data_2, CurByte,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1316 OS, Fixups);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1317 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1318
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1319 case X86II::AddRegFrm:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1320 EmitByte(BaseOpcode + GetX86RegNum(MI.getOperand(CurOp++)), CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1321 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1322
|
120
|
1323 case X86II::MRMDestReg: {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1324 EmitByte(BaseOpcode, CurByte, OS);
|
120
|
1325 unsigned SrcRegNum = CurOp + 1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1326
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1327 if (HasEVEX_K) // Skip writemask
|
120
|
1328 ++SrcRegNum;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1329
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1330 if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1331 ++SrcRegNum;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1332
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1333 EmitRegModRMByte(MI.getOperand(CurOp),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1334 GetX86RegNum(MI.getOperand(SrcRegNum)), CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1335 CurOp = SrcRegNum + 1;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1336 break;
|
120
|
1337 }
|
|
1338 case X86II::MRMDestMem: {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1339 EmitByte(BaseOpcode, CurByte, OS);
|
120
|
1340 unsigned SrcRegNum = CurOp + X86::AddrNumOperands;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1341
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1342 if (HasEVEX_K) // Skip writemask
|
120
|
1343 ++SrcRegNum;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1344
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1345 if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1346 ++SrcRegNum;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1347
|
120
|
1348 emitMemModRMByte(MI, CurOp, GetX86RegNum(MI.getOperand(SrcRegNum)), TSFlags,
|
|
1349 Rex, CurByte, OS, Fixups, STI);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1350 CurOp = SrcRegNum + 1;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1351 break;
|
120
|
1352 }
|
|
1353 case X86II::MRMSrcReg: {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1354 EmitByte(BaseOpcode, CurByte, OS);
|
120
|
1355 unsigned SrcRegNum = CurOp + 1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1356
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1357 if (HasEVEX_K) // Skip writemask
|
120
|
1358 ++SrcRegNum;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1359
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1360 if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1361 ++SrcRegNum;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1362
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1363 EmitRegModRMByte(MI.getOperand(SrcRegNum),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1364 GetX86RegNum(MI.getOperand(CurOp)), CurByte, OS);
|
120
|
1365 CurOp = SrcRegNum + 1;
|
|
1366 if (HasVEX_I8Reg)
|
|
1367 I8RegNum = getX86RegEncoding(MI, CurOp++);
|
77
|
1368 // do not count the rounding control operand
|
|
1369 if (HasEVEX_RC)
|
120
|
1370 --NumOps;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1371 break;
|
120
|
1372 }
|
|
1373 case X86II::MRMSrcReg4VOp3: {
|
|
1374 EmitByte(BaseOpcode, CurByte, OS);
|
|
1375 unsigned SrcRegNum = CurOp + 1;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1376
|
120
|
1377 EmitRegModRMByte(MI.getOperand(SrcRegNum),
|
|
1378 GetX86RegNum(MI.getOperand(CurOp)), CurByte, OS);
|
|
1379 CurOp = SrcRegNum + 1;
|
|
1380 ++CurOp; // Encoded in VEX.VVVV
|
|
1381 break;
|
|
1382 }
|
|
1383 case X86II::MRMSrcRegOp4: {
|
|
1384 EmitByte(BaseOpcode, CurByte, OS);
|
|
1385 unsigned SrcRegNum = CurOp + 1;
|
|
1386
|
|
1387 // Skip 1st src (which is encoded in VEX_VVVV)
|
|
1388 ++SrcRegNum;
|
|
1389
|
|
1390 // Capture 2nd src (which is encoded in Imm[7:4])
|
|
1391 assert(HasVEX_I8Reg && "MRMSrcRegOp4 should imply VEX_I8Reg");
|
|
1392 I8RegNum = getX86RegEncoding(MI, SrcRegNum++);
|
|
1393
|
|
1394 EmitRegModRMByte(MI.getOperand(SrcRegNum),
|
|
1395 GetX86RegNum(MI.getOperand(CurOp)), CurByte, OS);
|
|
1396 CurOp = SrcRegNum + 1;
|
|
1397 break;
|
|
1398 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1399 case X86II::MRMSrcMem: {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1400 unsigned FirstMemOp = CurOp+1;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1401
|
120
|
1402 if (HasEVEX_K) // Skip writemask
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1403 ++FirstMemOp;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1404
|
120
|
1405 if (HasVEX_4V)
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1406 ++FirstMemOp; // Skip the register source (which is encoded in VEX_VVVV).
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1407
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1408 EmitByte(BaseOpcode, CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1409
|
120
|
1410 emitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)),
|
|
1411 TSFlags, Rex, CurByte, OS, Fixups, STI);
|
|
1412 CurOp = FirstMemOp + X86::AddrNumOperands;
|
|
1413 if (HasVEX_I8Reg)
|
|
1414 I8RegNum = getX86RegEncoding(MI, CurOp++);
|
|
1415 break;
|
|
1416 }
|
|
1417 case X86II::MRMSrcMem4VOp3: {
|
|
1418 unsigned FirstMemOp = CurOp+1;
|
|
1419
|
|
1420 EmitByte(BaseOpcode, CurByte, OS);
|
|
1421
|
|
1422 emitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)),
|
|
1423 TSFlags, Rex, CurByte, OS, Fixups, STI);
|
|
1424 CurOp = FirstMemOp + X86::AddrNumOperands;
|
|
1425 ++CurOp; // Encoded in VEX.VVVV.
|
|
1426 break;
|
|
1427 }
|
|
1428 case X86II::MRMSrcMemOp4: {
|
|
1429 unsigned FirstMemOp = CurOp+1;
|
|
1430
|
|
1431 ++FirstMemOp; // Skip the register source (which is encoded in VEX_VVVV).
|
|
1432
|
|
1433 // Capture second register source (encoded in Imm[7:4])
|
|
1434 assert(HasVEX_I8Reg && "MRMSrcRegOp4 should imply VEX_I8Reg");
|
|
1435 I8RegNum = getX86RegEncoding(MI, FirstMemOp++);
|
|
1436
|
|
1437 EmitByte(BaseOpcode, CurByte, OS);
|
|
1438
|
|
1439 emitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)),
|
|
1440 TSFlags, Rex, CurByte, OS, Fixups, STI);
|
|
1441 CurOp = FirstMemOp + X86::AddrNumOperands;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1442 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1443 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1444
|
77
|
1445 case X86II::MRMXr:
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1446 case X86II::MRM0r: case X86II::MRM1r:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1447 case X86II::MRM2r: case X86II::MRM3r:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1448 case X86II::MRM4r: case X86II::MRM5r:
|
121
|
1449 case X86II::MRM6r: case X86II::MRM7r:
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1450 if (HasVEX_4V) // Skip the register dst (which is encoded in VEX_VVVV).
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1451 ++CurOp;
|
77
|
1452 if (HasEVEX_K) // Skip writemask
|
|
1453 ++CurOp;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1454 EmitByte(BaseOpcode, CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1455 EmitRegModRMByte(MI.getOperand(CurOp++),
|
77
|
1456 (Form == X86II::MRMXr) ? 0 : Form-X86II::MRM0r,
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1457 CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1458 break;
|
77
|
1459
|
|
1460 case X86II::MRMXm:
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1461 case X86II::MRM0m: case X86II::MRM1m:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1462 case X86II::MRM2m: case X86II::MRM3m:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1463 case X86II::MRM4m: case X86II::MRM5m:
|
121
|
1464 case X86II::MRM6m: case X86II::MRM7m:
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1465 if (HasVEX_4V) // Skip the register dst (which is encoded in VEX_VVVV).
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1466 ++CurOp;
|
77
|
1467 if (HasEVEX_K) // Skip writemask
|
|
1468 ++CurOp;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1469 EmitByte(BaseOpcode, CurByte, OS);
|
120
|
1470 emitMemModRMByte(MI, CurOp,
|
|
1471 (Form == X86II::MRMXm) ? 0 : Form - X86II::MRM0m, TSFlags,
|
|
1472 Rex, CurByte, OS, Fixups, STI);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1473 CurOp += X86::AddrNumOperands;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1474 break;
|
121
|
1475
|
77
|
1476 case X86II::MRM_C0: case X86II::MRM_C1: case X86II::MRM_C2:
|
83
|
1477 case X86II::MRM_C3: case X86II::MRM_C4: case X86II::MRM_C5:
|
|
1478 case X86II::MRM_C6: case X86II::MRM_C7: case X86II::MRM_C8:
|
77
|
1479 case X86II::MRM_C9: case X86II::MRM_CA: case X86II::MRM_CB:
|
83
|
1480 case X86II::MRM_CC: case X86II::MRM_CD: case X86II::MRM_CE:
|
77
|
1481 case X86II::MRM_CF: case X86II::MRM_D0: case X86II::MRM_D1:
|
83
|
1482 case X86II::MRM_D2: case X86II::MRM_D3: case X86II::MRM_D4:
|
|
1483 case X86II::MRM_D5: case X86II::MRM_D6: case X86II::MRM_D7:
|
|
1484 case X86II::MRM_D8: case X86II::MRM_D9: case X86II::MRM_DA:
|
|
1485 case X86II::MRM_DB: case X86II::MRM_DC: case X86II::MRM_DD:
|
|
1486 case X86II::MRM_DE: case X86II::MRM_DF: case X86II::MRM_E0:
|
|
1487 case X86II::MRM_E1: case X86II::MRM_E2: case X86II::MRM_E3:
|
|
1488 case X86II::MRM_E4: case X86II::MRM_E5: case X86II::MRM_E6:
|
|
1489 case X86II::MRM_E7: case X86II::MRM_E8: case X86II::MRM_E9:
|
|
1490 case X86II::MRM_EA: case X86II::MRM_EB: case X86II::MRM_EC:
|
|
1491 case X86II::MRM_ED: case X86II::MRM_EE: case X86II::MRM_EF:
|
|
1492 case X86II::MRM_F0: case X86II::MRM_F1: case X86II::MRM_F2:
|
|
1493 case X86II::MRM_F3: case X86II::MRM_F4: case X86II::MRM_F5:
|
|
1494 case X86II::MRM_F6: case X86II::MRM_F7: case X86II::MRM_F8:
|
|
1495 case X86II::MRM_F9: case X86II::MRM_FA: case X86II::MRM_FB:
|
|
1496 case X86II::MRM_FC: case X86II::MRM_FD: case X86II::MRM_FE:
|
|
1497 case X86II::MRM_FF:
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1498 EmitByte(BaseOpcode, CurByte, OS);
|
83
|
1499 EmitByte(0xC0 + Form - X86II::MRM_C0, CurByte, OS);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1500 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1501 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1502
|
120
|
1503 if (HasVEX_I8Reg) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1504 // The last source register of a 4 operand instruction in AVX is encoded
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1505 // in bits[7:4] of a immediate byte.
|
120
|
1506 assert(I8RegNum < 16 && "Register encoding out of range");
|
|
1507 I8RegNum <<= 4;
|
|
1508 if (CurOp != NumOps) {
|
|
1509 unsigned Val = MI.getOperand(CurOp++).getImm();
|
|
1510 assert(Val < 16 && "Immediate operand value out of range");
|
|
1511 I8RegNum |= Val;
|
|
1512 }
|
|
1513 EmitImmediate(MCOperand::createImm(I8RegNum), MI.getLoc(), 1, FK_Data_1,
|
|
1514 CurByte, OS, Fixups);
|
|
1515 } else {
|
|
1516 // If there is a remaining operand, it must be a trailing immediate. Emit it
|
|
1517 // according to the right size for the instruction. Some instructions
|
|
1518 // (SSE4a extrq and insertq) have two trailing immediates.
|
|
1519 while (CurOp != NumOps && NumOps - CurOp <= 2) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1520 EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
|
77
|
1521 X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1522 CurByte, OS, Fixups);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1523 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1524 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1525
|
83
|
1526 if (TSFlags & X86II::Has3DNow0F0FOpcode)
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1527 EmitByte(X86II::getBaseOpcodeFor(TSFlags), CurByte, OS);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1528
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1529 #ifndef NDEBUG
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1530 // FIXME: Verify.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1531 if (/*!Desc.isVariadic() &&*/ CurOp != NumOps) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1532 errs() << "Cannot encode all operands of: ";
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1533 MI.dump();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1534 errs() << '\n';
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1535 abort();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1536 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1537 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1538 }
|
121
|
1539
|
|
1540 MCCodeEmitter *llvm::createX86MCCodeEmitter(const MCInstrInfo &MCII,
|
|
1541 const MCRegisterInfo &MRI,
|
|
1542 MCContext &Ctx) {
|
|
1543 return new X86MCCodeEmitter(MCII, Ctx);
|
|
1544 }
|