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