Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(649)

Side by Side Diff: src/IceAssemblerX86Base.h

Issue 1548363002: Subzero. Code organization. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===- subzero/src/IceAssemblerX86Base.h - base x86 assembler -*- C++ -*---===// 1 //===- subzero/src/IceAssemblerX86Base.h - base x86 assembler -*- C++ -*---===//
2 // 2 //
3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
4 // for details. All rights reserved. Use of this source code is governed by a 4 // for details. All rights reserved. Use of this source code is governed by a
5 // BSD-style license that can be found in the LICENSE file. 5 // BSD-style license that can be found in the LICENSE file.
6 // 6 //
7 // Modified by the Subzero authors. 7 // Modified by the Subzero authors.
8 // 8 //
9 //===----------------------------------------------------------------------===// 9 //===----------------------------------------------------------------------===//
10 // 10 //
(...skipping 14 matching lines...) Expand all
25 #define SUBZERO_SRC_ICEASSEMBLERX86BASE_H 25 #define SUBZERO_SRC_ICEASSEMBLERX86BASE_H
26 26
27 #include "IceAssembler.h" 27 #include "IceAssembler.h"
28 #include "IceDefs.h" 28 #include "IceDefs.h"
29 #include "IceOperand.h" 29 #include "IceOperand.h"
30 #include "IceTypes.h" 30 #include "IceTypes.h"
31 #include "IceUtils.h" 31 #include "IceUtils.h"
32 32
33 namespace Ice { 33 namespace Ice {
34 34
35 namespace X86Internal { 35 #ifndef X86NAMESPACE
36 #error "You must define the X86 Target namespace."
37 #endif
36 38
37 template <class Machine> class AssemblerX86Base; 39 namespace X86NAMESPACE {
38 template <class Machine> struct MachineTraits;
39 40
40 constexpr int MAX_NOP_SIZE = 8; 41 template <typename TraitsType>
41 42 class AssemblerX86Base : public ::Ice::Assembler {
42 class Immediate {
43 Immediate(const Immediate &) = delete;
44 Immediate &operator=(const Immediate &) = delete;
45
46 public:
47 explicit Immediate(int32_t value) : value_(value) {}
48
49 Immediate(RelocOffsetT offset, AssemblerFixup *fixup)
50 : value_(offset), fixup_(fixup) {
51 // Use the Offset in the "value" for now. If we decide to process fixups,
52 // we'll need to patch that offset with the true value.
53 }
54
55 int32_t value() const { return value_; }
56 AssemblerFixup *fixup() const { return fixup_; }
57
58 bool is_int8() const {
59 // We currently only allow 32-bit fixups, and they usually have value = 0,
60 // so if fixup_ != nullptr, it shouldn't be classified as int8/16.
61 return fixup_ == nullptr && Utils::IsInt(8, value_);
62 }
63 bool is_uint8() const {
64 return fixup_ == nullptr && Utils::IsUint(8, value_);
65 }
66 bool is_uint16() const {
67 return fixup_ == nullptr && Utils::IsUint(16, value_);
68 }
69
70 private:
71 const int32_t value_;
72 AssemblerFixup *fixup_ = nullptr;
73 };
74
75 /// X86 allows near and far jumps.
76 class Label final : public Ice::Label {
77 Label(const Label &) = delete;
78 Label &operator=(const Label &) = delete;
79
80 public:
81 Label() = default;
82 ~Label() = default;
83
84 void finalCheck() const override {
85 Ice::Label::finalCheck();
86 assert(!hasNear());
87 }
88
89 /// Returns the position of an earlier branch instruction which assumes that
90 /// this label is "near", and bumps iterator to the next near position.
91 intptr_t getNearPosition() {
92 assert(hasNear());
93 intptr_t Pos = UnresolvedNearPositions.back();
94 UnresolvedNearPositions.pop_back();
95 return Pos;
96 }
97
98 bool hasNear() const { return !UnresolvedNearPositions.empty(); }
99 bool isUnused() const override {
100 return Ice::Label::isUnused() && !hasNear();
101 }
102
103 private:
104 void nearLinkTo(const Assembler &Asm, intptr_t position) {
105 if (Asm.getPreliminary())
106 return;
107 assert(!isBound());
108 UnresolvedNearPositions.push_back(position);
109 }
110
111 llvm::SmallVector<intptr_t, 20> UnresolvedNearPositions;
112
113 template <class> friend class AssemblerX86Base;
114 };
115
116 template <class Machine> class AssemblerX86Base : public Assembler {
117 AssemblerX86Base(const AssemblerX86Base &) = delete; 43 AssemblerX86Base(const AssemblerX86Base &) = delete;
118 AssemblerX86Base &operator=(const AssemblerX86Base &) = delete; 44 AssemblerX86Base &operator=(const AssemblerX86Base &) = delete;
119 45
120 protected: 46 protected:
121 AssemblerX86Base(AssemblerKind Kind, bool use_far_branches) 47 explicit AssemblerX86Base(bool use_far_branches = false)
122 : Assembler(Kind) { 48 : Assembler(Traits::AsmKind) {
123 // This mode is only needed and implemented for MIPS and ARM. 49 // This mode is only needed and implemented for MIPS and ARM.
124 assert(!use_far_branches); 50 assert(!use_far_branches);
125 (void)use_far_branches; 51 (void)use_far_branches;
126 } 52 }
127 53
128 public: 54 public:
129 using Traits = MachineTraits<Machine>; 55 using Traits = TraitsType;
56 using Address = typename Traits::Address;
57 using ByteRegister = typename Traits::ByteRegister;
58 using BrCond = typename Traits::Cond::BrCond;
59 using CmppsCond = typename Traits::Cond::CmppsCond;
60 using GPRRegister = typename Traits::GPRRegister;
61 using Operand = typename Traits::Operand;
62 using XmmRegister = typename Traits::XmmRegister;
130 63
64 static constexpr int MAX_NOP_SIZE = 8;
65
66 static bool classof(const Assembler *Asm) {
67 return Asm->getKind() == Traits::AsmKind;
68 }
69
70 class Immediate {
71 Immediate(const Immediate &) = delete;
72 Immediate &operator=(const Immediate &) = delete;
73
74 public:
75 explicit Immediate(int32_t value) : value_(value) {}
76
77 Immediate(RelocOffsetT offset, AssemblerFixup *fixup)
78 : value_(offset), fixup_(fixup) {
79 // Use the Offset in the "value" for now. If we decide to process fixups,
80 // we'll need to patch that offset with the true value.
81 }
82
83 int32_t value() const { return value_; }
84 AssemblerFixup *fixup() const { return fixup_; }
85
86 bool is_int8() const {
87 // We currently only allow 32-bit fixups, and they usually have value = 0,
88 // so if fixup_ != nullptr, it shouldn't be classified as int8/16.
89 return fixup_ == nullptr && Utils::IsInt(8, value_);
90 }
91 bool is_uint8() const {
92 return fixup_ == nullptr && Utils::IsUint(8, value_);
93 }
94 bool is_uint16() const {
95 return fixup_ == nullptr && Utils::IsUint(16, value_);
96 }
97
98 private:
99 const int32_t value_;
100 AssemblerFixup *fixup_ = nullptr;
101 };
102
103 /// X86 allows near and far jumps.
104 class Label final : public Ice::Label {
105 Label(const Label &) = delete;
106 Label &operator=(const Label &) = delete;
107
108 public:
109 Label() = default;
110 ~Label() = default;
111
112 void finalCheck() const override {
113 Ice::Label::finalCheck();
114 assert(!hasNear());
115 }
116
117 /// Returns the position of an earlier branch instruction which assumes that
118 /// this label is "near", and bumps iterator to the next near position.
119 intptr_t getNearPosition() {
120 assert(hasNear());
121 intptr_t Pos = UnresolvedNearPositions.back();
122 UnresolvedNearPositions.pop_back();
123 return Pos;
124 }
125
126 bool hasNear() const { return !UnresolvedNearPositions.empty(); }
127 bool isUnused() const override {
128 return Ice::Label::isUnused() && !hasNear();
129 }
130
131 private:
132 friend class AssemblerX86Base<TraitsType>;
133
134 void nearLinkTo(const Assembler &Asm, intptr_t position) {
135 if (Asm.getPreliminary())
136 return;
137 assert(!isBound());
138 UnresolvedNearPositions.push_back(position);
139 }
140
141 llvm::SmallVector<intptr_t, 20> UnresolvedNearPositions;
142 };
143
144 public:
131 ~AssemblerX86Base() override; 145 ~AssemblerX86Base() override;
132 146
133 static const bool kNearJump = true; 147 static const bool kNearJump = true;
134 static const bool kFarJump = false; 148 static const bool kFarJump = false;
135 149
136 void alignFunction() override; 150 void alignFunction() override;
137 151
138 SizeT getBundleAlignLog2Bytes() const override { return 5; } 152 SizeT getBundleAlignLog2Bytes() const override { return 5; }
139 153
140 const char *getAlignDirective() const override { return ".p2align"; } 154 const char *getAlignDirective() const override { return ".p2align"; }
(...skipping 18 matching lines...) Expand all
159 Label *getOrCreateLocalLabel(SizeT Number); 173 Label *getOrCreateLocalLabel(SizeT Number);
160 void bindLocalLabel(SizeT Number); 174 void bindLocalLabel(SizeT Number);
161 175
162 bool fixupIsPCRel(FixupKind Kind) const override { 176 bool fixupIsPCRel(FixupKind Kind) const override {
163 // Currently assuming this is the only PC-rel relocation type used. 177 // Currently assuming this is the only PC-rel relocation type used.
164 // TODO(jpp): Traits.PcRelTypes.count(Kind) != 0 178 // TODO(jpp): Traits.PcRelTypes.count(Kind) != 0
165 return Kind == Traits::PcRelFixup; 179 return Kind == Traits::PcRelFixup;
166 } 180 }
167 181
168 // Operations to emit GPR instructions (and dispatch on operand type). 182 // Operations to emit GPR instructions (and dispatch on operand type).
169 using TypedEmitGPR = void (AssemblerX86Base::*)(Type, 183 using TypedEmitGPR = void (AssemblerX86Base::*)(Type, GPRRegister);
170 typename Traits::GPRRegister); 184 using TypedEmitAddr = void (AssemblerX86Base::*)(Type, const Address &);
171 using TypedEmitAddr =
172 void (AssemblerX86Base::*)(Type, const typename Traits::Address &);
173 struct GPREmitterOneOp { 185 struct GPREmitterOneOp {
174 TypedEmitGPR Reg; 186 TypedEmitGPR Reg;
175 TypedEmitAddr Addr; 187 TypedEmitAddr Addr;
176 }; 188 };
177 189
178 using TypedEmitGPRGPR = void (AssemblerX86Base::*)( 190 using TypedEmitGPRGPR = void (AssemblerX86Base::*)(Type, GPRRegister,
179 Type, typename Traits::GPRRegister, typename Traits::GPRRegister); 191 GPRRegister);
180 using TypedEmitGPRAddr = void (AssemblerX86Base::*)( 192 using TypedEmitGPRAddr = void (AssemblerX86Base::*)(Type, GPRRegister,
181 Type, typename Traits::GPRRegister, const typename Traits::Address &); 193 const Address &);
182 using TypedEmitGPRImm = void (AssemblerX86Base::*)( 194 using TypedEmitGPRImm = void (AssemblerX86Base::*)(Type, GPRRegister,
183 Type, typename Traits::GPRRegister, const Immediate &); 195 const Immediate &);
184 struct GPREmitterRegOp { 196 struct GPREmitterRegOp {
185 TypedEmitGPRGPR GPRGPR; 197 TypedEmitGPRGPR GPRGPR;
186 TypedEmitGPRAddr GPRAddr; 198 TypedEmitGPRAddr GPRAddr;
187 TypedEmitGPRImm GPRImm; 199 TypedEmitGPRImm GPRImm;
188 }; 200 };
189 201
190 struct GPREmitterShiftOp { 202 struct GPREmitterShiftOp {
191 // Technically, Addr/GPR and Addr/Imm are also allowed, but */Addr are not. 203 // Technically, Addr/GPR and Addr/Imm are also allowed, but */Addr are
192 // In practice, we always normalize the Dest to a Register first. 204 // not. In practice, we always normalize the Dest to a Register first.
193 TypedEmitGPRGPR GPRGPR; 205 TypedEmitGPRGPR GPRGPR;
194 TypedEmitGPRImm GPRImm; 206 TypedEmitGPRImm GPRImm;
195 }; 207 };
196 208
197 using TypedEmitGPRGPRImm = void (AssemblerX86Base::*)( 209 using TypedEmitGPRGPRImm = void (AssemblerX86Base::*)(Type, GPRRegister,
198 Type, typename Traits::GPRRegister, typename Traits::GPRRegister, 210 GPRRegister,
199 const Immediate &); 211 const Immediate &);
200 struct GPREmitterShiftD { 212 struct GPREmitterShiftD {
201 // Technically AddrGPR and AddrGPRImm are also allowed, but in practice we 213 // Technically AddrGPR and AddrGPRImm are also allowed, but in practice we
202 // always normalize Dest to a Register first. 214 // always normalize Dest to a Register first.
203 TypedEmitGPRGPR GPRGPR; 215 TypedEmitGPRGPR GPRGPR;
204 TypedEmitGPRGPRImm GPRGPRImm; 216 TypedEmitGPRGPRImm GPRGPRImm;
205 }; 217 };
206 218
207 using TypedEmitAddrGPR = void (AssemblerX86Base::*)( 219 using TypedEmitAddrGPR = void (AssemblerX86Base::*)(Type, const Address &,
208 Type, const typename Traits::Address &, typename Traits::GPRRegister); 220 GPRRegister);
209 using TypedEmitAddrImm = void (AssemblerX86Base::*)( 221 using TypedEmitAddrImm = void (AssemblerX86Base::*)(Type, const Address &,
210 Type, const typename Traits::Address &, const Immediate &); 222 const Immediate &);
211 struct GPREmitterAddrOp { 223 struct GPREmitterAddrOp {
212 TypedEmitAddrGPR AddrGPR; 224 TypedEmitAddrGPR AddrGPR;
213 TypedEmitAddrImm AddrImm; 225 TypedEmitAddrImm AddrImm;
214 }; 226 };
215 227
216 // Operations to emit XMM instructions (and dispatch on operand type). 228 // Operations to emit XMM instructions (and dispatch on operand type).
217 using TypedEmitXmmXmm = void (AssemblerX86Base::*)( 229 using TypedEmitXmmXmm = void (AssemblerX86Base::*)(Type, XmmRegister,
218 Type, typename Traits::XmmRegister, typename Traits::XmmRegister); 230 XmmRegister);
219 using TypedEmitXmmAddr = void (AssemblerX86Base::*)( 231 using TypedEmitXmmAddr = void (AssemblerX86Base::*)(Type, XmmRegister,
220 Type, typename Traits::XmmRegister, const typename Traits::Address &); 232 const Address &);
221 struct XmmEmitterRegOp { 233 struct XmmEmitterRegOp {
222 TypedEmitXmmXmm XmmXmm; 234 TypedEmitXmmXmm XmmXmm;
223 TypedEmitXmmAddr XmmAddr; 235 TypedEmitXmmAddr XmmAddr;
224 }; 236 };
225 237
226 using EmitXmmXmm = void (AssemblerX86Base::*)(typename Traits::XmmRegister, 238 using EmitXmmXmm = void (AssemblerX86Base::*)(XmmRegister, XmmRegister);
227 typename Traits::XmmRegister); 239 using EmitXmmAddr = void (AssemblerX86Base::*)(XmmRegister, const Address &);
228 using EmitXmmAddr = void (AssemblerX86Base::*)( 240 using EmitAddrXmm = void (AssemblerX86Base::*)(const Address &, XmmRegister);
229 typename Traits::XmmRegister, const typename Traits::Address &);
230 using EmitAddrXmm = void (AssemblerX86Base::*)(
231 const typename Traits::Address &, typename Traits::XmmRegister);
232 struct XmmEmitterMovOps { 241 struct XmmEmitterMovOps {
233 EmitXmmXmm XmmXmm; 242 EmitXmmXmm XmmXmm;
234 EmitXmmAddr XmmAddr; 243 EmitXmmAddr XmmAddr;
235 EmitAddrXmm AddrXmm; 244 EmitAddrXmm AddrXmm;
236 }; 245 };
237 246
238 using TypedEmitXmmImm = void (AssemblerX86Base::*)( 247 using TypedEmitXmmImm = void (AssemblerX86Base::*)(Type, XmmRegister,
239 Type, typename Traits::XmmRegister, const Immediate &); 248 const Immediate &);
240 249
241 struct XmmEmitterShiftOp { 250 struct XmmEmitterShiftOp {
242 TypedEmitXmmXmm XmmXmm; 251 TypedEmitXmmXmm XmmXmm;
243 TypedEmitXmmAddr XmmAddr; 252 TypedEmitXmmAddr XmmAddr;
244 TypedEmitXmmImm XmmImm; 253 TypedEmitXmmImm XmmImm;
245 }; 254 };
246 255
247 // Cross Xmm/GPR cast instructions. 256 // Cross Xmm/GPR cast instructions.
248 template <typename DReg_t, typename SReg_t> struct CastEmitterRegOp { 257 template <typename DReg_t, typename SReg_t> struct CastEmitterRegOp {
249 using TypedEmitRegs = void (AssemblerX86Base::*)(Type, DReg_t, Type, 258 using TypedEmitRegs = void (AssemblerX86Base::*)(Type, DReg_t, Type,
250 SReg_t); 259 SReg_t);
251 using TypedEmitAddr = void (AssemblerX86Base::*)( 260 using TypedEmitAddr = void (AssemblerX86Base::*)(Type, DReg_t, Type,
252 Type, DReg_t, Type, const typename Traits::Address &); 261 const Address &);
253 262
254 TypedEmitRegs RegReg; 263 TypedEmitRegs RegReg;
255 TypedEmitAddr RegAddr; 264 TypedEmitAddr RegAddr;
256 }; 265 };
257 266
258 // Three operand (potentially) cross Xmm/GPR instructions. The last operand 267 // Three operand (potentially) cross Xmm/GPR instructions. The last operand
259 // must be an immediate. 268 // must be an immediate.
260 template <typename DReg_t, typename SReg_t> struct ThreeOpImmEmitter { 269 template <typename DReg_t, typename SReg_t> struct ThreeOpImmEmitter {
261 using TypedEmitRegRegImm = void (AssemblerX86Base::*)(Type, DReg_t, SReg_t, 270 using TypedEmitRegRegImm = void (AssemblerX86Base::*)(Type, DReg_t, SReg_t,
262 const Immediate &); 271 const Immediate &);
263 using TypedEmitRegAddrImm = void (AssemblerX86Base::*)( 272 using TypedEmitRegAddrImm = void (AssemblerX86Base::*)(Type, DReg_t,
264 Type, DReg_t, const typename Traits::Address &, const Immediate &); 273 const Address &,
274 const Immediate &);
265 275
266 TypedEmitRegRegImm RegRegImm; 276 TypedEmitRegRegImm RegRegImm;
267 TypedEmitRegAddrImm RegAddrImm; 277 TypedEmitRegAddrImm RegAddrImm;
268 }; 278 };
269 279
270 /* 280 /*
271 * Emit Machine Instructions. 281 * Emit Machine Instructions.
272 */ 282 */
273 void call(typename Traits::GPRRegister reg); 283 void call(GPRRegister reg);
274 void call(const typename Traits::Address &address); 284 void call(const Address &address);
275 void call(const ConstantRelocatable *label); // not testable. 285 void call(const ConstantRelocatable *label); // not testable.
276 void call(const Immediate &abs_address); 286 void call(const Immediate &abs_address);
277 287
278 static const intptr_t kCallExternalLabelSize = 5; 288 static const intptr_t kCallExternalLabelSize = 5;
279 289
280 void pushl(typename Traits::GPRRegister reg); 290 void pushl(GPRRegister reg);
281 291
282 void popl(typename Traits::GPRRegister reg); 292 void popl(GPRRegister reg);
283 void popl(const typename Traits::Address &address); 293 void popl(const Address &address);
284 294
285 template <typename T = Traits, 295 template <typename T = Traits,
286 typename = typename std::enable_if<T::HasPusha>::type> 296 typename = typename std::enable_if<T::HasPusha>::type>
287 void pushal(); 297 void pushal();
288 template <typename T = Traits, 298 template <typename T = Traits,
289 typename = typename std::enable_if<T::HasPopa>::type> 299 typename = typename std::enable_if<T::HasPopa>::type>
290 void popal(); 300 void popal();
291 301
292 void setcc(typename Traits::Cond::BrCond condition, 302 void setcc(BrCond condition, ByteRegister dst);
293 typename Traits::ByteRegister dst); 303 void setcc(BrCond condition, const Address &address);
294 void setcc(typename Traits::Cond::BrCond condition,
295 const typename Traits::Address &address);
296 304
297 void mov(Type Ty, typename Traits::GPRRegister dst, const Immediate &src); 305 void mov(Type Ty, GPRRegister dst, const Immediate &src);
298 void mov(Type Ty, typename Traits::GPRRegister dst, 306 void mov(Type Ty, GPRRegister dst, GPRRegister src);
299 typename Traits::GPRRegister src); 307 void mov(Type Ty, GPRRegister dst, const Address &src);
300 void mov(Type Ty, typename Traits::GPRRegister dst, 308 void mov(Type Ty, const Address &dst, GPRRegister src);
301 const typename Traits::Address &src); 309 void mov(Type Ty, const Address &dst, const Immediate &imm);
302 void mov(Type Ty, const typename Traits::Address &dst,
303 typename Traits::GPRRegister src);
304 void mov(Type Ty, const typename Traits::Address &dst, const Immediate &imm);
305 310
306 template <typename T = Traits> 311 template <typename T = Traits>
307 typename std::enable_if<T::Is64Bit, void>::type 312 typename std::enable_if<T::Is64Bit, void>::type movabs(const GPRRegister Dst,
308 movabs(const typename Traits::GPRRegister Dst, uint64_t Imm64); 313 uint64_t Imm64);
309 template <typename T = Traits> 314 template <typename T = Traits>
310 typename std::enable_if<!T::Is64Bit, void>::type 315 typename std::enable_if<!T::Is64Bit, void>::type movabs(const GPRRegister,
311 movabs(const typename Traits::GPRRegister, uint64_t) { 316 uint64_t) {
312 llvm::report_fatal_error("movabs is only supported in 64-bit x86 targets."); 317 llvm::report_fatal_error("movabs is only supported in 64-bit x86 targets.");
313 } 318 }
314 319
315 void movzx(Type Ty, typename Traits::GPRRegister dst, 320 void movzx(Type Ty, GPRRegister dst, GPRRegister src);
316 typename Traits::GPRRegister src); 321 void movzx(Type Ty, GPRRegister dst, const Address &src);
317 void movzx(Type Ty, typename Traits::GPRRegister dst, 322 void movsx(Type Ty, GPRRegister dst, GPRRegister src);
318 const typename Traits::Address &src); 323 void movsx(Type Ty, GPRRegister dst, const Address &src);
319 void movsx(Type Ty, typename Traits::GPRRegister dst,
320 typename Traits::GPRRegister src);
321 void movsx(Type Ty, typename Traits::GPRRegister dst,
322 const typename Traits::Address &src);
323 324
324 void lea(Type Ty, typename Traits::GPRRegister dst, 325 void lea(Type Ty, GPRRegister dst, const Address &src);
325 const typename Traits::Address &src);
326 326
327 void cmov(Type Ty, typename Traits::Cond::BrCond cond, 327 void cmov(Type Ty, BrCond cond, GPRRegister dst, GPRRegister src);
328 typename Traits::GPRRegister dst, typename Traits::GPRRegister src); 328 void cmov(Type Ty, BrCond cond, GPRRegister dst, const Address &src);
329 void cmov(Type Ty, typename Traits::Cond::BrCond cond,
330 typename Traits::GPRRegister dst,
331 const typename Traits::Address &src);
332 329
333 void rep_movsb(); 330 void rep_movsb();
334 331
335 void movss(Type Ty, typename Traits::XmmRegister dst, 332 void movss(Type Ty, XmmRegister dst, const Address &src);
336 const typename Traits::Address &src); 333 void movss(Type Ty, const Address &dst, XmmRegister src);
337 void movss(Type Ty, const typename Traits::Address &dst, 334 void movss(Type Ty, XmmRegister dst, XmmRegister src);
338 typename Traits::XmmRegister src);
339 void movss(Type Ty, typename Traits::XmmRegister dst,
340 typename Traits::XmmRegister src);
341 335
342 void movd(Type SrcTy, typename Traits::XmmRegister dst, 336 void movd(Type SrcTy, XmmRegister dst, GPRRegister src);
343 typename Traits::GPRRegister src); 337 void movd(Type SrcTy, XmmRegister dst, const Address &src);
344 void movd(Type SrcTy, typename Traits::XmmRegister dst, 338 void movd(Type DestTy, GPRRegister dst, XmmRegister src);
345 const typename Traits::Address &src); 339 void movd(Type DestTy, const Address &dst, XmmRegister src);
346 void movd(Type DestTy, typename Traits::GPRRegister dst,
347 typename Traits::XmmRegister src);
348 void movd(Type DestTy, const typename Traits::Address &dst,
349 typename Traits::XmmRegister src);
350 340
351 void movq(typename Traits::XmmRegister dst, typename Traits::XmmRegister src); 341 void movq(XmmRegister dst, XmmRegister src);
352 void movq(const typename Traits::Address &dst, 342 void movq(const Address &dst, XmmRegister src);
353 typename Traits::XmmRegister src); 343 void movq(XmmRegister dst, const Address &src);
354 void movq(typename Traits::XmmRegister dst,
355 const typename Traits::Address &src);
356 344
357 void addss(Type Ty, typename Traits::XmmRegister dst, 345 void addss(Type Ty, XmmRegister dst, XmmRegister src);
358 typename Traits::XmmRegister src); 346 void addss(Type Ty, XmmRegister dst, const Address &src);
359 void addss(Type Ty, typename Traits::XmmRegister dst, 347 void subss(Type Ty, XmmRegister dst, XmmRegister src);
360 const typename Traits::Address &src); 348 void subss(Type Ty, XmmRegister dst, const Address &src);
361 void subss(Type Ty, typename Traits::XmmRegister dst, 349 void mulss(Type Ty, XmmRegister dst, XmmRegister src);
362 typename Traits::XmmRegister src); 350 void mulss(Type Ty, XmmRegister dst, const Address &src);
363 void subss(Type Ty, typename Traits::XmmRegister dst, 351 void divss(Type Ty, XmmRegister dst, XmmRegister src);
364 const typename Traits::Address &src); 352 void divss(Type Ty, XmmRegister dst, const Address &src);
365 void mulss(Type Ty, typename Traits::XmmRegister dst,
366 typename Traits::XmmRegister src);
367 void mulss(Type Ty, typename Traits::XmmRegister dst,
368 const typename Traits::Address &src);
369 void divss(Type Ty, typename Traits::XmmRegister dst,
370 typename Traits::XmmRegister src);
371 void divss(Type Ty, typename Traits::XmmRegister dst,
372 const typename Traits::Address &src);
373 353
374 void movaps(typename Traits::XmmRegister dst, 354 void movaps(XmmRegister dst, XmmRegister src);
375 typename Traits::XmmRegister src);
376 355
377 void movups(typename Traits::XmmRegister dst, 356 void movups(XmmRegister dst, XmmRegister src);
378 typename Traits::XmmRegister src); 357 void movups(XmmRegister dst, const Address &src);
379 void movups(typename Traits::XmmRegister dst, 358 void movups(const Address &dst, XmmRegister src);
380 const typename Traits::Address &src);
381 void movups(const typename Traits::Address &dst,
382 typename Traits::XmmRegister src);
383 359
384 void padd(Type Ty, typename Traits::XmmRegister dst, 360 void padd(Type Ty, XmmRegister dst, XmmRegister src);
385 typename Traits::XmmRegister src); 361 void padd(Type Ty, XmmRegister dst, const Address &src);
386 void padd(Type Ty, typename Traits::XmmRegister dst, 362 void pand(Type Ty, XmmRegister dst, XmmRegister src);
387 const typename Traits::Address &src); 363 void pand(Type Ty, XmmRegister dst, const Address &src);
388 void pand(Type Ty, typename Traits::XmmRegister dst, 364 void pandn(Type Ty, XmmRegister dst, XmmRegister src);
389 typename Traits::XmmRegister src); 365 void pandn(Type Ty, XmmRegister dst, const Address &src);
390 void pand(Type Ty, typename Traits::XmmRegister dst, 366 void pmull(Type Ty, XmmRegister dst, XmmRegister src);
391 const typename Traits::Address &src); 367 void pmull(Type Ty, XmmRegister dst, const Address &src);
392 void pandn(Type Ty, typename Traits::XmmRegister dst, 368 void pmuludq(Type Ty, XmmRegister dst, XmmRegister src);
393 typename Traits::XmmRegister src); 369 void pmuludq(Type Ty, XmmRegister dst, const Address &src);
394 void pandn(Type Ty, typename Traits::XmmRegister dst, 370 void por(Type Ty, XmmRegister dst, XmmRegister src);
395 const typename Traits::Address &src); 371 void por(Type Ty, XmmRegister dst, const Address &src);
396 void pmull(Type Ty, typename Traits::XmmRegister dst, 372 void psub(Type Ty, XmmRegister dst, XmmRegister src);
397 typename Traits::XmmRegister src); 373 void psub(Type Ty, XmmRegister dst, const Address &src);
398 void pmull(Type Ty, typename Traits::XmmRegister dst, 374 void pxor(Type Ty, XmmRegister dst, XmmRegister src);
399 const typename Traits::Address &src); 375 void pxor(Type Ty, XmmRegister dst, const Address &src);
400 void pmuludq(Type Ty, typename Traits::XmmRegister dst,
401 typename Traits::XmmRegister src);
402 void pmuludq(Type Ty, typename Traits::XmmRegister dst,
403 const typename Traits::Address &src);
404 void por(Type Ty, typename Traits::XmmRegister dst,
405 typename Traits::XmmRegister src);
406 void por(Type Ty, typename Traits::XmmRegister dst,
407 const typename Traits::Address &src);
408 void psub(Type Ty, typename Traits::XmmRegister dst,
409 typename Traits::XmmRegister src);
410 void psub(Type Ty, typename Traits::XmmRegister dst,
411 const typename Traits::Address &src);
412 void pxor(Type Ty, typename Traits::XmmRegister dst,
413 typename Traits::XmmRegister src);
414 void pxor(Type Ty, typename Traits::XmmRegister dst,
415 const typename Traits::Address &src);
416 376
417 void psll(Type Ty, typename Traits::XmmRegister dst, 377 void psll(Type Ty, XmmRegister dst, XmmRegister src);
418 typename Traits::XmmRegister src); 378 void psll(Type Ty, XmmRegister dst, const Address &src);
419 void psll(Type Ty, typename Traits::XmmRegister dst, 379 void psll(Type Ty, XmmRegister dst, const Immediate &src);
420 const typename Traits::Address &src);
421 void psll(Type Ty, typename Traits::XmmRegister dst, const Immediate &src);
422 380
423 void psra(Type Ty, typename Traits::XmmRegister dst, 381 void psra(Type Ty, XmmRegister dst, XmmRegister src);
424 typename Traits::XmmRegister src); 382 void psra(Type Ty, XmmRegister dst, const Address &src);
425 void psra(Type Ty, typename Traits::XmmRegister dst, 383 void psra(Type Ty, XmmRegister dst, const Immediate &src);
426 const typename Traits::Address &src); 384 void psrl(Type Ty, XmmRegister dst, XmmRegister src);
427 void psra(Type Ty, typename Traits::XmmRegister dst, const Immediate &src); 385 void psrl(Type Ty, XmmRegister dst, const Address &src);
428 void psrl(Type Ty, typename Traits::XmmRegister dst, 386 void psrl(Type Ty, XmmRegister dst, const Immediate &src);
429 typename Traits::XmmRegister src);
430 void psrl(Type Ty, typename Traits::XmmRegister dst,
431 const typename Traits::Address &src);
432 void psrl(Type Ty, typename Traits::XmmRegister dst, const Immediate &src);
433 387
434 void addps(Type Ty, typename Traits::XmmRegister dst, 388 void addps(Type Ty, XmmRegister dst, XmmRegister src);
435 typename Traits::XmmRegister src); 389 void addps(Type Ty, XmmRegister dst, const Address &src);
436 void addps(Type Ty, typename Traits::XmmRegister dst, 390 void subps(Type Ty, XmmRegister dst, XmmRegister src);
437 const typename Traits::Address &src); 391 void subps(Type Ty, XmmRegister dst, const Address &src);
438 void subps(Type Ty, typename Traits::XmmRegister dst, 392 void divps(Type Ty, XmmRegister dst, XmmRegister src);
439 typename Traits::XmmRegister src); 393 void divps(Type Ty, XmmRegister dst, const Address &src);
440 void subps(Type Ty, typename Traits::XmmRegister dst, 394 void mulps(Type Ty, XmmRegister dst, XmmRegister src);
441 const typename Traits::Address &src); 395 void mulps(Type Ty, XmmRegister dst, const Address &src);
442 void divps(Type Ty, typename Traits::XmmRegister dst, 396 void minps(Type Ty, XmmRegister dst, const Address &src);
443 typename Traits::XmmRegister src); 397 void minps(Type Ty, XmmRegister dst, XmmRegister src);
444 void divps(Type Ty, typename Traits::XmmRegister dst, 398 void minss(Type Ty, XmmRegister dst, const Address &src);
445 const typename Traits::Address &src); 399 void minss(Type Ty, XmmRegister dst, XmmRegister src);
446 void mulps(Type Ty, typename Traits::XmmRegister dst, 400 void maxps(Type Ty, XmmRegister dst, const Address &src);
447 typename Traits::XmmRegister src); 401 void maxps(Type Ty, XmmRegister dst, XmmRegister src);
448 void mulps(Type Ty, typename Traits::XmmRegister dst, 402 void maxss(Type Ty, XmmRegister dst, const Address &src);
449 const typename Traits::Address &src); 403 void maxss(Type Ty, XmmRegister dst, XmmRegister src);
450 void minps(Type Ty, typename Traits::XmmRegister dst, 404 void andnps(Type Ty, XmmRegister dst, const Address &src);
451 const typename Traits::Address &src); 405 void andnps(Type Ty, XmmRegister dst, XmmRegister src);
452 void minps(Type Ty, typename Traits::XmmRegister dst, 406 void andps(Type Ty, XmmRegister dst, const Address &src);
453 typename Traits::XmmRegister src); 407 void andps(Type Ty, XmmRegister dst, XmmRegister src);
454 void minss(Type Ty, typename Traits::XmmRegister dst, 408 void orps(Type Ty, XmmRegister dst, const Address &src);
455 const typename Traits::Address &src); 409 void orps(Type Ty, XmmRegister dst, XmmRegister src);
456 void minss(Type Ty, typename Traits::XmmRegister dst,
457 typename Traits::XmmRegister src);
458 void maxps(Type Ty, typename Traits::XmmRegister dst,
459 const typename Traits::Address &src);
460 void maxps(Type Ty, typename Traits::XmmRegister dst,
461 typename Traits::XmmRegister src);
462 void maxss(Type Ty, typename Traits::XmmRegister dst,
463 const typename Traits::Address &src);
464 void maxss(Type Ty, typename Traits::XmmRegister dst,
465 typename Traits::XmmRegister src);
466 void andnps(Type Ty, typename Traits::XmmRegister dst,
467 const typename Traits::Address &src);
468 void andnps(Type Ty, typename Traits::XmmRegister dst,
469 typename Traits::XmmRegister src);
470 void andps(Type Ty, typename Traits::XmmRegister dst,
471 const typename Traits::Address &src);
472 void andps(Type Ty, typename Traits::XmmRegister dst,
473 typename Traits::XmmRegister src);
474 void orps(Type Ty, typename Traits::XmmRegister dst,
475 const typename Traits::Address &src);
476 void orps(Type Ty, typename Traits::XmmRegister dst,
477 typename Traits::XmmRegister src);
478 410
479 void blendvps(Type Ty, typename Traits::XmmRegister dst, 411 void blendvps(Type Ty, XmmRegister dst, XmmRegister src);
480 typename Traits::XmmRegister src); 412 void blendvps(Type Ty, XmmRegister dst, const Address &src);
481 void blendvps(Type Ty, typename Traits::XmmRegister dst, 413 void pblendvb(Type Ty, XmmRegister dst, XmmRegister src);
482 const typename Traits::Address &src); 414 void pblendvb(Type Ty, XmmRegister dst, const Address &src);
483 void pblendvb(Type Ty, typename Traits::XmmRegister dst,
484 typename Traits::XmmRegister src);
485 void pblendvb(Type Ty, typename Traits::XmmRegister dst,
486 const typename Traits::Address &src);
487 415
488 void cmpps(Type Ty, typename Traits::XmmRegister dst, 416 void cmpps(Type Ty, XmmRegister dst, XmmRegister src, CmppsCond CmpCondition);
489 typename Traits::XmmRegister src, 417 void cmpps(Type Ty, XmmRegister dst, const Address &src,
490 typename Traits::Cond::CmppsCond CmpCondition); 418 CmppsCond CmpCondition);
491 void cmpps(Type Ty, typename Traits::XmmRegister dst,
492 const typename Traits::Address &src,
493 typename Traits::Cond::CmppsCond CmpCondition);
494 419
495 void sqrtps(typename Traits::XmmRegister dst); 420 void sqrtps(XmmRegister dst);
496 void rsqrtps(typename Traits::XmmRegister dst); 421 void rsqrtps(XmmRegister dst);
497 void reciprocalps(typename Traits::XmmRegister dst); 422 void reciprocalps(XmmRegister dst);
498 423
499 void movhlps(typename Traits::XmmRegister dst, 424 void movhlps(XmmRegister dst, XmmRegister src);
500 typename Traits::XmmRegister src); 425 void movlhps(XmmRegister dst, XmmRegister src);
501 void movlhps(typename Traits::XmmRegister dst, 426 void unpcklps(XmmRegister dst, XmmRegister src);
502 typename Traits::XmmRegister src); 427 void unpckhps(XmmRegister dst, XmmRegister src);
503 void unpcklps(typename Traits::XmmRegister dst, 428 void unpcklpd(XmmRegister dst, XmmRegister src);
504 typename Traits::XmmRegister src); 429 void unpckhpd(XmmRegister dst, XmmRegister src);
505 void unpckhps(typename Traits::XmmRegister dst,
506 typename Traits::XmmRegister src);
507 void unpcklpd(typename Traits::XmmRegister dst,
508 typename Traits::XmmRegister src);
509 void unpckhpd(typename Traits::XmmRegister dst,
510 typename Traits::XmmRegister src);
511 430
512 void set1ps(typename Traits::XmmRegister dst, 431 void set1ps(XmmRegister dst, GPRRegister tmp, const Immediate &imm);
513 typename Traits::GPRRegister tmp, const Immediate &imm);
514 432
515 void sqrtpd(typename Traits::XmmRegister dst); 433 void sqrtpd(XmmRegister dst);
516 434
517 void pshufd(Type Ty, typename Traits::XmmRegister dst, 435 void pshufd(Type Ty, XmmRegister dst, XmmRegister src, const Immediate &mask);
518 typename Traits::XmmRegister src, const Immediate &mask); 436 void pshufd(Type Ty, XmmRegister dst, const Address &src,
519 void pshufd(Type Ty, typename Traits::XmmRegister dst, 437 const Immediate &mask);
520 const typename Traits::Address &src, const Immediate &mask); 438 void shufps(Type Ty, XmmRegister dst, XmmRegister src, const Immediate &mask);
521 void shufps(Type Ty, typename Traits::XmmRegister dst, 439 void shufps(Type Ty, XmmRegister dst, const Address &src,
522 typename Traits::XmmRegister src, const Immediate &mask); 440 const Immediate &mask);
523 void shufps(Type Ty, typename Traits::XmmRegister dst,
524 const typename Traits::Address &src, const Immediate &mask);
525 441
526 void cvtdq2ps(Type, typename Traits::XmmRegister dst, 442 void cvtdq2ps(Type, XmmRegister dst, XmmRegister src);
527 typename Traits::XmmRegister src); 443 void cvtdq2ps(Type, XmmRegister dst, const Address &src);
528 void cvtdq2ps(Type, typename Traits::XmmRegister dst,
529 const typename Traits::Address &src);
530 444
531 void cvttps2dq(Type, typename Traits::XmmRegister dst, 445 void cvttps2dq(Type, XmmRegister dst, XmmRegister src);
532 typename Traits::XmmRegister src); 446 void cvttps2dq(Type, XmmRegister dst, const Address &src);
533 void cvttps2dq(Type, typename Traits::XmmRegister dst,
534 const typename Traits::Address &src);
535 447
536 void cvtsi2ss(Type DestTy, typename Traits::XmmRegister dst, Type SrcTy, 448 void cvtsi2ss(Type DestTy, XmmRegister dst, Type SrcTy, GPRRegister src);
537 typename Traits::GPRRegister src); 449 void cvtsi2ss(Type DestTy, XmmRegister dst, Type SrcTy, const Address &src);
538 void cvtsi2ss(Type DestTy, typename Traits::XmmRegister dst, Type SrcTy,
539 const typename Traits::Address &src);
540 450
541 void cvtfloat2float(Type SrcTy, typename Traits::XmmRegister dst, 451 void cvtfloat2float(Type SrcTy, XmmRegister dst, XmmRegister src);
542 typename Traits::XmmRegister src); 452 void cvtfloat2float(Type SrcTy, XmmRegister dst, const Address &src);
543 void cvtfloat2float(Type SrcTy, typename Traits::XmmRegister dst,
544 const typename Traits::Address &src);
545 453
546 void cvttss2si(Type DestTy, typename Traits::GPRRegister dst, Type SrcTy, 454 void cvttss2si(Type DestTy, GPRRegister dst, Type SrcTy, XmmRegister src);
547 typename Traits::XmmRegister src); 455 void cvttss2si(Type DestTy, GPRRegister dst, Type SrcTy, const Address &src);
548 void cvttss2si(Type DestTy, typename Traits::GPRRegister dst, Type SrcTy,
549 const typename Traits::Address &src);
550 456
551 void ucomiss(Type Ty, typename Traits::XmmRegister a, 457 void ucomiss(Type Ty, XmmRegister a, XmmRegister b);
552 typename Traits::XmmRegister b); 458 void ucomiss(Type Ty, XmmRegister a, const Address &b);
553 void ucomiss(Type Ty, typename Traits::XmmRegister a,
554 const typename Traits::Address &b);
555 459
556 void movmskpd(typename Traits::GPRRegister dst, 460 void movmskpd(GPRRegister dst, XmmRegister src);
557 typename Traits::XmmRegister src); 461 void movmskps(GPRRegister dst, XmmRegister src);
558 void movmskps(typename Traits::GPRRegister dst,
559 typename Traits::XmmRegister src);
560 462
561 void sqrtss(Type Ty, typename Traits::XmmRegister dst, 463 void sqrtss(Type Ty, XmmRegister dst, const Address &src);
562 const typename Traits::Address &src); 464 void sqrtss(Type Ty, XmmRegister dst, XmmRegister src);
563 void sqrtss(Type Ty, typename Traits::XmmRegister dst,
564 typename Traits::XmmRegister src);
565 465
566 void xorps(Type Ty, typename Traits::XmmRegister dst, 466 void xorps(Type Ty, XmmRegister dst, const Address &src);
567 const typename Traits::Address &src); 467 void xorps(Type Ty, XmmRegister dst, XmmRegister src);
568 void xorps(Type Ty, typename Traits::XmmRegister dst,
569 typename Traits::XmmRegister src);
570 468
571 void insertps(Type Ty, typename Traits::XmmRegister dst, 469 void insertps(Type Ty, XmmRegister dst, XmmRegister src,
572 typename Traits::XmmRegister src, const Immediate &imm); 470 const Immediate &imm);
573 void insertps(Type Ty, typename Traits::XmmRegister dst, 471 void insertps(Type Ty, XmmRegister dst, const Address &src,
574 const typename Traits::Address &src, const Immediate &imm); 472 const Immediate &imm);
575 473
576 void pinsr(Type Ty, typename Traits::XmmRegister dst, 474 void pinsr(Type Ty, XmmRegister dst, GPRRegister src, const Immediate &imm);
577 typename Traits::GPRRegister src, const Immediate &imm); 475 void pinsr(Type Ty, XmmRegister dst, const Address &src,
578 void pinsr(Type Ty, typename Traits::XmmRegister dst, 476 const Immediate &imm);
579 const typename Traits::Address &src, const Immediate &imm);
580 477
581 void pextr(Type Ty, typename Traits::GPRRegister dst, 478 void pextr(Type Ty, GPRRegister dst, XmmRegister src, const Immediate &imm);
582 typename Traits::XmmRegister src, const Immediate &imm);
583 479
584 void pmovsxdq(typename Traits::XmmRegister dst, 480 void pmovsxdq(XmmRegister dst, XmmRegister src);
585 typename Traits::XmmRegister src);
586 481
587 void pcmpeq(Type Ty, typename Traits::XmmRegister dst, 482 void pcmpeq(Type Ty, XmmRegister dst, XmmRegister src);
588 typename Traits::XmmRegister src); 483 void pcmpeq(Type Ty, XmmRegister dst, const Address &src);
589 void pcmpeq(Type Ty, typename Traits::XmmRegister dst, 484 void pcmpgt(Type Ty, XmmRegister dst, XmmRegister src);
590 const typename Traits::Address &src); 485 void pcmpgt(Type Ty, XmmRegister dst, const Address &src);
591 void pcmpgt(Type Ty, typename Traits::XmmRegister dst,
592 typename Traits::XmmRegister src);
593 void pcmpgt(Type Ty, typename Traits::XmmRegister dst,
594 const typename Traits::Address &src);
595 486
596 enum RoundingMode { 487 enum RoundingMode {
597 kRoundToNearest = 0x0, 488 kRoundToNearest = 0x0,
598 kRoundDown = 0x1, 489 kRoundDown = 0x1,
599 kRoundUp = 0x2, 490 kRoundUp = 0x2,
600 kRoundToZero = 0x3 491 kRoundToZero = 0x3
601 }; 492 };
602 void roundsd(typename Traits::XmmRegister dst, 493 void roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode);
603 typename Traits::XmmRegister src, RoundingMode mode);
604 494
605 //---------------------------------------------------------------------------- 495 //----------------------------------------------------------------------------
606 // 496 //
607 // Begin: X87 instructions. Only available when Traits::UsesX87. 497 // Begin: X87 instructions. Only available when Traits::UsesX87.
608 // 498 //
609 //---------------------------------------------------------------------------- 499 //----------------------------------------------------------------------------
610 template <typename T = Traits, 500 template <typename T = Traits,
611 typename = typename std::enable_if<T::UsesX87>::type> 501 typename = typename std::enable_if<T::UsesX87>::type>
612 void fld(Type Ty, const typename T::Address &src); 502 void fld(Type Ty, const typename T::Address &src);
613 template <typename T = Traits, 503 template <typename T = Traits,
(...skipping 25 matching lines...) Expand all
639 529
640 template <typename T = Traits, 530 template <typename T = Traits,
641 typename = typename std::enable_if<T::UsesX87>::type> 531 typename = typename std::enable_if<T::UsesX87>::type>
642 void fincstp(); 532 void fincstp();
643 //---------------------------------------------------------------------------- 533 //----------------------------------------------------------------------------
644 // 534 //
645 // End: X87 instructions. 535 // End: X87 instructions.
646 // 536 //
647 //---------------------------------------------------------------------------- 537 //----------------------------------------------------------------------------
648 538
649 void cmp(Type Ty, typename Traits::GPRRegister reg0, 539 void cmp(Type Ty, GPRRegister reg0, GPRRegister reg1);
650 typename Traits::GPRRegister reg1); 540 void cmp(Type Ty, GPRRegister reg, const Address &address);
651 void cmp(Type Ty, typename Traits::GPRRegister reg, 541 void cmp(Type Ty, GPRRegister reg, const Immediate &imm);
652 const typename Traits::Address &address); 542 void cmp(Type Ty, const Address &address, GPRRegister reg);
653 void cmp(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); 543 void cmp(Type Ty, const Address &address, const Immediate &imm);
654 void cmp(Type Ty, const typename Traits::Address &address,
655 typename Traits::GPRRegister reg);
656 void cmp(Type Ty, const typename Traits::Address &address,
657 const Immediate &imm);
658 544
659 void test(Type Ty, typename Traits::GPRRegister reg0, 545 void test(Type Ty, GPRRegister reg0, GPRRegister reg1);
660 typename Traits::GPRRegister reg1); 546 void test(Type Ty, GPRRegister reg, const Immediate &imm);
661 void test(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); 547 void test(Type Ty, const Address &address, GPRRegister reg);
662 void test(Type Ty, const typename Traits::Address &address, 548 void test(Type Ty, const Address &address, const Immediate &imm);
663 typename Traits::GPRRegister reg);
664 void test(Type Ty, const typename Traits::Address &address,
665 const Immediate &imm);
666 549
667 void And(Type Ty, typename Traits::GPRRegister dst, 550 void And(Type Ty, GPRRegister dst, GPRRegister src);
668 typename Traits::GPRRegister src); 551 void And(Type Ty, GPRRegister dst, const Address &address);
669 void And(Type Ty, typename Traits::GPRRegister dst, 552 void And(Type Ty, GPRRegister dst, const Immediate &imm);
670 const typename Traits::Address &address); 553 void And(Type Ty, const Address &address, GPRRegister reg);
671 void And(Type Ty, typename Traits::GPRRegister dst, const Immediate &imm); 554 void And(Type Ty, const Address &address, const Immediate &imm);
672 void And(Type Ty, const typename Traits::Address &address,
673 typename Traits::GPRRegister reg);
674 void And(Type Ty, const typename Traits::Address &address,
675 const Immediate &imm);
676 555
677 void Or(Type Ty, typename Traits::GPRRegister dst, 556 void Or(Type Ty, GPRRegister dst, GPRRegister src);
678 typename Traits::GPRRegister src); 557 void Or(Type Ty, GPRRegister dst, const Address &address);
679 void Or(Type Ty, typename Traits::GPRRegister dst, 558 void Or(Type Ty, GPRRegister dst, const Immediate &imm);
680 const typename Traits::Address &address); 559 void Or(Type Ty, const Address &address, GPRRegister reg);
681 void Or(Type Ty, typename Traits::GPRRegister dst, const Immediate &imm); 560 void Or(Type Ty, const Address &address, const Immediate &imm);
682 void Or(Type Ty, const typename Traits::Address &address,
683 typename Traits::GPRRegister reg);
684 void Or(Type Ty, const typename Traits::Address &address,
685 const Immediate &imm);
686 561
687 void Xor(Type Ty, typename Traits::GPRRegister dst, 562 void Xor(Type Ty, GPRRegister dst, GPRRegister src);
688 typename Traits::GPRRegister src); 563 void Xor(Type Ty, GPRRegister dst, const Address &address);
689 void Xor(Type Ty, typename Traits::GPRRegister dst, 564 void Xor(Type Ty, GPRRegister dst, const Immediate &imm);
690 const typename Traits::Address &address); 565 void Xor(Type Ty, const Address &address, GPRRegister reg);
691 void Xor(Type Ty, typename Traits::GPRRegister dst, const Immediate &imm); 566 void Xor(Type Ty, const Address &address, const Immediate &imm);
692 void Xor(Type Ty, const typename Traits::Address &address,
693 typename Traits::GPRRegister reg);
694 void Xor(Type Ty, const typename Traits::Address &address,
695 const Immediate &imm);
696 567
697 void add(Type Ty, typename Traits::GPRRegister dst, 568 void add(Type Ty, GPRRegister dst, GPRRegister src);
698 typename Traits::GPRRegister src); 569 void add(Type Ty, GPRRegister reg, const Address &address);
699 void add(Type Ty, typename Traits::GPRRegister reg, 570 void add(Type Ty, GPRRegister reg, const Immediate &imm);
700 const typename Traits::Address &address); 571 void add(Type Ty, const Address &address, GPRRegister reg);
701 void add(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); 572 void add(Type Ty, const Address &address, const Immediate &imm);
702 void add(Type Ty, const typename Traits::Address &address,
703 typename Traits::GPRRegister reg);
704 void add(Type Ty, const typename Traits::Address &address,
705 const Immediate &imm);
706 573
707 void adc(Type Ty, typename Traits::GPRRegister dst, 574 void adc(Type Ty, GPRRegister dst, GPRRegister src);
708 typename Traits::GPRRegister src); 575 void adc(Type Ty, GPRRegister dst, const Address &address);
709 void adc(Type Ty, typename Traits::GPRRegister dst, 576 void adc(Type Ty, GPRRegister reg, const Immediate &imm);
710 const typename Traits::Address &address); 577 void adc(Type Ty, const Address &address, GPRRegister reg);
711 void adc(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); 578 void adc(Type Ty, const Address &address, const Immediate &imm);
712 void adc(Type Ty, const typename Traits::Address &address,
713 typename Traits::GPRRegister reg);
714 void adc(Type Ty, const typename Traits::Address &address,
715 const Immediate &imm);
716 579
717 void sub(Type Ty, typename Traits::GPRRegister dst, 580 void sub(Type Ty, GPRRegister dst, GPRRegister src);
718 typename Traits::GPRRegister src); 581 void sub(Type Ty, GPRRegister reg, const Address &address);
719 void sub(Type Ty, typename Traits::GPRRegister reg, 582 void sub(Type Ty, GPRRegister reg, const Immediate &imm);
720 const typename Traits::Address &address); 583 void sub(Type Ty, const Address &address, GPRRegister reg);
721 void sub(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); 584 void sub(Type Ty, const Address &address, const Immediate &imm);
722 void sub(Type Ty, const typename Traits::Address &address,
723 typename Traits::GPRRegister reg);
724 void sub(Type Ty, const typename Traits::Address &address,
725 const Immediate &imm);
726 585
727 void sbb(Type Ty, typename Traits::GPRRegister dst, 586 void sbb(Type Ty, GPRRegister dst, GPRRegister src);
728 typename Traits::GPRRegister src); 587 void sbb(Type Ty, GPRRegister reg, const Address &address);
729 void sbb(Type Ty, typename Traits::GPRRegister reg, 588 void sbb(Type Ty, GPRRegister reg, const Immediate &imm);
730 const typename Traits::Address &address); 589 void sbb(Type Ty, const Address &address, GPRRegister reg);
731 void sbb(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); 590 void sbb(Type Ty, const Address &address, const Immediate &imm);
732 void sbb(Type Ty, const typename Traits::Address &address,
733 typename Traits::GPRRegister reg);
734 void sbb(Type Ty, const typename Traits::Address &address,
735 const Immediate &imm);
736 591
737 void cbw(); 592 void cbw();
738 void cwd(); 593 void cwd();
739 void cdq(); 594 void cdq();
740 template <typename T = Traits> 595 template <typename T = Traits>
741 typename std::enable_if<T::Is64Bit, void>::type cqo(); 596 typename std::enable_if<T::Is64Bit, void>::type cqo();
742 template <typename T = Traits> 597 template <typename T = Traits>
743 typename std::enable_if<!T::Is64Bit, void>::type cqo() { 598 typename std::enable_if<!T::Is64Bit, void>::type cqo() {
744 llvm::report_fatal_error("CQO is only available in 64-bit x86 backends."); 599 llvm::report_fatal_error("CQO is only available in 64-bit x86 backends.");
745 } 600 }
746 601
747 void div(Type Ty, typename Traits::GPRRegister reg); 602 void div(Type Ty, GPRRegister reg);
748 void div(Type Ty, const typename Traits::Address &address); 603 void div(Type Ty, const Address &address);
749 604
750 void idiv(Type Ty, typename Traits::GPRRegister reg); 605 void idiv(Type Ty, GPRRegister reg);
751 void idiv(Type Ty, const typename Traits::Address &address); 606 void idiv(Type Ty, const Address &address);
752 607
753 void imul(Type Ty, typename Traits::GPRRegister dst, 608 void imul(Type Ty, GPRRegister dst, GPRRegister src);
754 typename Traits::GPRRegister src); 609 void imul(Type Ty, GPRRegister reg, const Immediate &imm);
755 void imul(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); 610 void imul(Type Ty, GPRRegister reg, const Address &address);
756 void imul(Type Ty, typename Traits::GPRRegister reg,
757 const typename Traits::Address &address);
758 611
759 void imul(Type Ty, typename Traits::GPRRegister reg); 612 void imul(Type Ty, GPRRegister reg);
760 void imul(Type Ty, const typename Traits::Address &address); 613 void imul(Type Ty, const Address &address);
761 614
762 void imul(Type Ty, typename Traits::GPRRegister dst, 615 void imul(Type Ty, GPRRegister dst, GPRRegister src, const Immediate &imm);
763 typename Traits::GPRRegister src, const Immediate &imm); 616 void imul(Type Ty, GPRRegister dst, const Address &address,
764 void imul(Type Ty, typename Traits::GPRRegister dst, 617 const Immediate &imm);
765 const typename Traits::Address &address, const Immediate &imm);
766 618
767 void mul(Type Ty, typename Traits::GPRRegister reg); 619 void mul(Type Ty, GPRRegister reg);
768 void mul(Type Ty, const typename Traits::Address &address); 620 void mul(Type Ty, const Address &address);
769 621
770 template <class T = Traits, 622 template <class T = Traits,
771 typename = typename std::enable_if<!T::Is64Bit>::type> 623 typename = typename std::enable_if<!T::Is64Bit>::type>
772 void incl(typename Traits::GPRRegister reg); 624 void incl(GPRRegister reg);
773 void incl(const typename Traits::Address &address); 625 void incl(const Address &address);
774 626
775 template <class T = Traits, 627 template <class T = Traits,
776 typename = typename std::enable_if<!T::Is64Bit>::type> 628 typename = typename std::enable_if<!T::Is64Bit>::type>
777 void decl(typename Traits::GPRRegister reg); 629 void decl(GPRRegister reg);
778 void decl(const typename Traits::Address &address); 630 void decl(const Address &address);
779 631
780 void rol(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); 632 void rol(Type Ty, GPRRegister reg, const Immediate &imm);
781 void rol(Type Ty, typename Traits::GPRRegister operand, 633 void rol(Type Ty, GPRRegister operand, GPRRegister shifter);
782 typename Traits::GPRRegister shifter); 634 void rol(Type Ty, const Address &operand, GPRRegister shifter);
783 void rol(Type Ty, const typename Traits::Address &operand,
784 typename Traits::GPRRegister shifter);
785 635
786 void shl(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); 636 void shl(Type Ty, GPRRegister reg, const Immediate &imm);
787 void shl(Type Ty, typename Traits::GPRRegister operand, 637 void shl(Type Ty, GPRRegister operand, GPRRegister shifter);
788 typename Traits::GPRRegister shifter); 638 void shl(Type Ty, const Address &operand, GPRRegister shifter);
789 void shl(Type Ty, const typename Traits::Address &operand,
790 typename Traits::GPRRegister shifter);
791 639
792 void shr(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); 640 void shr(Type Ty, GPRRegister reg, const Immediate &imm);
793 void shr(Type Ty, typename Traits::GPRRegister operand, 641 void shr(Type Ty, GPRRegister operand, GPRRegister shifter);
794 typename Traits::GPRRegister shifter); 642 void shr(Type Ty, const Address &operand, GPRRegister shifter);
795 void shr(Type Ty, const typename Traits::Address &operand,
796 typename Traits::GPRRegister shifter);
797 643
798 void sar(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); 644 void sar(Type Ty, GPRRegister reg, const Immediate &imm);
799 void sar(Type Ty, typename Traits::GPRRegister operand, 645 void sar(Type Ty, GPRRegister operand, GPRRegister shifter);
800 typename Traits::GPRRegister shifter); 646 void sar(Type Ty, const Address &address, GPRRegister shifter);
801 void sar(Type Ty, const typename Traits::Address &address,
802 typename Traits::GPRRegister shifter);
803 647
804 void shld(Type Ty, typename Traits::GPRRegister dst, 648 void shld(Type Ty, GPRRegister dst, GPRRegister src);
805 typename Traits::GPRRegister src); 649 void shld(Type Ty, GPRRegister dst, GPRRegister src, const Immediate &imm);
806 void shld(Type Ty, typename Traits::GPRRegister dst, 650 void shld(Type Ty, const Address &operand, GPRRegister src);
807 typename Traits::GPRRegister src, const Immediate &imm); 651 void shrd(Type Ty, GPRRegister dst, GPRRegister src);
808 void shld(Type Ty, const typename Traits::Address &operand, 652 void shrd(Type Ty, GPRRegister dst, GPRRegister src, const Immediate &imm);
809 typename Traits::GPRRegister src); 653 void shrd(Type Ty, const Address &dst, GPRRegister src);
810 void shrd(Type Ty, typename Traits::GPRRegister dst,
811 typename Traits::GPRRegister src);
812 void shrd(Type Ty, typename Traits::GPRRegister dst,
813 typename Traits::GPRRegister src, const Immediate &imm);
814 void shrd(Type Ty, const typename Traits::Address &dst,
815 typename Traits::GPRRegister src);
816 654
817 void neg(Type Ty, typename Traits::GPRRegister reg); 655 void neg(Type Ty, GPRRegister reg);
818 void neg(Type Ty, const typename Traits::Address &addr); 656 void neg(Type Ty, const Address &addr);
819 void notl(typename Traits::GPRRegister reg); 657 void notl(GPRRegister reg);
820 658
821 void bsf(Type Ty, typename Traits::GPRRegister dst, 659 void bsf(Type Ty, GPRRegister dst, GPRRegister src);
822 typename Traits::GPRRegister src); 660 void bsf(Type Ty, GPRRegister dst, const Address &src);
823 void bsf(Type Ty, typename Traits::GPRRegister dst, 661 void bsr(Type Ty, GPRRegister dst, GPRRegister src);
824 const typename Traits::Address &src); 662 void bsr(Type Ty, GPRRegister dst, const Address &src);
825 void bsr(Type Ty, typename Traits::GPRRegister dst,
826 typename Traits::GPRRegister src);
827 void bsr(Type Ty, typename Traits::GPRRegister dst,
828 const typename Traits::Address &src);
829 663
830 void bswap(Type Ty, typename Traits::GPRRegister reg); 664 void bswap(Type Ty, GPRRegister reg);
831 665
832 void bt(typename Traits::GPRRegister base, 666 void bt(GPRRegister base, GPRRegister offset);
833 typename Traits::GPRRegister offset);
834 667
835 void ret(); 668 void ret();
836 void ret(const Immediate &imm); 669 void ret(const Immediate &imm);
837 670
838 // 'size' indicates size in bytes and must be in the range 1..8. 671 // 'size' indicates size in bytes and must be in the range 1..8.
839 void nop(int size = 1); 672 void nop(int size = 1);
840 void int3(); 673 void int3();
841 void hlt(); 674 void hlt();
842 void ud2(); 675 void ud2();
843 676
844 // j(Label) is fully tested. 677 // j(Label) is fully tested.
845 void j(typename Traits::Cond::BrCond condition, Label *label, 678 void j(BrCond condition, Label *label, bool near = kFarJump);
846 bool near = kFarJump); 679 void j(BrCond condition, const ConstantRelocatable *label); // not testable.
847 void j(typename Traits::Cond::BrCond condition,
848 const ConstantRelocatable *label); // not testable.
849 680
850 void jmp(typename Traits::GPRRegister reg); 681 void jmp(GPRRegister reg);
851 void jmp(Label *label, bool near = kFarJump); 682 void jmp(Label *label, bool near = kFarJump);
852 void jmp(const ConstantRelocatable *label); // not testable. 683 void jmp(const ConstantRelocatable *label); // not testable.
853 684
854 void mfence(); 685 void mfence();
855 686
856 void lock(); 687 void lock();
857 void cmpxchg(Type Ty, const typename Traits::Address &address, 688 void cmpxchg(Type Ty, const Address &address, GPRRegister reg, bool Locked);
858 typename Traits::GPRRegister reg, bool Locked); 689 void cmpxchg8b(const Address &address, bool Locked);
859 void cmpxchg8b(const typename Traits::Address &address, bool Locked); 690 void xadd(Type Ty, const Address &address, GPRRegister reg, bool Locked);
860 void xadd(Type Ty, const typename Traits::Address &address, 691 void xchg(Type Ty, GPRRegister reg0, GPRRegister reg1);
861 typename Traits::GPRRegister reg, bool Locked); 692 void xchg(Type Ty, const Address &address, GPRRegister reg);
862 void xchg(Type Ty, typename Traits::GPRRegister reg0,
863 typename Traits::GPRRegister reg1);
864 void xchg(Type Ty, const typename Traits::Address &address,
865 typename Traits::GPRRegister reg);
866 693
867 /// \name Intel Architecture Code Analyzer markers. 694 /// \name Intel Architecture Code Analyzer markers.
868 /// @{ 695 /// @{
869 void iaca_start(); 696 void iaca_start();
870 void iaca_end(); 697 void iaca_end();
871 /// @} 698 /// @}
872 699
873 void emitSegmentOverride(uint8_t prefix); 700 void emitSegmentOverride(uint8_t prefix);
874 701
875 intptr_t preferredLoopAlignment() { return 16; } 702 intptr_t preferredLoopAlignment() { return 16; }
876 void align(intptr_t alignment, intptr_t offset); 703 void align(intptr_t alignment, intptr_t offset);
877 void bind(Label *label); 704 void bind(Label *label);
878 705
879 intptr_t CodeSize() const { return Buffer.size(); } 706 intptr_t CodeSize() const { return Buffer.size(); }
880 707
881 protected: 708 protected:
882 inline void emitUint8(uint8_t value); 709 inline void emitUint8(uint8_t value);
883 710
884 private: 711 private:
712 ENABLE_MAKE_UNIQUE;
713
885 static constexpr Type RexTypeIrrelevant = IceType_i32; 714 static constexpr Type RexTypeIrrelevant = IceType_i32;
886 static constexpr Type RexTypeForceRexW = IceType_i64; 715 static constexpr Type RexTypeForceRexW = IceType_i64;
887 static constexpr typename Traits::GPRRegister RexRegIrrelevant = 716 static constexpr GPRRegister RexRegIrrelevant =
888 Traits::GPRRegister::Encoded_Reg_eax; 717 Traits::GPRRegister::Encoded_Reg_eax;
889 718
890 inline void emitInt16(int16_t value); 719 inline void emitInt16(int16_t value);
891 inline void emitInt32(int32_t value); 720 inline void emitInt32(int32_t value);
892 inline void emitRegisterOperand(int rm, int reg); 721 inline void emitRegisterOperand(int rm, int reg);
893 template <typename RegType, typename RmType> 722 template <typename RegType, typename RmType>
894 inline void emitXmmRegisterOperand(RegType reg, RmType rm); 723 inline void emitXmmRegisterOperand(RegType reg, RmType rm);
895 inline void emitOperandSizeOverride(); 724 inline void emitOperandSizeOverride();
896 725
897 void emitOperand(int rm, const typename Traits::Operand &operand); 726 void emitOperand(int rm, const Operand &operand);
898 void emitImmediate(Type ty, const Immediate &imm); 727 void emitImmediate(Type ty, const Immediate &imm);
899 void emitComplexI8(int rm, const typename Traits::Operand &operand, 728 void emitComplexI8(int rm, const Operand &operand,
900 const Immediate &immediate); 729 const Immediate &immediate);
901 void emitComplex(Type Ty, int rm, const typename Traits::Operand &operand, 730 void emitComplex(Type Ty, int rm, const Operand &operand,
902 const Immediate &immediate); 731 const Immediate &immediate);
903 void emitLabel(Label *label, intptr_t instruction_size); 732 void emitLabel(Label *label, intptr_t instruction_size);
904 void emitLabelLink(Label *label); 733 void emitLabelLink(Label *label);
905 void emitNearLabelLink(Label *label); 734 void emitNearLabelLink(Label *label);
906 735
907 void emitGenericShift(int rm, Type Ty, typename Traits::GPRRegister reg, 736 void emitGenericShift(int rm, Type Ty, GPRRegister reg, const Immediate &imm);
908 const Immediate &imm); 737 void emitGenericShift(int rm, Type Ty, const Operand &operand,
909 void emitGenericShift(int rm, Type Ty, 738 GPRRegister shifter);
910 const typename Traits::Operand &operand,
911 typename Traits::GPRRegister shifter);
912 739
913 using LabelVector = std::vector<Label *>; 740 using LabelVector = std::vector<Label *>;
914 // A vector of pool-allocated x86 labels for CFG nodes. 741 // A vector of pool-allocated x86 labels for CFG nodes.
915 LabelVector CfgNodeLabels; 742 LabelVector CfgNodeLabels;
916 // A vector of pool-allocated x86 labels for Local labels. 743 // A vector of pool-allocated x86 labels for Local labels.
917 LabelVector LocalLabels; 744 LabelVector LocalLabels;
918 745
919 Label *getOrCreateLabel(SizeT Number, LabelVector &Labels); 746 Label *getOrCreateLabel(SizeT Number, LabelVector &Labels);
920 747
921 void emitAddrSizeOverridePrefix() { 748 void emitAddrSizeOverridePrefix() {
922 if (!Traits::Is64Bit) { 749 if (!Traits::Is64Bit) {
923 return; 750 return;
924 } 751 }
925 static constexpr uint8_t AddrSizeOverridePrefix = 0x67; 752 static constexpr uint8_t AddrSizeOverridePrefix = 0x67;
926 emitUint8(AddrSizeOverridePrefix); 753 emitUint8(AddrSizeOverridePrefix);
927 } 754 }
928 755
929 // The arith_int() methods factor out the commonality between the encodings 756 // The arith_int() methods factor out the commonality between the encodings
930 // of add(), Or(), adc(), sbb(), And(), sub(), Xor(), and cmp(). The Tag 757 // of add(), Or(), adc(), sbb(), And(), sub(), Xor(), and cmp(). The Tag
931 // parameter is statically asserted to be less than 8. 758 // parameter is statically asserted to be less than 8.
932 template <uint32_t Tag> 759 template <uint32_t Tag>
933 void arith_int(Type Ty, typename Traits::GPRRegister reg, 760 void arith_int(Type Ty, GPRRegister reg, const Immediate &imm);
934 const Immediate &imm);
935 761
936 template <uint32_t Tag> 762 template <uint32_t Tag>
937 void arith_int(Type Ty, typename Traits::GPRRegister reg0, 763 void arith_int(Type Ty, GPRRegister reg0, GPRRegister reg1);
938 typename Traits::GPRRegister reg1);
939 764
940 template <uint32_t Tag> 765 template <uint32_t Tag>
941 void arith_int(Type Ty, typename Traits::GPRRegister reg, 766 void arith_int(Type Ty, GPRRegister reg, const Address &address);
942 const typename Traits::Address &address);
943 767
944 template <uint32_t Tag> 768 template <uint32_t Tag>
945 void arith_int(Type Ty, const typename Traits::Address &address, 769 void arith_int(Type Ty, const Address &address, GPRRegister reg);
946 typename Traits::GPRRegister reg);
947 770
948 template <uint32_t Tag> 771 template <uint32_t Tag>
949 void arith_int(Type Ty, const typename Traits::Address &address, 772 void arith_int(Type Ty, const Address &address, const Immediate &imm);
950 const Immediate &imm);
951 773
952 // gprEncoding returns Reg encoding for operand emission. For x86-64 we mask 774 // gprEncoding returns Reg encoding for operand emission. For x86-64 we mask
953 // out the 4th bit as it is encoded in the REX.[RXB] bits. No other bits are 775 // out the 4th bit as it is encoded in the REX.[RXB] bits. No other bits are
954 // touched because we don't want to mask errors. 776 // touched because we don't want to mask errors.
955 template <typename RegType, typename T = Traits> 777 template <typename RegType, typename T = Traits>
956 typename std::enable_if<T::Is64Bit, typename T::GPRRegister>::type 778 typename std::enable_if<T::Is64Bit, typename T::GPRRegister>::type
957 gprEncoding(const RegType Reg) { 779 gprEncoding(const RegType Reg) {
958 return static_cast<typename Traits::GPRRegister>(static_cast<uint8_t>(Reg) & 780 return static_cast<GPRRegister>(static_cast<uint8_t>(Reg) & ~0x08);
959 ~0x08);
960 } 781 }
961 782
962 template <typename RegType, typename T = Traits> 783 template <typename RegType, typename T = Traits>
963 typename std::enable_if<!T::Is64Bit, typename T::GPRRegister>::type 784 typename std::enable_if<!T::Is64Bit, typename T::GPRRegister>::type
964 gprEncoding(const RegType Reg) { 785 gprEncoding(const RegType Reg) {
965 return static_cast<typename T::GPRRegister>(Reg); 786 return static_cast<typename T::GPRRegister>(Reg);
966 } 787 }
967 788
968 template <typename RegType> 789 template <typename RegType>
969 bool is8BitRegisterRequiringRex(const Type Ty, const RegType Reg) { 790 bool is8BitRegisterRequiringRex(const Type Ty, const RegType Reg) {
970 static constexpr bool IsGPR = 791 static constexpr bool IsGPR =
971 std::is_same<typename std::decay<RegType>::type, 792 std::is_same<typename std::decay<RegType>::type, ByteRegister>::value ||
972 typename Traits::ByteRegister>::value || 793 std::is_same<typename std::decay<RegType>::type, GPRRegister>::value;
973 std::is_same<typename std::decay<RegType>::type,
974 typename Traits::GPRRegister>::value;
975 794
976 // At this point in the assembler, we have encoded regs, so it is not 795 // At this point in the assembler, we have encoded regs, so it is not
977 // possible to distinguish between the "new" low byte registers introduced 796 // possible to distinguish between the "new" low byte registers introduced
978 // in x86-64 and the legacy [abcd]h registers. Because x86, we may still see 797 // in x86-64 and the legacy [abcd]h registers. Because x86, we may still
979 // ah (div) in the assembler, so we whitelist it here. 798 // see ah (div) in the assembler, so we whitelist it here.
980 // 799 //
981 // The "local" uint32_t Encoded_Reg_ah is needed because RegType is an enum 800 // The "local" uint32_t Encoded_Reg_ah is needed because RegType is an
982 // that is not necessarily the same type of 801 // enum that is not necessarily the same type of
983 // Traits::RegisterSet::Encoded_Reg_ah. 802 // Traits::RegisterSet::Encoded_Reg_ah.
984 constexpr uint32_t Encoded_Reg_ah = Traits::RegisterSet::Encoded_Reg_ah; 803 constexpr uint32_t Encoded_Reg_ah = Traits::RegisterSet::Encoded_Reg_ah;
985 return IsGPR && (Reg & 0x04) != 0 && (Reg & 0x08) == 0 && 804 return IsGPR && (Reg & 0x04) != 0 && (Reg & 0x08) == 0 &&
986 isByteSizedType(Ty) && (Reg != Encoded_Reg_ah); 805 isByteSizedType(Ty) && (Reg != Encoded_Reg_ah);
987 } 806 }
988 807
989 // assembleAndEmitRex is used for determining which (if any) rex prefix 808 // assembleAndEmitRex is used for determining which (if any) rex prefix
990 // should be emitted for the current instruction. It allows different types 809 // should be emitted for the current instruction. It allows different types
991 // for Reg and Rm because they could be of different types (e.g., in mov[sz]x 810 // for Reg and Rm because they could be of different types (e.g., in
992 // instructions.) If Addr is not nullptr, then Rm is ignored, and Rex.B is 811 // mov[sz]x instructions.) If Addr is not nullptr, then Rm is ignored, and
993 // determined by Addr instead. TyRm is still used to determine Addr's size. 812 // Rex.B is determined by Addr instead. TyRm is still used to determine
813 // Addr's size.
994 template <typename RegType, typename RmType, typename T = Traits> 814 template <typename RegType, typename RmType, typename T = Traits>
995 typename std::enable_if<T::Is64Bit, void>::type 815 typename std::enable_if<T::Is64Bit, void>::type
996 assembleAndEmitRex(const Type TyReg, const RegType Reg, const Type TyRm, 816 assembleAndEmitRex(const Type TyReg, const RegType Reg, const Type TyRm,
997 const RmType Rm, 817 const RmType Rm,
998 const typename T::Address *Addr = nullptr) { 818 const typename T::Address *Addr = nullptr) {
999 const uint8_t W = (TyReg == IceType_i64 || TyRm == IceType_i64) 819 const uint8_t W = (TyReg == IceType_i64 || TyRm == IceType_i64)
1000 ? T::Operand::RexW 820 ? T::Operand::RexW
1001 : T::Operand::RexNone; 821 : T::Operand::RexNone;
1002 const uint8_t R = (Reg & 0x08) ? T::Operand::RexR : T::Operand::RexNone; 822 const uint8_t R = (Reg & 0x08) ? T::Operand::RexR : T::Operand::RexNone;
1003 const uint8_t X = (Addr != nullptr) 823 const uint8_t X = (Addr != nullptr)
(...skipping 10 matching lines...) Expand all
1014 (Addr == nullptr && is8BitRegisterRequiringRex(TyRm, Rm))) { 834 (Addr == nullptr && is8BitRegisterRequiringRex(TyRm, Rm))) {
1015 emitUint8(T::Operand::RexBase); 835 emitUint8(T::Operand::RexBase);
1016 } 836 }
1017 } 837 }
1018 838
1019 template <typename RegType, typename RmType, typename T = Traits> 839 template <typename RegType, typename RmType, typename T = Traits>
1020 typename std::enable_if<!T::Is64Bit, void>::type 840 typename std::enable_if<!T::Is64Bit, void>::type
1021 assembleAndEmitRex(const Type, const RegType, const Type, const RmType, 841 assembleAndEmitRex(const Type, const RegType, const Type, const RmType,
1022 const typename T::Address * = nullptr) {} 842 const typename T::Address * = nullptr) {}
1023 843
1024 // emitRexRB is used for emitting a Rex prefix instructions with two explicit 844 // emitRexRB is used for emitting a Rex prefix instructions with two
1025 // register operands in its mod-rm byte. 845 // explicit register operands in its mod-rm byte.
1026 template <typename RegType, typename RmType> 846 template <typename RegType, typename RmType>
1027 void emitRexRB(const Type Ty, const RegType Reg, const RmType Rm) { 847 void emitRexRB(const Type Ty, const RegType Reg, const RmType Rm) {
1028 assembleAndEmitRex(Ty, Reg, Ty, Rm); 848 assembleAndEmitRex(Ty, Reg, Ty, Rm);
1029 } 849 }
1030 850
1031 template <typename RegType, typename RmType> 851 template <typename RegType, typename RmType>
1032 void emitRexRB(const Type TyReg, const RegType Reg, const Type TyRm, 852 void emitRexRB(const Type TyReg, const RegType Reg, const Type TyRm,
1033 const RmType Rm) { 853 const RmType Rm) {
1034 assembleAndEmitRex(TyReg, Reg, TyRm, Rm); 854 assembleAndEmitRex(TyReg, Reg, TyRm, Rm);
1035 } 855 }
1036 856
1037 // emitRexB is used for emitting a Rex prefix if one is needed on encoding 857 // emitRexB is used for emitting a Rex prefix if one is needed on encoding
1038 // the Reg field in an x86 instruction. It is invoked by the template when 858 // the Reg field in an x86 instruction. It is invoked by the template when
1039 // Reg is the single register operand in the instruction (e.g., push Reg.) 859 // Reg is the single register operand in the instruction (e.g., push Reg.)
1040 template <typename RmType> void emitRexB(const Type Ty, const RmType Rm) { 860 template <typename RmType> void emitRexB(const Type Ty, const RmType Rm) {
1041 emitRexRB(Ty, RexRegIrrelevant, Ty, Rm); 861 emitRexRB(Ty, RexRegIrrelevant, Ty, Rm);
1042 } 862 }
1043 863
1044 // emitRex is used for emitting a Rex prefix for an address and a GPR. The 864 // emitRex is used for emitting a Rex prefix for an address and a GPR. The
1045 // address may contain zero, one, or two registers. 865 // address may contain zero, one, or two registers.
1046 template <typename RegType> 866 template <typename RegType>
1047 void emitRex(const Type Ty, const typename Traits::Address &Addr, 867 void emitRex(const Type Ty, const Address &Addr, const RegType Reg) {
1048 const RegType Reg) {
1049 assembleAndEmitRex(Ty, Reg, Ty, RexRegIrrelevant, &Addr); 868 assembleAndEmitRex(Ty, Reg, Ty, RexRegIrrelevant, &Addr);
1050 } 869 }
1051 870
1052 template <typename RegType> 871 template <typename RegType>
1053 void emitRex(const Type AddrTy, const typename Traits::Address &Addr, 872 void emitRex(const Type AddrTy, const Address &Addr, const Type TyReg,
1054 const Type TyReg, const RegType Reg) { 873 const RegType Reg) {
1055 assembleAndEmitRex(TyReg, Reg, AddrTy, RexRegIrrelevant, &Addr); 874 assembleAndEmitRex(TyReg, Reg, AddrTy, RexRegIrrelevant, &Addr);
1056 } 875 }
1057 }; 876 };
1058 877
1059 template <class Machine> 878 template <typename TraitsType>
1060 inline void AssemblerX86Base<Machine>::emitUint8(uint8_t value) { 879 inline void AssemblerX86Base<TraitsType>::emitUint8(uint8_t value) {
1061 Buffer.emit<uint8_t>(value); 880 Buffer.emit<uint8_t>(value);
1062 } 881 }
1063 882
1064 template <class Machine> 883 template <typename TraitsType>
1065 inline void AssemblerX86Base<Machine>::emitInt16(int16_t value) { 884 inline void AssemblerX86Base<TraitsType>::emitInt16(int16_t value) {
1066 Buffer.emit<int16_t>(value); 885 Buffer.emit<int16_t>(value);
1067 } 886 }
1068 887
1069 template <class Machine> 888 template <typename TraitsType>
1070 inline void AssemblerX86Base<Machine>::emitInt32(int32_t value) { 889 inline void AssemblerX86Base<TraitsType>::emitInt32(int32_t value) {
1071 Buffer.emit<int32_t>(value); 890 Buffer.emit<int32_t>(value);
1072 } 891 }
1073 892
1074 template <class Machine> 893 template <typename TraitsType>
1075 inline void AssemblerX86Base<Machine>::emitRegisterOperand(int reg, int rm) { 894 inline void AssemblerX86Base<TraitsType>::emitRegisterOperand(int reg, int rm) {
1076 assert(reg >= 0 && reg < 8); 895 assert(reg >= 0 && reg < 8);
1077 assert(rm >= 0 && rm < 8); 896 assert(rm >= 0 && rm < 8);
1078 Buffer.emit<uint8_t>(0xC0 + (reg << 3) + rm); 897 Buffer.emit<uint8_t>(0xC0 + (reg << 3) + rm);
1079 } 898 }
1080 899
1081 template <class Machine> 900 template <typename TraitsType>
1082 template <typename RegType, typename RmType> 901 template <typename RegType, typename RmType>
1083 inline void AssemblerX86Base<Machine>::emitXmmRegisterOperand(RegType reg, 902 inline void AssemblerX86Base<TraitsType>::emitXmmRegisterOperand(RegType reg,
1084 RmType rm) { 903 RmType rm) {
1085 emitRegisterOperand(gprEncoding(reg), gprEncoding(rm)); 904 emitRegisterOperand(gprEncoding(reg), gprEncoding(rm));
1086 } 905 }
1087 906
1088 template <class Machine> 907 template <typename TraitsType>
1089 inline void AssemblerX86Base<Machine>::emitOperandSizeOverride() { 908 inline void AssemblerX86Base<TraitsType>::emitOperandSizeOverride() {
1090 emitUint8(0x66); 909 emitUint8(0x66);
1091 } 910 }
1092 911
1093 } // end of namespace X86Internal 912 } // end of namespace X86NAMESPACE
1094 913
1095 } // end of namespace Ice 914 } // end of namespace Ice
1096 915
1097 #include "IceAssemblerX86BaseImpl.h" 916 #include "IceAssemblerX86BaseImpl.h"
1098 917
1099 #endif // SUBZERO_SRC_ICEASSEMBLERX86BASE_H 918 #endif // SUBZERO_SRC_ICEASSEMBLERX86BASE_H
OLDNEW
« no previous file with comments | « src/IceAssemblerX8664.h ('k') | src/IceAssemblerX86BaseImpl.h » ('j') | src/IceInstX86Base.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698