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

Side by Side Diff: src/IceAssemblerX86BaseImpl.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/IceAssemblerX86BaseImpl.h - base x86 assembler -*- C++ -*-=// 1 //===- subzero/src/IceAssemblerX86BaseImpl.h - base x86 assembler -*- C++ -*-=//
2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
3 // for details. All rights reserved. Use of this source code is governed by a 3 // for details. All rights reserved. Use of this source code is governed by a
4 // BSD-style license that can be found in the LICENSE file. 4 // BSD-style license that can be found in the LICENSE file.
5 // 5 //
6 // Modified by the Subzero authors. 6 // Modified by the Subzero authors.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // The Subzero Code Generator 10 // The Subzero Code Generator
11 // 11 //
12 // This file is distributed under the University of Illinois Open Source 12 // This file is distributed under the University of Illinois Open Source
13 // License. See LICENSE.TXT for details. 13 // License. See LICENSE.TXT for details.
14 // 14 //
15 //===----------------------------------------------------------------------===// 15 //===----------------------------------------------------------------------===//
16 // 16 //
17 /// \file 17 /// \file
18 /// \brief Implements the AssemblerX86Base template class, which is the base 18 /// \brief Implements the AssemblerX86Base template class, which is the base
19 /// Assembler class for X86 assemblers. 19 /// Assembler class for X86 assemblers.
20 // 20 //
21 //===----------------------------------------------------------------------===// 21 //===----------------------------------------------------------------------===//
22 22
23 #include "IceAssemblerX86Base.h" 23 #include "IceAssemblerX86Base.h"
24 24
25 #include "IceCfg.h" 25 #include "IceCfg.h"
26 #include "IceCfgNode.h" 26 #include "IceCfgNode.h"
27 #include "IceOperand.h" 27 #include "IceOperand.h"
28 28
29 namespace Ice { 29 namespace Ice {
30 namespace X86Internal { 30 namespace X86NAMESPACE {
31 31
32 template <class Machine> 32 template <typename TraitsType>
33 AssemblerX86Base<Machine>::~AssemblerX86Base<Machine>() { 33 AssemblerX86Base<TraitsType>::~AssemblerX86Base() {
34 if (BuildDefs::asserts()) { 34 if (BuildDefs::asserts()) {
35 for (const Label *Label : CfgNodeLabels) { 35 for (const Label *Label : CfgNodeLabels) {
36 Label->finalCheck(); 36 Label->finalCheck();
37 } 37 }
38 for (const Label *Label : LocalLabels) { 38 for (const Label *Label : LocalLabels) {
39 Label->finalCheck(); 39 Label->finalCheck();
40 } 40 }
41 } 41 }
42 } 42 }
43 43
44 template <class Machine> void AssemblerX86Base<Machine>::alignFunction() { 44 template <typename TraitsType>
45 void AssemblerX86Base<TraitsType>::alignFunction() {
45 const SizeT Align = 1 << getBundleAlignLog2Bytes(); 46 const SizeT Align = 1 << getBundleAlignLog2Bytes();
46 SizeT BytesNeeded = Utils::OffsetToAlignment(Buffer.getPosition(), Align); 47 SizeT BytesNeeded = Utils::OffsetToAlignment(Buffer.getPosition(), Align);
47 constexpr SizeT HltSize = 1; 48 constexpr SizeT HltSize = 1;
48 while (BytesNeeded > 0) { 49 while (BytesNeeded > 0) {
49 hlt(); 50 hlt();
50 BytesNeeded -= HltSize; 51 BytesNeeded -= HltSize;
51 } 52 }
52 } 53 }
53 54
54 template <class Machine> 55 template <typename TraitsType>
55 Label *AssemblerX86Base<Machine>::getOrCreateLabel(SizeT Number, 56 typename AssemblerX86Base<TraitsType>::Label *
56 LabelVector &Labels) { 57 AssemblerX86Base<TraitsType>::getOrCreateLabel(SizeT Number,
58 LabelVector &Labels) {
57 Label *L = nullptr; 59 Label *L = nullptr;
58 if (Number == Labels.size()) { 60 if (Number == Labels.size()) {
59 L = new (this->allocate<Label>()) Label(); 61 L = new (this->allocate<Label>()) Label();
60 Labels.push_back(L); 62 Labels.push_back(L);
61 return L; 63 return L;
62 } 64 }
63 if (Number > Labels.size()) { 65 if (Number > Labels.size()) {
64 Labels.resize(Number + 1); 66 Labels.resize(Number + 1);
65 } 67 }
66 L = Labels[Number]; 68 L = Labels[Number];
67 if (!L) { 69 if (!L) {
68 L = new (this->allocate<Label>()) Label(); 70 L = new (this->allocate<Label>()) Label();
69 Labels[Number] = L; 71 Labels[Number] = L;
70 } 72 }
71 return L; 73 return L;
72 } 74 }
73 75
74 template <class Machine> 76 template <typename TraitsType>
75 Ice::Label *AssemblerX86Base<Machine>::getCfgNodeLabel(SizeT NodeNumber) { 77 Ice::Label *AssemblerX86Base<TraitsType>::getCfgNodeLabel(SizeT NodeNumber) {
76 assert(NodeNumber < CfgNodeLabels.size()); 78 assert(NodeNumber < CfgNodeLabels.size());
77 return CfgNodeLabels[NodeNumber]; 79 return CfgNodeLabels[NodeNumber];
78 } 80 }
79 81
80 template <class Machine> 82 template <typename TraitsType>
81 Label *AssemblerX86Base<Machine>::getOrCreateCfgNodeLabel(SizeT NodeNumber) { 83 typename AssemblerX86Base<TraitsType>::Label *
84 AssemblerX86Base<TraitsType>::getOrCreateCfgNodeLabel(SizeT NodeNumber) {
82 return getOrCreateLabel(NodeNumber, CfgNodeLabels); 85 return getOrCreateLabel(NodeNumber, CfgNodeLabels);
83 } 86 }
84 87
85 template <class Machine> 88 template <typename TraitsType>
86 Label *AssemblerX86Base<Machine>::getOrCreateLocalLabel(SizeT Number) { 89 typename AssemblerX86Base<TraitsType>::Label *
90 AssemblerX86Base<TraitsType>::getOrCreateLocalLabel(SizeT Number) {
87 return getOrCreateLabel(Number, LocalLabels); 91 return getOrCreateLabel(Number, LocalLabels);
88 } 92 }
89 93
90 template <class Machine> 94 template <typename TraitsType>
91 void AssemblerX86Base<Machine>::bindCfgNodeLabel(const CfgNode *Node) { 95 void AssemblerX86Base<TraitsType>::bindCfgNodeLabel(const CfgNode *Node) {
92 assert(!getPreliminary()); 96 assert(!getPreliminary());
93 Label *L = getOrCreateCfgNodeLabel(Node->getIndex()); 97 Label *L = getOrCreateCfgNodeLabel(Node->getIndex());
94 this->bind(L); 98 this->bind(L);
95 } 99 }
96 100
97 template <class Machine> 101 template <typename TraitsType>
98 void AssemblerX86Base<Machine>::bindLocalLabel(SizeT Number) { 102 void AssemblerX86Base<TraitsType>::bindLocalLabel(SizeT Number) {
99 Label *L = getOrCreateLocalLabel(Number); 103 Label *L = getOrCreateLocalLabel(Number);
100 if (!getPreliminary()) 104 if (!getPreliminary())
101 this->bind(L); 105 this->bind(L);
102 } 106 }
103 107
104 template <class Machine> 108 template <typename TraitsType>
105 void AssemblerX86Base<Machine>::call(typename Traits::GPRRegister reg) { 109 void AssemblerX86Base<TraitsType>::call(GPRRegister reg) {
106 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 110 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
107 emitRexB(RexTypeIrrelevant, reg); 111 emitRexB(RexTypeIrrelevant, reg);
108 emitUint8(0xFF); 112 emitUint8(0xFF);
109 emitRegisterOperand(2, gprEncoding(reg)); 113 emitRegisterOperand(2, gprEncoding(reg));
110 } 114 }
111 115
112 template <class Machine> 116 template <typename TraitsType>
113 void AssemblerX86Base<Machine>::call(const typename Traits::Address &address) { 117 void AssemblerX86Base<TraitsType>::call(const Address &address) {
114 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 118 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
115 emitAddrSizeOverridePrefix(); 119 emitAddrSizeOverridePrefix();
116 emitRex(RexTypeIrrelevant, address, RexRegIrrelevant); 120 emitRex(RexTypeIrrelevant, address, RexRegIrrelevant);
117 emitUint8(0xFF); 121 emitUint8(0xFF);
118 emitOperand(2, address); 122 emitOperand(2, address);
119 } 123 }
120 124
121 template <class Machine> 125 template <typename TraitsType>
122 void AssemblerX86Base<Machine>::call(const ConstantRelocatable *label) { 126 void AssemblerX86Base<TraitsType>::call(const ConstantRelocatable *label) {
123 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 127 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
124 intptr_t call_start = Buffer.getPosition(); 128 intptr_t call_start = Buffer.getPosition();
125 emitUint8(0xE8); 129 emitUint8(0xE8);
126 emitFixup(this->createFixup(Traits::PcRelFixup, label)); 130 emitFixup(this->createFixup(Traits::PcRelFixup, label));
127 emitInt32(-4); 131 emitInt32(-4);
128 assert((Buffer.getPosition() - call_start) == kCallExternalLabelSize); 132 assert((Buffer.getPosition() - call_start) == kCallExternalLabelSize);
129 (void)call_start; 133 (void)call_start;
130 } 134 }
131 135
132 template <class Machine> 136 template <typename TraitsType>
133 void AssemblerX86Base<Machine>::call(const Immediate &abs_address) { 137 void AssemblerX86Base<TraitsType>::call(const Immediate &abs_address) {
134 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 138 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
135 intptr_t call_start = Buffer.getPosition(); 139 intptr_t call_start = Buffer.getPosition();
136 emitUint8(0xE8); 140 emitUint8(0xE8);
137 emitFixup(this->createFixup(Traits::PcRelFixup, AssemblerFixup::NullSymbol)); 141 emitFixup(this->createFixup(Traits::PcRelFixup, AssemblerFixup::NullSymbol));
138 emitInt32(abs_address.value() - 4); 142 emitInt32(abs_address.value() - 4);
139 assert((Buffer.getPosition() - call_start) == kCallExternalLabelSize); 143 assert((Buffer.getPosition() - call_start) == kCallExternalLabelSize);
140 (void)call_start; 144 (void)call_start;
141 } 145 }
142 146
143 template <class Machine> 147 template <typename TraitsType>
144 void AssemblerX86Base<Machine>::pushl(typename Traits::GPRRegister reg) { 148 void AssemblerX86Base<TraitsType>::pushl(GPRRegister reg) {
145 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 149 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
146 emitRexB(RexTypeIrrelevant, reg); 150 emitRexB(RexTypeIrrelevant, reg);
147 emitUint8(0x50 + gprEncoding(reg)); 151 emitUint8(0x50 + gprEncoding(reg));
148 } 152 }
149 153
150 template <class Machine> 154 template <typename TraitsType>
151 void AssemblerX86Base<Machine>::popl(typename Traits::GPRRegister reg) { 155 void AssemblerX86Base<TraitsType>::popl(GPRRegister reg) {
152 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 156 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
153 // Any type that would not force a REX prefix to be emitted can be provided 157 // Any type that would not force a REX prefix to be emitted can be provided
154 // here. 158 // here.
155 emitRexB(RexTypeIrrelevant, reg); 159 emitRexB(RexTypeIrrelevant, reg);
156 emitUint8(0x58 + gprEncoding(reg)); 160 emitUint8(0x58 + gprEncoding(reg));
157 } 161 }
158 162
159 template <class Machine> 163 template <typename TraitsType>
160 void AssemblerX86Base<Machine>::popl(const typename Traits::Address &address) { 164 void AssemblerX86Base<TraitsType>::popl(const Address &address) {
161 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 165 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
162 emitAddrSizeOverridePrefix(); 166 emitAddrSizeOverridePrefix();
163 emitRex(RexTypeIrrelevant, address, RexRegIrrelevant); 167 emitRex(RexTypeIrrelevant, address, RexRegIrrelevant);
164 emitUint8(0x8F); 168 emitUint8(0x8F);
165 emitOperand(0, address); 169 emitOperand(0, address);
166 } 170 }
167 171
168 template <class Machine> 172 template <typename TraitsType>
169 template <typename, typename> 173 template <typename, typename>
170 void AssemblerX86Base<Machine>::pushal() { 174 void AssemblerX86Base<TraitsType>::pushal() {
171 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 175 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
172 emitUint8(0x60); 176 emitUint8(0x60);
173 } 177 }
174 178
175 template <class Machine> 179 template <typename TraitsType>
176 template <typename, typename> 180 template <typename, typename>
177 void AssemblerX86Base<Machine>::popal() { 181 void AssemblerX86Base<TraitsType>::popal() {
178 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 182 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
179 emitUint8(0x61); 183 emitUint8(0x61);
180 } 184 }
181 185
182 template <class Machine> 186 template <typename TraitsType>
183 void AssemblerX86Base<Machine>::setcc(typename Traits::Cond::BrCond condition, 187 void AssemblerX86Base<TraitsType>::setcc(BrCond condition, ByteRegister dst) {
184 typename Traits::ByteRegister dst) {
185 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 188 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
186 emitRexB(IceType_i8, dst); 189 emitRexB(IceType_i8, dst);
187 emitUint8(0x0F); 190 emitUint8(0x0F);
188 emitUint8(0x90 + condition); 191 emitUint8(0x90 + condition);
189 emitUint8(0xC0 + gprEncoding(dst)); 192 emitUint8(0xC0 + gprEncoding(dst));
190 } 193 }
191 194
192 template <class Machine> 195 template <typename TraitsType>
193 void AssemblerX86Base<Machine>::setcc(typename Traits::Cond::BrCond condition, 196 void AssemblerX86Base<TraitsType>::setcc(BrCond condition,
194 const typename Traits::Address &address) { 197 const Address &address) {
195 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 198 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
196 emitAddrSizeOverridePrefix(); 199 emitAddrSizeOverridePrefix();
197 emitRex(RexTypeIrrelevant, address, RexRegIrrelevant); 200 emitRex(RexTypeIrrelevant, address, RexRegIrrelevant);
198 emitUint8(0x0F); 201 emitUint8(0x0F);
199 emitUint8(0x90 + condition); 202 emitUint8(0x90 + condition);
200 emitOperand(0, address); 203 emitOperand(0, address);
201 } 204 }
202 205
203 template <class Machine> 206 template <typename TraitsType>
204 void AssemblerX86Base<Machine>::mov(Type Ty, typename Traits::GPRRegister dst, 207 void AssemblerX86Base<TraitsType>::mov(Type Ty, GPRRegister dst,
205 const Immediate &imm) { 208 const Immediate &imm) {
206 assert(Ty != IceType_i64 && "i64 not supported yet."); 209 assert(Ty != IceType_i64 && "i64 not supported yet.");
207 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 210 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
208 if (Ty == IceType_i16) 211 if (Ty == IceType_i16)
209 emitOperandSizeOverride(); 212 emitOperandSizeOverride();
210 emitRexB(Ty, dst); 213 emitRexB(Ty, dst);
211 if (isByteSizedType(Ty)) { 214 if (isByteSizedType(Ty)) {
212 emitUint8(0xB0 + gprEncoding(dst)); 215 emitUint8(0xB0 + gprEncoding(dst));
213 emitUint8(imm.value() & 0xFF); 216 emitUint8(imm.value() & 0xFF);
214 } else { 217 } else {
215 // TODO(jpp): When removing the assertion above ensure that in x86-64 we 218 // TODO(jpp): When removing the assertion above ensure that in x86-64 we
216 // emit a 64-bit immediate. 219 // emit a 64-bit immediate.
217 emitUint8(0xB8 + gprEncoding(dst)); 220 emitUint8(0xB8 + gprEncoding(dst));
218 emitImmediate(Ty, imm); 221 emitImmediate(Ty, imm);
219 } 222 }
220 } 223 }
221 224
222 template <class Machine> 225 template <typename TraitsType>
223 void AssemblerX86Base<Machine>::mov(Type Ty, typename Traits::GPRRegister dst, 226 void AssemblerX86Base<TraitsType>::mov(Type Ty, GPRRegister dst,
224 typename Traits::GPRRegister src) { 227 GPRRegister src) {
225 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 228 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
226 if (Ty == IceType_i16) 229 if (Ty == IceType_i16)
227 emitOperandSizeOverride(); 230 emitOperandSizeOverride();
228 emitRexRB(Ty, src, dst); 231 emitRexRB(Ty, src, dst);
229 if (isByteSizedType(Ty)) { 232 if (isByteSizedType(Ty)) {
230 emitUint8(0x88); 233 emitUint8(0x88);
231 } else { 234 } else {
232 emitUint8(0x89); 235 emitUint8(0x89);
233 } 236 }
234 emitRegisterOperand(gprEncoding(src), gprEncoding(dst)); 237 emitRegisterOperand(gprEncoding(src), gprEncoding(dst));
235 } 238 }
236 239
237 template <class Machine> 240 template <typename TraitsType>
238 void AssemblerX86Base<Machine>::mov(Type Ty, typename Traits::GPRRegister dst, 241 void AssemblerX86Base<TraitsType>::mov(Type Ty, GPRRegister dst,
239 const typename Traits::Address &src) { 242 const Address &src) {
240 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 243 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
241 if (Ty == IceType_i16) 244 if (Ty == IceType_i16)
242 emitOperandSizeOverride(); 245 emitOperandSizeOverride();
243 emitAddrSizeOverridePrefix(); 246 emitAddrSizeOverridePrefix();
244 emitRex(Ty, src, dst); 247 emitRex(Ty, src, dst);
245 if (isByteSizedType(Ty)) { 248 if (isByteSizedType(Ty)) {
246 emitUint8(0x8A); 249 emitUint8(0x8A);
247 } else { 250 } else {
248 emitUint8(0x8B); 251 emitUint8(0x8B);
249 } 252 }
250 emitOperand(gprEncoding(dst), src); 253 emitOperand(gprEncoding(dst), src);
251 } 254 }
252 255
253 template <class Machine> 256 template <typename TraitsType>
254 void AssemblerX86Base<Machine>::mov(Type Ty, 257 void AssemblerX86Base<TraitsType>::mov(Type Ty, const Address &dst,
255 const typename Traits::Address &dst, 258 GPRRegister src) {
256 typename Traits::GPRRegister src) {
257 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 259 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
258 if (Ty == IceType_i16) 260 if (Ty == IceType_i16)
259 emitOperandSizeOverride(); 261 emitOperandSizeOverride();
260 emitAddrSizeOverridePrefix(); 262 emitAddrSizeOverridePrefix();
261 emitRex(Ty, dst, src); 263 emitRex(Ty, dst, src);
262 if (isByteSizedType(Ty)) { 264 if (isByteSizedType(Ty)) {
263 emitUint8(0x88); 265 emitUint8(0x88);
264 } else { 266 } else {
265 emitUint8(0x89); 267 emitUint8(0x89);
266 } 268 }
267 emitOperand(gprEncoding(src), dst); 269 emitOperand(gprEncoding(src), dst);
268 } 270 }
269 271
270 template <class Machine> 272 template <typename TraitsType>
271 void AssemblerX86Base<Machine>::mov(Type Ty, 273 void AssemblerX86Base<TraitsType>::mov(Type Ty, const Address &dst,
272 const typename Traits::Address &dst, 274 const Immediate &imm) {
273 const Immediate &imm) {
274 assert(Ty != IceType_i64 && "i64 not supported yet."); 275 assert(Ty != IceType_i64 && "i64 not supported yet.");
275 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 276 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
276 if (Ty == IceType_i16) 277 if (Ty == IceType_i16)
277 emitOperandSizeOverride(); 278 emitOperandSizeOverride();
278 emitAddrSizeOverridePrefix(); 279 emitAddrSizeOverridePrefix();
279 emitRex(Ty, dst, RexRegIrrelevant); 280 emitRex(Ty, dst, RexRegIrrelevant);
280 if (isByteSizedType(Ty)) { 281 if (isByteSizedType(Ty)) {
281 emitUint8(0xC6); 282 emitUint8(0xC6);
282 emitOperand(0, dst); 283 emitOperand(0, dst);
283 emitUint8(imm.value() & 0xFF); 284 emitUint8(imm.value() & 0xFF);
284 } else { 285 } else {
285 emitUint8(0xC7); 286 emitUint8(0xC7);
286 emitOperand(0, dst); 287 emitOperand(0, dst);
287 emitImmediate(Ty, imm); 288 emitImmediate(Ty, imm);
288 } 289 }
289 } 290 }
290 291
291 template <class Machine> 292 template <typename TraitsType>
292 template <typename T> 293 template <typename T>
293 typename std::enable_if<T::Is64Bit, void>::type 294 typename std::enable_if<T::Is64Bit, void>::type
294 AssemblerX86Base<Machine>::movabs(const typename Traits::GPRRegister Dst, 295 AssemblerX86Base<TraitsType>::movabs(const GPRRegister Dst, uint64_t Imm64) {
295 uint64_t Imm64) {
296 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 296 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
297 const bool NeedsRexW = (Imm64 & ~0xFFFFFFFFull) != 0; 297 const bool NeedsRexW = (Imm64 & ~0xFFFFFFFFull) != 0;
298 const Type RexType = NeedsRexW ? RexTypeForceRexW : RexTypeIrrelevant; 298 const Type RexType = NeedsRexW ? RexTypeForceRexW : RexTypeIrrelevant;
299 emitRexB(RexType, Dst); 299 emitRexB(RexType, Dst);
300 emitUint8(0xB8 | gprEncoding(Dst)); 300 emitUint8(0xB8 | gprEncoding(Dst));
301 // When emitting Imm64, we don't have to mask out the upper 32 bits for 301 // When emitting Imm64, we don't have to mask out the upper 32 bits for
302 // emitInt32 will/should only emit a 32-bit constant. In reality, we are 302 // emitInt32 will/should only emit a 32-bit constant. In reality, we are
303 // paranoid, so we go ahead an mask the upper bits out anyway. 303 // paranoid, so we go ahead an mask the upper bits out anyway.
304 emitInt32(Imm64 & 0xFFFFFFFF); 304 emitInt32(Imm64 & 0xFFFFFFFF);
305 if (NeedsRexW) 305 if (NeedsRexW)
306 emitInt32((Imm64 >> 32) & 0xFFFFFFFF); 306 emitInt32((Imm64 >> 32) & 0xFFFFFFFF);
307 } 307 }
308 308
309 template <class Machine> 309 template <typename TraitsType>
310 void AssemblerX86Base<Machine>::movzx(Type SrcTy, 310 void AssemblerX86Base<TraitsType>::movzx(Type SrcTy, GPRRegister dst,
311 typename Traits::GPRRegister dst, 311 GPRRegister src) {
312 typename Traits::GPRRegister src) {
313 if (Traits::Is64Bit && SrcTy == IceType_i32) { 312 if (Traits::Is64Bit && SrcTy == IceType_i32) {
314 // 32-bit mov clears the upper 32 bits, hence zero-extending the 32-bit 313 // 32-bit mov clears the upper 32 bits, hence zero-extending the 32-bit
315 // operand to 64-bit. 314 // operand to 64-bit.
316 mov(IceType_i32, dst, src); 315 mov(IceType_i32, dst, src);
317 return; 316 return;
318 } 317 }
319 318
320 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 319 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
321 bool ByteSized = isByteSizedType(SrcTy); 320 bool ByteSized = isByteSizedType(SrcTy);
322 assert(ByteSized || SrcTy == IceType_i16); 321 assert(ByteSized || SrcTy == IceType_i16);
323 emitRexRB(RexTypeIrrelevant, dst, SrcTy, src); 322 emitRexRB(RexTypeIrrelevant, dst, SrcTy, src);
324 emitUint8(0x0F); 323 emitUint8(0x0F);
325 emitUint8(ByteSized ? 0xB6 : 0xB7); 324 emitUint8(ByteSized ? 0xB6 : 0xB7);
326 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); 325 emitRegisterOperand(gprEncoding(dst), gprEncoding(src));
327 } 326 }
328 327
329 template <class Machine> 328 template <typename TraitsType>
330 void AssemblerX86Base<Machine>::movzx(Type SrcTy, 329 void AssemblerX86Base<TraitsType>::movzx(Type SrcTy, GPRRegister dst,
331 typename Traits::GPRRegister dst, 330 const Address &src) {
332 const typename Traits::Address &src) {
333 if (Traits::Is64Bit && SrcTy == IceType_i32) { 331 if (Traits::Is64Bit && SrcTy == IceType_i32) {
334 // 32-bit mov clears the upper 32 bits, hence zero-extending the 32-bit 332 // 32-bit mov clears the upper 32 bits, hence zero-extending the 32-bit
335 // operand to 64-bit. 333 // operand to 64-bit.
336 mov(IceType_i32, dst, src); 334 mov(IceType_i32, dst, src);
337 return; 335 return;
338 } 336 }
339 337
340 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 338 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
341 bool ByteSized = isByteSizedType(SrcTy); 339 bool ByteSized = isByteSizedType(SrcTy);
342 assert(ByteSized || SrcTy == IceType_i16); 340 assert(ByteSized || SrcTy == IceType_i16);
343 emitAddrSizeOverridePrefix(); 341 emitAddrSizeOverridePrefix();
344 emitRex(SrcTy, src, RexTypeIrrelevant, dst); 342 emitRex(SrcTy, src, RexTypeIrrelevant, dst);
345 emitUint8(0x0F); 343 emitUint8(0x0F);
346 emitUint8(ByteSized ? 0xB6 : 0xB7); 344 emitUint8(ByteSized ? 0xB6 : 0xB7);
347 emitOperand(gprEncoding(dst), src); 345 emitOperand(gprEncoding(dst), src);
348 } 346 }
349 347
350 template <class Machine> 348 template <typename TraitsType>
351 void AssemblerX86Base<Machine>::movsx(Type SrcTy, 349 void AssemblerX86Base<TraitsType>::movsx(Type SrcTy, GPRRegister dst,
352 typename Traits::GPRRegister dst, 350 GPRRegister src) {
353 typename Traits::GPRRegister src) {
354 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 351 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
355 bool ByteSized = isByteSizedType(SrcTy); 352 bool ByteSized = isByteSizedType(SrcTy);
356 emitRexRB(RexTypeForceRexW, dst, SrcTy, src); 353 emitRexRB(RexTypeForceRexW, dst, SrcTy, src);
357 if (ByteSized || SrcTy == IceType_i16) { 354 if (ByteSized || SrcTy == IceType_i16) {
358 emitUint8(0x0F); 355 emitUint8(0x0F);
359 emitUint8(ByteSized ? 0xBE : 0xBF); 356 emitUint8(ByteSized ? 0xBE : 0xBF);
360 } else { 357 } else {
361 assert(Traits::Is64Bit && SrcTy == IceType_i32); 358 assert(Traits::Is64Bit && SrcTy == IceType_i32);
362 emitUint8(0x63); 359 emitUint8(0x63);
363 } 360 }
364 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); 361 emitRegisterOperand(gprEncoding(dst), gprEncoding(src));
365 } 362 }
366 363
367 template <class Machine> 364 template <typename TraitsType>
368 void AssemblerX86Base<Machine>::movsx(Type SrcTy, 365 void AssemblerX86Base<TraitsType>::movsx(Type SrcTy, GPRRegister dst,
369 typename Traits::GPRRegister dst, 366 const Address &src) {
370 const typename Traits::Address &src) {
371 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 367 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
372 bool ByteSized = isByteSizedType(SrcTy); 368 bool ByteSized = isByteSizedType(SrcTy);
373 emitAddrSizeOverridePrefix(); 369 emitAddrSizeOverridePrefix();
374 emitRex(SrcTy, src, RexTypeForceRexW, dst); 370 emitRex(SrcTy, src, RexTypeForceRexW, dst);
375 if (ByteSized || SrcTy == IceType_i16) { 371 if (ByteSized || SrcTy == IceType_i16) {
376 emitUint8(0x0F); 372 emitUint8(0x0F);
377 emitUint8(ByteSized ? 0xBE : 0xBF); 373 emitUint8(ByteSized ? 0xBE : 0xBF);
378 } else { 374 } else {
379 assert(Traits::Is64Bit && SrcTy == IceType_i32); 375 assert(Traits::Is64Bit && SrcTy == IceType_i32);
380 emitUint8(0x63); 376 emitUint8(0x63);
381 } 377 }
382 emitOperand(gprEncoding(dst), src); 378 emitOperand(gprEncoding(dst), src);
383 } 379 }
384 380
385 template <class Machine> 381 template <typename TraitsType>
386 void AssemblerX86Base<Machine>::lea(Type Ty, typename Traits::GPRRegister dst, 382 void AssemblerX86Base<TraitsType>::lea(Type Ty, GPRRegister dst,
387 const typename Traits::Address &src) { 383 const Address &src) {
388 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 384 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
389 assert(Ty == IceType_i16 || Ty == IceType_i32); 385 assert(Ty == IceType_i16 || Ty == IceType_i32);
390 if (Ty == IceType_i16) 386 if (Ty == IceType_i16)
391 emitOperandSizeOverride(); 387 emitOperandSizeOverride();
392 emitAddrSizeOverridePrefix(); 388 emitAddrSizeOverridePrefix();
393 emitRex(Ty, src, dst); 389 emitRex(Ty, src, dst);
394 emitUint8(0x8D); 390 emitUint8(0x8D);
395 emitOperand(gprEncoding(dst), src); 391 emitOperand(gprEncoding(dst), src);
396 } 392 }
397 393
398 template <class Machine> 394 template <typename TraitsType>
399 void AssemblerX86Base<Machine>::cmov(Type Ty, 395 void AssemblerX86Base<TraitsType>::cmov(Type Ty, BrCond cond, GPRRegister dst,
400 typename Traits::Cond::BrCond cond, 396 GPRRegister src) {
401 typename Traits::GPRRegister dst,
402 typename Traits::GPRRegister src) {
403 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 397 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
404 if (Ty == IceType_i16) 398 if (Ty == IceType_i16)
405 emitOperandSizeOverride(); 399 emitOperandSizeOverride();
406 else 400 else
407 assert(Ty == IceType_i32 || (Traits::Is64Bit && Ty == IceType_i64)); 401 assert(Ty == IceType_i32 || (Traits::Is64Bit && Ty == IceType_i64));
408 emitRexRB(Ty, dst, src); 402 emitRexRB(Ty, dst, src);
409 emitUint8(0x0F); 403 emitUint8(0x0F);
410 emitUint8(0x40 + cond); 404 emitUint8(0x40 + cond);
411 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); 405 emitRegisterOperand(gprEncoding(dst), gprEncoding(src));
412 } 406 }
413 407
414 template <class Machine> 408 template <typename TraitsType>
415 void AssemblerX86Base<Machine>::cmov(Type Ty, 409 void AssemblerX86Base<TraitsType>::cmov(Type Ty, BrCond cond, GPRRegister dst,
416 typename Traits::Cond::BrCond cond, 410 const Address &src) {
417 typename Traits::GPRRegister dst,
418 const typename Traits::Address &src) {
419 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 411 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
420 if (Ty == IceType_i16) 412 if (Ty == IceType_i16)
421 emitOperandSizeOverride(); 413 emitOperandSizeOverride();
422 else 414 else
423 assert(Ty == IceType_i32 || (Traits::Is64Bit && Ty == IceType_i64)); 415 assert(Ty == IceType_i32 || (Traits::Is64Bit && Ty == IceType_i64));
424 emitAddrSizeOverridePrefix(); 416 emitAddrSizeOverridePrefix();
425 emitRex(Ty, src, dst); 417 emitRex(Ty, src, dst);
426 emitUint8(0x0F); 418 emitUint8(0x0F);
427 emitUint8(0x40 + cond); 419 emitUint8(0x40 + cond);
428 emitOperand(gprEncoding(dst), src); 420 emitOperand(gprEncoding(dst), src);
429 } 421 }
430 422
431 template <class Machine> void AssemblerX86Base<Machine>::rep_movsb() { 423 template <typename TraitsType> void AssemblerX86Base<TraitsType>::rep_movsb() {
432 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 424 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
433 emitUint8(0xF3); 425 emitUint8(0xF3);
434 emitUint8(0xA4); 426 emitUint8(0xA4);
435 } 427 }
436 428
437 template <class Machine> 429 template <typename TraitsType>
438 void AssemblerX86Base<Machine>::movss(Type Ty, typename Traits::XmmRegister dst, 430 void AssemblerX86Base<TraitsType>::movss(Type Ty, XmmRegister dst,
439 const typename Traits::Address &src) { 431 const Address &src) {
440 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 432 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
441 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); 433 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
442 emitAddrSizeOverridePrefix(); 434 emitAddrSizeOverridePrefix();
443 emitRex(RexTypeIrrelevant, src, dst); 435 emitRex(RexTypeIrrelevant, src, dst);
444 emitUint8(0x0F); 436 emitUint8(0x0F);
445 emitUint8(0x10); 437 emitUint8(0x10);
446 emitOperand(gprEncoding(dst), src); 438 emitOperand(gprEncoding(dst), src);
447 } 439 }
448 440
449 template <class Machine> 441 template <typename TraitsType>
450 void AssemblerX86Base<Machine>::movss(Type Ty, 442 void AssemblerX86Base<TraitsType>::movss(Type Ty, const Address &dst,
451 const typename Traits::Address &dst, 443 XmmRegister src) {
452 typename Traits::XmmRegister src) {
453 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 444 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
454 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); 445 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
455 emitAddrSizeOverridePrefix(); 446 emitAddrSizeOverridePrefix();
456 emitRex(RexTypeIrrelevant, dst, src); 447 emitRex(RexTypeIrrelevant, dst, src);
457 emitUint8(0x0F); 448 emitUint8(0x0F);
458 emitUint8(0x11); 449 emitUint8(0x11);
459 emitOperand(gprEncoding(src), dst); 450 emitOperand(gprEncoding(src), dst);
460 } 451 }
461 452
462 template <class Machine> 453 template <typename TraitsType>
463 void AssemblerX86Base<Machine>::movss(Type Ty, typename Traits::XmmRegister dst, 454 void AssemblerX86Base<TraitsType>::movss(Type Ty, XmmRegister dst,
464 typename Traits::XmmRegister src) { 455 XmmRegister src) {
465 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 456 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
466 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); 457 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
467 emitRexRB(RexTypeIrrelevant, src, dst); 458 emitRexRB(RexTypeIrrelevant, src, dst);
468 emitUint8(0x0F); 459 emitUint8(0x0F);
469 emitUint8(0x11); 460 emitUint8(0x11);
470 emitXmmRegisterOperand(src, dst); 461 emitXmmRegisterOperand(src, dst);
471 } 462 }
472 463
473 template <class Machine> 464 template <typename TraitsType>
474 void AssemblerX86Base<Machine>::movd(Type SrcTy, 465 void AssemblerX86Base<TraitsType>::movd(Type SrcTy, XmmRegister dst,
475 typename Traits::XmmRegister dst, 466 GPRRegister src) {
476 typename Traits::GPRRegister src) {
477 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 467 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
478 emitUint8(0x66); 468 emitUint8(0x66);
479 emitRexRB(SrcTy, dst, src); 469 emitRexRB(SrcTy, dst, src);
480 emitUint8(0x0F); 470 emitUint8(0x0F);
481 emitUint8(0x6E); 471 emitUint8(0x6E);
482 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); 472 emitRegisterOperand(gprEncoding(dst), gprEncoding(src));
483 } 473 }
484 474
485 template <class Machine> 475 template <typename TraitsType>
486 void AssemblerX86Base<Machine>::movd(Type SrcTy, 476 void AssemblerX86Base<TraitsType>::movd(Type SrcTy, XmmRegister dst,
487 typename Traits::XmmRegister dst, 477 const Address &src) {
488 const typename Traits::Address &src) {
489 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 478 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
490 emitUint8(0x66); 479 emitUint8(0x66);
491 emitAddrSizeOverridePrefix(); 480 emitAddrSizeOverridePrefix();
492 emitRex(SrcTy, src, dst); 481 emitRex(SrcTy, src, dst);
493 emitUint8(0x0F); 482 emitUint8(0x0F);
494 emitUint8(0x6E); 483 emitUint8(0x6E);
495 emitOperand(gprEncoding(dst), src); 484 emitOperand(gprEncoding(dst), src);
496 } 485 }
497 486
498 template <class Machine> 487 template <typename TraitsType>
499 void AssemblerX86Base<Machine>::movd(Type DestTy, 488 void AssemblerX86Base<TraitsType>::movd(Type DestTy, GPRRegister dst,
500 typename Traits::GPRRegister dst, 489 XmmRegister src) {
501 typename Traits::XmmRegister src) {
502 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 490 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
503 emitUint8(0x66); 491 emitUint8(0x66);
504 emitRexRB(DestTy, src, dst); 492 emitRexRB(DestTy, src, dst);
505 emitUint8(0x0F); 493 emitUint8(0x0F);
506 emitUint8(0x7E); 494 emitUint8(0x7E);
507 emitRegisterOperand(gprEncoding(src), gprEncoding(dst)); 495 emitRegisterOperand(gprEncoding(src), gprEncoding(dst));
508 } 496 }
509 497
510 template <class Machine> 498 template <typename TraitsType>
511 void AssemblerX86Base<Machine>::movd(Type DestTy, 499 void AssemblerX86Base<TraitsType>::movd(Type DestTy, const Address &dst,
512 const typename Traits::Address &dst, 500 XmmRegister src) {
513 typename Traits::XmmRegister src) {
514 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 501 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
515 emitUint8(0x66); 502 emitUint8(0x66);
516 emitAddrSizeOverridePrefix(); 503 emitAddrSizeOverridePrefix();
517 emitRex(DestTy, dst, src); 504 emitRex(DestTy, dst, src);
518 emitUint8(0x0F); 505 emitUint8(0x0F);
519 emitUint8(0x7E); 506 emitUint8(0x7E);
520 emitOperand(gprEncoding(src), dst); 507 emitOperand(gprEncoding(src), dst);
521 } 508 }
522 509
523 template <class Machine> 510 template <typename TraitsType>
524 void AssemblerX86Base<Machine>::movq(typename Traits::XmmRegister dst, 511 void AssemblerX86Base<TraitsType>::movq(XmmRegister dst, XmmRegister src) {
525 typename Traits::XmmRegister src) {
526 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 512 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
527 emitUint8(0xF3); 513 emitUint8(0xF3);
528 emitRexRB(RexTypeIrrelevant, dst, src); 514 emitRexRB(RexTypeIrrelevant, dst, src);
529 emitUint8(0x0F); 515 emitUint8(0x0F);
530 emitUint8(0x7E); 516 emitUint8(0x7E);
531 emitXmmRegisterOperand(dst, src); 517 emitXmmRegisterOperand(dst, src);
532 } 518 }
533 519
534 template <class Machine> 520 template <typename TraitsType>
535 void AssemblerX86Base<Machine>::movq(const typename Traits::Address &dst, 521 void AssemblerX86Base<TraitsType>::movq(const Address &dst, XmmRegister src) {
536 typename Traits::XmmRegister src) {
537 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 522 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
538 emitUint8(0x66); 523 emitUint8(0x66);
539 emitAddrSizeOverridePrefix(); 524 emitAddrSizeOverridePrefix();
540 emitRex(RexTypeIrrelevant, dst, src); 525 emitRex(RexTypeIrrelevant, dst, src);
541 emitUint8(0x0F); 526 emitUint8(0x0F);
542 emitUint8(0xD6); 527 emitUint8(0xD6);
543 emitOperand(gprEncoding(src), dst); 528 emitOperand(gprEncoding(src), dst);
544 } 529 }
545 530
546 template <class Machine> 531 template <typename TraitsType>
547 void AssemblerX86Base<Machine>::movq(typename Traits::XmmRegister dst, 532 void AssemblerX86Base<TraitsType>::movq(XmmRegister dst, const Address &src) {
548 const typename Traits::Address &src) {
549 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 533 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
550 emitUint8(0xF3); 534 emitUint8(0xF3);
551 emitAddrSizeOverridePrefix(); 535 emitAddrSizeOverridePrefix();
552 emitRex(RexTypeIrrelevant, src, dst); 536 emitRex(RexTypeIrrelevant, src, dst);
553 emitUint8(0x0F); 537 emitUint8(0x0F);
554 emitUint8(0x7E); 538 emitUint8(0x7E);
555 emitOperand(gprEncoding(dst), src); 539 emitOperand(gprEncoding(dst), src);
556 } 540 }
557 541
558 template <class Machine> 542 template <typename TraitsType>
559 void AssemblerX86Base<Machine>::addss(Type Ty, typename Traits::XmmRegister dst, 543 void AssemblerX86Base<TraitsType>::addss(Type Ty, XmmRegister dst,
560 typename Traits::XmmRegister src) { 544 XmmRegister src) {
561 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 545 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
562 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); 546 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
563 emitRexRB(RexTypeIrrelevant, dst, src); 547 emitRexRB(RexTypeIrrelevant, dst, src);
564 emitUint8(0x0F); 548 emitUint8(0x0F);
565 emitUint8(0x58); 549 emitUint8(0x58);
566 emitXmmRegisterOperand(dst, src); 550 emitXmmRegisterOperand(dst, src);
567 } 551 }
568 552
569 template <class Machine> 553 template <typename TraitsType>
570 void AssemblerX86Base<Machine>::addss(Type Ty, typename Traits::XmmRegister dst, 554 void AssemblerX86Base<TraitsType>::addss(Type Ty, XmmRegister dst,
571 const typename Traits::Address &src) { 555 const Address &src) {
572 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 556 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
573 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); 557 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
574 emitAddrSizeOverridePrefix(); 558 emitAddrSizeOverridePrefix();
575 emitRex(RexTypeIrrelevant, src, dst); 559 emitRex(RexTypeIrrelevant, src, dst);
576 emitUint8(0x0F); 560 emitUint8(0x0F);
577 emitUint8(0x58); 561 emitUint8(0x58);
578 emitOperand(gprEncoding(dst), src); 562 emitOperand(gprEncoding(dst), src);
579 } 563 }
580 564
581 template <class Machine> 565 template <typename TraitsType>
582 void AssemblerX86Base<Machine>::subss(Type Ty, typename Traits::XmmRegister dst, 566 void AssemblerX86Base<TraitsType>::subss(Type Ty, XmmRegister dst,
583 typename Traits::XmmRegister src) { 567 XmmRegister src) {
584 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 568 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
585 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); 569 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
586 emitRexRB(RexTypeIrrelevant, dst, src); 570 emitRexRB(RexTypeIrrelevant, dst, src);
587 emitUint8(0x0F); 571 emitUint8(0x0F);
588 emitUint8(0x5C); 572 emitUint8(0x5C);
589 emitXmmRegisterOperand(dst, src); 573 emitXmmRegisterOperand(dst, src);
590 } 574 }
591 575
592 template <class Machine> 576 template <typename TraitsType>
593 void AssemblerX86Base<Machine>::subss(Type Ty, typename Traits::XmmRegister dst, 577 void AssemblerX86Base<TraitsType>::subss(Type Ty, XmmRegister dst,
594 const typename Traits::Address &src) { 578 const Address &src) {
595 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 579 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
596 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); 580 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
597 emitAddrSizeOverridePrefix(); 581 emitAddrSizeOverridePrefix();
598 emitRex(RexTypeIrrelevant, src, dst); 582 emitRex(RexTypeIrrelevant, src, dst);
599 emitUint8(0x0F); 583 emitUint8(0x0F);
600 emitUint8(0x5C); 584 emitUint8(0x5C);
601 emitOperand(gprEncoding(dst), src); 585 emitOperand(gprEncoding(dst), src);
602 } 586 }
603 587
604 template <class Machine> 588 template <typename TraitsType>
605 void AssemblerX86Base<Machine>::mulss(Type Ty, typename Traits::XmmRegister dst, 589 void AssemblerX86Base<TraitsType>::mulss(Type Ty, XmmRegister dst,
606 typename Traits::XmmRegister src) { 590 XmmRegister src) {
607 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 591 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
608 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); 592 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
609 emitRexRB(RexTypeIrrelevant, dst, src); 593 emitRexRB(RexTypeIrrelevant, dst, src);
610 emitUint8(0x0F); 594 emitUint8(0x0F);
611 emitUint8(0x59); 595 emitUint8(0x59);
612 emitXmmRegisterOperand(dst, src); 596 emitXmmRegisterOperand(dst, src);
613 } 597 }
614 598
615 template <class Machine> 599 template <typename TraitsType>
616 void AssemblerX86Base<Machine>::mulss(Type Ty, typename Traits::XmmRegister dst, 600 void AssemblerX86Base<TraitsType>::mulss(Type Ty, XmmRegister dst,
617 const typename Traits::Address &src) { 601 const Address &src) {
618 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 602 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
619 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); 603 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
620 emitAddrSizeOverridePrefix(); 604 emitAddrSizeOverridePrefix();
621 emitRex(RexTypeIrrelevant, src, dst); 605 emitRex(RexTypeIrrelevant, src, dst);
622 emitUint8(0x0F); 606 emitUint8(0x0F);
623 emitUint8(0x59); 607 emitUint8(0x59);
624 emitOperand(gprEncoding(dst), src); 608 emitOperand(gprEncoding(dst), src);
625 } 609 }
626 610
627 template <class Machine> 611 template <typename TraitsType>
628 void AssemblerX86Base<Machine>::divss(Type Ty, typename Traits::XmmRegister dst, 612 void AssemblerX86Base<TraitsType>::divss(Type Ty, XmmRegister dst,
629 typename Traits::XmmRegister src) { 613 XmmRegister src) {
630 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 614 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
631 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); 615 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
632 emitRexRB(RexTypeIrrelevant, dst, src); 616 emitRexRB(RexTypeIrrelevant, dst, src);
633 emitUint8(0x0F); 617 emitUint8(0x0F);
634 emitUint8(0x5E); 618 emitUint8(0x5E);
635 emitXmmRegisterOperand(dst, src); 619 emitXmmRegisterOperand(dst, src);
636 } 620 }
637 621
638 template <class Machine> 622 template <typename TraitsType>
639 void AssemblerX86Base<Machine>::divss(Type Ty, typename Traits::XmmRegister dst, 623 void AssemblerX86Base<TraitsType>::divss(Type Ty, XmmRegister dst,
640 const typename Traits::Address &src) { 624 const Address &src) {
641 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 625 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
642 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); 626 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
643 emitAddrSizeOverridePrefix(); 627 emitAddrSizeOverridePrefix();
644 emitRex(RexTypeIrrelevant, src, dst); 628 emitRex(RexTypeIrrelevant, src, dst);
645 emitUint8(0x0F); 629 emitUint8(0x0F);
646 emitUint8(0x5E); 630 emitUint8(0x5E);
647 emitOperand(gprEncoding(dst), src); 631 emitOperand(gprEncoding(dst), src);
648 } 632 }
649 633
650 template <class Machine> 634 template <typename TraitsType>
651 template <typename T, typename> 635 template <typename T, typename>
652 void AssemblerX86Base<Machine>::fld(Type Ty, const typename T::Address &src) { 636 void AssemblerX86Base<TraitsType>::fld(Type Ty,
637 const typename T::Address &src) {
653 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 638 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
654 emitAddrSizeOverridePrefix(); 639 emitAddrSizeOverridePrefix();
655 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xD9 : 0xDD); 640 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xD9 : 0xDD);
656 emitOperand(0, src); 641 emitOperand(0, src);
657 } 642 }
658 643
659 template <class Machine> 644 template <typename TraitsType>
660 template <typename T, typename> 645 template <typename T, typename>
661 void AssemblerX86Base<Machine>::fstp(Type Ty, const typename T::Address &dst) { 646 void AssemblerX86Base<TraitsType>::fstp(Type Ty,
647 const typename T::Address &dst) {
662 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 648 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
663 emitAddrSizeOverridePrefix(); 649 emitAddrSizeOverridePrefix();
664 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xD9 : 0xDD); 650 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xD9 : 0xDD);
665 emitOperand(3, dst); 651 emitOperand(3, dst);
666 } 652 }
667 653
668 template <class Machine> 654 template <typename TraitsType>
669 template <typename T, typename> 655 template <typename T, typename>
670 void AssemblerX86Base<Machine>::fstp(typename T::X87STRegister st) { 656 void AssemblerX86Base<TraitsType>::fstp(typename T::X87STRegister st) {
671 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 657 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
672 emitUint8(0xDD); 658 emitUint8(0xDD);
673 emitUint8(0xD8 + st); 659 emitUint8(0xD8 + st);
674 } 660 }
675 661
676 template <class Machine> 662 template <typename TraitsType>
677 void AssemblerX86Base<Machine>::movaps(typename Traits::XmmRegister dst, 663 void AssemblerX86Base<TraitsType>::movaps(XmmRegister dst, XmmRegister src) {
678 typename Traits::XmmRegister src) {
679 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 664 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
680 emitRexRB(RexTypeIrrelevant, dst, src); 665 emitRexRB(RexTypeIrrelevant, dst, src);
681 emitUint8(0x0F); 666 emitUint8(0x0F);
682 emitUint8(0x28); 667 emitUint8(0x28);
683 emitXmmRegisterOperand(dst, src); 668 emitXmmRegisterOperand(dst, src);
684 } 669 }
685 670
686 template <class Machine> 671 template <typename TraitsType>
687 void AssemblerX86Base<Machine>::movups(typename Traits::XmmRegister dst, 672 void AssemblerX86Base<TraitsType>::movups(XmmRegister dst, XmmRegister src) {
688 typename Traits::XmmRegister src) {
689 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 673 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
690 emitRexRB(RexTypeIrrelevant, dst, src); 674 emitRexRB(RexTypeIrrelevant, dst, src);
691 emitUint8(0x0F); 675 emitUint8(0x0F);
692 emitUint8(0x10); 676 emitUint8(0x10);
693 emitXmmRegisterOperand(dst, src); 677 emitXmmRegisterOperand(dst, src);
694 } 678 }
695 679
696 template <class Machine> 680 template <typename TraitsType>
697 void AssemblerX86Base<Machine>::movups(typename Traits::XmmRegister dst, 681 void AssemblerX86Base<TraitsType>::movups(XmmRegister dst, const Address &src) {
698 const typename Traits::Address &src) {
699 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 682 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
700 emitAddrSizeOverridePrefix(); 683 emitAddrSizeOverridePrefix();
701 emitRex(RexTypeIrrelevant, src, dst); 684 emitRex(RexTypeIrrelevant, src, dst);
702 emitUint8(0x0F); 685 emitUint8(0x0F);
703 emitUint8(0x10); 686 emitUint8(0x10);
704 emitOperand(gprEncoding(dst), src); 687 emitOperand(gprEncoding(dst), src);
705 } 688 }
706 689
707 template <class Machine> 690 template <typename TraitsType>
708 void AssemblerX86Base<Machine>::movups(const typename Traits::Address &dst, 691 void AssemblerX86Base<TraitsType>::movups(const Address &dst, XmmRegister src) {
709 typename Traits::XmmRegister src) {
710 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 692 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
711 emitAddrSizeOverridePrefix(); 693 emitAddrSizeOverridePrefix();
712 emitRex(RexTypeIrrelevant, dst, src); 694 emitRex(RexTypeIrrelevant, dst, src);
713 emitUint8(0x0F); 695 emitUint8(0x0F);
714 emitUint8(0x11); 696 emitUint8(0x11);
715 emitOperand(gprEncoding(src), dst); 697 emitOperand(gprEncoding(src), dst);
716 } 698 }
717 699
718 template <class Machine> 700 template <typename TraitsType>
719 void AssemblerX86Base<Machine>::padd(Type Ty, typename Traits::XmmRegister dst, 701 void AssemblerX86Base<TraitsType>::padd(Type Ty, XmmRegister dst,
720 typename Traits::XmmRegister src) { 702 XmmRegister src) {
721 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 703 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
722 emitUint8(0x66); 704 emitUint8(0x66);
723 emitRexRB(RexTypeIrrelevant, dst, src); 705 emitRexRB(RexTypeIrrelevant, dst, src);
724 emitUint8(0x0F); 706 emitUint8(0x0F);
725 if (isByteSizedArithType(Ty)) { 707 if (isByteSizedArithType(Ty)) {
726 emitUint8(0xFC); 708 emitUint8(0xFC);
727 } else if (Ty == IceType_i16) { 709 } else if (Ty == IceType_i16) {
728 emitUint8(0xFD); 710 emitUint8(0xFD);
729 } else { 711 } else {
730 emitUint8(0xFE); 712 emitUint8(0xFE);
731 } 713 }
732 emitXmmRegisterOperand(dst, src); 714 emitXmmRegisterOperand(dst, src);
733 } 715 }
734 716
735 template <class Machine> 717 template <typename TraitsType>
736 void AssemblerX86Base<Machine>::padd(Type Ty, typename Traits::XmmRegister dst, 718 void AssemblerX86Base<TraitsType>::padd(Type Ty, XmmRegister dst,
737 const typename Traits::Address &src) { 719 const Address &src) {
738 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 720 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
739 emitUint8(0x66); 721 emitUint8(0x66);
740 emitAddrSizeOverridePrefix(); 722 emitAddrSizeOverridePrefix();
741 emitRex(RexTypeIrrelevant, src, dst); 723 emitRex(RexTypeIrrelevant, src, dst);
742 emitUint8(0x0F); 724 emitUint8(0x0F);
743 if (isByteSizedArithType(Ty)) { 725 if (isByteSizedArithType(Ty)) {
744 emitUint8(0xFC); 726 emitUint8(0xFC);
745 } else if (Ty == IceType_i16) { 727 } else if (Ty == IceType_i16) {
746 emitUint8(0xFD); 728 emitUint8(0xFD);
747 } else { 729 } else {
748 emitUint8(0xFE); 730 emitUint8(0xFE);
749 } 731 }
750 emitOperand(gprEncoding(dst), src); 732 emitOperand(gprEncoding(dst), src);
751 } 733 }
752 734
753 template <class Machine> 735 template <typename TraitsType>
754 void AssemblerX86Base<Machine>::pand(Type /* Ty */, 736 void AssemblerX86Base<TraitsType>::pand(Type /* Ty */, XmmRegister dst,
755 typename Traits::XmmRegister dst, 737 XmmRegister src) {
756 typename Traits::XmmRegister src) {
757 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 738 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
758 emitUint8(0x66); 739 emitUint8(0x66);
759 emitRexRB(RexTypeIrrelevant, dst, src); 740 emitRexRB(RexTypeIrrelevant, dst, src);
760 emitUint8(0x0F); 741 emitUint8(0x0F);
761 emitUint8(0xDB); 742 emitUint8(0xDB);
762 emitXmmRegisterOperand(dst, src); 743 emitXmmRegisterOperand(dst, src);
763 } 744 }
764 745
765 template <class Machine> 746 template <typename TraitsType>
766 void AssemblerX86Base<Machine>::pand(Type /* Ty */, 747 void AssemblerX86Base<TraitsType>::pand(Type /* Ty */, XmmRegister dst,
767 typename Traits::XmmRegister dst, 748 const Address &src) {
768 const typename Traits::Address &src) {
769 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 749 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
770 emitUint8(0x66); 750 emitUint8(0x66);
771 emitAddrSizeOverridePrefix(); 751 emitAddrSizeOverridePrefix();
772 emitRex(RexTypeIrrelevant, src, dst); 752 emitRex(RexTypeIrrelevant, src, dst);
773 emitUint8(0x0F); 753 emitUint8(0x0F);
774 emitUint8(0xDB); 754 emitUint8(0xDB);
775 emitOperand(gprEncoding(dst), src); 755 emitOperand(gprEncoding(dst), src);
776 } 756 }
777 757
778 template <class Machine> 758 template <typename TraitsType>
779 void AssemblerX86Base<Machine>::pandn(Type /* Ty */, 759 void AssemblerX86Base<TraitsType>::pandn(Type /* Ty */, XmmRegister dst,
780 typename Traits::XmmRegister dst, 760 XmmRegister src) {
781 typename Traits::XmmRegister src) {
782 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 761 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
783 emitUint8(0x66); 762 emitUint8(0x66);
784 emitRexRB(RexTypeIrrelevant, dst, src); 763 emitRexRB(RexTypeIrrelevant, dst, src);
785 emitUint8(0x0F); 764 emitUint8(0x0F);
786 emitUint8(0xDF); 765 emitUint8(0xDF);
787 emitXmmRegisterOperand(dst, src); 766 emitXmmRegisterOperand(dst, src);
788 } 767 }
789 768
790 template <class Machine> 769 template <typename TraitsType>
791 void AssemblerX86Base<Machine>::pandn(Type /* Ty */, 770 void AssemblerX86Base<TraitsType>::pandn(Type /* Ty */, XmmRegister dst,
792 typename Traits::XmmRegister dst, 771 const Address &src) {
793 const typename Traits::Address &src) {
794 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 772 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
795 emitUint8(0x66); 773 emitUint8(0x66);
796 emitAddrSizeOverridePrefix(); 774 emitAddrSizeOverridePrefix();
797 emitRex(RexTypeIrrelevant, src, dst); 775 emitRex(RexTypeIrrelevant, src, dst);
798 emitUint8(0x0F); 776 emitUint8(0x0F);
799 emitUint8(0xDF); 777 emitUint8(0xDF);
800 emitOperand(gprEncoding(dst), src); 778 emitOperand(gprEncoding(dst), src);
801 } 779 }
802 780
803 template <class Machine> 781 template <typename TraitsType>
804 void AssemblerX86Base<Machine>::pmull(Type Ty, typename Traits::XmmRegister dst, 782 void AssemblerX86Base<TraitsType>::pmull(Type Ty, XmmRegister dst,
805 typename Traits::XmmRegister src) { 783 XmmRegister src) {
806 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 784 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
807 emitUint8(0x66); 785 emitUint8(0x66);
808 emitRexRB(RexTypeIrrelevant, dst, src); 786 emitRexRB(RexTypeIrrelevant, dst, src);
809 emitUint8(0x0F); 787 emitUint8(0x0F);
810 if (Ty == IceType_i16) { 788 if (Ty == IceType_i16) {
811 emitUint8(0xD5); 789 emitUint8(0xD5);
812 } else { 790 } else {
813 assert(Ty == IceType_i32); 791 assert(Ty == IceType_i32);
814 emitUint8(0x38); 792 emitUint8(0x38);
815 emitUint8(0x40); 793 emitUint8(0x40);
816 } 794 }
817 emitXmmRegisterOperand(dst, src); 795 emitXmmRegisterOperand(dst, src);
818 } 796 }
819 797
820 template <class Machine> 798 template <typename TraitsType>
821 void AssemblerX86Base<Machine>::pmull(Type Ty, typename Traits::XmmRegister dst, 799 void AssemblerX86Base<TraitsType>::pmull(Type Ty, XmmRegister dst,
822 const typename Traits::Address &src) { 800 const Address &src) {
823 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 801 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
824 emitUint8(0x66); 802 emitUint8(0x66);
825 emitAddrSizeOverridePrefix(); 803 emitAddrSizeOverridePrefix();
826 emitRex(RexTypeIrrelevant, src, dst); 804 emitRex(RexTypeIrrelevant, src, dst);
827 emitUint8(0x0F); 805 emitUint8(0x0F);
828 if (Ty == IceType_i16) { 806 if (Ty == IceType_i16) {
829 emitUint8(0xD5); 807 emitUint8(0xD5);
830 } else { 808 } else {
831 assert(Ty == IceType_i32); 809 assert(Ty == IceType_i32);
832 emitUint8(0x38); 810 emitUint8(0x38);
833 emitUint8(0x40); 811 emitUint8(0x40);
834 } 812 }
835 emitOperand(gprEncoding(dst), src); 813 emitOperand(gprEncoding(dst), src);
836 } 814 }
837 815
838 template <class Machine> 816 template <typename TraitsType>
839 void AssemblerX86Base<Machine>::pmuludq(Type /* Ty */, 817 void AssemblerX86Base<TraitsType>::pmuludq(Type /* Ty */, XmmRegister dst,
840 typename Traits::XmmRegister dst, 818 XmmRegister src) {
841 typename Traits::XmmRegister src) {
842 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 819 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
843 emitUint8(0x66); 820 emitUint8(0x66);
844 emitRexRB(RexTypeIrrelevant, dst, src); 821 emitRexRB(RexTypeIrrelevant, dst, src);
845 emitUint8(0x0F); 822 emitUint8(0x0F);
846 emitUint8(0xF4); 823 emitUint8(0xF4);
847 emitXmmRegisterOperand(dst, src); 824 emitXmmRegisterOperand(dst, src);
848 } 825 }
849 826
850 template <class Machine> 827 template <typename TraitsType>
851 void AssemblerX86Base<Machine>::pmuludq(Type /* Ty */, 828 void AssemblerX86Base<TraitsType>::pmuludq(Type /* Ty */, XmmRegister dst,
852 typename Traits::XmmRegister dst, 829 const Address &src) {
853 const typename Traits::Address &src) {
854 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 830 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
855 emitUint8(0x66); 831 emitUint8(0x66);
856 emitAddrSizeOverridePrefix(); 832 emitAddrSizeOverridePrefix();
857 emitRex(RexTypeIrrelevant, src, dst); 833 emitRex(RexTypeIrrelevant, src, dst);
858 emitUint8(0x0F); 834 emitUint8(0x0F);
859 emitUint8(0xF4); 835 emitUint8(0xF4);
860 emitOperand(gprEncoding(dst), src); 836 emitOperand(gprEncoding(dst), src);
861 } 837 }
862 838
863 template <class Machine> 839 template <typename TraitsType>
864 void AssemblerX86Base<Machine>::por(Type /* Ty */, 840 void AssemblerX86Base<TraitsType>::por(Type /* Ty */, XmmRegister dst,
865 typename Traits::XmmRegister dst, 841 XmmRegister src) {
866 typename Traits::XmmRegister src) {
867 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 842 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
868 emitUint8(0x66); 843 emitUint8(0x66);
869 emitRexRB(RexTypeIrrelevant, dst, src); 844 emitRexRB(RexTypeIrrelevant, dst, src);
870 emitUint8(0x0F); 845 emitUint8(0x0F);
871 emitUint8(0xEB); 846 emitUint8(0xEB);
872 emitXmmRegisterOperand(dst, src); 847 emitXmmRegisterOperand(dst, src);
873 } 848 }
874 849
875 template <class Machine> 850 template <typename TraitsType>
876 void AssemblerX86Base<Machine>::por(Type /* Ty */, 851 void AssemblerX86Base<TraitsType>::por(Type /* Ty */, XmmRegister dst,
877 typename Traits::XmmRegister dst, 852 const Address &src) {
878 const typename Traits::Address &src) {
879 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 853 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
880 emitUint8(0x66); 854 emitUint8(0x66);
881 emitAddrSizeOverridePrefix(); 855 emitAddrSizeOverridePrefix();
882 emitRex(RexTypeIrrelevant, src, dst); 856 emitRex(RexTypeIrrelevant, src, dst);
883 emitUint8(0x0F); 857 emitUint8(0x0F);
884 emitUint8(0xEB); 858 emitUint8(0xEB);
885 emitOperand(gprEncoding(dst), src); 859 emitOperand(gprEncoding(dst), src);
886 } 860 }
887 861
888 template <class Machine> 862 template <typename TraitsType>
889 void AssemblerX86Base<Machine>::psub(Type Ty, typename Traits::XmmRegister dst, 863 void AssemblerX86Base<TraitsType>::psub(Type Ty, XmmRegister dst,
890 typename Traits::XmmRegister src) { 864 XmmRegister src) {
891 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 865 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
892 emitUint8(0x66); 866 emitUint8(0x66);
893 emitRexRB(RexTypeIrrelevant, dst, src); 867 emitRexRB(RexTypeIrrelevant, dst, src);
894 emitUint8(0x0F); 868 emitUint8(0x0F);
895 if (isByteSizedArithType(Ty)) { 869 if (isByteSizedArithType(Ty)) {
896 emitUint8(0xF8); 870 emitUint8(0xF8);
897 } else if (Ty == IceType_i16) { 871 } else if (Ty == IceType_i16) {
898 emitUint8(0xF9); 872 emitUint8(0xF9);
899 } else { 873 } else {
900 emitUint8(0xFA); 874 emitUint8(0xFA);
901 } 875 }
902 emitXmmRegisterOperand(dst, src); 876 emitXmmRegisterOperand(dst, src);
903 } 877 }
904 878
905 template <class Machine> 879 template <typename TraitsType>
906 void AssemblerX86Base<Machine>::psub(Type Ty, typename Traits::XmmRegister dst, 880 void AssemblerX86Base<TraitsType>::psub(Type Ty, XmmRegister dst,
907 const typename Traits::Address &src) { 881 const Address &src) {
908 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 882 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
909 emitUint8(0x66); 883 emitUint8(0x66);
910 emitAddrSizeOverridePrefix(); 884 emitAddrSizeOverridePrefix();
911 emitRex(RexTypeIrrelevant, src, dst); 885 emitRex(RexTypeIrrelevant, src, dst);
912 emitUint8(0x0F); 886 emitUint8(0x0F);
913 if (isByteSizedArithType(Ty)) { 887 if (isByteSizedArithType(Ty)) {
914 emitUint8(0xF8); 888 emitUint8(0xF8);
915 } else if (Ty == IceType_i16) { 889 } else if (Ty == IceType_i16) {
916 emitUint8(0xF9); 890 emitUint8(0xF9);
917 } else { 891 } else {
918 emitUint8(0xFA); 892 emitUint8(0xFA);
919 } 893 }
920 emitOperand(gprEncoding(dst), src); 894 emitOperand(gprEncoding(dst), src);
921 } 895 }
922 896
923 template <class Machine> 897 template <typename TraitsType>
924 void AssemblerX86Base<Machine>::pxor(Type /* Ty */, 898 void AssemblerX86Base<TraitsType>::pxor(Type /* Ty */, XmmRegister dst,
925 typename Traits::XmmRegister dst, 899 XmmRegister src) {
926 typename Traits::XmmRegister src) {
927 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 900 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
928 emitUint8(0x66); 901 emitUint8(0x66);
929 emitRexRB(RexTypeIrrelevant, dst, src); 902 emitRexRB(RexTypeIrrelevant, dst, src);
930 emitUint8(0x0F); 903 emitUint8(0x0F);
931 emitUint8(0xEF); 904 emitUint8(0xEF);
932 emitXmmRegisterOperand(dst, src); 905 emitXmmRegisterOperand(dst, src);
933 } 906 }
934 907
935 template <class Machine> 908 template <typename TraitsType>
936 void AssemblerX86Base<Machine>::pxor(Type /* Ty */, 909 void AssemblerX86Base<TraitsType>::pxor(Type /* Ty */, XmmRegister dst,
937 typename Traits::XmmRegister dst, 910 const Address &src) {
938 const typename Traits::Address &src) {
939 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 911 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
940 emitUint8(0x66); 912 emitUint8(0x66);
941 emitAddrSizeOverridePrefix(); 913 emitAddrSizeOverridePrefix();
942 emitRex(RexTypeIrrelevant, src, dst); 914 emitRex(RexTypeIrrelevant, src, dst);
943 emitUint8(0x0F); 915 emitUint8(0x0F);
944 emitUint8(0xEF); 916 emitUint8(0xEF);
945 emitOperand(gprEncoding(dst), src); 917 emitOperand(gprEncoding(dst), src);
946 } 918 }
947 919
948 template <class Machine> 920 template <typename TraitsType>
949 void AssemblerX86Base<Machine>::psll(Type Ty, typename Traits::XmmRegister dst, 921 void AssemblerX86Base<TraitsType>::psll(Type Ty, XmmRegister dst,
950 typename Traits::XmmRegister src) { 922 XmmRegister src) {
951 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 923 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
952 emitUint8(0x66); 924 emitUint8(0x66);
953 emitRexRB(RexTypeIrrelevant, dst, src); 925 emitRexRB(RexTypeIrrelevant, dst, src);
954 emitUint8(0x0F); 926 emitUint8(0x0F);
955 if (Ty == IceType_i16) { 927 if (Ty == IceType_i16) {
956 emitUint8(0xF1); 928 emitUint8(0xF1);
957 } else { 929 } else {
958 assert(Ty == IceType_i32); 930 assert(Ty == IceType_i32);
959 emitUint8(0xF2); 931 emitUint8(0xF2);
960 } 932 }
961 emitXmmRegisterOperand(dst, src); 933 emitXmmRegisterOperand(dst, src);
962 } 934 }
963 935
964 template <class Machine> 936 template <typename TraitsType>
965 void AssemblerX86Base<Machine>::psll(Type Ty, typename Traits::XmmRegister dst, 937 void AssemblerX86Base<TraitsType>::psll(Type Ty, XmmRegister dst,
966 const typename Traits::Address &src) { 938 const Address &src) {
967 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 939 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
968 emitUint8(0x66); 940 emitUint8(0x66);
969 emitAddrSizeOverridePrefix(); 941 emitAddrSizeOverridePrefix();
970 emitRex(RexTypeIrrelevant, src, dst); 942 emitRex(RexTypeIrrelevant, src, dst);
971 emitUint8(0x0F); 943 emitUint8(0x0F);
972 if (Ty == IceType_i16) { 944 if (Ty == IceType_i16) {
973 emitUint8(0xF1); 945 emitUint8(0xF1);
974 } else { 946 } else {
975 assert(Ty == IceType_i32); 947 assert(Ty == IceType_i32);
976 emitUint8(0xF2); 948 emitUint8(0xF2);
977 } 949 }
978 emitOperand(gprEncoding(dst), src); 950 emitOperand(gprEncoding(dst), src);
979 } 951 }
980 952
981 template <class Machine> 953 template <typename TraitsType>
982 void AssemblerX86Base<Machine>::psll(Type Ty, typename Traits::XmmRegister dst, 954 void AssemblerX86Base<TraitsType>::psll(Type Ty, XmmRegister dst,
983 const Immediate &imm) { 955 const Immediate &imm) {
984 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 956 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
985 assert(imm.is_int8()); 957 assert(imm.is_int8());
986 emitUint8(0x66); 958 emitUint8(0x66);
987 emitRexB(RexTypeIrrelevant, dst); 959 emitRexB(RexTypeIrrelevant, dst);
988 emitUint8(0x0F); 960 emitUint8(0x0F);
989 if (Ty == IceType_i16) { 961 if (Ty == IceType_i16) {
990 emitUint8(0x71); 962 emitUint8(0x71);
991 } else { 963 } else {
992 assert(Ty == IceType_i32); 964 assert(Ty == IceType_i32);
993 emitUint8(0x72); 965 emitUint8(0x72);
994 } 966 }
995 emitRegisterOperand(6, gprEncoding(dst)); 967 emitRegisterOperand(6, gprEncoding(dst));
996 emitUint8(imm.value() & 0xFF); 968 emitUint8(imm.value() & 0xFF);
997 } 969 }
998 970
999 template <class Machine> 971 template <typename TraitsType>
1000 void AssemblerX86Base<Machine>::psra(Type Ty, typename Traits::XmmRegister dst, 972 void AssemblerX86Base<TraitsType>::psra(Type Ty, XmmRegister dst,
1001 typename Traits::XmmRegister src) { 973 XmmRegister src) {
1002 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 974 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1003 emitUint8(0x66); 975 emitUint8(0x66);
1004 emitRexRB(RexTypeIrrelevant, dst, src); 976 emitRexRB(RexTypeIrrelevant, dst, src);
1005 emitUint8(0x0F); 977 emitUint8(0x0F);
1006 if (Ty == IceType_i16) { 978 if (Ty == IceType_i16) {
1007 emitUint8(0xE1); 979 emitUint8(0xE1);
1008 } else { 980 } else {
1009 assert(Ty == IceType_i32); 981 assert(Ty == IceType_i32);
1010 emitUint8(0xE2); 982 emitUint8(0xE2);
1011 } 983 }
1012 emitXmmRegisterOperand(dst, src); 984 emitXmmRegisterOperand(dst, src);
1013 } 985 }
1014 986
1015 template <class Machine> 987 template <typename TraitsType>
1016 void AssemblerX86Base<Machine>::psra(Type Ty, typename Traits::XmmRegister dst, 988 void AssemblerX86Base<TraitsType>::psra(Type Ty, XmmRegister dst,
1017 const typename Traits::Address &src) { 989 const Address &src) {
1018 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 990 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1019 emitUint8(0x66); 991 emitUint8(0x66);
1020 emitAddrSizeOverridePrefix(); 992 emitAddrSizeOverridePrefix();
1021 emitRex(RexTypeIrrelevant, src, dst); 993 emitRex(RexTypeIrrelevant, src, dst);
1022 emitUint8(0x0F); 994 emitUint8(0x0F);
1023 if (Ty == IceType_i16) { 995 if (Ty == IceType_i16) {
1024 emitUint8(0xE1); 996 emitUint8(0xE1);
1025 } else { 997 } else {
1026 assert(Ty == IceType_i32); 998 assert(Ty == IceType_i32);
1027 emitUint8(0xE2); 999 emitUint8(0xE2);
1028 } 1000 }
1029 emitOperand(gprEncoding(dst), src); 1001 emitOperand(gprEncoding(dst), src);
1030 } 1002 }
1031 1003
1032 template <class Machine> 1004 template <typename TraitsType>
1033 void AssemblerX86Base<Machine>::psra(Type Ty, typename Traits::XmmRegister dst, 1005 void AssemblerX86Base<TraitsType>::psra(Type Ty, XmmRegister dst,
1034 const Immediate &imm) { 1006 const Immediate &imm) {
1035 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1007 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1036 assert(imm.is_int8()); 1008 assert(imm.is_int8());
1037 emitUint8(0x66); 1009 emitUint8(0x66);
1038 emitRexB(RexTypeIrrelevant, dst); 1010 emitRexB(RexTypeIrrelevant, dst);
1039 emitUint8(0x0F); 1011 emitUint8(0x0F);
1040 if (Ty == IceType_i16) { 1012 if (Ty == IceType_i16) {
1041 emitUint8(0x71); 1013 emitUint8(0x71);
1042 } else { 1014 } else {
1043 assert(Ty == IceType_i32); 1015 assert(Ty == IceType_i32);
1044 emitUint8(0x72); 1016 emitUint8(0x72);
1045 } 1017 }
1046 emitRegisterOperand(4, gprEncoding(dst)); 1018 emitRegisterOperand(4, gprEncoding(dst));
1047 emitUint8(imm.value() & 0xFF); 1019 emitUint8(imm.value() & 0xFF);
1048 } 1020 }
1049 1021
1050 template <class Machine> 1022 template <typename TraitsType>
1051 void AssemblerX86Base<Machine>::psrl(Type Ty, typename Traits::XmmRegister dst, 1023 void AssemblerX86Base<TraitsType>::psrl(Type Ty, XmmRegister dst,
1052 typename Traits::XmmRegister src) { 1024 XmmRegister src) {
1053 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1025 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1054 emitUint8(0x66); 1026 emitUint8(0x66);
1055 emitRexRB(RexTypeIrrelevant, dst, src); 1027 emitRexRB(RexTypeIrrelevant, dst, src);
1056 emitUint8(0x0F); 1028 emitUint8(0x0F);
1057 if (Ty == IceType_i16) { 1029 if (Ty == IceType_i16) {
1058 emitUint8(0xD1); 1030 emitUint8(0xD1);
1059 } else if (Ty == IceType_f64) { 1031 } else if (Ty == IceType_f64) {
1060 emitUint8(0xD3); 1032 emitUint8(0xD3);
1061 } else { 1033 } else {
1062 assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32); 1034 assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32);
1063 emitUint8(0xD2); 1035 emitUint8(0xD2);
1064 } 1036 }
1065 emitXmmRegisterOperand(dst, src); 1037 emitXmmRegisterOperand(dst, src);
1066 } 1038 }
1067 1039
1068 template <class Machine> 1040 template <typename TraitsType>
1069 void AssemblerX86Base<Machine>::psrl(Type Ty, typename Traits::XmmRegister dst, 1041 void AssemblerX86Base<TraitsType>::psrl(Type Ty, XmmRegister dst,
1070 const typename Traits::Address &src) { 1042 const Address &src) {
1071 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1043 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1072 emitUint8(0x66); 1044 emitUint8(0x66);
1073 emitAddrSizeOverridePrefix(); 1045 emitAddrSizeOverridePrefix();
1074 emitRex(RexTypeIrrelevant, src, dst); 1046 emitRex(RexTypeIrrelevant, src, dst);
1075 emitUint8(0x0F); 1047 emitUint8(0x0F);
1076 if (Ty == IceType_i16) { 1048 if (Ty == IceType_i16) {
1077 emitUint8(0xD1); 1049 emitUint8(0xD1);
1078 } else if (Ty == IceType_f64) { 1050 } else if (Ty == IceType_f64) {
1079 emitUint8(0xD3); 1051 emitUint8(0xD3);
1080 } else { 1052 } else {
1081 assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32); 1053 assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32);
1082 emitUint8(0xD2); 1054 emitUint8(0xD2);
1083 } 1055 }
1084 emitOperand(gprEncoding(dst), src); 1056 emitOperand(gprEncoding(dst), src);
1085 } 1057 }
1086 1058
1087 template <class Machine> 1059 template <typename TraitsType>
1088 void AssemblerX86Base<Machine>::psrl(Type Ty, typename Traits::XmmRegister dst, 1060 void AssemblerX86Base<TraitsType>::psrl(Type Ty, XmmRegister dst,
1089 const Immediate &imm) { 1061 const Immediate &imm) {
1090 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1062 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1091 assert(imm.is_int8()); 1063 assert(imm.is_int8());
1092 emitUint8(0x66); 1064 emitUint8(0x66);
1093 emitRexB(RexTypeIrrelevant, dst); 1065 emitRexB(RexTypeIrrelevant, dst);
1094 emitUint8(0x0F); 1066 emitUint8(0x0F);
1095 if (Ty == IceType_i16) { 1067 if (Ty == IceType_i16) {
1096 emitUint8(0x71); 1068 emitUint8(0x71);
1097 } else if (Ty == IceType_f64) { 1069 } else if (Ty == IceType_f64) {
1098 emitUint8(0x73); 1070 emitUint8(0x73);
1099 } else { 1071 } else {
1100 assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32); 1072 assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32);
1101 emitUint8(0x72); 1073 emitUint8(0x72);
1102 } 1074 }
1103 emitRegisterOperand(2, gprEncoding(dst)); 1075 emitRegisterOperand(2, gprEncoding(dst));
1104 emitUint8(imm.value() & 0xFF); 1076 emitUint8(imm.value() & 0xFF);
1105 } 1077 }
1106 1078
1107 // {add,sub,mul,div}ps are given a Ty parameter for consistency with 1079 // {add,sub,mul,div}ps are given a Ty parameter for consistency with
1108 // {add,sub,mul,div}ss. In the future, when the PNaCl ABI allows addpd, etc., 1080 // {add,sub,mul,div}ss. In the future, when the PNaCl ABI allows addpd, etc.,
1109 // we can use the Ty parameter to decide on adding a 0x66 prefix. 1081 // we can use the Ty parameter to decide on adding a 0x66 prefix.
1110 template <class Machine> 1082 template <typename TraitsType>
1111 void AssemblerX86Base<Machine>::addps(Type /* Ty */, 1083 void AssemblerX86Base<TraitsType>::addps(Type /* Ty */, XmmRegister dst,
1112 typename Traits::XmmRegister dst, 1084 XmmRegister src) {
1113 typename Traits::XmmRegister src) {
1114 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1085 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1115 emitRexRB(RexTypeIrrelevant, dst, src); 1086 emitRexRB(RexTypeIrrelevant, dst, src);
1116 emitUint8(0x0F); 1087 emitUint8(0x0F);
1117 emitUint8(0x58); 1088 emitUint8(0x58);
1118 emitXmmRegisterOperand(dst, src); 1089 emitXmmRegisterOperand(dst, src);
1119 } 1090 }
1120 1091
1121 template <class Machine> 1092 template <typename TraitsType>
1122 void AssemblerX86Base<Machine>::addps(Type /* Ty */, 1093 void AssemblerX86Base<TraitsType>::addps(Type /* Ty */, XmmRegister dst,
1123 typename Traits::XmmRegister dst, 1094 const Address &src) {
1124 const typename Traits::Address &src) {
1125 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1095 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1126 emitAddrSizeOverridePrefix(); 1096 emitAddrSizeOverridePrefix();
1127 emitRex(RexTypeIrrelevant, src, dst); 1097 emitRex(RexTypeIrrelevant, src, dst);
1128 emitUint8(0x0F); 1098 emitUint8(0x0F);
1129 emitUint8(0x58); 1099 emitUint8(0x58);
1130 emitOperand(gprEncoding(dst), src); 1100 emitOperand(gprEncoding(dst), src);
1131 } 1101 }
1132 1102
1133 template <class Machine> 1103 template <typename TraitsType>
1134 void AssemblerX86Base<Machine>::subps(Type /* Ty */, 1104 void AssemblerX86Base<TraitsType>::subps(Type /* Ty */, XmmRegister dst,
1135 typename Traits::XmmRegister dst, 1105 XmmRegister src) {
1136 typename Traits::XmmRegister src) {
1137 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1106 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1138 emitRexRB(RexTypeIrrelevant, dst, src); 1107 emitRexRB(RexTypeIrrelevant, dst, src);
1139 emitUint8(0x0F); 1108 emitUint8(0x0F);
1140 emitUint8(0x5C); 1109 emitUint8(0x5C);
1141 emitXmmRegisterOperand(dst, src); 1110 emitXmmRegisterOperand(dst, src);
1142 } 1111 }
1143 1112
1144 template <class Machine> 1113 template <typename TraitsType>
1145 void AssemblerX86Base<Machine>::subps(Type /* Ty */, 1114 void AssemblerX86Base<TraitsType>::subps(Type /* Ty */, XmmRegister dst,
1146 typename Traits::XmmRegister dst, 1115 const Address &src) {
1147 const typename Traits::Address &src) {
1148 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1116 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1149 emitAddrSizeOverridePrefix(); 1117 emitAddrSizeOverridePrefix();
1150 emitRex(RexTypeIrrelevant, src, dst); 1118 emitRex(RexTypeIrrelevant, src, dst);
1151 emitUint8(0x0F); 1119 emitUint8(0x0F);
1152 emitUint8(0x5C); 1120 emitUint8(0x5C);
1153 emitOperand(gprEncoding(dst), src); 1121 emitOperand(gprEncoding(dst), src);
1154 } 1122 }
1155 1123
1156 template <class Machine> 1124 template <typename TraitsType>
1157 void AssemblerX86Base<Machine>::divps(Type /* Ty */, 1125 void AssemblerX86Base<TraitsType>::divps(Type /* Ty */, XmmRegister dst,
1158 typename Traits::XmmRegister dst, 1126 XmmRegister src) {
1159 typename Traits::XmmRegister src) {
1160 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1127 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1161 emitRexRB(RexTypeIrrelevant, dst, src); 1128 emitRexRB(RexTypeIrrelevant, dst, src);
1162 emitUint8(0x0F); 1129 emitUint8(0x0F);
1163 emitUint8(0x5E); 1130 emitUint8(0x5E);
1164 emitXmmRegisterOperand(dst, src); 1131 emitXmmRegisterOperand(dst, src);
1165 } 1132 }
1166 1133
1167 template <class Machine> 1134 template <typename TraitsType>
1168 void AssemblerX86Base<Machine>::divps(Type /* Ty */, 1135 void AssemblerX86Base<TraitsType>::divps(Type /* Ty */, XmmRegister dst,
1169 typename Traits::XmmRegister dst, 1136 const Address &src) {
1170 const typename Traits::Address &src) {
1171 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1137 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1172 emitAddrSizeOverridePrefix(); 1138 emitAddrSizeOverridePrefix();
1173 emitRex(RexTypeIrrelevant, src, dst); 1139 emitRex(RexTypeIrrelevant, src, dst);
1174 emitUint8(0x0F); 1140 emitUint8(0x0F);
1175 emitUint8(0x5E); 1141 emitUint8(0x5E);
1176 emitOperand(gprEncoding(dst), src); 1142 emitOperand(gprEncoding(dst), src);
1177 } 1143 }
1178 1144
1179 template <class Machine> 1145 template <typename TraitsType>
1180 void AssemblerX86Base<Machine>::mulps(Type /* Ty */, 1146 void AssemblerX86Base<TraitsType>::mulps(Type /* Ty */, XmmRegister dst,
1181 typename Traits::XmmRegister dst, 1147 XmmRegister src) {
1182 typename Traits::XmmRegister src) {
1183 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1148 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1184 emitRexRB(RexTypeIrrelevant, dst, src); 1149 emitRexRB(RexTypeIrrelevant, dst, src);
1185 emitUint8(0x0F); 1150 emitUint8(0x0F);
1186 emitUint8(0x59); 1151 emitUint8(0x59);
1187 emitXmmRegisterOperand(dst, src); 1152 emitXmmRegisterOperand(dst, src);
1188 } 1153 }
1189 1154
1190 template <class Machine> 1155 template <typename TraitsType>
1191 void AssemblerX86Base<Machine>::mulps(Type /* Ty */, 1156 void AssemblerX86Base<TraitsType>::mulps(Type /* Ty */, XmmRegister dst,
1192 typename Traits::XmmRegister dst, 1157 const Address &src) {
1193 const typename Traits::Address &src) {
1194 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1158 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1195 emitAddrSizeOverridePrefix(); 1159 emitAddrSizeOverridePrefix();
1196 emitRex(RexTypeIrrelevant, src, dst); 1160 emitRex(RexTypeIrrelevant, src, dst);
1197 emitUint8(0x0F); 1161 emitUint8(0x0F);
1198 emitUint8(0x59); 1162 emitUint8(0x59);
1199 emitOperand(gprEncoding(dst), src); 1163 emitOperand(gprEncoding(dst), src);
1200 } 1164 }
1201 1165
1202 template <class Machine> 1166 template <typename TraitsType>
1203 void AssemblerX86Base<Machine>::minps(Type Ty, typename Traits::XmmRegister dst, 1167 void AssemblerX86Base<TraitsType>::minps(Type Ty, XmmRegister dst,
1204 typename Traits::XmmRegister src) { 1168 XmmRegister src) {
1205 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1169 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1206 if (!isFloat32Asserting32Or64(Ty)) 1170 if (!isFloat32Asserting32Or64(Ty))
1207 emitUint8(0x66); 1171 emitUint8(0x66);
1208 emitRexRB(RexTypeIrrelevant, dst, src); 1172 emitRexRB(RexTypeIrrelevant, dst, src);
1209 emitUint8(0x0F); 1173 emitUint8(0x0F);
1210 emitUint8(0x5D); 1174 emitUint8(0x5D);
1211 emitXmmRegisterOperand(dst, src); 1175 emitXmmRegisterOperand(dst, src);
1212 } 1176 }
1213 1177
1214 template <class Machine> 1178 template <typename TraitsType>
1215 void AssemblerX86Base<Machine>::minps(Type Ty, typename Traits::XmmRegister dst, 1179 void AssemblerX86Base<TraitsType>::minps(Type Ty, XmmRegister dst,
1216 const typename Traits::Address &src) { 1180 const Address &src) {
1217 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1181 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1218 if (!isFloat32Asserting32Or64(Ty)) 1182 if (!isFloat32Asserting32Or64(Ty))
1219 emitUint8(0x66); 1183 emitUint8(0x66);
1220 emitAddrSizeOverridePrefix(); 1184 emitAddrSizeOverridePrefix();
1221 emitRex(RexTypeIrrelevant, src, dst); 1185 emitRex(RexTypeIrrelevant, src, dst);
1222 emitUint8(0x0F); 1186 emitUint8(0x0F);
1223 emitUint8(0x5D); 1187 emitUint8(0x5D);
1224 emitOperand(gprEncoding(dst), src); 1188 emitOperand(gprEncoding(dst), src);
1225 } 1189 }
1226 1190
1227 template <class Machine> 1191 template <typename TraitsType>
1228 void AssemblerX86Base<Machine>::minss(Type Ty, typename Traits::XmmRegister dst, 1192 void AssemblerX86Base<TraitsType>::minss(Type Ty, XmmRegister dst,
1229 typename Traits::XmmRegister src) { 1193 XmmRegister src) {
1230 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1194 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1231 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); 1195 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
1232 emitRexRB(RexTypeIrrelevant, dst, src); 1196 emitRexRB(RexTypeIrrelevant, dst, src);
1233 emitUint8(0x0F); 1197 emitUint8(0x0F);
1234 emitUint8(0x5D); 1198 emitUint8(0x5D);
1235 emitXmmRegisterOperand(dst, src); 1199 emitXmmRegisterOperand(dst, src);
1236 } 1200 }
1237 1201
1238 template <class Machine> 1202 template <typename TraitsType>
1239 void AssemblerX86Base<Machine>::minss(Type Ty, typename Traits::XmmRegister dst, 1203 void AssemblerX86Base<TraitsType>::minss(Type Ty, XmmRegister dst,
1240 const typename Traits::Address &src) { 1204 const Address &src) {
1241 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1205 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1242 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); 1206 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
1243 emitAddrSizeOverridePrefix(); 1207 emitAddrSizeOverridePrefix();
1244 emitRex(RexTypeIrrelevant, src, dst); 1208 emitRex(RexTypeIrrelevant, src, dst);
1245 emitUint8(0x0F); 1209 emitUint8(0x0F);
1246 emitUint8(0x5D); 1210 emitUint8(0x5D);
1247 emitOperand(gprEncoding(dst), src); 1211 emitOperand(gprEncoding(dst), src);
1248 } 1212 }
1249 1213
1250 template <class Machine> 1214 template <typename TraitsType>
1251 void AssemblerX86Base<Machine>::maxps(Type Ty, typename Traits::XmmRegister dst, 1215 void AssemblerX86Base<TraitsType>::maxps(Type Ty, XmmRegister dst,
1252 typename Traits::XmmRegister src) { 1216 XmmRegister src) {
1253 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1217 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1254 if (!isFloat32Asserting32Or64(Ty)) 1218 if (!isFloat32Asserting32Or64(Ty))
1255 emitUint8(0x66); 1219 emitUint8(0x66);
1256 emitRexRB(RexTypeIrrelevant, dst, src); 1220 emitRexRB(RexTypeIrrelevant, dst, src);
1257 emitUint8(0x0F); 1221 emitUint8(0x0F);
1258 emitUint8(0x5F); 1222 emitUint8(0x5F);
1259 emitXmmRegisterOperand(dst, src); 1223 emitXmmRegisterOperand(dst, src);
1260 } 1224 }
1261 1225
1262 template <class Machine> 1226 template <typename TraitsType>
1263 void AssemblerX86Base<Machine>::maxps(Type Ty, typename Traits::XmmRegister dst, 1227 void AssemblerX86Base<TraitsType>::maxps(Type Ty, XmmRegister dst,
1264 const typename Traits::Address &src) { 1228 const Address &src) {
1265 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1229 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1266 if (!isFloat32Asserting32Or64(Ty)) 1230 if (!isFloat32Asserting32Or64(Ty))
1267 emitUint8(0x66); 1231 emitUint8(0x66);
1268 emitAddrSizeOverridePrefix(); 1232 emitAddrSizeOverridePrefix();
1269 emitRex(RexTypeIrrelevant, src, dst); 1233 emitRex(RexTypeIrrelevant, src, dst);
1270 emitUint8(0x0F); 1234 emitUint8(0x0F);
1271 emitUint8(0x5F); 1235 emitUint8(0x5F);
1272 emitOperand(gprEncoding(dst), src); 1236 emitOperand(gprEncoding(dst), src);
1273 } 1237 }
1274 1238
1275 template <class Machine> 1239 template <typename TraitsType>
1276 void AssemblerX86Base<Machine>::maxss(Type Ty, typename Traits::XmmRegister dst, 1240 void AssemblerX86Base<TraitsType>::maxss(Type Ty, XmmRegister dst,
1277 typename Traits::XmmRegister src) { 1241 XmmRegister src) {
1278 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1242 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1279 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); 1243 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
1280 emitRexRB(RexTypeIrrelevant, dst, src); 1244 emitRexRB(RexTypeIrrelevant, dst, src);
1281 emitUint8(0x0F); 1245 emitUint8(0x0F);
1282 emitUint8(0x5F); 1246 emitUint8(0x5F);
1283 emitXmmRegisterOperand(dst, src); 1247 emitXmmRegisterOperand(dst, src);
1284 } 1248 }
1285 1249
1286 template <class Machine> 1250 template <typename TraitsType>
1287 void AssemblerX86Base<Machine>::maxss(Type Ty, typename Traits::XmmRegister dst, 1251 void AssemblerX86Base<TraitsType>::maxss(Type Ty, XmmRegister dst,
1288 const typename Traits::Address &src) { 1252 const Address &src) {
1289 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1253 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1290 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); 1254 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
1291 emitAddrSizeOverridePrefix(); 1255 emitAddrSizeOverridePrefix();
1292 emitRex(RexTypeIrrelevant, src, dst); 1256 emitRex(RexTypeIrrelevant, src, dst);
1293 emitUint8(0x0F); 1257 emitUint8(0x0F);
1294 emitUint8(0x5F); 1258 emitUint8(0x5F);
1295 emitOperand(gprEncoding(dst), src); 1259 emitOperand(gprEncoding(dst), src);
1296 } 1260 }
1297 1261
1298 template <class Machine> 1262 template <typename TraitsType>
1299 void AssemblerX86Base<Machine>::andnps(Type Ty, 1263 void AssemblerX86Base<TraitsType>::andnps(Type Ty, XmmRegister dst,
1300 typename Traits::XmmRegister dst, 1264 XmmRegister src) {
1301 typename Traits::XmmRegister src) {
1302 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1265 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1303 if (!isFloat32Asserting32Or64(Ty)) 1266 if (!isFloat32Asserting32Or64(Ty))
1304 emitUint8(0x66); 1267 emitUint8(0x66);
1305 emitRexRB(RexTypeIrrelevant, dst, src); 1268 emitRexRB(RexTypeIrrelevant, dst, src);
1306 emitUint8(0x0F); 1269 emitUint8(0x0F);
1307 emitUint8(0x55); 1270 emitUint8(0x55);
1308 emitXmmRegisterOperand(dst, src); 1271 emitXmmRegisterOperand(dst, src);
1309 } 1272 }
1310 1273
1311 template <class Machine> 1274 template <typename TraitsType>
1312 void AssemblerX86Base<Machine>::andnps(Type Ty, 1275 void AssemblerX86Base<TraitsType>::andnps(Type Ty, XmmRegister dst,
1313 typename Traits::XmmRegister dst, 1276 const Address &src) {
1314 const typename Traits::Address &src) {
1315 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1277 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1316 if (!isFloat32Asserting32Or64(Ty)) 1278 if (!isFloat32Asserting32Or64(Ty))
1317 emitUint8(0x66); 1279 emitUint8(0x66);
1318 emitAddrSizeOverridePrefix(); 1280 emitAddrSizeOverridePrefix();
1319 emitRex(RexTypeIrrelevant, src, dst); 1281 emitRex(RexTypeIrrelevant, src, dst);
1320 emitUint8(0x0F); 1282 emitUint8(0x0F);
1321 emitUint8(0x55); 1283 emitUint8(0x55);
1322 emitOperand(gprEncoding(dst), src); 1284 emitOperand(gprEncoding(dst), src);
1323 } 1285 }
1324 1286
1325 template <class Machine> 1287 template <typename TraitsType>
1326 void AssemblerX86Base<Machine>::andps(Type Ty, typename Traits::XmmRegister dst, 1288 void AssemblerX86Base<TraitsType>::andps(Type Ty, XmmRegister dst,
1327 typename Traits::XmmRegister src) { 1289 XmmRegister src) {
1328 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1290 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1329 if (!isFloat32Asserting32Or64(Ty)) 1291 if (!isFloat32Asserting32Or64(Ty))
1330 emitUint8(0x66); 1292 emitUint8(0x66);
1331 emitRexRB(RexTypeIrrelevant, dst, src); 1293 emitRexRB(RexTypeIrrelevant, dst, src);
1332 emitUint8(0x0F); 1294 emitUint8(0x0F);
1333 emitUint8(0x54); 1295 emitUint8(0x54);
1334 emitXmmRegisterOperand(dst, src); 1296 emitXmmRegisterOperand(dst, src);
1335 } 1297 }
1336 1298
1337 template <class Machine> 1299 template <typename TraitsType>
1338 void AssemblerX86Base<Machine>::andps(Type Ty, typename Traits::XmmRegister dst, 1300 void AssemblerX86Base<TraitsType>::andps(Type Ty, XmmRegister dst,
1339 const typename Traits::Address &src) { 1301 const Address &src) {
1340 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1302 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1341 if (!isFloat32Asserting32Or64(Ty)) 1303 if (!isFloat32Asserting32Or64(Ty))
1342 emitUint8(0x66); 1304 emitUint8(0x66);
1343 emitAddrSizeOverridePrefix(); 1305 emitAddrSizeOverridePrefix();
1344 emitRex(RexTypeIrrelevant, src, dst); 1306 emitRex(RexTypeIrrelevant, src, dst);
1345 emitUint8(0x0F); 1307 emitUint8(0x0F);
1346 emitUint8(0x54); 1308 emitUint8(0x54);
1347 emitOperand(gprEncoding(dst), src); 1309 emitOperand(gprEncoding(dst), src);
1348 } 1310 }
1349 1311
1350 template <class Machine> 1312 template <typename TraitsType>
1351 void AssemblerX86Base<Machine>::orps(Type Ty, typename Traits::XmmRegister dst, 1313 void AssemblerX86Base<TraitsType>::orps(Type Ty, XmmRegister dst,
1352 typename Traits::XmmRegister src) { 1314 XmmRegister src) {
1353 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1315 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1354 if (!isFloat32Asserting32Or64(Ty)) 1316 if (!isFloat32Asserting32Or64(Ty))
1355 emitUint8(0x66); 1317 emitUint8(0x66);
1356 emitRexRB(RexTypeIrrelevant, dst, src); 1318 emitRexRB(RexTypeIrrelevant, dst, src);
1357 emitUint8(0x0F); 1319 emitUint8(0x0F);
1358 emitUint8(0x56); 1320 emitUint8(0x56);
1359 emitXmmRegisterOperand(dst, src); 1321 emitXmmRegisterOperand(dst, src);
1360 } 1322 }
1361 1323
1362 template <class Machine> 1324 template <typename TraitsType>
1363 void AssemblerX86Base<Machine>::orps(Type Ty, typename Traits::XmmRegister dst, 1325 void AssemblerX86Base<TraitsType>::orps(Type Ty, XmmRegister dst,
1364 const typename Traits::Address &src) { 1326 const Address &src) {
1365 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1327 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1366 if (!isFloat32Asserting32Or64(Ty)) 1328 if (!isFloat32Asserting32Or64(Ty))
1367 emitUint8(0x66); 1329 emitUint8(0x66);
1368 emitAddrSizeOverridePrefix(); 1330 emitAddrSizeOverridePrefix();
1369 emitRex(RexTypeIrrelevant, src, dst); 1331 emitRex(RexTypeIrrelevant, src, dst);
1370 emitUint8(0x0F); 1332 emitUint8(0x0F);
1371 emitUint8(0x56); 1333 emitUint8(0x56);
1372 emitOperand(gprEncoding(dst), src); 1334 emitOperand(gprEncoding(dst), src);
1373 } 1335 }
1374 1336
1375 template <class Machine> 1337 template <typename TraitsType>
1376 void AssemblerX86Base<Machine>::blendvps(Type /* Ty */, 1338 void AssemblerX86Base<TraitsType>::blendvps(Type /* Ty */, XmmRegister dst,
1377 typename Traits::XmmRegister dst, 1339 XmmRegister src) {
1378 typename Traits::XmmRegister src) {
1379 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1340 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1380 emitUint8(0x66); 1341 emitUint8(0x66);
1381 emitRexRB(RexTypeIrrelevant, dst, src); 1342 emitRexRB(RexTypeIrrelevant, dst, src);
1382 emitUint8(0x0F); 1343 emitUint8(0x0F);
1383 emitUint8(0x38); 1344 emitUint8(0x38);
1384 emitUint8(0x14); 1345 emitUint8(0x14);
1385 emitXmmRegisterOperand(dst, src); 1346 emitXmmRegisterOperand(dst, src);
1386 } 1347 }
1387 1348
1388 template <class Machine> 1349 template <typename TraitsType>
1389 void AssemblerX86Base<Machine>::blendvps(Type /* Ty */, 1350 void AssemblerX86Base<TraitsType>::blendvps(Type /* Ty */, XmmRegister dst,
1390 typename Traits::XmmRegister dst, 1351 const Address &src) {
1391 const typename Traits::Address &src) {
1392 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1352 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1393 emitUint8(0x66); 1353 emitUint8(0x66);
1394 emitAddrSizeOverridePrefix(); 1354 emitAddrSizeOverridePrefix();
1395 emitRex(RexTypeIrrelevant, src, dst); 1355 emitRex(RexTypeIrrelevant, src, dst);
1396 emitUint8(0x0F); 1356 emitUint8(0x0F);
1397 emitUint8(0x38); 1357 emitUint8(0x38);
1398 emitUint8(0x14); 1358 emitUint8(0x14);
1399 emitOperand(gprEncoding(dst), src); 1359 emitOperand(gprEncoding(dst), src);
1400 } 1360 }
1401 1361
1402 template <class Machine> 1362 template <typename TraitsType>
1403 void AssemblerX86Base<Machine>::pblendvb(Type /* Ty */, 1363 void AssemblerX86Base<TraitsType>::pblendvb(Type /* Ty */, XmmRegister dst,
1404 typename Traits::XmmRegister dst, 1364 XmmRegister src) {
1405 typename Traits::XmmRegister src) {
1406 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1365 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1407 emitUint8(0x66); 1366 emitUint8(0x66);
1408 emitRexRB(RexTypeIrrelevant, dst, src); 1367 emitRexRB(RexTypeIrrelevant, dst, src);
1409 emitUint8(0x0F); 1368 emitUint8(0x0F);
1410 emitUint8(0x38); 1369 emitUint8(0x38);
1411 emitUint8(0x10); 1370 emitUint8(0x10);
1412 emitXmmRegisterOperand(dst, src); 1371 emitXmmRegisterOperand(dst, src);
1413 } 1372 }
1414 1373
1415 template <class Machine> 1374 template <typename TraitsType>
1416 void AssemblerX86Base<Machine>::pblendvb(Type /* Ty */, 1375 void AssemblerX86Base<TraitsType>::pblendvb(Type /* Ty */, XmmRegister dst,
1417 typename Traits::XmmRegister dst, 1376 const Address &src) {
1418 const typename Traits::Address &src) {
1419 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1377 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1420 emitUint8(0x66); 1378 emitUint8(0x66);
1421 emitAddrSizeOverridePrefix(); 1379 emitAddrSizeOverridePrefix();
1422 emitRex(RexTypeIrrelevant, src, dst); 1380 emitRex(RexTypeIrrelevant, src, dst);
1423 emitUint8(0x0F); 1381 emitUint8(0x0F);
1424 emitUint8(0x38); 1382 emitUint8(0x38);
1425 emitUint8(0x10); 1383 emitUint8(0x10);
1426 emitOperand(gprEncoding(dst), src); 1384 emitOperand(gprEncoding(dst), src);
1427 } 1385 }
1428 1386
1429 template <class Machine> 1387 template <typename TraitsType>
1430 void AssemblerX86Base<Machine>::cmpps( 1388 void AssemblerX86Base<TraitsType>::cmpps(Type Ty, XmmRegister dst,
1431 Type Ty, typename Traits::XmmRegister dst, typename Traits::XmmRegister src, 1389 XmmRegister src,
1432 typename Traits::Cond::CmppsCond CmpCondition) { 1390 CmppsCond CmpCondition) {
1433 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1391 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1434 if (Ty == IceType_f64) 1392 if (Ty == IceType_f64)
1435 emitUint8(0x66); 1393 emitUint8(0x66);
1436 emitRexRB(RexTypeIrrelevant, dst, src); 1394 emitRexRB(RexTypeIrrelevant, dst, src);
1437 emitUint8(0x0F); 1395 emitUint8(0x0F);
1438 emitUint8(0xC2); 1396 emitUint8(0xC2);
1439 emitXmmRegisterOperand(dst, src); 1397 emitXmmRegisterOperand(dst, src);
1440 emitUint8(CmpCondition); 1398 emitUint8(CmpCondition);
1441 } 1399 }
1442 1400
1443 template <class Machine> 1401 template <typename TraitsType>
1444 void AssemblerX86Base<Machine>::cmpps( 1402 void AssemblerX86Base<TraitsType>::cmpps(Type Ty, XmmRegister dst,
1445 Type Ty, typename Traits::XmmRegister dst, 1403 const Address &src,
1446 const typename Traits::Address &src, 1404 CmppsCond CmpCondition) {
1447 typename Traits::Cond::CmppsCond CmpCondition) {
1448 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1405 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1449 if (Ty == IceType_f64) 1406 if (Ty == IceType_f64)
1450 emitUint8(0x66); 1407 emitUint8(0x66);
1451 emitAddrSizeOverridePrefix(); 1408 emitAddrSizeOverridePrefix();
1452 emitRex(RexTypeIrrelevant, src, dst); 1409 emitRex(RexTypeIrrelevant, src, dst);
1453 emitUint8(0x0F); 1410 emitUint8(0x0F);
1454 emitUint8(0xC2); 1411 emitUint8(0xC2);
1455 emitOperand(gprEncoding(dst), src); 1412 emitOperand(gprEncoding(dst), src);
1456 emitUint8(CmpCondition); 1413 emitUint8(CmpCondition);
1457 } 1414 }
1458 1415
1459 template <class Machine> 1416 template <typename TraitsType>
1460 void AssemblerX86Base<Machine>::sqrtps(typename Traits::XmmRegister dst) { 1417 void AssemblerX86Base<TraitsType>::sqrtps(XmmRegister dst) {
1461 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1418 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1462 emitRexRB(RexTypeIrrelevant, dst, dst); 1419 emitRexRB(RexTypeIrrelevant, dst, dst);
1463 emitUint8(0x0F); 1420 emitUint8(0x0F);
1464 emitUint8(0x51); 1421 emitUint8(0x51);
1465 emitXmmRegisterOperand(dst, dst); 1422 emitXmmRegisterOperand(dst, dst);
1466 } 1423 }
1467 1424
1468 template <class Machine> 1425 template <typename TraitsType>
1469 void AssemblerX86Base<Machine>::rsqrtps(typename Traits::XmmRegister dst) { 1426 void AssemblerX86Base<TraitsType>::rsqrtps(XmmRegister dst) {
1470 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1427 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1471 emitRexRB(RexTypeIrrelevant, dst, dst); 1428 emitRexRB(RexTypeIrrelevant, dst, dst);
1472 emitUint8(0x0F); 1429 emitUint8(0x0F);
1473 emitUint8(0x52); 1430 emitUint8(0x52);
1474 emitXmmRegisterOperand(dst, dst); 1431 emitXmmRegisterOperand(dst, dst);
1475 } 1432 }
1476 1433
1477 template <class Machine> 1434 template <typename TraitsType>
1478 void AssemblerX86Base<Machine>::reciprocalps(typename Traits::XmmRegister dst) { 1435 void AssemblerX86Base<TraitsType>::reciprocalps(XmmRegister dst) {
1479 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1436 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1480 emitRexRB(RexTypeIrrelevant, dst, dst); 1437 emitRexRB(RexTypeIrrelevant, dst, dst);
1481 emitUint8(0x0F); 1438 emitUint8(0x0F);
1482 emitUint8(0x53); 1439 emitUint8(0x53);
1483 emitXmmRegisterOperand(dst, dst); 1440 emitXmmRegisterOperand(dst, dst);
1484 } 1441 }
1485 1442
1486 template <class Machine> 1443 template <typename TraitsType>
1487 void AssemblerX86Base<Machine>::movhlps(typename Traits::XmmRegister dst, 1444 void AssemblerX86Base<TraitsType>::movhlps(XmmRegister dst, XmmRegister src) {
1488 typename Traits::XmmRegister src) {
1489 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1445 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1490 emitRexRB(RexTypeIrrelevant, dst, src); 1446 emitRexRB(RexTypeIrrelevant, dst, src);
1491 emitUint8(0x0F); 1447 emitUint8(0x0F);
1492 emitUint8(0x12); 1448 emitUint8(0x12);
1493 emitXmmRegisterOperand(dst, src); 1449 emitXmmRegisterOperand(dst, src);
1494 } 1450 }
1495 1451
1496 template <class Machine> 1452 template <typename TraitsType>
1497 void AssemblerX86Base<Machine>::movlhps(typename Traits::XmmRegister dst, 1453 void AssemblerX86Base<TraitsType>::movlhps(XmmRegister dst, XmmRegister src) {
1498 typename Traits::XmmRegister src) {
1499 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1454 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1500 emitRexRB(RexTypeIrrelevant, dst, src); 1455 emitRexRB(RexTypeIrrelevant, dst, src);
1501 emitUint8(0x0F); 1456 emitUint8(0x0F);
1502 emitUint8(0x16); 1457 emitUint8(0x16);
1503 emitXmmRegisterOperand(dst, src); 1458 emitXmmRegisterOperand(dst, src);
1504 } 1459 }
1505 1460
1506 template <class Machine> 1461 template <typename TraitsType>
1507 void AssemblerX86Base<Machine>::unpcklps(typename Traits::XmmRegister dst, 1462 void AssemblerX86Base<TraitsType>::unpcklps(XmmRegister dst, XmmRegister src) {
1508 typename Traits::XmmRegister src) {
1509 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1463 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1510 emitRexRB(RexTypeIrrelevant, dst, src); 1464 emitRexRB(RexTypeIrrelevant, dst, src);
1511 emitUint8(0x0F); 1465 emitUint8(0x0F);
1512 emitUint8(0x14); 1466 emitUint8(0x14);
1513 emitXmmRegisterOperand(dst, src); 1467 emitXmmRegisterOperand(dst, src);
1514 } 1468 }
1515 1469
1516 template <class Machine> 1470 template <typename TraitsType>
1517 void AssemblerX86Base<Machine>::unpckhps(typename Traits::XmmRegister dst, 1471 void AssemblerX86Base<TraitsType>::unpckhps(XmmRegister dst, XmmRegister src) {
1518 typename Traits::XmmRegister src) {
1519 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1472 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1520 emitRexRB(RexTypeIrrelevant, dst, src); 1473 emitRexRB(RexTypeIrrelevant, dst, src);
1521 emitUint8(0x0F); 1474 emitUint8(0x0F);
1522 emitUint8(0x15); 1475 emitUint8(0x15);
1523 emitXmmRegisterOperand(dst, src); 1476 emitXmmRegisterOperand(dst, src);
1524 } 1477 }
1525 1478
1526 template <class Machine> 1479 template <typename TraitsType>
1527 void AssemblerX86Base<Machine>::unpcklpd(typename Traits::XmmRegister dst, 1480 void AssemblerX86Base<TraitsType>::unpcklpd(XmmRegister dst, XmmRegister src) {
1528 typename Traits::XmmRegister src) {
1529 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1481 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1530 emitUint8(0x66); 1482 emitUint8(0x66);
1531 emitRexRB(RexTypeIrrelevant, dst, src); 1483 emitRexRB(RexTypeIrrelevant, dst, src);
1532 emitUint8(0x0F); 1484 emitUint8(0x0F);
1533 emitUint8(0x14); 1485 emitUint8(0x14);
1534 emitXmmRegisterOperand(dst, src); 1486 emitXmmRegisterOperand(dst, src);
1535 } 1487 }
1536 1488
1537 template <class Machine> 1489 template <typename TraitsType>
1538 void AssemblerX86Base<Machine>::unpckhpd(typename Traits::XmmRegister dst, 1490 void AssemblerX86Base<TraitsType>::unpckhpd(XmmRegister dst, XmmRegister src) {
1539 typename Traits::XmmRegister src) {
1540 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1491 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1541 emitUint8(0x66); 1492 emitUint8(0x66);
1542 emitRexRB(RexTypeIrrelevant, dst, src); 1493 emitRexRB(RexTypeIrrelevant, dst, src);
1543 emitUint8(0x0F); 1494 emitUint8(0x0F);
1544 emitUint8(0x15); 1495 emitUint8(0x15);
1545 emitXmmRegisterOperand(dst, src); 1496 emitXmmRegisterOperand(dst, src);
1546 } 1497 }
1547 1498
1548 template <class Machine> 1499 template <typename TraitsType>
1549 void AssemblerX86Base<Machine>::set1ps(typename Traits::XmmRegister dst, 1500 void AssemblerX86Base<TraitsType>::set1ps(XmmRegister dst, GPRRegister tmp1,
1550 typename Traits::GPRRegister tmp1, 1501 const Immediate &imm) {
1551 const Immediate &imm) {
1552 // Load 32-bit immediate value into tmp1. 1502 // Load 32-bit immediate value into tmp1.
1553 mov(IceType_i32, tmp1, imm); 1503 mov(IceType_i32, tmp1, imm);
1554 // Move value from tmp1 into dst. 1504 // Move value from tmp1 into dst.
1555 movd(IceType_i32, dst, tmp1); 1505 movd(IceType_i32, dst, tmp1);
1556 // Broadcast low lane into other three lanes. 1506 // Broadcast low lane into other three lanes.
1557 shufps(RexTypeIrrelevant, dst, dst, Immediate(0x0)); 1507 shufps(RexTypeIrrelevant, dst, dst, Immediate(0x0));
1558 } 1508 }
1559 1509
1560 template <class Machine> 1510 template <typename TraitsType>
1561 void AssemblerX86Base<Machine>::pshufd(Type /* Ty */, 1511 void AssemblerX86Base<TraitsType>::pshufd(Type /* Ty */, XmmRegister dst,
1562 typename Traits::XmmRegister dst, 1512 XmmRegister src,
1563 typename Traits::XmmRegister src, 1513 const Immediate &imm) {
1564 const Immediate &imm) {
1565 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1514 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1566 emitUint8(0x66); 1515 emitUint8(0x66);
1567 emitRexRB(RexTypeIrrelevant, dst, src); 1516 emitRexRB(RexTypeIrrelevant, dst, src);
1568 emitUint8(0x0F); 1517 emitUint8(0x0F);
1569 emitUint8(0x70); 1518 emitUint8(0x70);
1570 emitXmmRegisterOperand(dst, src); 1519 emitXmmRegisterOperand(dst, src);
1571 assert(imm.is_uint8()); 1520 assert(imm.is_uint8());
1572 emitUint8(imm.value()); 1521 emitUint8(imm.value());
1573 } 1522 }
1574 1523
1575 template <class Machine> 1524 template <typename TraitsType>
1576 void AssemblerX86Base<Machine>::pshufd(Type /* Ty */, 1525 void AssemblerX86Base<TraitsType>::pshufd(Type /* Ty */, XmmRegister dst,
1577 typename Traits::XmmRegister dst, 1526 const Address &src,
1578 const typename Traits::Address &src, 1527 const Immediate &imm) {
1579 const Immediate &imm) {
1580 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1528 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1581 emitUint8(0x66); 1529 emitUint8(0x66);
1582 emitAddrSizeOverridePrefix(); 1530 emitAddrSizeOverridePrefix();
1583 emitRex(RexTypeIrrelevant, src, dst); 1531 emitRex(RexTypeIrrelevant, src, dst);
1584 emitUint8(0x0F); 1532 emitUint8(0x0F);
1585 emitUint8(0x70); 1533 emitUint8(0x70);
1586 emitOperand(gprEncoding(dst), src); 1534 emitOperand(gprEncoding(dst), src);
1587 assert(imm.is_uint8()); 1535 assert(imm.is_uint8());
1588 emitUint8(imm.value()); 1536 emitUint8(imm.value());
1589 } 1537 }
1590 1538
1591 template <class Machine> 1539 template <typename TraitsType>
1592 void AssemblerX86Base<Machine>::shufps(Type /* Ty */, 1540 void AssemblerX86Base<TraitsType>::shufps(Type /* Ty */, XmmRegister dst,
1593 typename Traits::XmmRegister dst, 1541 XmmRegister src,
1594 typename Traits::XmmRegister src, 1542 const Immediate &imm) {
1595 const Immediate &imm) {
1596 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1543 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1597 emitRexRB(RexTypeIrrelevant, dst, src); 1544 emitRexRB(RexTypeIrrelevant, dst, src);
1598 emitUint8(0x0F); 1545 emitUint8(0x0F);
1599 emitUint8(0xC6); 1546 emitUint8(0xC6);
1600 emitXmmRegisterOperand(dst, src); 1547 emitXmmRegisterOperand(dst, src);
1601 assert(imm.is_uint8()); 1548 assert(imm.is_uint8());
1602 emitUint8(imm.value()); 1549 emitUint8(imm.value());
1603 } 1550 }
1604 1551
1605 template <class Machine> 1552 template <typename TraitsType>
1606 void AssemblerX86Base<Machine>::shufps(Type /* Ty */, 1553 void AssemblerX86Base<TraitsType>::shufps(Type /* Ty */, XmmRegister dst,
1607 typename Traits::XmmRegister dst, 1554 const Address &src,
1608 const typename Traits::Address &src, 1555 const Immediate &imm) {
1609 const Immediate &imm) {
1610 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1556 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1611 emitAddrSizeOverridePrefix(); 1557 emitAddrSizeOverridePrefix();
1612 emitRex(RexTypeIrrelevant, src, dst); 1558 emitRex(RexTypeIrrelevant, src, dst);
1613 emitUint8(0x0F); 1559 emitUint8(0x0F);
1614 emitUint8(0xC6); 1560 emitUint8(0xC6);
1615 emitOperand(gprEncoding(dst), src); 1561 emitOperand(gprEncoding(dst), src);
1616 assert(imm.is_uint8()); 1562 assert(imm.is_uint8());
1617 emitUint8(imm.value()); 1563 emitUint8(imm.value());
1618 } 1564 }
1619 1565
1620 template <class Machine> 1566 template <typename TraitsType>
1621 void AssemblerX86Base<Machine>::sqrtpd(typename Traits::XmmRegister dst) { 1567 void AssemblerX86Base<TraitsType>::sqrtpd(XmmRegister dst) {
1622 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1568 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1623 emitUint8(0x66); 1569 emitUint8(0x66);
1624 emitRexRB(RexTypeIrrelevant, dst, dst); 1570 emitRexRB(RexTypeIrrelevant, dst, dst);
1625 emitUint8(0x0F); 1571 emitUint8(0x0F);
1626 emitUint8(0x51); 1572 emitUint8(0x51);
1627 emitXmmRegisterOperand(dst, dst); 1573 emitXmmRegisterOperand(dst, dst);
1628 } 1574 }
1629 1575
1630 template <class Machine> 1576 template <typename TraitsType>
1631 void AssemblerX86Base<Machine>::cvtdq2ps(Type /* Ignore */, 1577 void AssemblerX86Base<TraitsType>::cvtdq2ps(Type /* Ignore */, XmmRegister dst,
1632 typename Traits::XmmRegister dst, 1578 XmmRegister src) {
1633 typename Traits::XmmRegister src) {
1634 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1579 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1635 emitRexRB(RexTypeIrrelevant, dst, src); 1580 emitRexRB(RexTypeIrrelevant, dst, src);
1636 emitUint8(0x0F); 1581 emitUint8(0x0F);
1637 emitUint8(0x5B); 1582 emitUint8(0x5B);
1638 emitXmmRegisterOperand(dst, src); 1583 emitXmmRegisterOperand(dst, src);
1639 } 1584 }
1640 1585
1641 template <class Machine> 1586 template <typename TraitsType>
1642 void AssemblerX86Base<Machine>::cvtdq2ps(Type /* Ignore */, 1587 void AssemblerX86Base<TraitsType>::cvtdq2ps(Type /* Ignore */, XmmRegister dst,
1643 typename Traits::XmmRegister dst, 1588 const Address &src) {
1644 const typename Traits::Address &src) {
1645 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1589 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1646 emitAddrSizeOverridePrefix(); 1590 emitAddrSizeOverridePrefix();
1647 emitRex(RexTypeIrrelevant, src, dst); 1591 emitRex(RexTypeIrrelevant, src, dst);
1648 emitUint8(0x0F); 1592 emitUint8(0x0F);
1649 emitUint8(0x5B); 1593 emitUint8(0x5B);
1650 emitOperand(gprEncoding(dst), src); 1594 emitOperand(gprEncoding(dst), src);
1651 } 1595 }
1652 1596
1653 template <class Machine> 1597 template <typename TraitsType>
1654 void AssemblerX86Base<Machine>::cvttps2dq(Type /* Ignore */, 1598 void AssemblerX86Base<TraitsType>::cvttps2dq(Type /* Ignore */, XmmRegister dst,
1655 typename Traits::XmmRegister dst, 1599 XmmRegister src) {
1656 typename Traits::XmmRegister src) {
1657 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1600 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1658 emitUint8(0xF3); 1601 emitUint8(0xF3);
1659 emitRexRB(RexTypeIrrelevant, dst, src); 1602 emitRexRB(RexTypeIrrelevant, dst, src);
1660 emitUint8(0x0F); 1603 emitUint8(0x0F);
1661 emitUint8(0x5B); 1604 emitUint8(0x5B);
1662 emitXmmRegisterOperand(dst, src); 1605 emitXmmRegisterOperand(dst, src);
1663 } 1606 }
1664 1607
1665 template <class Machine> 1608 template <typename TraitsType>
1666 void AssemblerX86Base<Machine>::cvttps2dq(Type /* Ignore */, 1609 void AssemblerX86Base<TraitsType>::cvttps2dq(Type /* Ignore */, XmmRegister dst,
1667 typename Traits::XmmRegister dst, 1610 const Address &src) {
1668 const typename Traits::Address &src) {
1669 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1611 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1670 emitUint8(0xF3); 1612 emitUint8(0xF3);
1671 emitAddrSizeOverridePrefix(); 1613 emitAddrSizeOverridePrefix();
1672 emitRex(RexTypeIrrelevant, src, dst); 1614 emitRex(RexTypeIrrelevant, src, dst);
1673 emitUint8(0x0F); 1615 emitUint8(0x0F);
1674 emitUint8(0x5B); 1616 emitUint8(0x5B);
1675 emitOperand(gprEncoding(dst), src); 1617 emitOperand(gprEncoding(dst), src);
1676 } 1618 }
1677 1619
1678 template <class Machine> 1620 template <typename TraitsType>
1679 void AssemblerX86Base<Machine>::cvtsi2ss(Type DestTy, 1621 void AssemblerX86Base<TraitsType>::cvtsi2ss(Type DestTy, XmmRegister dst,
1680 typename Traits::XmmRegister dst, 1622 Type SrcTy, GPRRegister src) {
1681 Type SrcTy,
1682 typename Traits::GPRRegister src) {
1683 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1623 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1684 emitUint8(isFloat32Asserting32Or64(DestTy) ? 0xF3 : 0xF2); 1624 emitUint8(isFloat32Asserting32Or64(DestTy) ? 0xF3 : 0xF2);
1685 emitRexRB(SrcTy, dst, src); 1625 emitRexRB(SrcTy, dst, src);
1686 emitUint8(0x0F); 1626 emitUint8(0x0F);
1687 emitUint8(0x2A); 1627 emitUint8(0x2A);
1688 emitXmmRegisterOperand(dst, src); 1628 emitXmmRegisterOperand(dst, src);
1689 } 1629 }
1690 1630
1691 template <class Machine> 1631 template <typename TraitsType>
1692 void AssemblerX86Base<Machine>::cvtsi2ss(Type DestTy, 1632 void AssemblerX86Base<TraitsType>::cvtsi2ss(Type DestTy, XmmRegister dst,
1693 typename Traits::XmmRegister dst, 1633 Type SrcTy, const Address &src) {
1694 Type SrcTy,
1695 const typename Traits::Address &src) {
1696 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1634 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1697 emitUint8(isFloat32Asserting32Or64(DestTy) ? 0xF3 : 0xF2); 1635 emitUint8(isFloat32Asserting32Or64(DestTy) ? 0xF3 : 0xF2);
1698 emitAddrSizeOverridePrefix(); 1636 emitAddrSizeOverridePrefix();
1699 emitRex(SrcTy, src, dst); 1637 emitRex(SrcTy, src, dst);
1700 emitUint8(0x0F); 1638 emitUint8(0x0F);
1701 emitUint8(0x2A); 1639 emitUint8(0x2A);
1702 emitOperand(gprEncoding(dst), src); 1640 emitOperand(gprEncoding(dst), src);
1703 } 1641 }
1704 1642
1705 template <class Machine> 1643 template <typename TraitsType>
1706 void AssemblerX86Base<Machine>::cvtfloat2float( 1644 void AssemblerX86Base<TraitsType>::cvtfloat2float(Type SrcTy, XmmRegister dst,
1707 Type SrcTy, typename Traits::XmmRegister dst, 1645 XmmRegister src) {
1708 typename Traits::XmmRegister src) {
1709 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1646 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1710 // ss2sd or sd2ss 1647 // ss2sd or sd2ss
1711 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2); 1648 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
1712 emitRexRB(RexTypeIrrelevant, dst, src); 1649 emitRexRB(RexTypeIrrelevant, dst, src);
1713 emitUint8(0x0F); 1650 emitUint8(0x0F);
1714 emitUint8(0x5A); 1651 emitUint8(0x5A);
1715 emitXmmRegisterOperand(dst, src); 1652 emitXmmRegisterOperand(dst, src);
1716 } 1653 }
1717 1654
1718 template <class Machine> 1655 template <typename TraitsType>
1719 void AssemblerX86Base<Machine>::cvtfloat2float( 1656 void AssemblerX86Base<TraitsType>::cvtfloat2float(Type SrcTy, XmmRegister dst,
1720 Type SrcTy, typename Traits::XmmRegister dst, 1657 const Address &src) {
1721 const typename Traits::Address &src) {
1722 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1658 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1723 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2); 1659 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
1724 emitAddrSizeOverridePrefix(); 1660 emitAddrSizeOverridePrefix();
1725 emitRex(RexTypeIrrelevant, src, dst); 1661 emitRex(RexTypeIrrelevant, src, dst);
1726 emitUint8(0x0F); 1662 emitUint8(0x0F);
1727 emitUint8(0x5A); 1663 emitUint8(0x5A);
1728 emitOperand(gprEncoding(dst), src); 1664 emitOperand(gprEncoding(dst), src);
1729 } 1665 }
1730 1666
1731 template <class Machine> 1667 template <typename TraitsType>
1732 void AssemblerX86Base<Machine>::cvttss2si(Type DestTy, 1668 void AssemblerX86Base<TraitsType>::cvttss2si(Type DestTy, GPRRegister dst,
1733 typename Traits::GPRRegister dst, 1669 Type SrcTy, XmmRegister src) {
1734 Type SrcTy,
1735 typename Traits::XmmRegister src) {
1736 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1670 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1737 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2); 1671 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
1738 emitRexRB(DestTy, dst, src); 1672 emitRexRB(DestTy, dst, src);
1739 emitUint8(0x0F); 1673 emitUint8(0x0F);
1740 emitUint8(0x2C); 1674 emitUint8(0x2C);
1741 emitXmmRegisterOperand(dst, src); 1675 emitXmmRegisterOperand(dst, src);
1742 } 1676 }
1743 1677
1744 template <class Machine> 1678 template <typename TraitsType>
1745 void AssemblerX86Base<Machine>::cvttss2si(Type DestTy, 1679 void AssemblerX86Base<TraitsType>::cvttss2si(Type DestTy, GPRRegister dst,
1746 typename Traits::GPRRegister dst, 1680 Type SrcTy, const Address &src) {
1747 Type SrcTy,
1748 const typename Traits::Address &src) {
1749 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1681 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1750 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2); 1682 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
1751 emitAddrSizeOverridePrefix(); 1683 emitAddrSizeOverridePrefix();
1752 emitRex(DestTy, src, dst); 1684 emitRex(DestTy, src, dst);
1753 emitUint8(0x0F); 1685 emitUint8(0x0F);
1754 emitUint8(0x2C); 1686 emitUint8(0x2C);
1755 emitOperand(gprEncoding(dst), src); 1687 emitOperand(gprEncoding(dst), src);
1756 } 1688 }
1757 1689
1758 template <class Machine> 1690 template <typename TraitsType>
1759 void AssemblerX86Base<Machine>::ucomiss(Type Ty, typename Traits::XmmRegister a, 1691 void AssemblerX86Base<TraitsType>::ucomiss(Type Ty, XmmRegister a,
1760 typename Traits::XmmRegister b) { 1692 XmmRegister b) {
1761 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1693 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1762 if (Ty == IceType_f64) 1694 if (Ty == IceType_f64)
1763 emitUint8(0x66); 1695 emitUint8(0x66);
1764 emitRexRB(RexTypeIrrelevant, a, b); 1696 emitRexRB(RexTypeIrrelevant, a, b);
1765 emitUint8(0x0F); 1697 emitUint8(0x0F);
1766 emitUint8(0x2E); 1698 emitUint8(0x2E);
1767 emitXmmRegisterOperand(a, b); 1699 emitXmmRegisterOperand(a, b);
1768 } 1700 }
1769 1701
1770 template <class Machine> 1702 template <typename TraitsType>
1771 void AssemblerX86Base<Machine>::ucomiss(Type Ty, typename Traits::XmmRegister a, 1703 void AssemblerX86Base<TraitsType>::ucomiss(Type Ty, XmmRegister a,
1772 const typename Traits::Address &b) { 1704 const Address &b) {
1773 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1705 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1774 if (Ty == IceType_f64) 1706 if (Ty == IceType_f64)
1775 emitUint8(0x66); 1707 emitUint8(0x66);
1776 emitAddrSizeOverridePrefix(); 1708 emitAddrSizeOverridePrefix();
1777 emitRex(RexTypeIrrelevant, b, a); 1709 emitRex(RexTypeIrrelevant, b, a);
1778 emitUint8(0x0F); 1710 emitUint8(0x0F);
1779 emitUint8(0x2E); 1711 emitUint8(0x2E);
1780 emitOperand(gprEncoding(a), b); 1712 emitOperand(gprEncoding(a), b);
1781 } 1713 }
1782 1714
1783 template <class Machine> 1715 template <typename TraitsType>
1784 void AssemblerX86Base<Machine>::movmskpd(typename Traits::GPRRegister dst, 1716 void AssemblerX86Base<TraitsType>::movmskpd(GPRRegister dst, XmmRegister src) {
1785 typename Traits::XmmRegister src) {
1786 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1717 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1787 emitUint8(0x66); 1718 emitUint8(0x66);
1788 emitRexRB(RexTypeIrrelevant, dst, src); 1719 emitRexRB(RexTypeIrrelevant, dst, src);
1789 emitUint8(0x0F); 1720 emitUint8(0x0F);
1790 emitUint8(0x50); 1721 emitUint8(0x50);
1791 emitXmmRegisterOperand(dst, src); 1722 emitXmmRegisterOperand(dst, src);
1792 } 1723 }
1793 1724
1794 template <class Machine> 1725 template <typename TraitsType>
1795 void AssemblerX86Base<Machine>::movmskps(typename Traits::GPRRegister dst, 1726 void AssemblerX86Base<TraitsType>::movmskps(GPRRegister dst, XmmRegister src) {
1796 typename Traits::XmmRegister src) {
1797 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1727 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1798 emitRexRB(RexTypeIrrelevant, dst, src); 1728 emitRexRB(RexTypeIrrelevant, dst, src);
1799 emitUint8(0x0F); 1729 emitUint8(0x0F);
1800 emitUint8(0x50); 1730 emitUint8(0x50);
1801 emitXmmRegisterOperand(dst, src); 1731 emitXmmRegisterOperand(dst, src);
1802 } 1732 }
1803 1733
1804 template <class Machine> 1734 template <typename TraitsType>
1805 void AssemblerX86Base<Machine>::sqrtss(Type Ty, 1735 void AssemblerX86Base<TraitsType>::sqrtss(Type Ty, XmmRegister dst,
1806 typename Traits::XmmRegister dst, 1736 const Address &src) {
1807 const typename Traits::Address &src) {
1808 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1737 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1809 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); 1738 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
1810 emitAddrSizeOverridePrefix(); 1739 emitAddrSizeOverridePrefix();
1811 emitRex(RexTypeIrrelevant, src, dst); 1740 emitRex(RexTypeIrrelevant, src, dst);
1812 emitUint8(0x0F); 1741 emitUint8(0x0F);
1813 emitUint8(0x51); 1742 emitUint8(0x51);
1814 emitOperand(gprEncoding(dst), src); 1743 emitOperand(gprEncoding(dst), src);
1815 } 1744 }
1816 1745
1817 template <class Machine> 1746 template <typename TraitsType>
1818 void AssemblerX86Base<Machine>::sqrtss(Type Ty, 1747 void AssemblerX86Base<TraitsType>::sqrtss(Type Ty, XmmRegister dst,
1819 typename Traits::XmmRegister dst, 1748 XmmRegister src) {
1820 typename Traits::XmmRegister src) {
1821 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1749 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1822 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); 1750 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
1823 emitRexRB(RexTypeIrrelevant, dst, src); 1751 emitRexRB(RexTypeIrrelevant, dst, src);
1824 emitUint8(0x0F); 1752 emitUint8(0x0F);
1825 emitUint8(0x51); 1753 emitUint8(0x51);
1826 emitXmmRegisterOperand(dst, src); 1754 emitXmmRegisterOperand(dst, src);
1827 } 1755 }
1828 1756
1829 template <class Machine> 1757 template <typename TraitsType>
1830 void AssemblerX86Base<Machine>::xorps(Type Ty, typename Traits::XmmRegister dst, 1758 void AssemblerX86Base<TraitsType>::xorps(Type Ty, XmmRegister dst,
1831 const typename Traits::Address &src) { 1759 const Address &src) {
1832 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1760 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1833 if (!isFloat32Asserting32Or64(Ty)) 1761 if (!isFloat32Asserting32Or64(Ty))
1834 emitUint8(0x66); 1762 emitUint8(0x66);
1835 emitAddrSizeOverridePrefix(); 1763 emitAddrSizeOverridePrefix();
1836 emitRex(RexTypeIrrelevant, src, dst); 1764 emitRex(RexTypeIrrelevant, src, dst);
1837 emitUint8(0x0F); 1765 emitUint8(0x0F);
1838 emitUint8(0x57); 1766 emitUint8(0x57);
1839 emitOperand(gprEncoding(dst), src); 1767 emitOperand(gprEncoding(dst), src);
1840 } 1768 }
1841 1769
1842 template <class Machine> 1770 template <typename TraitsType>
1843 void AssemblerX86Base<Machine>::xorps(Type Ty, typename Traits::XmmRegister dst, 1771 void AssemblerX86Base<TraitsType>::xorps(Type Ty, XmmRegister dst,
1844 typename Traits::XmmRegister src) { 1772 XmmRegister src) {
1845 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1773 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1846 if (!isFloat32Asserting32Or64(Ty)) 1774 if (!isFloat32Asserting32Or64(Ty))
1847 emitUint8(0x66); 1775 emitUint8(0x66);
1848 emitRexRB(RexTypeIrrelevant, dst, src); 1776 emitRexRB(RexTypeIrrelevant, dst, src);
1849 emitUint8(0x0F); 1777 emitUint8(0x0F);
1850 emitUint8(0x57); 1778 emitUint8(0x57);
1851 emitXmmRegisterOperand(dst, src); 1779 emitXmmRegisterOperand(dst, src);
1852 } 1780 }
1853 1781
1854 template <class Machine> 1782 template <typename TraitsType>
1855 void AssemblerX86Base<Machine>::insertps(Type Ty, 1783 void AssemblerX86Base<TraitsType>::insertps(Type Ty, XmmRegister dst,
1856 typename Traits::XmmRegister dst, 1784 XmmRegister src,
1857 typename Traits::XmmRegister src, 1785 const Immediate &imm) {
1858 const Immediate &imm) {
1859 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1786 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1860 assert(imm.is_uint8()); 1787 assert(imm.is_uint8());
1861 assert(isVectorFloatingType(Ty)); 1788 assert(isVectorFloatingType(Ty));
1862 (void)Ty; 1789 (void)Ty;
1863 emitUint8(0x66); 1790 emitUint8(0x66);
1864 emitRexRB(RexTypeIrrelevant, dst, src); 1791 emitRexRB(RexTypeIrrelevant, dst, src);
1865 emitUint8(0x0F); 1792 emitUint8(0x0F);
1866 emitUint8(0x3A); 1793 emitUint8(0x3A);
1867 emitUint8(0x21); 1794 emitUint8(0x21);
1868 emitXmmRegisterOperand(dst, src); 1795 emitXmmRegisterOperand(dst, src);
1869 emitUint8(imm.value()); 1796 emitUint8(imm.value());
1870 } 1797 }
1871 1798
1872 template <class Machine> 1799 template <typename TraitsType>
1873 void AssemblerX86Base<Machine>::insertps(Type Ty, 1800 void AssemblerX86Base<TraitsType>::insertps(Type Ty, XmmRegister dst,
1874 typename Traits::XmmRegister dst, 1801 const Address &src,
1875 const typename Traits::Address &src, 1802 const Immediate &imm) {
1876 const Immediate &imm) {
1877 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1803 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1878 assert(imm.is_uint8()); 1804 assert(imm.is_uint8());
1879 assert(isVectorFloatingType(Ty)); 1805 assert(isVectorFloatingType(Ty));
1880 (void)Ty; 1806 (void)Ty;
1881 emitUint8(0x66); 1807 emitUint8(0x66);
1882 emitAddrSizeOverridePrefix(); 1808 emitAddrSizeOverridePrefix();
1883 emitRex(RexTypeIrrelevant, src, dst); 1809 emitRex(RexTypeIrrelevant, src, dst);
1884 emitUint8(0x0F); 1810 emitUint8(0x0F);
1885 emitUint8(0x3A); 1811 emitUint8(0x3A);
1886 emitUint8(0x21); 1812 emitUint8(0x21);
1887 emitOperand(gprEncoding(dst), src); 1813 emitOperand(gprEncoding(dst), src);
1888 emitUint8(imm.value()); 1814 emitUint8(imm.value());
1889 } 1815 }
1890 1816
1891 template <class Machine> 1817 template <typename TraitsType>
1892 void AssemblerX86Base<Machine>::pinsr(Type Ty, typename Traits::XmmRegister dst, 1818 void AssemblerX86Base<TraitsType>::pinsr(Type Ty, XmmRegister dst,
1893 typename Traits::GPRRegister src, 1819 GPRRegister src,
1894 const Immediate &imm) { 1820 const Immediate &imm) {
1895 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1821 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1896 assert(imm.is_uint8()); 1822 assert(imm.is_uint8());
1897 emitUint8(0x66); 1823 emitUint8(0x66);
1898 emitRexRB(Ty, dst, src); 1824 emitRexRB(Ty, dst, src);
1899 emitUint8(0x0F); 1825 emitUint8(0x0F);
1900 if (Ty == IceType_i16) { 1826 if (Ty == IceType_i16) {
1901 emitUint8(0xC4); 1827 emitUint8(0xC4);
1902 } else { 1828 } else {
1903 emitUint8(0x3A); 1829 emitUint8(0x3A);
1904 emitUint8(isByteSizedType(Ty) ? 0x20 : 0x22); 1830 emitUint8(isByteSizedType(Ty) ? 0x20 : 0x22);
1905 } 1831 }
1906 emitXmmRegisterOperand(dst, src); 1832 emitXmmRegisterOperand(dst, src);
1907 emitUint8(imm.value()); 1833 emitUint8(imm.value());
1908 } 1834 }
1909 1835
1910 template <class Machine> 1836 template <typename TraitsType>
1911 void AssemblerX86Base<Machine>::pinsr(Type Ty, typename Traits::XmmRegister dst, 1837 void AssemblerX86Base<TraitsType>::pinsr(Type Ty, XmmRegister dst,
1912 const typename Traits::Address &src, 1838 const Address &src,
1913 const Immediate &imm) { 1839 const Immediate &imm) {
1914 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1840 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1915 assert(imm.is_uint8()); 1841 assert(imm.is_uint8());
1916 emitUint8(0x66); 1842 emitUint8(0x66);
1917 emitAddrSizeOverridePrefix(); 1843 emitAddrSizeOverridePrefix();
1918 emitRex(RexTypeIrrelevant, src, dst); 1844 emitRex(RexTypeIrrelevant, src, dst);
1919 emitUint8(0x0F); 1845 emitUint8(0x0F);
1920 if (Ty == IceType_i16) { 1846 if (Ty == IceType_i16) {
1921 emitUint8(0xC4); 1847 emitUint8(0xC4);
1922 } else { 1848 } else {
1923 emitUint8(0x3A); 1849 emitUint8(0x3A);
1924 emitUint8(isByteSizedType(Ty) ? 0x20 : 0x22); 1850 emitUint8(isByteSizedType(Ty) ? 0x20 : 0x22);
1925 } 1851 }
1926 emitOperand(gprEncoding(dst), src); 1852 emitOperand(gprEncoding(dst), src);
1927 emitUint8(imm.value()); 1853 emitUint8(imm.value());
1928 } 1854 }
1929 1855
1930 template <class Machine> 1856 template <typename TraitsType>
1931 void AssemblerX86Base<Machine>::pextr(Type Ty, typename Traits::GPRRegister dst, 1857 void AssemblerX86Base<TraitsType>::pextr(Type Ty, GPRRegister dst,
1932 typename Traits::XmmRegister src, 1858 XmmRegister src,
1933 const Immediate &imm) { 1859 const Immediate &imm) {
1934 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1860 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1935 assert(imm.is_uint8()); 1861 assert(imm.is_uint8());
1936 if (Ty == IceType_i16) { 1862 if (Ty == IceType_i16) {
1937 emitUint8(0x66); 1863 emitUint8(0x66);
1938 emitRexRB(Ty, dst, src); 1864 emitRexRB(Ty, dst, src);
1939 emitUint8(0x0F); 1865 emitUint8(0x0F);
1940 emitUint8(0xC5); 1866 emitUint8(0xC5);
1941 emitXmmRegisterOperand(dst, src); 1867 emitXmmRegisterOperand(dst, src);
1942 emitUint8(imm.value()); 1868 emitUint8(imm.value());
1943 } else { 1869 } else {
1944 emitUint8(0x66); 1870 emitUint8(0x66);
1945 emitRexRB(Ty, src, dst); 1871 emitRexRB(Ty, src, dst);
1946 emitUint8(0x0F); 1872 emitUint8(0x0F);
1947 emitUint8(0x3A); 1873 emitUint8(0x3A);
1948 emitUint8(isByteSizedType(Ty) ? 0x14 : 0x16); 1874 emitUint8(isByteSizedType(Ty) ? 0x14 : 0x16);
1949 // SSE 4.1 versions are "MRI" because dst can be mem, while pextrw (SSE2) 1875 // SSE 4.1 versions are "MRI" because dst can be mem, while pextrw (SSE2)
1950 // is RMI because dst must be reg. 1876 // is RMI because dst must be reg.
1951 emitXmmRegisterOperand(src, dst); 1877 emitXmmRegisterOperand(src, dst);
1952 emitUint8(imm.value()); 1878 emitUint8(imm.value());
1953 } 1879 }
1954 } 1880 }
1955 1881
1956 template <class Machine> 1882 template <typename TraitsType>
1957 void AssemblerX86Base<Machine>::pmovsxdq(typename Traits::XmmRegister dst, 1883 void AssemblerX86Base<TraitsType>::pmovsxdq(XmmRegister dst, XmmRegister src) {
1958 typename Traits::XmmRegister src) {
1959 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1884 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1960 emitUint8(0x66); 1885 emitUint8(0x66);
1961 emitRexRB(RexTypeIrrelevant, dst, src); 1886 emitRexRB(RexTypeIrrelevant, dst, src);
1962 emitUint8(0x0F); 1887 emitUint8(0x0F);
1963 emitUint8(0x38); 1888 emitUint8(0x38);
1964 emitUint8(0x25); 1889 emitUint8(0x25);
1965 emitXmmRegisterOperand(dst, src); 1890 emitXmmRegisterOperand(dst, src);
1966 } 1891 }
1967 1892
1968 template <class Machine> 1893 template <typename TraitsType>
1969 void AssemblerX86Base<Machine>::pcmpeq(Type Ty, 1894 void AssemblerX86Base<TraitsType>::pcmpeq(Type Ty, XmmRegister dst,
1970 typename Traits::XmmRegister dst, 1895 XmmRegister src) {
1971 typename Traits::XmmRegister src) {
1972 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1896 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1973 emitUint8(0x66); 1897 emitUint8(0x66);
1974 emitRexRB(RexTypeIrrelevant, dst, src); 1898 emitRexRB(RexTypeIrrelevant, dst, src);
1975 emitUint8(0x0F); 1899 emitUint8(0x0F);
1976 if (isByteSizedArithType(Ty)) { 1900 if (isByteSizedArithType(Ty)) {
1977 emitUint8(0x74); 1901 emitUint8(0x74);
1978 } else if (Ty == IceType_i16) { 1902 } else if (Ty == IceType_i16) {
1979 emitUint8(0x75); 1903 emitUint8(0x75);
1980 } else { 1904 } else {
1981 emitUint8(0x76); 1905 emitUint8(0x76);
1982 } 1906 }
1983 emitXmmRegisterOperand(dst, src); 1907 emitXmmRegisterOperand(dst, src);
1984 } 1908 }
1985 1909
1986 template <class Machine> 1910 template <typename TraitsType>
1987 void AssemblerX86Base<Machine>::pcmpeq(Type Ty, 1911 void AssemblerX86Base<TraitsType>::pcmpeq(Type Ty, XmmRegister dst,
1988 typename Traits::XmmRegister dst, 1912 const Address &src) {
1989 const typename Traits::Address &src) {
1990 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1913 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1991 emitUint8(0x66); 1914 emitUint8(0x66);
1992 emitAddrSizeOverridePrefix(); 1915 emitAddrSizeOverridePrefix();
1993 emitRex(RexTypeIrrelevant, src, dst); 1916 emitRex(RexTypeIrrelevant, src, dst);
1994 emitUint8(0x0F); 1917 emitUint8(0x0F);
1995 if (isByteSizedArithType(Ty)) { 1918 if (isByteSizedArithType(Ty)) {
1996 emitUint8(0x74); 1919 emitUint8(0x74);
1997 } else if (Ty == IceType_i16) { 1920 } else if (Ty == IceType_i16) {
1998 emitUint8(0x75); 1921 emitUint8(0x75);
1999 } else { 1922 } else {
2000 emitUint8(0x76); 1923 emitUint8(0x76);
2001 } 1924 }
2002 emitOperand(gprEncoding(dst), src); 1925 emitOperand(gprEncoding(dst), src);
2003 } 1926 }
2004 1927
2005 template <class Machine> 1928 template <typename TraitsType>
2006 void AssemblerX86Base<Machine>::pcmpgt(Type Ty, 1929 void AssemblerX86Base<TraitsType>::pcmpgt(Type Ty, XmmRegister dst,
2007 typename Traits::XmmRegister dst, 1930 XmmRegister src) {
2008 typename Traits::XmmRegister src) {
2009 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1931 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2010 emitUint8(0x66); 1932 emitUint8(0x66);
2011 emitRexRB(RexTypeIrrelevant, dst, src); 1933 emitRexRB(RexTypeIrrelevant, dst, src);
2012 emitUint8(0x0F); 1934 emitUint8(0x0F);
2013 if (isByteSizedArithType(Ty)) { 1935 if (isByteSizedArithType(Ty)) {
2014 emitUint8(0x64); 1936 emitUint8(0x64);
2015 } else if (Ty == IceType_i16) { 1937 } else if (Ty == IceType_i16) {
2016 emitUint8(0x65); 1938 emitUint8(0x65);
2017 } else { 1939 } else {
2018 emitUint8(0x66); 1940 emitUint8(0x66);
2019 } 1941 }
2020 emitXmmRegisterOperand(dst, src); 1942 emitXmmRegisterOperand(dst, src);
2021 } 1943 }
2022 1944
2023 template <class Machine> 1945 template <typename TraitsType>
2024 void AssemblerX86Base<Machine>::pcmpgt(Type Ty, 1946 void AssemblerX86Base<TraitsType>::pcmpgt(Type Ty, XmmRegister dst,
2025 typename Traits::XmmRegister dst, 1947 const Address &src) {
2026 const typename Traits::Address &src) {
2027 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1948 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2028 emitUint8(0x66); 1949 emitUint8(0x66);
2029 emitAddrSizeOverridePrefix(); 1950 emitAddrSizeOverridePrefix();
2030 emitRex(RexTypeIrrelevant, src, dst); 1951 emitRex(RexTypeIrrelevant, src, dst);
2031 emitUint8(0x0F); 1952 emitUint8(0x0F);
2032 if (isByteSizedArithType(Ty)) { 1953 if (isByteSizedArithType(Ty)) {
2033 emitUint8(0x64); 1954 emitUint8(0x64);
2034 } else if (Ty == IceType_i16) { 1955 } else if (Ty == IceType_i16) {
2035 emitUint8(0x65); 1956 emitUint8(0x65);
2036 } else { 1957 } else {
2037 emitUint8(0x66); 1958 emitUint8(0x66);
2038 } 1959 }
2039 emitOperand(gprEncoding(dst), src); 1960 emitOperand(gprEncoding(dst), src);
2040 } 1961 }
2041 1962
2042 template <class Machine> 1963 template <typename TraitsType>
2043 void AssemblerX86Base<Machine>::roundsd(typename Traits::XmmRegister dst, 1964 void AssemblerX86Base<TraitsType>::roundsd(XmmRegister dst, XmmRegister src,
2044 typename Traits::XmmRegister src, 1965 RoundingMode mode) {
2045 RoundingMode mode) {
2046 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1966 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2047 emitUint8(0x66); 1967 emitUint8(0x66);
2048 emitRexRB(RexTypeIrrelevant, dst, src); 1968 emitRexRB(RexTypeIrrelevant, dst, src);
2049 emitUint8(0x0F); 1969 emitUint8(0x0F);
2050 emitUint8(0x3A); 1970 emitUint8(0x3A);
2051 emitUint8(0x0B); 1971 emitUint8(0x0B);
2052 emitXmmRegisterOperand(dst, src); 1972 emitXmmRegisterOperand(dst, src);
2053 // Mask precision exeption. 1973 // Mask precision exeption.
2054 emitUint8(static_cast<uint8_t>(mode) | 0x8); 1974 emitUint8(static_cast<uint8_t>(mode) | 0x8);
2055 } 1975 }
2056 1976
2057 template <class Machine> 1977 template <typename TraitsType>
2058 template <typename T, typename> 1978 template <typename T, typename>
2059 void AssemblerX86Base<Machine>::fnstcw(const typename T::Address &dst) { 1979 void AssemblerX86Base<TraitsType>::fnstcw(const typename T::Address &dst) {
2060 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1980 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2061 emitAddrSizeOverridePrefix(); 1981 emitAddrSizeOverridePrefix();
2062 emitUint8(0xD9); 1982 emitUint8(0xD9);
2063 emitOperand(7, dst); 1983 emitOperand(7, dst);
2064 } 1984 }
2065 1985
2066 template <class Machine> 1986 template <typename TraitsType>
2067 template <typename T, typename> 1987 template <typename T, typename>
2068 void AssemblerX86Base<Machine>::fldcw(const typename T::Address &src) { 1988 void AssemblerX86Base<TraitsType>::fldcw(const typename T::Address &src) {
2069 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1989 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2070 emitAddrSizeOverridePrefix(); 1990 emitAddrSizeOverridePrefix();
2071 emitUint8(0xD9); 1991 emitUint8(0xD9);
2072 emitOperand(5, src); 1992 emitOperand(5, src);
2073 } 1993 }
2074 1994
2075 template <class Machine> 1995 template <typename TraitsType>
2076 template <typename T, typename> 1996 template <typename T, typename>
2077 void AssemblerX86Base<Machine>::fistpl(const typename T::Address &dst) { 1997 void AssemblerX86Base<TraitsType>::fistpl(const typename T::Address &dst) {
2078 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1998 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2079 emitAddrSizeOverridePrefix(); 1999 emitAddrSizeOverridePrefix();
2080 emitUint8(0xDF); 2000 emitUint8(0xDF);
2081 emitOperand(7, dst); 2001 emitOperand(7, dst);
2082 } 2002 }
2083 2003
2084 template <class Machine> 2004 template <typename TraitsType>
2085 template <typename T, typename> 2005 template <typename T, typename>
2086 void AssemblerX86Base<Machine>::fistps(const typename T::Address &dst) { 2006 void AssemblerX86Base<TraitsType>::fistps(const typename T::Address &dst) {
2087 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2007 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2088 emitAddrSizeOverridePrefix(); 2008 emitAddrSizeOverridePrefix();
2089 emitUint8(0xDB); 2009 emitUint8(0xDB);
2090 emitOperand(3, dst); 2010 emitOperand(3, dst);
2091 } 2011 }
2092 2012
2093 template <class Machine> 2013 template <typename TraitsType>
2094 template <typename T, typename> 2014 template <typename T, typename>
2095 void AssemblerX86Base<Machine>::fildl(const typename T::Address &src) { 2015 void AssemblerX86Base<TraitsType>::fildl(const typename T::Address &src) {
2096 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2016 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2097 emitAddrSizeOverridePrefix(); 2017 emitAddrSizeOverridePrefix();
2098 emitUint8(0xDF); 2018 emitUint8(0xDF);
2099 emitOperand(5, src); 2019 emitOperand(5, src);
2100 } 2020 }
2101 2021
2102 template <class Machine> 2022 template <typename TraitsType>
2103 template <typename T, typename> 2023 template <typename T, typename>
2104 void AssemblerX86Base<Machine>::filds(const typename T::Address &src) { 2024 void AssemblerX86Base<TraitsType>::filds(const typename T::Address &src) {
2105 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2025 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2106 emitAddrSizeOverridePrefix(); 2026 emitAddrSizeOverridePrefix();
2107 emitUint8(0xDB); 2027 emitUint8(0xDB);
2108 emitOperand(0, src); 2028 emitOperand(0, src);
2109 } 2029 }
2110 2030
2111 template <class Machine> 2031 template <typename TraitsType>
2112 template <typename, typename> 2032 template <typename, typename>
2113 void AssemblerX86Base<Machine>::fincstp() { 2033 void AssemblerX86Base<TraitsType>::fincstp() {
2114 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2034 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2115 emitUint8(0xD9); 2035 emitUint8(0xD9);
2116 emitUint8(0xF7); 2036 emitUint8(0xF7);
2117 } 2037 }
2118 2038
2119 template <class Machine> 2039 template <typename TraitsType>
2120 template <uint32_t Tag> 2040 template <uint32_t Tag>
2121 void AssemblerX86Base<Machine>::arith_int(Type Ty, 2041 void AssemblerX86Base<TraitsType>::arith_int(Type Ty, GPRRegister reg,
2122 typename Traits::GPRRegister reg, 2042 const Immediate &imm) {
2123 const Immediate &imm) {
2124 static_assert(Tag < 8, "Tag must be between 0..7"); 2043 static_assert(Tag < 8, "Tag must be between 0..7");
2125 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2044 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2126 if (Ty == IceType_i16) 2045 if (Ty == IceType_i16)
2127 emitOperandSizeOverride(); 2046 emitOperandSizeOverride();
2128 emitRexB(Ty, reg); 2047 emitRexB(Ty, reg);
2129 if (isByteSizedType(Ty)) { 2048 if (isByteSizedType(Ty)) {
2130 emitComplexI8(Tag, typename Traits::Operand(reg), imm); 2049 emitComplexI8(Tag, Operand(reg), imm);
2131 } else { 2050 } else {
2132 emitComplex(Ty, Tag, typename Traits::Operand(reg), imm); 2051 emitComplex(Ty, Tag, Operand(reg), imm);
2133 } 2052 }
2134 } 2053 }
2135 2054
2136 template <class Machine> 2055 template <typename TraitsType>
2137 template <uint32_t Tag> 2056 template <uint32_t Tag>
2138 void AssemblerX86Base<Machine>::arith_int(Type Ty, 2057 void AssemblerX86Base<TraitsType>::arith_int(Type Ty, GPRRegister reg0,
2139 typename Traits::GPRRegister reg0, 2058 GPRRegister reg1) {
2140 typename Traits::GPRRegister reg1) {
2141 static_assert(Tag < 8, "Tag must be between 0..7"); 2059 static_assert(Tag < 8, "Tag must be between 0..7");
2142 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2060 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2143 if (Ty == IceType_i16) 2061 if (Ty == IceType_i16)
2144 emitOperandSizeOverride(); 2062 emitOperandSizeOverride();
2145 emitRexRB(Ty, reg0, reg1); 2063 emitRexRB(Ty, reg0, reg1);
2146 if (isByteSizedType(Ty)) 2064 if (isByteSizedType(Ty))
2147 emitUint8(Tag * 8 + 2); 2065 emitUint8(Tag * 8 + 2);
2148 else 2066 else
2149 emitUint8(Tag * 8 + 3); 2067 emitUint8(Tag * 8 + 3);
2150 emitRegisterOperand(gprEncoding(reg0), gprEncoding(reg1)); 2068 emitRegisterOperand(gprEncoding(reg0), gprEncoding(reg1));
2151 } 2069 }
2152 2070
2153 template <class Machine> 2071 template <typename TraitsType>
2154 template <uint32_t Tag> 2072 template <uint32_t Tag>
2155 void AssemblerX86Base<Machine>::arith_int( 2073 void AssemblerX86Base<TraitsType>::arith_int(Type Ty, GPRRegister reg,
2156 Type Ty, typename Traits::GPRRegister reg, 2074 const Address &address) {
2157 const typename Traits::Address &address) {
2158 static_assert(Tag < 8, "Tag must be between 0..7"); 2075 static_assert(Tag < 8, "Tag must be between 0..7");
2159 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2076 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2160 if (Ty == IceType_i16) 2077 if (Ty == IceType_i16)
2161 emitOperandSizeOverride(); 2078 emitOperandSizeOverride();
2162 emitAddrSizeOverridePrefix(); 2079 emitAddrSizeOverridePrefix();
2163 emitRex(Ty, address, reg); 2080 emitRex(Ty, address, reg);
2164 if (isByteSizedType(Ty)) 2081 if (isByteSizedType(Ty))
2165 emitUint8(Tag * 8 + 2); 2082 emitUint8(Tag * 8 + 2);
2166 else 2083 else
2167 emitUint8(Tag * 8 + 3); 2084 emitUint8(Tag * 8 + 3);
2168 emitOperand(gprEncoding(reg), address); 2085 emitOperand(gprEncoding(reg), address);
2169 } 2086 }
2170 2087
2171 template <class Machine> 2088 template <typename TraitsType>
2172 template <uint32_t Tag> 2089 template <uint32_t Tag>
2173 void AssemblerX86Base<Machine>::arith_int( 2090 void AssemblerX86Base<TraitsType>::arith_int(Type Ty, const Address &address,
2174 Type Ty, const typename Traits::Address &address, 2091 GPRRegister reg) {
2175 typename Traits::GPRRegister reg) {
2176 static_assert(Tag < 8, "Tag must be between 0..7"); 2092 static_assert(Tag < 8, "Tag must be between 0..7");
2177 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2093 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2178 if (Ty == IceType_i16) 2094 if (Ty == IceType_i16)
2179 emitOperandSizeOverride(); 2095 emitOperandSizeOverride();
2180 emitAddrSizeOverridePrefix(); 2096 emitAddrSizeOverridePrefix();
2181 emitRex(Ty, address, reg); 2097 emitRex(Ty, address, reg);
2182 if (isByteSizedType(Ty)) 2098 if (isByteSizedType(Ty))
2183 emitUint8(Tag * 8 + 0); 2099 emitUint8(Tag * 8 + 0);
2184 else 2100 else
2185 emitUint8(Tag * 8 + 1); 2101 emitUint8(Tag * 8 + 1);
2186 emitOperand(gprEncoding(reg), address); 2102 emitOperand(gprEncoding(reg), address);
2187 } 2103 }
2188 2104
2189 template <class Machine> 2105 template <typename TraitsType>
2190 template <uint32_t Tag> 2106 template <uint32_t Tag>
2191 void AssemblerX86Base<Machine>::arith_int( 2107 void AssemblerX86Base<TraitsType>::arith_int(Type Ty, const Address &address,
2192 Type Ty, const typename Traits::Address &address, const Immediate &imm) { 2108 const Immediate &imm) {
2193 static_assert(Tag < 8, "Tag must be between 0..7"); 2109 static_assert(Tag < 8, "Tag must be between 0..7");
2194 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2110 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2195 if (Ty == IceType_i16) 2111 if (Ty == IceType_i16)
2196 emitOperandSizeOverride(); 2112 emitOperandSizeOverride();
2197 emitAddrSizeOverridePrefix(); 2113 emitAddrSizeOverridePrefix();
2198 emitRex(Ty, address, RexRegIrrelevant); 2114 emitRex(Ty, address, RexRegIrrelevant);
2199 if (isByteSizedType(Ty)) { 2115 if (isByteSizedType(Ty)) {
2200 emitComplexI8(Tag, address, imm); 2116 emitComplexI8(Tag, address, imm);
2201 } else { 2117 } else {
2202 emitComplex(Ty, Tag, address, imm); 2118 emitComplex(Ty, Tag, address, imm);
2203 } 2119 }
2204 } 2120 }
2205 2121
2206 template <class Machine> 2122 template <typename TraitsType>
2207 void AssemblerX86Base<Machine>::cmp(Type Ty, typename Traits::GPRRegister reg, 2123 void AssemblerX86Base<TraitsType>::cmp(Type Ty, GPRRegister reg,
2208 const Immediate &imm) { 2124 const Immediate &imm) {
2209 arith_int<7>(Ty, reg, imm); 2125 arith_int<7>(Ty, reg, imm);
2210 } 2126 }
2211 2127
2212 template <class Machine> 2128 template <typename TraitsType>
2213 void AssemblerX86Base<Machine>::cmp(Type Ty, typename Traits::GPRRegister reg0, 2129 void AssemblerX86Base<TraitsType>::cmp(Type Ty, GPRRegister reg0,
2214 typename Traits::GPRRegister reg1) { 2130 GPRRegister reg1) {
2215 arith_int<7>(Ty, reg0, reg1); 2131 arith_int<7>(Ty, reg0, reg1);
2216 } 2132 }
2217 2133
2218 template <class Machine> 2134 template <typename TraitsType>
2219 void AssemblerX86Base<Machine>::cmp(Type Ty, typename Traits::GPRRegister reg, 2135 void AssemblerX86Base<TraitsType>::cmp(Type Ty, GPRRegister reg,
2220 const typename Traits::Address &address) { 2136 const Address &address) {
2221 arith_int<7>(Ty, reg, address); 2137 arith_int<7>(Ty, reg, address);
2222 } 2138 }
2223 2139
2224 template <class Machine> 2140 template <typename TraitsType>
2225 void AssemblerX86Base<Machine>::cmp(Type Ty, 2141 void AssemblerX86Base<TraitsType>::cmp(Type Ty, const Address &address,
2226 const typename Traits::Address &address, 2142 GPRRegister reg) {
2227 typename Traits::GPRRegister reg) {
2228 arith_int<7>(Ty, address, reg); 2143 arith_int<7>(Ty, address, reg);
2229 } 2144 }
2230 2145
2231 template <class Machine> 2146 template <typename TraitsType>
2232 void AssemblerX86Base<Machine>::cmp(Type Ty, 2147 void AssemblerX86Base<TraitsType>::cmp(Type Ty, const Address &address,
2233 const typename Traits::Address &address, 2148 const Immediate &imm) {
2234 const Immediate &imm) {
2235 arith_int<7>(Ty, address, imm); 2149 arith_int<7>(Ty, address, imm);
2236 } 2150 }
2237 2151
2238 template <class Machine> 2152 template <typename TraitsType>
2239 void AssemblerX86Base<Machine>::test(Type Ty, typename Traits::GPRRegister reg1, 2153 void AssemblerX86Base<TraitsType>::test(Type Ty, GPRRegister reg1,
2240 typename Traits::GPRRegister reg2) { 2154 GPRRegister reg2) {
2241 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2155 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2242 if (Ty == IceType_i16) 2156 if (Ty == IceType_i16)
2243 emitOperandSizeOverride(); 2157 emitOperandSizeOverride();
2244 emitRexRB(Ty, reg1, reg2); 2158 emitRexRB(Ty, reg1, reg2);
2245 if (isByteSizedType(Ty)) 2159 if (isByteSizedType(Ty))
2246 emitUint8(0x84); 2160 emitUint8(0x84);
2247 else 2161 else
2248 emitUint8(0x85); 2162 emitUint8(0x85);
2249 emitRegisterOperand(gprEncoding(reg1), gprEncoding(reg2)); 2163 emitRegisterOperand(gprEncoding(reg1), gprEncoding(reg2));
2250 } 2164 }
2251 2165
2252 template <class Machine> 2166 template <typename TraitsType>
2253 void AssemblerX86Base<Machine>::test(Type Ty, 2167 void AssemblerX86Base<TraitsType>::test(Type Ty, const Address &addr,
2254 const typename Traits::Address &addr, 2168 GPRRegister reg) {
2255 typename Traits::GPRRegister reg) {
2256 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2169 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2257 if (Ty == IceType_i16) 2170 if (Ty == IceType_i16)
2258 emitOperandSizeOverride(); 2171 emitOperandSizeOverride();
2259 emitAddrSizeOverridePrefix(); 2172 emitAddrSizeOverridePrefix();
2260 emitRex(Ty, addr, reg); 2173 emitRex(Ty, addr, reg);
2261 if (isByteSizedType(Ty)) 2174 if (isByteSizedType(Ty))
2262 emitUint8(0x84); 2175 emitUint8(0x84);
2263 else 2176 else
2264 emitUint8(0x85); 2177 emitUint8(0x85);
2265 emitOperand(gprEncoding(reg), addr); 2178 emitOperand(gprEncoding(reg), addr);
2266 } 2179 }
2267 2180
2268 template <class Machine> 2181 template <typename TraitsType>
2269 void AssemblerX86Base<Machine>::test(Type Ty, typename Traits::GPRRegister reg, 2182 void AssemblerX86Base<TraitsType>::test(Type Ty, GPRRegister reg,
2270 const Immediate &immediate) { 2183 const Immediate &immediate) {
2271 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2184 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2272 // For registers that have a byte variant (EAX, EBX, ECX, and EDX) we only 2185 // For registers that have a byte variant (EAX, EBX, ECX, and EDX) we only
2273 // test the byte register to keep the encoding short. This is legal even if 2186 // test the byte register to keep the encoding short. This is legal even if
2274 // the register had high bits set since this only sets flags registers based 2187 // the register had high bits set since this only sets flags registers based
2275 // on the "AND" of the two operands, and the immediate had zeros at those 2188 // on the "AND" of the two operands, and the immediate had zeros at those
2276 // high bits. 2189 // high bits.
2277 if (immediate.is_uint8() && reg <= Traits::Last8BitGPR) { 2190 if (immediate.is_uint8() && reg <= Traits::Last8BitGPR) {
2278 // Use zero-extended 8-bit immediate. 2191 // Use zero-extended 8-bit immediate.
2279 emitRexB(Ty, reg); 2192 emitRexB(Ty, reg);
2280 if (reg == Traits::Encoded_Reg_Accumulator) { 2193 if (reg == Traits::Encoded_Reg_Accumulator) {
(...skipping 12 matching lines...) Expand all
2293 } else { 2206 } else {
2294 if (Ty == IceType_i16) 2207 if (Ty == IceType_i16)
2295 emitOperandSizeOverride(); 2208 emitOperandSizeOverride();
2296 emitRexB(Ty, reg); 2209 emitRexB(Ty, reg);
2297 emitUint8(0xF7); 2210 emitUint8(0xF7);
2298 emitRegisterOperand(0, gprEncoding(reg)); 2211 emitRegisterOperand(0, gprEncoding(reg));
2299 emitImmediate(Ty, immediate); 2212 emitImmediate(Ty, immediate);
2300 } 2213 }
2301 } 2214 }
2302 2215
2303 template <class Machine> 2216 template <typename TraitsType>
2304 void AssemblerX86Base<Machine>::test(Type Ty, 2217 void AssemblerX86Base<TraitsType>::test(Type Ty, const Address &addr,
2305 const typename Traits::Address &addr, 2218 const Immediate &immediate) {
2306 const Immediate &immediate) {
2307 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2219 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2308 // If the immediate is short, we only test the byte addr to keep the encoding 2220 // If the immediate is short, we only test the byte addr to keep the encoding
2309 // short. 2221 // short.
2310 if (immediate.is_uint8()) { 2222 if (immediate.is_uint8()) {
2311 // Use zero-extended 8-bit immediate. 2223 // Use zero-extended 8-bit immediate.
2312 emitAddrSizeOverridePrefix(); 2224 emitAddrSizeOverridePrefix();
2313 emitRex(Ty, addr, RexRegIrrelevant); 2225 emitRex(Ty, addr, RexRegIrrelevant);
2314 emitUint8(0xF6); 2226 emitUint8(0xF6);
2315 emitOperand(0, addr); 2227 emitOperand(0, addr);
2316 emitUint8(immediate.value() & 0xFF); 2228 emitUint8(immediate.value() & 0xFF);
2317 } else { 2229 } else {
2318 if (Ty == IceType_i16) 2230 if (Ty == IceType_i16)
2319 emitOperandSizeOverride(); 2231 emitOperandSizeOverride();
2320 emitAddrSizeOverridePrefix(); 2232 emitAddrSizeOverridePrefix();
2321 emitRex(Ty, addr, RexRegIrrelevant); 2233 emitRex(Ty, addr, RexRegIrrelevant);
2322 emitUint8(0xF7); 2234 emitUint8(0xF7);
2323 emitOperand(0, addr); 2235 emitOperand(0, addr);
2324 emitImmediate(Ty, immediate); 2236 emitImmediate(Ty, immediate);
2325 } 2237 }
2326 } 2238 }
2327 2239
2328 template <class Machine> 2240 template <typename TraitsType>
2329 void AssemblerX86Base<Machine>::And(Type Ty, typename Traits::GPRRegister dst, 2241 void AssemblerX86Base<TraitsType>::And(Type Ty, GPRRegister dst,
2330 typename Traits::GPRRegister src) { 2242 GPRRegister src) {
2331 arith_int<4>(Ty, dst, src); 2243 arith_int<4>(Ty, dst, src);
2332 } 2244 }
2333 2245
2334 template <class Machine> 2246 template <typename TraitsType>
2335 void AssemblerX86Base<Machine>::And(Type Ty, typename Traits::GPRRegister dst, 2247 void AssemblerX86Base<TraitsType>::And(Type Ty, GPRRegister dst,
2336 const typename Traits::Address &address) { 2248 const Address &address) {
2337 arith_int<4>(Ty, dst, address); 2249 arith_int<4>(Ty, dst, address);
2338 } 2250 }
2339 2251
2340 template <class Machine> 2252 template <typename TraitsType>
2341 void AssemblerX86Base<Machine>::And(Type Ty, typename Traits::GPRRegister dst, 2253 void AssemblerX86Base<TraitsType>::And(Type Ty, GPRRegister dst,
2342 const Immediate &imm) { 2254 const Immediate &imm) {
2343 arith_int<4>(Ty, dst, imm); 2255 arith_int<4>(Ty, dst, imm);
2344 } 2256 }
2345 2257
2346 template <class Machine> 2258 template <typename TraitsType>
2347 void AssemblerX86Base<Machine>::And(Type Ty, 2259 void AssemblerX86Base<TraitsType>::And(Type Ty, const Address &address,
2348 const typename Traits::Address &address, 2260 GPRRegister reg) {
2349 typename Traits::GPRRegister reg) {
2350 arith_int<4>(Ty, address, reg); 2261 arith_int<4>(Ty, address, reg);
2351 } 2262 }
2352 2263
2353 template <class Machine> 2264 template <typename TraitsType>
2354 void AssemblerX86Base<Machine>::And(Type Ty, 2265 void AssemblerX86Base<TraitsType>::And(Type Ty, const Address &address,
2355 const typename Traits::Address &address, 2266 const Immediate &imm) {
2356 const Immediate &imm) {
2357 arith_int<4>(Ty, address, imm); 2267 arith_int<4>(Ty, address, imm);
2358 } 2268 }
2359 2269
2360 template <class Machine> 2270 template <typename TraitsType>
2361 void AssemblerX86Base<Machine>::Or(Type Ty, typename Traits::GPRRegister dst, 2271 void AssemblerX86Base<TraitsType>::Or(Type Ty, GPRRegister dst,
2362 typename Traits::GPRRegister src) { 2272 GPRRegister src) {
2363 arith_int<1>(Ty, dst, src); 2273 arith_int<1>(Ty, dst, src);
2364 } 2274 }
2365 2275
2366 template <class Machine> 2276 template <typename TraitsType>
2367 void AssemblerX86Base<Machine>::Or(Type Ty, typename Traits::GPRRegister dst, 2277 void AssemblerX86Base<TraitsType>::Or(Type Ty, GPRRegister dst,
2368 const typename Traits::Address &address) { 2278 const Address &address) {
2369 arith_int<1>(Ty, dst, address); 2279 arith_int<1>(Ty, dst, address);
2370 } 2280 }
2371 2281
2372 template <class Machine> 2282 template <typename TraitsType>
2373 void AssemblerX86Base<Machine>::Or(Type Ty, typename Traits::GPRRegister dst, 2283 void AssemblerX86Base<TraitsType>::Or(Type Ty, GPRRegister dst,
2374 const Immediate &imm) { 2284 const Immediate &imm) {
2375 arith_int<1>(Ty, dst, imm); 2285 arith_int<1>(Ty, dst, imm);
2376 } 2286 }
2377 2287
2378 template <class Machine> 2288 template <typename TraitsType>
2379 void AssemblerX86Base<Machine>::Or(Type Ty, 2289 void AssemblerX86Base<TraitsType>::Or(Type Ty, const Address &address,
2380 const typename Traits::Address &address, 2290 GPRRegister reg) {
2381 typename Traits::GPRRegister reg) {
2382 arith_int<1>(Ty, address, reg); 2291 arith_int<1>(Ty, address, reg);
2383 } 2292 }
2384 2293
2385 template <class Machine> 2294 template <typename TraitsType>
2386 void AssemblerX86Base<Machine>::Or(Type Ty, 2295 void AssemblerX86Base<TraitsType>::Or(Type Ty, const Address &address,
2387 const typename Traits::Address &address, 2296 const Immediate &imm) {
2388 const Immediate &imm) {
2389 arith_int<1>(Ty, address, imm); 2297 arith_int<1>(Ty, address, imm);
2390 } 2298 }
2391 2299
2392 template <class Machine> 2300 template <typename TraitsType>
2393 void AssemblerX86Base<Machine>::Xor(Type Ty, typename Traits::GPRRegister dst, 2301 void AssemblerX86Base<TraitsType>::Xor(Type Ty, GPRRegister dst,
2394 typename Traits::GPRRegister src) { 2302 GPRRegister src) {
2395 arith_int<6>(Ty, dst, src); 2303 arith_int<6>(Ty, dst, src);
2396 } 2304 }
2397 2305
2398 template <class Machine> 2306 template <typename TraitsType>
2399 void AssemblerX86Base<Machine>::Xor(Type Ty, typename Traits::GPRRegister dst, 2307 void AssemblerX86Base<TraitsType>::Xor(Type Ty, GPRRegister dst,
2400 const typename Traits::Address &address) { 2308 const Address &address) {
2401 arith_int<6>(Ty, dst, address); 2309 arith_int<6>(Ty, dst, address);
2402 } 2310 }
2403 2311
2404 template <class Machine> 2312 template <typename TraitsType>
2405 void AssemblerX86Base<Machine>::Xor(Type Ty, typename Traits::GPRRegister dst, 2313 void AssemblerX86Base<TraitsType>::Xor(Type Ty, GPRRegister dst,
2406 const Immediate &imm) { 2314 const Immediate &imm) {
2407 arith_int<6>(Ty, dst, imm); 2315 arith_int<6>(Ty, dst, imm);
2408 } 2316 }
2409 2317
2410 template <class Machine> 2318 template <typename TraitsType>
2411 void AssemblerX86Base<Machine>::Xor(Type Ty, 2319 void AssemblerX86Base<TraitsType>::Xor(Type Ty, const Address &address,
2412 const typename Traits::Address &address, 2320 GPRRegister reg) {
2413 typename Traits::GPRRegister reg) {
2414 arith_int<6>(Ty, address, reg); 2321 arith_int<6>(Ty, address, reg);
2415 } 2322 }
2416 2323
2417 template <class Machine> 2324 template <typename TraitsType>
2418 void AssemblerX86Base<Machine>::Xor(Type Ty, 2325 void AssemblerX86Base<TraitsType>::Xor(Type Ty, const Address &address,
2419 const typename Traits::Address &address, 2326 const Immediate &imm) {
2420 const Immediate &imm) {
2421 arith_int<6>(Ty, address, imm); 2327 arith_int<6>(Ty, address, imm);
2422 } 2328 }
2423 2329
2424 template <class Machine> 2330 template <typename TraitsType>
2425 void AssemblerX86Base<Machine>::add(Type Ty, typename Traits::GPRRegister dst, 2331 void AssemblerX86Base<TraitsType>::add(Type Ty, GPRRegister dst,
2426 typename Traits::GPRRegister src) { 2332 GPRRegister src) {
2427 arith_int<0>(Ty, dst, src); 2333 arith_int<0>(Ty, dst, src);
2428 } 2334 }
2429 2335
2430 template <class Machine> 2336 template <typename TraitsType>
2431 void AssemblerX86Base<Machine>::add(Type Ty, typename Traits::GPRRegister reg, 2337 void AssemblerX86Base<TraitsType>::add(Type Ty, GPRRegister reg,
2432 const typename Traits::Address &address) { 2338 const Address &address) {
2433 arith_int<0>(Ty, reg, address); 2339 arith_int<0>(Ty, reg, address);
2434 } 2340 }
2435 2341
2436 template <class Machine> 2342 template <typename TraitsType>
2437 void AssemblerX86Base<Machine>::add(Type Ty, typename Traits::GPRRegister reg, 2343 void AssemblerX86Base<TraitsType>::add(Type Ty, GPRRegister reg,
2438 const Immediate &imm) { 2344 const Immediate &imm) {
2439 arith_int<0>(Ty, reg, imm); 2345 arith_int<0>(Ty, reg, imm);
2440 } 2346 }
2441 2347
2442 template <class Machine> 2348 template <typename TraitsType>
2443 void AssemblerX86Base<Machine>::add(Type Ty, 2349 void AssemblerX86Base<TraitsType>::add(Type Ty, const Address &address,
2444 const typename Traits::Address &address, 2350 GPRRegister reg) {
2445 typename Traits::GPRRegister reg) {
2446 arith_int<0>(Ty, address, reg); 2351 arith_int<0>(Ty, address, reg);
2447 } 2352 }
2448 2353
2449 template <class Machine> 2354 template <typename TraitsType>
2450 void AssemblerX86Base<Machine>::add(Type Ty, 2355 void AssemblerX86Base<TraitsType>::add(Type Ty, const Address &address,
2451 const typename Traits::Address &address, 2356 const Immediate &imm) {
2452 const Immediate &imm) {
2453 arith_int<0>(Ty, address, imm); 2357 arith_int<0>(Ty, address, imm);
2454 } 2358 }
2455 2359
2456 template <class Machine> 2360 template <typename TraitsType>
2457 void AssemblerX86Base<Machine>::adc(Type Ty, typename Traits::GPRRegister dst, 2361 void AssemblerX86Base<TraitsType>::adc(Type Ty, GPRRegister dst,
2458 typename Traits::GPRRegister src) { 2362 GPRRegister src) {
2459 arith_int<2>(Ty, dst, src); 2363 arith_int<2>(Ty, dst, src);
2460 } 2364 }
2461 2365
2462 template <class Machine> 2366 template <typename TraitsType>
2463 void AssemblerX86Base<Machine>::adc(Type Ty, typename Traits::GPRRegister dst, 2367 void AssemblerX86Base<TraitsType>::adc(Type Ty, GPRRegister dst,
2464 const typename Traits::Address &address) { 2368 const Address &address) {
2465 arith_int<2>(Ty, dst, address); 2369 arith_int<2>(Ty, dst, address);
2466 } 2370 }
2467 2371
2468 template <class Machine> 2372 template <typename TraitsType>
2469 void AssemblerX86Base<Machine>::adc(Type Ty, typename Traits::GPRRegister reg, 2373 void AssemblerX86Base<TraitsType>::adc(Type Ty, GPRRegister reg,
2470 const Immediate &imm) { 2374 const Immediate &imm) {
2471 arith_int<2>(Ty, reg, imm); 2375 arith_int<2>(Ty, reg, imm);
2472 } 2376 }
2473 2377
2474 template <class Machine> 2378 template <typename TraitsType>
2475 void AssemblerX86Base<Machine>::adc(Type Ty, 2379 void AssemblerX86Base<TraitsType>::adc(Type Ty, const Address &address,
2476 const typename Traits::Address &address, 2380 GPRRegister reg) {
2477 typename Traits::GPRRegister reg) {
2478 arith_int<2>(Ty, address, reg); 2381 arith_int<2>(Ty, address, reg);
2479 } 2382 }
2480 2383
2481 template <class Machine> 2384 template <typename TraitsType>
2482 void AssemblerX86Base<Machine>::adc(Type Ty, 2385 void AssemblerX86Base<TraitsType>::adc(Type Ty, const Address &address,
2483 const typename Traits::Address &address, 2386 const Immediate &imm) {
2484 const Immediate &imm) {
2485 arith_int<2>(Ty, address, imm); 2387 arith_int<2>(Ty, address, imm);
2486 } 2388 }
2487 2389
2488 template <class Machine> 2390 template <typename TraitsType>
2489 void AssemblerX86Base<Machine>::sub(Type Ty, typename Traits::GPRRegister dst, 2391 void AssemblerX86Base<TraitsType>::sub(Type Ty, GPRRegister dst,
2490 typename Traits::GPRRegister src) { 2392 GPRRegister src) {
2491 arith_int<5>(Ty, dst, src); 2393 arith_int<5>(Ty, dst, src);
2492 } 2394 }
2493 2395
2494 template <class Machine> 2396 template <typename TraitsType>
2495 void AssemblerX86Base<Machine>::sub(Type Ty, typename Traits::GPRRegister reg, 2397 void AssemblerX86Base<TraitsType>::sub(Type Ty, GPRRegister reg,
2496 const typename Traits::Address &address) { 2398 const Address &address) {
2497 arith_int<5>(Ty, reg, address); 2399 arith_int<5>(Ty, reg, address);
2498 } 2400 }
2499 2401
2500 template <class Machine> 2402 template <typename TraitsType>
2501 void AssemblerX86Base<Machine>::sub(Type Ty, typename Traits::GPRRegister reg, 2403 void AssemblerX86Base<TraitsType>::sub(Type Ty, GPRRegister reg,
2502 const Immediate &imm) { 2404 const Immediate &imm) {
2503 arith_int<5>(Ty, reg, imm); 2405 arith_int<5>(Ty, reg, imm);
2504 } 2406 }
2505 2407
2506 template <class Machine> 2408 template <typename TraitsType>
2507 void AssemblerX86Base<Machine>::sub(Type Ty, 2409 void AssemblerX86Base<TraitsType>::sub(Type Ty, const Address &address,
2508 const typename Traits::Address &address, 2410 GPRRegister reg) {
2509 typename Traits::GPRRegister reg) {
2510 arith_int<5>(Ty, address, reg); 2411 arith_int<5>(Ty, address, reg);
2511 } 2412 }
2512 2413
2513 template <class Machine> 2414 template <typename TraitsType>
2514 void AssemblerX86Base<Machine>::sub(Type Ty, 2415 void AssemblerX86Base<TraitsType>::sub(Type Ty, const Address &address,
2515 const typename Traits::Address &address, 2416 const Immediate &imm) {
2516 const Immediate &imm) {
2517 arith_int<5>(Ty, address, imm); 2417 arith_int<5>(Ty, address, imm);
2518 } 2418 }
2519 2419
2520 template <class Machine> 2420 template <typename TraitsType>
2521 void AssemblerX86Base<Machine>::sbb(Type Ty, typename Traits::GPRRegister dst, 2421 void AssemblerX86Base<TraitsType>::sbb(Type Ty, GPRRegister dst,
2522 typename Traits::GPRRegister src) { 2422 GPRRegister src) {
2523 arith_int<3>(Ty, dst, src); 2423 arith_int<3>(Ty, dst, src);
2524 } 2424 }
2525 2425
2526 template <class Machine> 2426 template <typename TraitsType>
2527 void AssemblerX86Base<Machine>::sbb(Type Ty, typename Traits::GPRRegister dst, 2427 void AssemblerX86Base<TraitsType>::sbb(Type Ty, GPRRegister dst,
2528 const typename Traits::Address &address) { 2428 const Address &address) {
2529 arith_int<3>(Ty, dst, address); 2429 arith_int<3>(Ty, dst, address);
2530 } 2430 }
2531 2431
2532 template <class Machine> 2432 template <typename TraitsType>
2533 void AssemblerX86Base<Machine>::sbb(Type Ty, typename Traits::GPRRegister reg, 2433 void AssemblerX86Base<TraitsType>::sbb(Type Ty, GPRRegister reg,
2534 const Immediate &imm) { 2434 const Immediate &imm) {
2535 arith_int<3>(Ty, reg, imm); 2435 arith_int<3>(Ty, reg, imm);
2536 } 2436 }
2537 2437
2538 template <class Machine> 2438 template <typename TraitsType>
2539 void AssemblerX86Base<Machine>::sbb(Type Ty, 2439 void AssemblerX86Base<TraitsType>::sbb(Type Ty, const Address &address,
2540 const typename Traits::Address &address, 2440 GPRRegister reg) {
2541 typename Traits::GPRRegister reg) {
2542 arith_int<3>(Ty, address, reg); 2441 arith_int<3>(Ty, address, reg);
2543 } 2442 }
2544 2443
2545 template <class Machine> 2444 template <typename TraitsType>
2546 void AssemblerX86Base<Machine>::sbb(Type Ty, 2445 void AssemblerX86Base<TraitsType>::sbb(Type Ty, const Address &address,
2547 const typename Traits::Address &address, 2446 const Immediate &imm) {
2548 const Immediate &imm) {
2549 arith_int<3>(Ty, address, imm); 2447 arith_int<3>(Ty, address, imm);
2550 } 2448 }
2551 2449
2552 template <class Machine> void AssemblerX86Base<Machine>::cbw() { 2450 template <typename TraitsType> void AssemblerX86Base<TraitsType>::cbw() {
2553 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2451 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2554 emitOperandSizeOverride(); 2452 emitOperandSizeOverride();
2555 emitUint8(0x98); 2453 emitUint8(0x98);
2556 } 2454 }
2557 2455
2558 template <class Machine> void AssemblerX86Base<Machine>::cwd() { 2456 template <typename TraitsType> void AssemblerX86Base<TraitsType>::cwd() {
2559 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2457 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2560 emitOperandSizeOverride(); 2458 emitOperandSizeOverride();
2561 emitUint8(0x99); 2459 emitUint8(0x99);
2562 } 2460 }
2563 2461
2564 template <class Machine> void AssemblerX86Base<Machine>::cdq() { 2462 template <typename TraitsType> void AssemblerX86Base<TraitsType>::cdq() {
2565 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2463 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2566 emitUint8(0x99); 2464 emitUint8(0x99);
2567 } 2465 }
2568 2466
2569 template <class Machine> 2467 template <typename TraitsType>
2570 template <typename T> 2468 template <typename T>
2571 typename std::enable_if<T::Is64Bit, void>::type 2469 typename std::enable_if<T::Is64Bit, void>::type
2572 AssemblerX86Base<Machine>::cqo() { 2470 AssemblerX86Base<TraitsType>::cqo() {
2573 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2471 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2574 emitRexB(RexTypeForceRexW, RexRegIrrelevant); 2472 emitRexB(RexTypeForceRexW, RexRegIrrelevant);
2575 emitUint8(0x99); 2473 emitUint8(0x99);
2576 } 2474 }
2577 2475
2578 template <class Machine> 2476 template <typename TraitsType>
2579 void AssemblerX86Base<Machine>::div(Type Ty, typename Traits::GPRRegister reg) { 2477 void AssemblerX86Base<TraitsType>::div(Type Ty, GPRRegister reg) {
2580 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2478 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2581 if (Ty == IceType_i16) 2479 if (Ty == IceType_i16)
2582 emitOperandSizeOverride(); 2480 emitOperandSizeOverride();
2583 emitRexB(Ty, reg); 2481 emitRexB(Ty, reg);
2584 if (isByteSizedArithType(Ty)) 2482 if (isByteSizedArithType(Ty))
2585 emitUint8(0xF6); 2483 emitUint8(0xF6);
2586 else 2484 else
2587 emitUint8(0xF7); 2485 emitUint8(0xF7);
2588 emitRegisterOperand(6, gprEncoding(reg)); 2486 emitRegisterOperand(6, gprEncoding(reg));
2589 } 2487 }
2590 2488
2591 template <class Machine> 2489 template <typename TraitsType>
2592 void AssemblerX86Base<Machine>::div(Type Ty, 2490 void AssemblerX86Base<TraitsType>::div(Type Ty, const Address &addr) {
2593 const typename Traits::Address &addr) {
2594 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2491 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2595 if (Ty == IceType_i16) 2492 if (Ty == IceType_i16)
2596 emitOperandSizeOverride(); 2493 emitOperandSizeOverride();
2597 emitAddrSizeOverridePrefix(); 2494 emitAddrSizeOverridePrefix();
2598 emitRex(Ty, addr, RexRegIrrelevant); 2495 emitRex(Ty, addr, RexRegIrrelevant);
2599 if (isByteSizedArithType(Ty)) 2496 if (isByteSizedArithType(Ty))
2600 emitUint8(0xF6); 2497 emitUint8(0xF6);
2601 else 2498 else
2602 emitUint8(0xF7); 2499 emitUint8(0xF7);
2603 emitOperand(6, addr); 2500 emitOperand(6, addr);
2604 } 2501 }
2605 2502
2606 template <class Machine> 2503 template <typename TraitsType>
2607 void AssemblerX86Base<Machine>::idiv(Type Ty, 2504 void AssemblerX86Base<TraitsType>::idiv(Type Ty, GPRRegister reg) {
2608 typename Traits::GPRRegister reg) {
2609 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2505 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2610 if (Ty == IceType_i16) 2506 if (Ty == IceType_i16)
2611 emitOperandSizeOverride(); 2507 emitOperandSizeOverride();
2612 emitRexB(Ty, reg); 2508 emitRexB(Ty, reg);
2613 if (isByteSizedArithType(Ty)) 2509 if (isByteSizedArithType(Ty))
2614 emitUint8(0xF6); 2510 emitUint8(0xF6);
2615 else 2511 else
2616 emitUint8(0xF7); 2512 emitUint8(0xF7);
2617 emitRegisterOperand(7, gprEncoding(reg)); 2513 emitRegisterOperand(7, gprEncoding(reg));
2618 } 2514 }
2619 2515
2620 template <class Machine> 2516 template <typename TraitsType>
2621 void AssemblerX86Base<Machine>::idiv(Type Ty, 2517 void AssemblerX86Base<TraitsType>::idiv(Type Ty, const Address &addr) {
2622 const typename Traits::Address &addr) {
2623 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2518 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2624 if (Ty == IceType_i16) 2519 if (Ty == IceType_i16)
2625 emitOperandSizeOverride(); 2520 emitOperandSizeOverride();
2626 emitAddrSizeOverridePrefix(); 2521 emitAddrSizeOverridePrefix();
2627 emitRex(Ty, addr, RexRegIrrelevant); 2522 emitRex(Ty, addr, RexRegIrrelevant);
2628 if (isByteSizedArithType(Ty)) 2523 if (isByteSizedArithType(Ty))
2629 emitUint8(0xF6); 2524 emitUint8(0xF6);
2630 else 2525 else
2631 emitUint8(0xF7); 2526 emitUint8(0xF7);
2632 emitOperand(7, addr); 2527 emitOperand(7, addr);
2633 } 2528 }
2634 2529
2635 template <class Machine> 2530 template <typename TraitsType>
2636 void AssemblerX86Base<Machine>::imul(Type Ty, typename Traits::GPRRegister dst, 2531 void AssemblerX86Base<TraitsType>::imul(Type Ty, GPRRegister dst,
2637 typename Traits::GPRRegister src) { 2532 GPRRegister src) {
2638 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2533 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2639 assert(Ty == IceType_i16 || Ty == IceType_i32 || 2534 assert(Ty == IceType_i16 || Ty == IceType_i32 ||
2640 (Traits::Is64Bit && Ty == IceType_i64)); 2535 (Traits::Is64Bit && Ty == IceType_i64));
2641 if (Ty == IceType_i16) 2536 if (Ty == IceType_i16)
2642 emitOperandSizeOverride(); 2537 emitOperandSizeOverride();
2643 emitRexRB(Ty, dst, src); 2538 emitRexRB(Ty, dst, src);
2644 emitUint8(0x0F); 2539 emitUint8(0x0F);
2645 emitUint8(0xAF); 2540 emitUint8(0xAF);
2646 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); 2541 emitRegisterOperand(gprEncoding(dst), gprEncoding(src));
2647 } 2542 }
2648 2543
2649 template <class Machine> 2544 template <typename TraitsType>
2650 void AssemblerX86Base<Machine>::imul(Type Ty, typename Traits::GPRRegister reg, 2545 void AssemblerX86Base<TraitsType>::imul(Type Ty, GPRRegister reg,
2651 const typename Traits::Address &address) { 2546 const Address &address) {
2652 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2547 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2653 assert(Ty == IceType_i16 || Ty == IceType_i32 || 2548 assert(Ty == IceType_i16 || Ty == IceType_i32 ||
2654 (Traits::Is64Bit && Ty == IceType_i64)); 2549 (Traits::Is64Bit && Ty == IceType_i64));
2655 if (Ty == IceType_i16) 2550 if (Ty == IceType_i16)
2656 emitOperandSizeOverride(); 2551 emitOperandSizeOverride();
2657 emitAddrSizeOverridePrefix(); 2552 emitAddrSizeOverridePrefix();
2658 emitRex(Ty, address, reg); 2553 emitRex(Ty, address, reg);
2659 emitUint8(0x0F); 2554 emitUint8(0x0F);
2660 emitUint8(0xAF); 2555 emitUint8(0xAF);
2661 emitOperand(gprEncoding(reg), address); 2556 emitOperand(gprEncoding(reg), address);
2662 } 2557 }
2663 2558
2664 template <class Machine> 2559 template <typename TraitsType>
2665 void AssemblerX86Base<Machine>::imul(Type Ty, typename Traits::GPRRegister reg, 2560 void AssemblerX86Base<TraitsType>::imul(Type Ty, GPRRegister reg,
2666 const Immediate &imm) { 2561 const Immediate &imm) {
2667 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2562 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2668 assert(Ty == IceType_i16 || Ty == IceType_i32); 2563 assert(Ty == IceType_i16 || Ty == IceType_i32);
2669 if (Ty == IceType_i16) 2564 if (Ty == IceType_i16)
2670 emitOperandSizeOverride(); 2565 emitOperandSizeOverride();
2671 emitRexRB(Ty, reg, reg); 2566 emitRexRB(Ty, reg, reg);
2672 if (imm.is_int8()) { 2567 if (imm.is_int8()) {
2673 emitUint8(0x6B); 2568 emitUint8(0x6B);
2674 emitRegisterOperand(gprEncoding(reg), gprEncoding(reg)); 2569 emitRegisterOperand(gprEncoding(reg), gprEncoding(reg));
2675 emitUint8(imm.value() & 0xFF); 2570 emitUint8(imm.value() & 0xFF);
2676 } else { 2571 } else {
2677 emitUint8(0x69); 2572 emitUint8(0x69);
2678 emitRegisterOperand(gprEncoding(reg), gprEncoding(reg)); 2573 emitRegisterOperand(gprEncoding(reg), gprEncoding(reg));
2679 emitImmediate(Ty, imm); 2574 emitImmediate(Ty, imm);
2680 } 2575 }
2681 } 2576 }
2682 2577
2683 template <class Machine> 2578 template <typename TraitsType>
2684 void AssemblerX86Base<Machine>::imul(Type Ty, 2579 void AssemblerX86Base<TraitsType>::imul(Type Ty, GPRRegister reg) {
2685 typename Traits::GPRRegister reg) {
2686 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2580 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2687 if (Ty == IceType_i16) 2581 if (Ty == IceType_i16)
2688 emitOperandSizeOverride(); 2582 emitOperandSizeOverride();
2689 emitRexB(Ty, reg); 2583 emitRexB(Ty, reg);
2690 if (isByteSizedArithType(Ty)) 2584 if (isByteSizedArithType(Ty))
2691 emitUint8(0xF6); 2585 emitUint8(0xF6);
2692 else 2586 else
2693 emitUint8(0xF7); 2587 emitUint8(0xF7);
2694 emitRegisterOperand(5, gprEncoding(reg)); 2588 emitRegisterOperand(5, gprEncoding(reg));
2695 } 2589 }
2696 2590
2697 template <class Machine> 2591 template <typename TraitsType>
2698 void AssemblerX86Base<Machine>::imul(Type Ty, 2592 void AssemblerX86Base<TraitsType>::imul(Type Ty, const Address &address) {
2699 const typename Traits::Address &address) {
2700 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2593 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2701 if (Ty == IceType_i16) 2594 if (Ty == IceType_i16)
2702 emitOperandSizeOverride(); 2595 emitOperandSizeOverride();
2703 emitAddrSizeOverridePrefix(); 2596 emitAddrSizeOverridePrefix();
2704 emitRex(Ty, address, RexRegIrrelevant); 2597 emitRex(Ty, address, RexRegIrrelevant);
2705 if (isByteSizedArithType(Ty)) 2598 if (isByteSizedArithType(Ty))
2706 emitUint8(0xF6); 2599 emitUint8(0xF6);
2707 else 2600 else
2708 emitUint8(0xF7); 2601 emitUint8(0xF7);
2709 emitOperand(5, address); 2602 emitOperand(5, address);
2710 } 2603 }
2711 2604
2712 template <class Machine> 2605 template <typename TraitsType>
2713 void AssemblerX86Base<Machine>::imul(Type Ty, typename Traits::GPRRegister dst, 2606 void AssemblerX86Base<TraitsType>::imul(Type Ty, GPRRegister dst,
2714 typename Traits::GPRRegister src, 2607 GPRRegister src, const Immediate &imm) {
2715 const Immediate &imm) {
2716 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2608 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2717 assert(Ty == IceType_i16 || Ty == IceType_i32); 2609 assert(Ty == IceType_i16 || Ty == IceType_i32);
2718 if (Ty == IceType_i16) 2610 if (Ty == IceType_i16)
2719 emitOperandSizeOverride(); 2611 emitOperandSizeOverride();
2720 emitRexRB(Ty, dst, src); 2612 emitRexRB(Ty, dst, src);
2721 if (imm.is_int8()) { 2613 if (imm.is_int8()) {
2722 emitUint8(0x6B); 2614 emitUint8(0x6B);
2723 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); 2615 emitRegisterOperand(gprEncoding(dst), gprEncoding(src));
2724 emitUint8(imm.value() & 0xFF); 2616 emitUint8(imm.value() & 0xFF);
2725 } else { 2617 } else {
2726 emitUint8(0x69); 2618 emitUint8(0x69);
2727 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); 2619 emitRegisterOperand(gprEncoding(dst), gprEncoding(src));
2728 emitImmediate(Ty, imm); 2620 emitImmediate(Ty, imm);
2729 } 2621 }
2730 } 2622 }
2731 2623
2732 template <class Machine> 2624 template <typename TraitsType>
2733 void AssemblerX86Base<Machine>::imul(Type Ty, typename Traits::GPRRegister dst, 2625 void AssemblerX86Base<TraitsType>::imul(Type Ty, GPRRegister dst,
2734 const typename Traits::Address &address, 2626 const Address &address,
2735 const Immediate &imm) { 2627 const Immediate &imm) {
2736 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2628 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2737 assert(Ty == IceType_i16 || Ty == IceType_i32); 2629 assert(Ty == IceType_i16 || Ty == IceType_i32);
2738 if (Ty == IceType_i16) 2630 if (Ty == IceType_i16)
2739 emitOperandSizeOverride(); 2631 emitOperandSizeOverride();
2740 emitAddrSizeOverridePrefix(); 2632 emitAddrSizeOverridePrefix();
2741 emitRex(Ty, address, dst); 2633 emitRex(Ty, address, dst);
2742 if (imm.is_int8()) { 2634 if (imm.is_int8()) {
2743 emitUint8(0x6B); 2635 emitUint8(0x6B);
2744 emitOperand(gprEncoding(dst), address); 2636 emitOperand(gprEncoding(dst), address);
2745 emitUint8(imm.value() & 0xFF); 2637 emitUint8(imm.value() & 0xFF);
2746 } else { 2638 } else {
2747 emitUint8(0x69); 2639 emitUint8(0x69);
2748 emitOperand(gprEncoding(dst), address); 2640 emitOperand(gprEncoding(dst), address);
2749 emitImmediate(Ty, imm); 2641 emitImmediate(Ty, imm);
2750 } 2642 }
2751 } 2643 }
2752 2644
2753 template <class Machine> 2645 template <typename TraitsType>
2754 void AssemblerX86Base<Machine>::mul(Type Ty, typename Traits::GPRRegister reg) { 2646 void AssemblerX86Base<TraitsType>::mul(Type Ty, GPRRegister reg) {
2755 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2647 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2756 if (Ty == IceType_i16) 2648 if (Ty == IceType_i16)
2757 emitOperandSizeOverride(); 2649 emitOperandSizeOverride();
2758 emitRexB(Ty, reg); 2650 emitRexB(Ty, reg);
2759 if (isByteSizedArithType(Ty)) 2651 if (isByteSizedArithType(Ty))
2760 emitUint8(0xF6); 2652 emitUint8(0xF6);
2761 else 2653 else
2762 emitUint8(0xF7); 2654 emitUint8(0xF7);
2763 emitRegisterOperand(4, gprEncoding(reg)); 2655 emitRegisterOperand(4, gprEncoding(reg));
2764 } 2656 }
2765 2657
2766 template <class Machine> 2658 template <typename TraitsType>
2767 void AssemblerX86Base<Machine>::mul(Type Ty, 2659 void AssemblerX86Base<TraitsType>::mul(Type Ty, const Address &address) {
2768 const typename Traits::Address &address) {
2769 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2660 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2770 if (Ty == IceType_i16) 2661 if (Ty == IceType_i16)
2771 emitOperandSizeOverride(); 2662 emitOperandSizeOverride();
2772 emitAddrSizeOverridePrefix(); 2663 emitAddrSizeOverridePrefix();
2773 emitRex(Ty, address, RexRegIrrelevant); 2664 emitRex(Ty, address, RexRegIrrelevant);
2774 if (isByteSizedArithType(Ty)) 2665 if (isByteSizedArithType(Ty))
2775 emitUint8(0xF6); 2666 emitUint8(0xF6);
2776 else 2667 else
2777 emitUint8(0xF7); 2668 emitUint8(0xF7);
2778 emitOperand(4, address); 2669 emitOperand(4, address);
2779 } 2670 }
2780 2671
2781 template <class Machine> 2672 template <typename TraitsType>
2782 template <typename, typename> 2673 template <typename, typename>
2783 void AssemblerX86Base<Machine>::incl(typename Traits::GPRRegister reg) { 2674 void AssemblerX86Base<TraitsType>::incl(GPRRegister reg) {
2784 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2675 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2785 emitUint8(0x40 + reg); 2676 emitUint8(0x40 + reg);
2786 } 2677 }
2787 2678
2788 template <class Machine> 2679 template <typename TraitsType>
2789 void AssemblerX86Base<Machine>::incl(const typename Traits::Address &address) { 2680 void AssemblerX86Base<TraitsType>::incl(const Address &address) {
2790 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2681 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2791 emitAddrSizeOverridePrefix(); 2682 emitAddrSizeOverridePrefix();
2792 emitRex(IceType_i32, address, RexRegIrrelevant); 2683 emitRex(IceType_i32, address, RexRegIrrelevant);
2793 emitUint8(0xFF); 2684 emitUint8(0xFF);
2794 emitOperand(0, address); 2685 emitOperand(0, address);
2795 } 2686 }
2796 2687
2797 template <class Machine> 2688 template <typename TraitsType>
2798 template <typename, typename> 2689 template <typename, typename>
2799 void AssemblerX86Base<Machine>::decl(typename Traits::GPRRegister reg) { 2690 void AssemblerX86Base<TraitsType>::decl(GPRRegister reg) {
2800 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2691 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2801 emitUint8(0x48 + reg); 2692 emitUint8(0x48 + reg);
2802 } 2693 }
2803 2694
2804 template <class Machine> 2695 template <typename TraitsType>
2805 void AssemblerX86Base<Machine>::decl(const typename Traits::Address &address) { 2696 void AssemblerX86Base<TraitsType>::decl(const Address &address) {
2806 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2697 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2807 emitAddrSizeOverridePrefix(); 2698 emitAddrSizeOverridePrefix();
2808 emitRex(IceType_i32, address, RexRegIrrelevant); 2699 emitRex(IceType_i32, address, RexRegIrrelevant);
2809 emitUint8(0xFF); 2700 emitUint8(0xFF);
2810 emitOperand(1, address); 2701 emitOperand(1, address);
2811 } 2702 }
2812 2703
2813 template <class Machine> 2704 template <typename TraitsType>
2814 void AssemblerX86Base<Machine>::rol(Type Ty, typename Traits::GPRRegister reg, 2705 void AssemblerX86Base<TraitsType>::rol(Type Ty, GPRRegister reg,
2815 const Immediate &imm) { 2706 const Immediate &imm) {
2816 emitGenericShift(0, Ty, reg, imm); 2707 emitGenericShift(0, Ty, reg, imm);
2817 } 2708 }
2818 2709
2819 template <class Machine> 2710 template <typename TraitsType>
2820 void AssemblerX86Base<Machine>::rol(Type Ty, 2711 void AssemblerX86Base<TraitsType>::rol(Type Ty, GPRRegister operand,
2821 typename Traits::GPRRegister operand, 2712 GPRRegister shifter) {
2822 typename Traits::GPRRegister shifter) { 2713 emitGenericShift(0, Ty, Operand(operand), shifter);
2823 emitGenericShift(0, Ty, typename Traits::Operand(operand), shifter);
2824 } 2714 }
2825 2715
2826 template <class Machine> 2716 template <typename TraitsType>
2827 void AssemblerX86Base<Machine>::rol(Type Ty, 2717 void AssemblerX86Base<TraitsType>::rol(Type Ty, const Address &operand,
2828 const typename Traits::Address &operand, 2718 GPRRegister shifter) {
2829 typename Traits::GPRRegister shifter) {
2830 emitGenericShift(0, Ty, operand, shifter); 2719 emitGenericShift(0, Ty, operand, shifter);
2831 } 2720 }
2832 2721
2833 template <class Machine> 2722 template <typename TraitsType>
2834 void AssemblerX86Base<Machine>::shl(Type Ty, typename Traits::GPRRegister reg, 2723 void AssemblerX86Base<TraitsType>::shl(Type Ty, GPRRegister reg,
2835 const Immediate &imm) { 2724 const Immediate &imm) {
2836 emitGenericShift(4, Ty, reg, imm); 2725 emitGenericShift(4, Ty, reg, imm);
2837 } 2726 }
2838 2727
2839 template <class Machine> 2728 template <typename TraitsType>
2840 void AssemblerX86Base<Machine>::shl(Type Ty, 2729 void AssemblerX86Base<TraitsType>::shl(Type Ty, GPRRegister operand,
2841 typename Traits::GPRRegister operand, 2730 GPRRegister shifter) {
2842 typename Traits::GPRRegister shifter) { 2731 emitGenericShift(4, Ty, Operand(operand), shifter);
2843 emitGenericShift(4, Ty, typename Traits::Operand(operand), shifter);
2844 } 2732 }
2845 2733
2846 template <class Machine> 2734 template <typename TraitsType>
2847 void AssemblerX86Base<Machine>::shl(Type Ty, 2735 void AssemblerX86Base<TraitsType>::shl(Type Ty, const Address &operand,
2848 const typename Traits::Address &operand, 2736 GPRRegister shifter) {
2849 typename Traits::GPRRegister shifter) {
2850 emitGenericShift(4, Ty, operand, shifter); 2737 emitGenericShift(4, Ty, operand, shifter);
2851 } 2738 }
2852 2739
2853 template <class Machine> 2740 template <typename TraitsType>
2854 void AssemblerX86Base<Machine>::shr(Type Ty, typename Traits::GPRRegister reg, 2741 void AssemblerX86Base<TraitsType>::shr(Type Ty, GPRRegister reg,
2855 const Immediate &imm) { 2742 const Immediate &imm) {
2856 emitGenericShift(5, Ty, reg, imm); 2743 emitGenericShift(5, Ty, reg, imm);
2857 } 2744 }
2858 2745
2859 template <class Machine> 2746 template <typename TraitsType>
2860 void AssemblerX86Base<Machine>::shr(Type Ty, 2747 void AssemblerX86Base<TraitsType>::shr(Type Ty, GPRRegister operand,
2861 typename Traits::GPRRegister operand, 2748 GPRRegister shifter) {
2862 typename Traits::GPRRegister shifter) { 2749 emitGenericShift(5, Ty, Operand(operand), shifter);
2863 emitGenericShift(5, Ty, typename Traits::Operand(operand), shifter);
2864 } 2750 }
2865 2751
2866 template <class Machine> 2752 template <typename TraitsType>
2867 void AssemblerX86Base<Machine>::shr(Type Ty, 2753 void AssemblerX86Base<TraitsType>::shr(Type Ty, const Address &operand,
2868 const typename Traits::Address &operand, 2754 GPRRegister shifter) {
2869 typename Traits::GPRRegister shifter) {
2870 emitGenericShift(5, Ty, operand, shifter); 2755 emitGenericShift(5, Ty, operand, shifter);
2871 } 2756 }
2872 2757
2873 template <class Machine> 2758 template <typename TraitsType>
2874 void AssemblerX86Base<Machine>::sar(Type Ty, typename Traits::GPRRegister reg, 2759 void AssemblerX86Base<TraitsType>::sar(Type Ty, GPRRegister reg,
2875 const Immediate &imm) { 2760 const Immediate &imm) {
2876 emitGenericShift(7, Ty, reg, imm); 2761 emitGenericShift(7, Ty, reg, imm);
2877 } 2762 }
2878 2763
2879 template <class Machine> 2764 template <typename TraitsType>
2880 void AssemblerX86Base<Machine>::sar(Type Ty, 2765 void AssemblerX86Base<TraitsType>::sar(Type Ty, GPRRegister operand,
2881 typename Traits::GPRRegister operand, 2766 GPRRegister shifter) {
2882 typename Traits::GPRRegister shifter) { 2767 emitGenericShift(7, Ty, Operand(operand), shifter);
2883 emitGenericShift(7, Ty, typename Traits::Operand(operand), shifter);
2884 } 2768 }
2885 2769
2886 template <class Machine> 2770 template <typename TraitsType>
2887 void AssemblerX86Base<Machine>::sar(Type Ty, 2771 void AssemblerX86Base<TraitsType>::sar(Type Ty, const Address &address,
2888 const typename Traits::Address &address, 2772 GPRRegister shifter) {
2889 typename Traits::GPRRegister shifter) {
2890 emitGenericShift(7, Ty, address, shifter); 2773 emitGenericShift(7, Ty, address, shifter);
2891 } 2774 }
2892 2775
2893 template <class Machine> 2776 template <typename TraitsType>
2894 void AssemblerX86Base<Machine>::shld(Type Ty, typename Traits::GPRRegister dst, 2777 void AssemblerX86Base<TraitsType>::shld(Type Ty, GPRRegister dst,
2895 typename Traits::GPRRegister src) { 2778 GPRRegister src) {
2896 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2779 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2897 assert(Ty == IceType_i16 || Ty == IceType_i32); 2780 assert(Ty == IceType_i16 || Ty == IceType_i32);
2898 if (Ty == IceType_i16) 2781 if (Ty == IceType_i16)
2899 emitOperandSizeOverride(); 2782 emitOperandSizeOverride();
2900 emitRexRB(Ty, src, dst); 2783 emitRexRB(Ty, src, dst);
2901 emitUint8(0x0F); 2784 emitUint8(0x0F);
2902 emitUint8(0xA5); 2785 emitUint8(0xA5);
2903 emitRegisterOperand(gprEncoding(src), gprEncoding(dst)); 2786 emitRegisterOperand(gprEncoding(src), gprEncoding(dst));
2904 } 2787 }
2905 2788
2906 template <class Machine> 2789 template <typename TraitsType>
2907 void AssemblerX86Base<Machine>::shld(Type Ty, typename Traits::GPRRegister dst, 2790 void AssemblerX86Base<TraitsType>::shld(Type Ty, GPRRegister dst,
2908 typename Traits::GPRRegister src, 2791 GPRRegister src, const Immediate &imm) {
2909 const Immediate &imm) {
2910 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2792 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2911 assert(Ty == IceType_i16 || Ty == IceType_i32); 2793 assert(Ty == IceType_i16 || Ty == IceType_i32);
2912 assert(imm.is_int8()); 2794 assert(imm.is_int8());
2913 if (Ty == IceType_i16) 2795 if (Ty == IceType_i16)
2914 emitOperandSizeOverride(); 2796 emitOperandSizeOverride();
2915 emitRexRB(Ty, src, dst); 2797 emitRexRB(Ty, src, dst);
2916 emitUint8(0x0F); 2798 emitUint8(0x0F);
2917 emitUint8(0xA4); 2799 emitUint8(0xA4);
2918 emitRegisterOperand(gprEncoding(src), gprEncoding(dst)); 2800 emitRegisterOperand(gprEncoding(src), gprEncoding(dst));
2919 emitUint8(imm.value() & 0xFF); 2801 emitUint8(imm.value() & 0xFF);
2920 } 2802 }
2921 2803
2922 template <class Machine> 2804 template <typename TraitsType>
2923 void AssemblerX86Base<Machine>::shld(Type Ty, 2805 void AssemblerX86Base<TraitsType>::shld(Type Ty, const Address &operand,
2924 const typename Traits::Address &operand, 2806 GPRRegister src) {
2925 typename Traits::GPRRegister src) {
2926 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2807 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2927 assert(Ty == IceType_i16 || Ty == IceType_i32); 2808 assert(Ty == IceType_i16 || Ty == IceType_i32);
2928 if (Ty == IceType_i16) 2809 if (Ty == IceType_i16)
2929 emitOperandSizeOverride(); 2810 emitOperandSizeOverride();
2930 emitAddrSizeOverridePrefix(); 2811 emitAddrSizeOverridePrefix();
2931 emitRex(Ty, operand, src); 2812 emitRex(Ty, operand, src);
2932 emitUint8(0x0F); 2813 emitUint8(0x0F);
2933 emitUint8(0xA5); 2814 emitUint8(0xA5);
2934 emitOperand(gprEncoding(src), operand); 2815 emitOperand(gprEncoding(src), operand);
2935 } 2816 }
2936 2817
2937 template <class Machine> 2818 template <typename TraitsType>
2938 void AssemblerX86Base<Machine>::shrd(Type Ty, typename Traits::GPRRegister dst, 2819 void AssemblerX86Base<TraitsType>::shrd(Type Ty, GPRRegister dst,
2939 typename Traits::GPRRegister src) { 2820 GPRRegister src) {
2940 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2821 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2941 assert(Ty == IceType_i16 || Ty == IceType_i32); 2822 assert(Ty == IceType_i16 || Ty == IceType_i32);
2942 if (Ty == IceType_i16) 2823 if (Ty == IceType_i16)
2943 emitOperandSizeOverride(); 2824 emitOperandSizeOverride();
2944 emitRexRB(Ty, src, dst); 2825 emitRexRB(Ty, src, dst);
2945 emitUint8(0x0F); 2826 emitUint8(0x0F);
2946 emitUint8(0xAD); 2827 emitUint8(0xAD);
2947 emitRegisterOperand(gprEncoding(src), gprEncoding(dst)); 2828 emitRegisterOperand(gprEncoding(src), gprEncoding(dst));
2948 } 2829 }
2949 2830
2950 template <class Machine> 2831 template <typename TraitsType>
2951 void AssemblerX86Base<Machine>::shrd(Type Ty, typename Traits::GPRRegister dst, 2832 void AssemblerX86Base<TraitsType>::shrd(Type Ty, GPRRegister dst,
2952 typename Traits::GPRRegister src, 2833 GPRRegister src, const Immediate &imm) {
2953 const Immediate &imm) {
2954 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2834 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2955 assert(Ty == IceType_i16 || Ty == IceType_i32); 2835 assert(Ty == IceType_i16 || Ty == IceType_i32);
2956 assert(imm.is_int8()); 2836 assert(imm.is_int8());
2957 if (Ty == IceType_i16) 2837 if (Ty == IceType_i16)
2958 emitOperandSizeOverride(); 2838 emitOperandSizeOverride();
2959 emitRexRB(Ty, src, dst); 2839 emitRexRB(Ty, src, dst);
2960 emitUint8(0x0F); 2840 emitUint8(0x0F);
2961 emitUint8(0xAC); 2841 emitUint8(0xAC);
2962 emitRegisterOperand(gprEncoding(src), gprEncoding(dst)); 2842 emitRegisterOperand(gprEncoding(src), gprEncoding(dst));
2963 emitUint8(imm.value() & 0xFF); 2843 emitUint8(imm.value() & 0xFF);
2964 } 2844 }
2965 2845
2966 template <class Machine> 2846 template <typename TraitsType>
2967 void AssemblerX86Base<Machine>::shrd(Type Ty, 2847 void AssemblerX86Base<TraitsType>::shrd(Type Ty, const Address &dst,
2968 const typename Traits::Address &dst, 2848 GPRRegister src) {
2969 typename Traits::GPRRegister src) {
2970 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2849 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2971 assert(Ty == IceType_i16 || Ty == IceType_i32); 2850 assert(Ty == IceType_i16 || Ty == IceType_i32);
2972 if (Ty == IceType_i16) 2851 if (Ty == IceType_i16)
2973 emitOperandSizeOverride(); 2852 emitOperandSizeOverride();
2974 emitAddrSizeOverridePrefix(); 2853 emitAddrSizeOverridePrefix();
2975 emitRex(Ty, dst, src); 2854 emitRex(Ty, dst, src);
2976 emitUint8(0x0F); 2855 emitUint8(0x0F);
2977 emitUint8(0xAD); 2856 emitUint8(0xAD);
2978 emitOperand(gprEncoding(src), dst); 2857 emitOperand(gprEncoding(src), dst);
2979 } 2858 }
2980 2859
2981 template <class Machine> 2860 template <typename TraitsType>
2982 void AssemblerX86Base<Machine>::neg(Type Ty, typename Traits::GPRRegister reg) { 2861 void AssemblerX86Base<TraitsType>::neg(Type Ty, GPRRegister reg) {
2983 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2862 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2984 if (Ty == IceType_i16) 2863 if (Ty == IceType_i16)
2985 emitOperandSizeOverride(); 2864 emitOperandSizeOverride();
2986 emitRexB(Ty, reg); 2865 emitRexB(Ty, reg);
2987 if (isByteSizedArithType(Ty)) 2866 if (isByteSizedArithType(Ty))
2988 emitUint8(0xF6); 2867 emitUint8(0xF6);
2989 else 2868 else
2990 emitUint8(0xF7); 2869 emitUint8(0xF7);
2991 emitRegisterOperand(3, gprEncoding(reg)); 2870 emitRegisterOperand(3, gprEncoding(reg));
2992 } 2871 }
2993 2872
2994 template <class Machine> 2873 template <typename TraitsType>
2995 void AssemblerX86Base<Machine>::neg(Type Ty, 2874 void AssemblerX86Base<TraitsType>::neg(Type Ty, const Address &addr) {
2996 const typename Traits::Address &addr) {
2997 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2875 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2998 if (Ty == IceType_i16) 2876 if (Ty == IceType_i16)
2999 emitOperandSizeOverride(); 2877 emitOperandSizeOverride();
3000 emitAddrSizeOverridePrefix(); 2878 emitAddrSizeOverridePrefix();
3001 emitRex(Ty, addr, RexRegIrrelevant); 2879 emitRex(Ty, addr, RexRegIrrelevant);
3002 if (isByteSizedArithType(Ty)) 2880 if (isByteSizedArithType(Ty))
3003 emitUint8(0xF6); 2881 emitUint8(0xF6);
3004 else 2882 else
3005 emitUint8(0xF7); 2883 emitUint8(0xF7);
3006 emitOperand(3, addr); 2884 emitOperand(3, addr);
3007 } 2885 }
3008 2886
3009 template <class Machine> 2887 template <typename TraitsType>
3010 void AssemblerX86Base<Machine>::notl(typename Traits::GPRRegister reg) { 2888 void AssemblerX86Base<TraitsType>::notl(GPRRegister reg) {
3011 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2889 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3012 emitRexB(IceType_i32, reg); 2890 emitRexB(IceType_i32, reg);
3013 emitUint8(0xF7); 2891 emitUint8(0xF7);
3014 emitUint8(0xD0 | gprEncoding(reg)); 2892 emitUint8(0xD0 | gprEncoding(reg));
3015 } 2893 }
3016 2894
3017 template <class Machine> 2895 template <typename TraitsType>
3018 void AssemblerX86Base<Machine>::bswap(Type Ty, 2896 void AssemblerX86Base<TraitsType>::bswap(Type Ty, GPRRegister reg) {
3019 typename Traits::GPRRegister reg) {
3020 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2897 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3021 assert(Ty == IceType_i32 || (Traits::Is64Bit && Ty == IceType_i64)); 2898 assert(Ty == IceType_i32 || (Traits::Is64Bit && Ty == IceType_i64));
3022 emitRexB(Ty, reg); 2899 emitRexB(Ty, reg);
3023 emitUint8(0x0F); 2900 emitUint8(0x0F);
3024 emitUint8(0xC8 | gprEncoding(reg)); 2901 emitUint8(0xC8 | gprEncoding(reg));
3025 } 2902 }
3026 2903
3027 template <class Machine> 2904 template <typename TraitsType>
3028 void AssemblerX86Base<Machine>::bsf(Type Ty, typename Traits::GPRRegister dst, 2905 void AssemblerX86Base<TraitsType>::bsf(Type Ty, GPRRegister dst,
3029 typename Traits::GPRRegister src) { 2906 GPRRegister src) {
3030 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2907 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3031 assert(Ty == IceType_i16 || Ty == IceType_i32 || 2908 assert(Ty == IceType_i16 || Ty == IceType_i32 ||
3032 (Traits::Is64Bit && Ty == IceType_i64)); 2909 (Traits::Is64Bit && Ty == IceType_i64));
3033 if (Ty == IceType_i16) 2910 if (Ty == IceType_i16)
3034 emitOperandSizeOverride(); 2911 emitOperandSizeOverride();
3035 emitRexRB(Ty, dst, src); 2912 emitRexRB(Ty, dst, src);
3036 emitUint8(0x0F); 2913 emitUint8(0x0F);
3037 emitUint8(0xBC); 2914 emitUint8(0xBC);
3038 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); 2915 emitRegisterOperand(gprEncoding(dst), gprEncoding(src));
3039 } 2916 }
3040 2917
3041 template <class Machine> 2918 template <typename TraitsType>
3042 void AssemblerX86Base<Machine>::bsf(Type Ty, typename Traits::GPRRegister dst, 2919 void AssemblerX86Base<TraitsType>::bsf(Type Ty, GPRRegister dst,
3043 const typename Traits::Address &src) { 2920 const Address &src) {
3044 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2921 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3045 assert(Ty == IceType_i16 || Ty == IceType_i32 || 2922 assert(Ty == IceType_i16 || Ty == IceType_i32 ||
3046 (Traits::Is64Bit && Ty == IceType_i64)); 2923 (Traits::Is64Bit && Ty == IceType_i64));
3047 if (Ty == IceType_i16) 2924 if (Ty == IceType_i16)
3048 emitOperandSizeOverride(); 2925 emitOperandSizeOverride();
3049 emitAddrSizeOverridePrefix(); 2926 emitAddrSizeOverridePrefix();
3050 emitRex(Ty, src, dst); 2927 emitRex(Ty, src, dst);
3051 emitUint8(0x0F); 2928 emitUint8(0x0F);
3052 emitUint8(0xBC); 2929 emitUint8(0xBC);
3053 emitOperand(gprEncoding(dst), src); 2930 emitOperand(gprEncoding(dst), src);
3054 } 2931 }
3055 2932
3056 template <class Machine> 2933 template <typename TraitsType>
3057 void AssemblerX86Base<Machine>::bsr(Type Ty, typename Traits::GPRRegister dst, 2934 void AssemblerX86Base<TraitsType>::bsr(Type Ty, GPRRegister dst,
3058 typename Traits::GPRRegister src) { 2935 GPRRegister src) {
3059 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2936 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3060 assert(Ty == IceType_i16 || Ty == IceType_i32 || 2937 assert(Ty == IceType_i16 || Ty == IceType_i32 ||
3061 (Traits::Is64Bit && Ty == IceType_i64)); 2938 (Traits::Is64Bit && Ty == IceType_i64));
3062 if (Ty == IceType_i16) 2939 if (Ty == IceType_i16)
3063 emitOperandSizeOverride(); 2940 emitOperandSizeOverride();
3064 emitRexRB(Ty, dst, src); 2941 emitRexRB(Ty, dst, src);
3065 emitUint8(0x0F); 2942 emitUint8(0x0F);
3066 emitUint8(0xBD); 2943 emitUint8(0xBD);
3067 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); 2944 emitRegisterOperand(gprEncoding(dst), gprEncoding(src));
3068 } 2945 }
3069 2946
3070 template <class Machine> 2947 template <typename TraitsType>
3071 void AssemblerX86Base<Machine>::bsr(Type Ty, typename Traits::GPRRegister dst, 2948 void AssemblerX86Base<TraitsType>::bsr(Type Ty, GPRRegister dst,
3072 const typename Traits::Address &src) { 2949 const Address &src) {
3073 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2950 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3074 assert(Ty == IceType_i16 || Ty == IceType_i32 || 2951 assert(Ty == IceType_i16 || Ty == IceType_i32 ||
3075 (Traits::Is64Bit && Ty == IceType_i64)); 2952 (Traits::Is64Bit && Ty == IceType_i64));
3076 if (Ty == IceType_i16) 2953 if (Ty == IceType_i16)
3077 emitOperandSizeOverride(); 2954 emitOperandSizeOverride();
3078 emitAddrSizeOverridePrefix(); 2955 emitAddrSizeOverridePrefix();
3079 emitRex(Ty, src, dst); 2956 emitRex(Ty, src, dst);
3080 emitUint8(0x0F); 2957 emitUint8(0x0F);
3081 emitUint8(0xBD); 2958 emitUint8(0xBD);
3082 emitOperand(gprEncoding(dst), src); 2959 emitOperand(gprEncoding(dst), src);
3083 } 2960 }
3084 2961
3085 template <class Machine> 2962 template <typename TraitsType>
3086 void AssemblerX86Base<Machine>::bt(typename Traits::GPRRegister base, 2963 void AssemblerX86Base<TraitsType>::bt(GPRRegister base, GPRRegister offset) {
3087 typename Traits::GPRRegister offset) {
3088 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2964 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3089 emitRexRB(IceType_i32, offset, base); 2965 emitRexRB(IceType_i32, offset, base);
3090 emitUint8(0x0F); 2966 emitUint8(0x0F);
3091 emitUint8(0xA3); 2967 emitUint8(0xA3);
3092 emitRegisterOperand(gprEncoding(offset), gprEncoding(base)); 2968 emitRegisterOperand(gprEncoding(offset), gprEncoding(base));
3093 } 2969 }
3094 2970
3095 template <class Machine> void AssemblerX86Base<Machine>::ret() { 2971 template <typename TraitsType> void AssemblerX86Base<TraitsType>::ret() {
3096 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2972 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3097 emitUint8(0xC3); 2973 emitUint8(0xC3);
3098 } 2974 }
3099 2975
3100 template <class Machine> 2976 template <typename TraitsType>
3101 void AssemblerX86Base<Machine>::ret(const Immediate &imm) { 2977 void AssemblerX86Base<TraitsType>::ret(const Immediate &imm) {
3102 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2978 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3103 emitUint8(0xC2); 2979 emitUint8(0xC2);
3104 assert(imm.is_uint16()); 2980 assert(imm.is_uint16());
3105 emitUint8(imm.value() & 0xFF); 2981 emitUint8(imm.value() & 0xFF);
3106 emitUint8((imm.value() >> 8) & 0xFF); 2982 emitUint8((imm.value() >> 8) & 0xFF);
3107 } 2983 }
3108 2984
3109 template <class Machine> void AssemblerX86Base<Machine>::nop(int size) { 2985 template <typename TraitsType>
2986 void AssemblerX86Base<TraitsType>::nop(int size) {
3110 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2987 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3111 // There are nops up to size 15, but for now just provide up to size 8. 2988 // There are nops up to size 15, but for now just provide up to size 8.
3112 assert(0 < size && size <= MAX_NOP_SIZE); 2989 assert(0 < size && size <= MAX_NOP_SIZE);
3113 switch (size) { 2990 switch (size) {
3114 case 1: 2991 case 1:
3115 emitUint8(0x90); 2992 emitUint8(0x90);
3116 break; 2993 break;
3117 case 2: 2994 case 2:
3118 emitUint8(0x66); 2995 emitUint8(0x66);
3119 emitUint8(0x90); 2996 emitUint8(0x90);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3161 emitUint8(0x00); 3038 emitUint8(0x00);
3162 emitUint8(0x00); 3039 emitUint8(0x00);
3163 emitUint8(0x00); 3040 emitUint8(0x00);
3164 emitUint8(0x00); 3041 emitUint8(0x00);
3165 break; 3042 break;
3166 default: 3043 default:
3167 llvm_unreachable("Unimplemented"); 3044 llvm_unreachable("Unimplemented");
3168 } 3045 }
3169 } 3046 }
3170 3047
3171 template <class Machine> void AssemblerX86Base<Machine>::int3() { 3048 template <typename TraitsType> void AssemblerX86Base<TraitsType>::int3() {
3172 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3049 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3173 emitUint8(0xCC); 3050 emitUint8(0xCC);
3174 } 3051 }
3175 3052
3176 template <class Machine> void AssemblerX86Base<Machine>::hlt() { 3053 template <typename TraitsType> void AssemblerX86Base<TraitsType>::hlt() {
3177 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3054 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3178 emitUint8(0xF4); 3055 emitUint8(0xF4);
3179 } 3056 }
3180 3057
3181 template <class Machine> void AssemblerX86Base<Machine>::ud2() { 3058 template <typename TraitsType> void AssemblerX86Base<TraitsType>::ud2() {
3182 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3059 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3183 emitUint8(0x0F); 3060 emitUint8(0x0F);
3184 emitUint8(0x0B); 3061 emitUint8(0x0B);
3185 } 3062 }
3186 3063
3187 template <class Machine> 3064 template <typename TraitsType>
3188 void AssemblerX86Base<Machine>::j(typename Traits::Cond::BrCond condition, 3065 void AssemblerX86Base<TraitsType>::j(BrCond condition, Label *label,
3189 Label *label, bool near) { 3066 bool near) {
3190 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3067 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3191 if (label->isBound()) { 3068 if (label->isBound()) {
3192 static const int kShortSize = 2; 3069 static const int kShortSize = 2;
3193 static const int kLongSize = 6; 3070 static const int kLongSize = 6;
3194 intptr_t offset = label->getPosition() - Buffer.size(); 3071 intptr_t offset = label->getPosition() - Buffer.size();
3195 assert(offset <= 0); 3072 assert(offset <= 0);
3196 if (Utils::IsInt(8, offset - kShortSize)) { 3073 if (Utils::IsInt(8, offset - kShortSize)) {
3197 // TODO(stichnot): Here and in jmp(), we may need to be more 3074 // TODO(stichnot): Here and in jmp(), we may need to be more
3198 // conservative about the backward branch distance if the branch 3075 // conservative about the backward branch distance if the branch
3199 // instruction is within a bundle_lock sequence, because the 3076 // instruction is within a bundle_lock sequence, because the
(...skipping 11 matching lines...) Expand all
3211 } else if (near) { 3088 } else if (near) {
3212 emitUint8(0x70 + condition); 3089 emitUint8(0x70 + condition);
3213 emitNearLabelLink(label); 3090 emitNearLabelLink(label);
3214 } else { 3091 } else {
3215 emitUint8(0x0F); 3092 emitUint8(0x0F);
3216 emitUint8(0x80 + condition); 3093 emitUint8(0x80 + condition);
3217 emitLabelLink(label); 3094 emitLabelLink(label);
3218 } 3095 }
3219 } 3096 }
3220 3097
3221 template <class Machine> 3098 template <typename TraitsType>
3222 void AssemblerX86Base<Machine>::j(typename Traits::Cond::BrCond condition, 3099 void AssemblerX86Base<TraitsType>::j(BrCond condition,
3223 const ConstantRelocatable *label) { 3100 const ConstantRelocatable *label) {
3224 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3101 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3225 emitUint8(0x0F); 3102 emitUint8(0x0F);
3226 emitUint8(0x80 + condition); 3103 emitUint8(0x80 + condition);
3227 emitFixup(this->createFixup(Traits::PcRelFixup, label)); 3104 emitFixup(this->createFixup(Traits::PcRelFixup, label));
3228 emitInt32(-4); 3105 emitInt32(-4);
3229 } 3106 }
3230 3107
3231 template <class Machine> 3108 template <typename TraitsType>
3232 void AssemblerX86Base<Machine>::jmp(typename Traits::GPRRegister reg) { 3109 void AssemblerX86Base<TraitsType>::jmp(GPRRegister reg) {
3233 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3110 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3234 emitRexB(RexTypeIrrelevant, reg); 3111 emitRexB(RexTypeIrrelevant, reg);
3235 emitUint8(0xFF); 3112 emitUint8(0xFF);
3236 emitRegisterOperand(4, gprEncoding(reg)); 3113 emitRegisterOperand(4, gprEncoding(reg));
3237 } 3114 }
3238 3115
3239 template <class Machine> 3116 template <typename TraitsType>
3240 void AssemblerX86Base<Machine>::jmp(Label *label, bool near) { 3117 void AssemblerX86Base<TraitsType>::jmp(Label *label, bool near) {
3241 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3118 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3242 if (label->isBound()) { 3119 if (label->isBound()) {
3243 static const int kShortSize = 2; 3120 static const int kShortSize = 2;
3244 static const int kLongSize = 5; 3121 static const int kLongSize = 5;
3245 intptr_t offset = label->getPosition() - Buffer.size(); 3122 intptr_t offset = label->getPosition() - Buffer.size();
3246 assert(offset <= 0); 3123 assert(offset <= 0);
3247 if (Utils::IsInt(8, offset - kShortSize)) { 3124 if (Utils::IsInt(8, offset - kShortSize)) {
3248 emitUint8(0xEB); 3125 emitUint8(0xEB);
3249 emitUint8((offset - kShortSize) & 0xFF); 3126 emitUint8((offset - kShortSize) & 0xFF);
3250 } else { 3127 } else {
3251 emitUint8(0xE9); 3128 emitUint8(0xE9);
3252 emitInt32(offset - kLongSize); 3129 emitInt32(offset - kLongSize);
3253 } 3130 }
3254 } else if (near) { 3131 } else if (near) {
3255 emitUint8(0xEB); 3132 emitUint8(0xEB);
3256 emitNearLabelLink(label); 3133 emitNearLabelLink(label);
3257 } else { 3134 } else {
3258 emitUint8(0xE9); 3135 emitUint8(0xE9);
3259 emitLabelLink(label); 3136 emitLabelLink(label);
3260 } 3137 }
3261 } 3138 }
3262 3139
3263 template <class Machine> 3140 template <typename TraitsType>
3264 void AssemblerX86Base<Machine>::jmp(const ConstantRelocatable *label) { 3141 void AssemblerX86Base<TraitsType>::jmp(const ConstantRelocatable *label) {
3265 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3142 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3266 emitUint8(0xE9); 3143 emitUint8(0xE9);
3267 emitFixup(this->createFixup(Traits::PcRelFixup, label)); 3144 emitFixup(this->createFixup(Traits::PcRelFixup, label));
3268 emitInt32(-4); 3145 emitInt32(-4);
3269 } 3146 }
3270 3147
3271 template <class Machine> void AssemblerX86Base<Machine>::mfence() { 3148 template <typename TraitsType> void AssemblerX86Base<TraitsType>::mfence() {
3272 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3149 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3273 emitUint8(0x0F); 3150 emitUint8(0x0F);
3274 emitUint8(0xAE); 3151 emitUint8(0xAE);
3275 emitUint8(0xF0); 3152 emitUint8(0xF0);
3276 } 3153 }
3277 3154
3278 template <class Machine> void AssemblerX86Base<Machine>::lock() { 3155 template <typename TraitsType> void AssemblerX86Base<TraitsType>::lock() {
3279 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3156 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3280 emitUint8(0xF0); 3157 emitUint8(0xF0);
3281 } 3158 }
3282 3159
3283 template <class Machine> 3160 template <typename TraitsType>
3284 void AssemblerX86Base<Machine>::cmpxchg(Type Ty, 3161 void AssemblerX86Base<TraitsType>::cmpxchg(Type Ty, const Address &address,
3285 const typename Traits::Address &address, 3162 GPRRegister reg, bool Locked) {
3286 typename Traits::GPRRegister reg,
3287 bool Locked) {
3288 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3163 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3289 if (Ty == IceType_i16) 3164 if (Ty == IceType_i16)
3290 emitOperandSizeOverride(); 3165 emitOperandSizeOverride();
3291 if (Locked) 3166 if (Locked)
3292 emitUint8(0xF0); 3167 emitUint8(0xF0);
3293 emitAddrSizeOverridePrefix(); 3168 emitAddrSizeOverridePrefix();
3294 emitRex(Ty, address, reg); 3169 emitRex(Ty, address, reg);
3295 emitUint8(0x0F); 3170 emitUint8(0x0F);
3296 if (isByteSizedArithType(Ty)) 3171 if (isByteSizedArithType(Ty))
3297 emitUint8(0xB0); 3172 emitUint8(0xB0);
3298 else 3173 else
3299 emitUint8(0xB1); 3174 emitUint8(0xB1);
3300 emitOperand(gprEncoding(reg), address); 3175 emitOperand(gprEncoding(reg), address);
3301 } 3176 }
3302 3177
3303 template <class Machine> 3178 template <typename TraitsType>
3304 void AssemblerX86Base<Machine>::cmpxchg8b( 3179 void AssemblerX86Base<TraitsType>::cmpxchg8b(const Address &address,
3305 const typename Traits::Address &address, bool Locked) { 3180 bool Locked) {
3306 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3181 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3307 if (Locked) 3182 if (Locked)
3308 emitUint8(0xF0); 3183 emitUint8(0xF0);
3309 emitAddrSizeOverridePrefix(); 3184 emitAddrSizeOverridePrefix();
3310 emitRex(IceType_i32, address, RexRegIrrelevant); 3185 emitRex(IceType_i32, address, RexRegIrrelevant);
3311 emitUint8(0x0F); 3186 emitUint8(0x0F);
3312 emitUint8(0xC7); 3187 emitUint8(0xC7);
3313 emitOperand(1, address); 3188 emitOperand(1, address);
3314 } 3189 }
3315 3190
3316 template <class Machine> 3191 template <typename TraitsType>
3317 void AssemblerX86Base<Machine>::xadd(Type Ty, 3192 void AssemblerX86Base<TraitsType>::xadd(Type Ty, const Address &addr,
3318 const typename Traits::Address &addr, 3193 GPRRegister reg, bool Locked) {
3319 typename Traits::GPRRegister reg,
3320 bool Locked) {
3321 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3194 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3322 if (Ty == IceType_i16) 3195 if (Ty == IceType_i16)
3323 emitOperandSizeOverride(); 3196 emitOperandSizeOverride();
3324 if (Locked) 3197 if (Locked)
3325 emitUint8(0xF0); 3198 emitUint8(0xF0);
3326 emitAddrSizeOverridePrefix(); 3199 emitAddrSizeOverridePrefix();
3327 emitRex(Ty, addr, reg); 3200 emitRex(Ty, addr, reg);
3328 emitUint8(0x0F); 3201 emitUint8(0x0F);
3329 if (isByteSizedArithType(Ty)) 3202 if (isByteSizedArithType(Ty))
3330 emitUint8(0xC0); 3203 emitUint8(0xC0);
3331 else 3204 else
3332 emitUint8(0xC1); 3205 emitUint8(0xC1);
3333 emitOperand(gprEncoding(reg), addr); 3206 emitOperand(gprEncoding(reg), addr);
3334 } 3207 }
3335 3208
3336 template <class Machine> 3209 template <typename TraitsType>
3337 void AssemblerX86Base<Machine>::xchg(Type Ty, typename Traits::GPRRegister reg0, 3210 void AssemblerX86Base<TraitsType>::xchg(Type Ty, GPRRegister reg0,
3338 typename Traits::GPRRegister reg1) { 3211 GPRRegister reg1) {
3339 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3212 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3340 if (Ty == IceType_i16) 3213 if (Ty == IceType_i16)
3341 emitOperandSizeOverride(); 3214 emitOperandSizeOverride();
3342 // Use short form if either register is EAX. 3215 // Use short form if either register is EAX.
3343 if (reg0 == Traits::Encoded_Reg_Accumulator) { 3216 if (reg0 == Traits::Encoded_Reg_Accumulator) {
3344 emitRexB(Ty, reg1); 3217 emitRexB(Ty, reg1);
3345 emitUint8(0x90 + gprEncoding(reg1)); 3218 emitUint8(0x90 + gprEncoding(reg1));
3346 } else if (reg1 == Traits::Encoded_Reg_Accumulator) { 3219 } else if (reg1 == Traits::Encoded_Reg_Accumulator) {
3347 emitRexB(Ty, reg0); 3220 emitRexB(Ty, reg0);
3348 emitUint8(0x90 + gprEncoding(reg0)); 3221 emitUint8(0x90 + gprEncoding(reg0));
3349 } else { 3222 } else {
3350 emitRexRB(Ty, reg0, reg1); 3223 emitRexRB(Ty, reg0, reg1);
3351 if (isByteSizedArithType(Ty)) 3224 if (isByteSizedArithType(Ty))
3352 emitUint8(0x86); 3225 emitUint8(0x86);
3353 else 3226 else
3354 emitUint8(0x87); 3227 emitUint8(0x87);
3355 emitRegisterOperand(gprEncoding(reg0), gprEncoding(reg1)); 3228 emitRegisterOperand(gprEncoding(reg0), gprEncoding(reg1));
3356 } 3229 }
3357 } 3230 }
3358 3231
3359 template <class Machine> 3232 template <typename TraitsType>
3360 void AssemblerX86Base<Machine>::xchg(Type Ty, 3233 void AssemblerX86Base<TraitsType>::xchg(Type Ty, const Address &addr,
3361 const typename Traits::Address &addr, 3234 GPRRegister reg) {
3362 typename Traits::GPRRegister reg) {
3363 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3235 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3364 if (Ty == IceType_i16) 3236 if (Ty == IceType_i16)
3365 emitOperandSizeOverride(); 3237 emitOperandSizeOverride();
3366 emitAddrSizeOverridePrefix(); 3238 emitAddrSizeOverridePrefix();
3367 emitRex(Ty, addr, reg); 3239 emitRex(Ty, addr, reg);
3368 if (isByteSizedArithType(Ty)) 3240 if (isByteSizedArithType(Ty))
3369 emitUint8(0x86); 3241 emitUint8(0x86);
3370 else 3242 else
3371 emitUint8(0x87); 3243 emitUint8(0x87);
3372 emitOperand(gprEncoding(reg), addr); 3244 emitOperand(gprEncoding(reg), addr);
3373 } 3245 }
3374 3246
3375 template <class Machine> void AssemblerX86Base<Machine>::iaca_start() { 3247 template <typename TraitsType> void AssemblerX86Base<TraitsType>::iaca_start() {
3376 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3248 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3377 emitUint8(0x0F); 3249 emitUint8(0x0F);
3378 emitUint8(0x0B); 3250 emitUint8(0x0B);
3379 3251
3380 // mov $111, ebx 3252 // mov $111, ebx
3381 constexpr typename Traits::GPRRegister dst = 3253 constexpr GPRRegister dst = Traits::GPRRegister::Encoded_Reg_ebx;
3382 Traits::GPRRegister::Encoded_Reg_ebx;
3383 constexpr Type Ty = IceType_i32; 3254 constexpr Type Ty = IceType_i32;
3384 emitRexB(Ty, dst); 3255 emitRexB(Ty, dst);
3385 emitUint8(0xB8 + gprEncoding(dst)); 3256 emitUint8(0xB8 + gprEncoding(dst));
3386 emitImmediate(Ty, Immediate(111)); 3257 emitImmediate(Ty, Immediate(111));
3387 3258
3388 emitUint8(0x64); 3259 emitUint8(0x64);
3389 emitUint8(0x67); 3260 emitUint8(0x67);
3390 emitUint8(0x90); 3261 emitUint8(0x90);
3391 } 3262 }
3392 3263
3393 template <class Machine> void AssemblerX86Base<Machine>::iaca_end() { 3264 template <typename TraitsType> void AssemblerX86Base<TraitsType>::iaca_end() {
3394 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3265 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3395 3266
3396 // mov $222, ebx 3267 // mov $222, ebx
3397 constexpr typename Traits::GPRRegister dst = 3268 constexpr GPRRegister dst = Traits::GPRRegister::Encoded_Reg_ebx;
3398 Traits::GPRRegister::Encoded_Reg_ebx;
3399 constexpr Type Ty = IceType_i32; 3269 constexpr Type Ty = IceType_i32;
3400 emitRexB(Ty, dst); 3270 emitRexB(Ty, dst);
3401 emitUint8(0xB8 + gprEncoding(dst)); 3271 emitUint8(0xB8 + gprEncoding(dst));
3402 emitImmediate(Ty, Immediate(222)); 3272 emitImmediate(Ty, Immediate(222));
3403 3273
3404 emitUint8(0x64); 3274 emitUint8(0x64);
3405 emitUint8(0x67); 3275 emitUint8(0x67);
3406 emitUint8(0x90); 3276 emitUint8(0x90);
3407 3277
3408 emitUint8(0x0F); 3278 emitUint8(0x0F);
3409 emitUint8(0x0B); 3279 emitUint8(0x0B);
3410 } 3280 }
3411 3281
3412 template <class Machine> 3282 template <typename TraitsType>
3413 void AssemblerX86Base<Machine>::emitSegmentOverride(uint8_t prefix) { 3283 void AssemblerX86Base<TraitsType>::emitSegmentOverride(uint8_t prefix) {
3414 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3284 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3415 emitUint8(prefix); 3285 emitUint8(prefix);
3416 } 3286 }
3417 3287
3418 template <class Machine> 3288 template <typename TraitsType>
3419 void AssemblerX86Base<Machine>::align(intptr_t alignment, intptr_t offset) { 3289 void AssemblerX86Base<TraitsType>::align(intptr_t alignment, intptr_t offset) {
3420 assert(llvm::isPowerOf2_32(alignment)); 3290 assert(llvm::isPowerOf2_32(alignment));
3421 intptr_t pos = offset + Buffer.getPosition(); 3291 intptr_t pos = offset + Buffer.getPosition();
3422 intptr_t mod = pos & (alignment - 1); 3292 intptr_t mod = pos & (alignment - 1);
3423 if (mod == 0) { 3293 if (mod == 0) {
3424 return; 3294 return;
3425 } 3295 }
3426 intptr_t bytes_needed = alignment - mod; 3296 intptr_t bytes_needed = alignment - mod;
3427 while (bytes_needed > MAX_NOP_SIZE) { 3297 while (bytes_needed > MAX_NOP_SIZE) {
3428 nop(MAX_NOP_SIZE); 3298 nop(MAX_NOP_SIZE);
3429 bytes_needed -= MAX_NOP_SIZE; 3299 bytes_needed -= MAX_NOP_SIZE;
3430 } 3300 }
3431 if (bytes_needed) { 3301 if (bytes_needed) {
3432 nop(bytes_needed); 3302 nop(bytes_needed);
3433 } 3303 }
3434 assert(((offset + Buffer.getPosition()) & (alignment - 1)) == 0); 3304 assert(((offset + Buffer.getPosition()) & (alignment - 1)) == 0);
3435 } 3305 }
3436 3306
3437 template <class Machine> void AssemblerX86Base<Machine>::bind(Label *label) { 3307 template <typename TraitsType>
3308 void AssemblerX86Base<TraitsType>::bind(Label *label) {
3438 intptr_t bound = Buffer.size(); 3309 intptr_t bound = Buffer.size();
3439 assert(!label->isBound()); // Labels can only be bound once. 3310 assert(!label->isBound()); // Labels can only be bound once.
3440 while (label->isLinked()) { 3311 while (label->isLinked()) {
3441 intptr_t position = label->getLinkPosition(); 3312 intptr_t position = label->getLinkPosition();
3442 intptr_t next = Buffer.load<int32_t>(position); 3313 intptr_t next = Buffer.load<int32_t>(position);
3443 Buffer.store<int32_t>(position, bound - (position + 4)); 3314 Buffer.store<int32_t>(position, bound - (position + 4));
3444 label->Position = next; 3315 label->Position = next;
3445 } 3316 }
3446 while (label->hasNear()) { 3317 while (label->hasNear()) {
3447 intptr_t position = label->getNearPosition(); 3318 intptr_t position = label->getNearPosition();
3448 intptr_t offset = bound - (position + 1); 3319 intptr_t offset = bound - (position + 1);
3449 assert(Utils::IsInt(8, offset)); 3320 assert(Utils::IsInt(8, offset));
3450 Buffer.store<int8_t>(position, offset); 3321 Buffer.store<int8_t>(position, offset);
3451 } 3322 }
3452 label->bindTo(bound); 3323 label->bindTo(bound);
3453 } 3324 }
3454 3325
3455 template <class Machine> 3326 template <typename TraitsType>
3456 void AssemblerX86Base<Machine>::emitOperand( 3327 void AssemblerX86Base<TraitsType>::emitOperand(int rm, const Operand &operand) {
3457 int rm, const typename Traits::Operand &operand) {
3458 assert(rm >= 0 && rm < 8); 3328 assert(rm >= 0 && rm < 8);
3459 const intptr_t length = operand.length_; 3329 const intptr_t length = operand.length_;
3460 assert(length > 0); 3330 assert(length > 0);
3461 intptr_t displacement_start = 1; 3331 intptr_t displacement_start = 1;
3462 // Emit the ModRM byte updated with the given RM value. 3332 // Emit the ModRM byte updated with the given RM value.
3463 assert((operand.encoding_[0] & 0x38) == 0); 3333 assert((operand.encoding_[0] & 0x38) == 0);
3464 emitUint8(operand.encoding_[0] + (rm << 3)); 3334 emitUint8(operand.encoding_[0] + (rm << 3));
3465 // Whenever the addressing mode is not register indirect, using esp == 0x4 3335 // Whenever the addressing mode is not register indirect, using esp == 0x4
3466 // as the register operation indicates an SIB byte follows. 3336 // as the register operation indicates an SIB byte follows.
3467 if (((operand.encoding_[0] & 0xc0) != 0xc0) && 3337 if (((operand.encoding_[0] & 0xc0) != 0xc0) &&
3468 ((operand.encoding_[0] & 0x07) == 0x04)) { 3338 ((operand.encoding_[0] & 0x07) == 0x04)) {
3469 emitUint8(operand.encoding_[1]); 3339 emitUint8(operand.encoding_[1]);
3470 displacement_start = 2; 3340 displacement_start = 2;
3471 } 3341 }
3472 // Emit the displacement and the fixup that affects it, if any. 3342 // Emit the displacement and the fixup that affects it, if any.
3473 if (operand.fixup()) { 3343 if (operand.fixup()) {
3474 emitFixup(operand.fixup()); 3344 emitFixup(operand.fixup());
3475 assert(length - displacement_start == 4); 3345 assert(length - displacement_start == 4);
3476 } 3346 }
3477 for (intptr_t i = displacement_start; i < length; i++) { 3347 for (intptr_t i = displacement_start; i < length; i++) {
3478 emitUint8(operand.encoding_[i]); 3348 emitUint8(operand.encoding_[i]);
3479 } 3349 }
3480 } 3350 }
3481 3351
3482 template <class Machine> 3352 template <typename TraitsType>
3483 void AssemblerX86Base<Machine>::emitImmediate(Type Ty, const Immediate &imm) { 3353 void AssemblerX86Base<TraitsType>::emitImmediate(Type Ty,
3354 const Immediate &imm) {
3484 if (Ty == IceType_i16) { 3355 if (Ty == IceType_i16) {
3485 assert(!imm.fixup()); 3356 assert(!imm.fixup());
3486 emitInt16(imm.value()); 3357 emitInt16(imm.value());
3487 } else { 3358 } else {
3488 if (imm.fixup()) { 3359 if (imm.fixup()) {
3489 emitFixup(imm.fixup()); 3360 emitFixup(imm.fixup());
3490 } 3361 }
3491 emitInt32(imm.value()); 3362 emitInt32(imm.value());
3492 } 3363 }
3493 } 3364 }
3494 3365
3495 template <class Machine> 3366 template <typename TraitsType>
3496 void AssemblerX86Base<Machine>::emitComplexI8( 3367 void AssemblerX86Base<TraitsType>::emitComplexI8(int rm, const Operand &operand,
3497 int rm, const typename Traits::Operand &operand, 3368 const Immediate &immediate) {
3498 const Immediate &immediate) {
3499 assert(rm >= 0 && rm < 8); 3369 assert(rm >= 0 && rm < 8);
3500 assert(immediate.is_int8()); 3370 assert(immediate.is_int8());
3501 if (operand.IsRegister(Traits::Encoded_Reg_Accumulator)) { 3371 if (operand.IsRegister(Traits::Encoded_Reg_Accumulator)) {
3502 // Use short form if the destination is al. 3372 // Use short form if the destination is al.
3503 emitUint8(0x04 + (rm << 3)); 3373 emitUint8(0x04 + (rm << 3));
3504 emitUint8(immediate.value() & 0xFF); 3374 emitUint8(immediate.value() & 0xFF);
3505 } else { 3375 } else {
3506 // Use sign-extended 8-bit immediate. 3376 // Use sign-extended 8-bit immediate.
3507 emitUint8(0x80); 3377 emitUint8(0x80);
3508 emitOperand(rm, operand); 3378 emitOperand(rm, operand);
3509 emitUint8(immediate.value() & 0xFF); 3379 emitUint8(immediate.value() & 0xFF);
3510 } 3380 }
3511 } 3381 }
3512 3382
3513 template <class Machine> 3383 template <typename TraitsType>
3514 void AssemblerX86Base<Machine>::emitComplex( 3384 void AssemblerX86Base<TraitsType>::emitComplex(Type Ty, int rm,
3515 Type Ty, int rm, const typename Traits::Operand &operand, 3385 const Operand &operand,
3516 const Immediate &immediate) { 3386 const Immediate &immediate) {
3517 assert(rm >= 0 && rm < 8); 3387 assert(rm >= 0 && rm < 8);
3518 if (immediate.is_int8()) { 3388 if (immediate.is_int8()) {
3519 // Use sign-extended 8-bit immediate. 3389 // Use sign-extended 8-bit immediate.
3520 emitUint8(0x83); 3390 emitUint8(0x83);
3521 emitOperand(rm, operand); 3391 emitOperand(rm, operand);
3522 emitUint8(immediate.value() & 0xFF); 3392 emitUint8(immediate.value() & 0xFF);
3523 } else if (operand.IsRegister(Traits::Encoded_Reg_Accumulator)) { 3393 } else if (operand.IsRegister(Traits::Encoded_Reg_Accumulator)) {
3524 // Use short form if the destination is eax. 3394 // Use short form if the destination is eax.
3525 emitUint8(0x05 + (rm << 3)); 3395 emitUint8(0x05 + (rm << 3));
3526 emitImmediate(Ty, immediate); 3396 emitImmediate(Ty, immediate);
3527 } else { 3397 } else {
3528 emitUint8(0x81); 3398 emitUint8(0x81);
3529 emitOperand(rm, operand); 3399 emitOperand(rm, operand);
3530 emitImmediate(Ty, immediate); 3400 emitImmediate(Ty, immediate);
3531 } 3401 }
3532 } 3402 }
3533 3403
3534 template <class Machine> 3404 template <typename TraitsType>
3535 void AssemblerX86Base<Machine>::emitLabel(Label *label, 3405 void AssemblerX86Base<TraitsType>::emitLabel(Label *label,
3536 intptr_t instruction_size) { 3406 intptr_t instruction_size) {
3537 if (label->isBound()) { 3407 if (label->isBound()) {
3538 intptr_t offset = label->getPosition() - Buffer.size(); 3408 intptr_t offset = label->getPosition() - Buffer.size();
3539 assert(offset <= 0); 3409 assert(offset <= 0);
3540 emitInt32(offset - instruction_size); 3410 emitInt32(offset - instruction_size);
3541 } else { 3411 } else {
3542 emitLabelLink(label); 3412 emitLabelLink(label);
3543 } 3413 }
3544 } 3414 }
3545 3415
3546 template <class Machine> 3416 template <typename TraitsType>
3547 void AssemblerX86Base<Machine>::emitLabelLink(Label *Label) { 3417 void AssemblerX86Base<TraitsType>::emitLabelLink(Label *Label) {
3548 assert(!Label->isBound()); 3418 assert(!Label->isBound());
3549 intptr_t Position = Buffer.size(); 3419 intptr_t Position = Buffer.size();
3550 emitInt32(Label->Position); 3420 emitInt32(Label->Position);
3551 Label->linkTo(*this, Position); 3421 Label->linkTo(*this, Position);
3552 } 3422 }
3553 3423
3554 template <class Machine> 3424 template <typename TraitsType>
3555 void AssemblerX86Base<Machine>::emitNearLabelLink(Label *Label) { 3425 void AssemblerX86Base<TraitsType>::emitNearLabelLink(Label *Label) {
3556 assert(!Label->isBound()); 3426 assert(!Label->isBound());
3557 intptr_t Position = Buffer.size(); 3427 intptr_t Position = Buffer.size();
3558 emitUint8(0); 3428 emitUint8(0);
3559 Label->nearLinkTo(*this, Position); 3429 Label->nearLinkTo(*this, Position);
3560 } 3430 }
3561 3431
3562 template <class Machine> 3432 template <typename TraitsType>
3563 void AssemblerX86Base<Machine>::emitGenericShift( 3433 void AssemblerX86Base<TraitsType>::emitGenericShift(int rm, Type Ty,
3564 int rm, Type Ty, typename Traits::GPRRegister reg, const Immediate &imm) { 3434 GPRRegister reg,
3435 const Immediate &imm) {
3565 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3436 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3566 // We don't assert that imm fits into 8 bits; instead, it gets masked below. 3437 // We don't assert that imm fits into 8 bits; instead, it gets masked below.
3567 // Note that we don't mask it further (e.g. to 5 bits) because we want the 3438 // Note that we don't mask it further (e.g. to 5 bits) because we want the
3568 // same processor behavior regardless of whether it's an immediate (masked to 3439 // same processor behavior regardless of whether it's an immediate (masked to
3569 // 8 bits) or in register cl (essentially ecx masked to 8 bits). 3440 // 8 bits) or in register cl (essentially ecx masked to 8 bits).
3570 if (Ty == IceType_i16) 3441 if (Ty == IceType_i16)
3571 emitOperandSizeOverride(); 3442 emitOperandSizeOverride();
3572 emitRexB(Ty, reg); 3443 emitRexB(Ty, reg);
3573 if (imm.value() == 1) { 3444 if (imm.value() == 1) {
3574 emitUint8(isByteSizedArithType(Ty) ? 0xD0 : 0xD1); 3445 emitUint8(isByteSizedArithType(Ty) ? 0xD0 : 0xD1);
3575 emitOperand(rm, typename Traits::Operand(reg)); 3446 emitOperand(rm, Operand(reg));
3576 } else { 3447 } else {
3577 emitUint8(isByteSizedArithType(Ty) ? 0xC0 : 0xC1); 3448 emitUint8(isByteSizedArithType(Ty) ? 0xC0 : 0xC1);
3578 emitOperand(rm, typename Traits::Operand(reg)); 3449 emitOperand(rm, Operand(reg));
3579 emitUint8(imm.value() & 0xFF); 3450 emitUint8(imm.value() & 0xFF);
3580 } 3451 }
3581 } 3452 }
3582 3453
3583 template <class Machine> 3454 template <typename TraitsType>
3584 void AssemblerX86Base<Machine>::emitGenericShift( 3455 void AssemblerX86Base<TraitsType>::emitGenericShift(int rm, Type Ty,
3585 int rm, Type Ty, const typename Traits::Operand &operand, 3456 const Operand &operand,
3586 typename Traits::GPRRegister shifter) { 3457 GPRRegister shifter) {
3587 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3458 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3588 assert(shifter == Traits::Encoded_Reg_Counter); 3459 assert(shifter == Traits::Encoded_Reg_Counter);
3589 (void)shifter; 3460 (void)shifter;
3590 if (Ty == IceType_i16) 3461 if (Ty == IceType_i16)
3591 emitOperandSizeOverride(); 3462 emitOperandSizeOverride();
3592 emitRexB(Ty, operand.rm()); 3463 emitRexB(Ty, operand.rm());
3593 emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); 3464 emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3);
3594 emitOperand(rm, operand); 3465 emitOperand(rm, operand);
3595 } 3466 }
3596 3467
3597 } // end of namespace X86Internal 3468 } // end of namespace X86NAMESPACE
3598 } // end of namespace Ice 3469 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceAssemblerX86Base.h ('k') | src/IceInstARM32.h » ('j') | src/IceInstX86Base.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698