OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |