blob: 88ad7ef79aa03f60d58c3df20443797449d54175 [file] [log] [blame]
Jan Voungf76fd372014-10-16 15:39:22 -07001//===- subzero/src/assembler_ia32.cpp - Assembler for x86-32 -------------===//
Jan Voung8acded02014-09-22 18:02:25 -07002// 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
4// BSD-style license that can be found in the LICENSE file.
5//
6// Modified by the Subzero authors.
7//
Jan Voungf76fd372014-10-16 15:39:22 -07008//===----------------------------------------------------------------------===//
Jan Voung8acded02014-09-22 18:02:25 -07009//
10// The Subzero Code Generator
11//
12// This file is distributed under the University of Illinois Open Source
13// License. See LICENSE.TXT for details.
14//
15//===----------------------------------------------------------------------===//
16//
17// This file implements the Assembler class for x86-32.
18//
19//===----------------------------------------------------------------------===//
20
21#include "assembler_ia32.h"
22#include "IceCfg.h"
Jan Voung8acded02014-09-22 18:02:25 -070023#include "IceOperand.h"
24
25namespace Ice {
26namespace x86 {
27
Jan Voung1d62cf02015-01-09 14:57:32 -080028Address Address::ofConstPool(Assembler *Asm, const Constant *Imm) {
Jan Voungec270732015-01-12 17:00:22 -080029 AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Imm);
Jan Voungfe14fb82014-10-13 15:56:32 -070030 const RelocOffsetT Offset = 0;
Jan Voung1d62cf02015-01-09 14:57:32 -080031 return x86::Address::Absolute(Offset, Fixup);
Jan Voung8acded02014-09-22 18:02:25 -070032}
33
Jan Voung7e1e4852014-10-24 10:29:30 -070034AssemblerX86::~AssemblerX86() {
35#ifndef NDEBUG
36 for (const Label *Label : CfgNodeLabels) {
37 Label->FinalCheck();
38 }
39 for (const Label *Label : LocalLabels) {
40 Label->FinalCheck();
41 }
42#endif
43}
44
Jan Voung08c3bcd2014-12-01 17:55:16 -080045void AssemblerX86::alignFunction() {
46 intptr_t Pos = buffer_.GetPosition();
47 SizeT Align = 1 << getBundleAlignLog2Bytes();
48 intptr_t Mod = Pos & (Align - 1);
49 if (Mod == 0) {
50 return;
51 }
52 SizeT BytesNeeded = Align - Mod;
53 const SizeT HltSize = 1;
54 while (BytesNeeded > 0) {
55 hlt();
56 BytesNeeded -= HltSize;
57 }
58 assert((buffer_.GetPosition() & (Align - 1)) == 0);
59}
60
Jan Voung7e1e4852014-10-24 10:29:30 -070061Label *AssemblerX86::GetOrCreateLabel(SizeT Number, LabelVector &Labels) {
62 Label *L = nullptr;
63 if (Number == Labels.size()) {
64 L = new (this->Allocate<Label>()) Label();
65 Labels.push_back(L);
66 return L;
67 }
68 if (Number > Labels.size()) {
69 Labels.resize(Number + 1);
70 }
71 L = Labels[Number];
72 if (!L) {
73 L = new (this->Allocate<Label>()) Label();
74 Labels[Number] = L;
75 }
76 return L;
77}
78
79Label *AssemblerX86::GetOrCreateCfgNodeLabel(SizeT NodeNumber) {
80 return GetOrCreateLabel(NodeNumber, CfgNodeLabels);
81}
82
83Label *AssemblerX86::GetOrCreateLocalLabel(SizeT Number) {
84 return GetOrCreateLabel(Number, LocalLabels);
85}
86
87void AssemblerX86::BindCfgNodeLabel(SizeT NodeNumber) {
88 Label *L = GetOrCreateCfgNodeLabel(NodeNumber);
89 this->Bind(L);
90}
91
92void AssemblerX86::BindLocalLabel(SizeT Number) {
93 Label *L = GetOrCreateLocalLabel(Number);
94 this->Bind(L);
95}
96
Jan Voung8acded02014-09-22 18:02:25 -070097void AssemblerX86::call(GPRRegister reg) {
98 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
99 EmitUint8(0xFF);
100 EmitRegisterOperand(2, reg);
101}
102
103void AssemblerX86::call(const Address &address) {
104 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
105 EmitUint8(0xFF);
106 EmitOperand(2, address);
107}
108
Jan Voung8acded02014-09-22 18:02:25 -0700109void AssemblerX86::call(const ConstantRelocatable *label) {
110 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
111 intptr_t call_start = buffer_.GetPosition();
112 EmitUint8(0xE8);
Jan Voungec270732015-01-12 17:00:22 -0800113 EmitFixup(this->createFixup(llvm::ELF::R_386_PC32, label));
Jan Voung8acded02014-09-22 18:02:25 -0700114 EmitInt32(-4);
115 assert((buffer_.GetPosition() - call_start) == kCallExternalLabelSize);
Jim Stichnoth9c234e22014-10-01 09:28:21 -0700116 (void)call_start;
Jan Voung8acded02014-09-22 18:02:25 -0700117}
118
119void AssemblerX86::pushl(GPRRegister reg) {
120 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
121 EmitUint8(0x50 + reg);
122}
123
Jan Voung8acded02014-09-22 18:02:25 -0700124void AssemblerX86::popl(GPRRegister reg) {
125 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
126 EmitUint8(0x58 + reg);
127}
128
129void AssemblerX86::popl(const Address &address) {
130 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
131 EmitUint8(0x8F);
132 EmitOperand(0, address);
133}
134
135void AssemblerX86::pushal() {
136 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
137 EmitUint8(0x60);
138}
139
140void AssemblerX86::popal() {
141 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
142 EmitUint8(0x61);
143}
144
145void AssemblerX86::setcc(CondX86::BrCond condition, ByteRegister dst) {
146 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
147 EmitUint8(0x0F);
148 EmitUint8(0x90 + condition);
149 EmitUint8(0xC0 + dst);
150}
151
Jan Voungfe14fb82014-10-13 15:56:32 -0700152void AssemblerX86::mov(Type Ty, GPRRegister dst, const Immediate &imm) {
Jan Voung8acded02014-09-22 18:02:25 -0700153 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voungfe14fb82014-10-13 15:56:32 -0700154 if (isByteSizedType(Ty)) {
155 EmitUint8(0xB0 + dst);
156 EmitUint8(imm.value() & 0xFF);
157 return;
158 }
159 if (Ty == IceType_i16)
160 EmitOperandSizeOverride();
Jan Voung8acded02014-09-22 18:02:25 -0700161 EmitUint8(0xB8 + dst);
Jan Voungfe14fb82014-10-13 15:56:32 -0700162 EmitImmediate(Ty, imm);
Jan Voung8acded02014-09-22 18:02:25 -0700163}
164
Jan Voungfe14fb82014-10-13 15:56:32 -0700165void AssemblerX86::mov(Type Ty, GPRRegister dst, GPRRegister src) {
Jan Voung8acded02014-09-22 18:02:25 -0700166 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voungfe14fb82014-10-13 15:56:32 -0700167 if (Ty == IceType_i16)
168 EmitOperandSizeOverride();
169 if (isByteSizedType(Ty)) {
170 EmitUint8(0x88);
171 } else {
172 EmitUint8(0x89);
173 }
Jan Voung8acded02014-09-22 18:02:25 -0700174 EmitRegisterOperand(src, dst);
175}
176
Jan Voungfe14fb82014-10-13 15:56:32 -0700177void AssemblerX86::mov(Type Ty, GPRRegister dst, const Address &src) {
Jan Voung8acded02014-09-22 18:02:25 -0700178 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voungfe14fb82014-10-13 15:56:32 -0700179 if (Ty == IceType_i16)
180 EmitOperandSizeOverride();
181 if (isByteSizedType(Ty)) {
182 EmitUint8(0x8A);
183 } else {
184 EmitUint8(0x8B);
185 }
Jan Voung8acded02014-09-22 18:02:25 -0700186 EmitOperand(dst, src);
187}
188
Jan Voungfe14fb82014-10-13 15:56:32 -0700189void AssemblerX86::mov(Type Ty, const Address &dst, GPRRegister src) {
Jan Voung8acded02014-09-22 18:02:25 -0700190 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voungfe14fb82014-10-13 15:56:32 -0700191 if (Ty == IceType_i16)
192 EmitOperandSizeOverride();
193 if (isByteSizedType(Ty)) {
194 EmitUint8(0x88);
195 } else {
196 EmitUint8(0x89);
197 }
Jan Voung8acded02014-09-22 18:02:25 -0700198 EmitOperand(src, dst);
199}
200
Jan Voungfe14fb82014-10-13 15:56:32 -0700201void AssemblerX86::mov(Type Ty, const Address &dst, const Immediate &imm) {
Jan Voung8acded02014-09-22 18:02:25 -0700202 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voungfe14fb82014-10-13 15:56:32 -0700203 if (Ty == IceType_i16)
204 EmitOperandSizeOverride();
205 if (isByteSizedType(Ty)) {
206 EmitUint8(0xC6);
207 EmitOperand(0, dst);
208 EmitUint8(imm.value() & 0xFF);
209 } else {
210 EmitUint8(0xC7);
211 EmitOperand(0, dst);
212 EmitImmediate(Ty, imm);
213 }
Jan Voung8acded02014-09-22 18:02:25 -0700214}
215
Jan Voung39d4aca2014-10-15 15:16:54 -0700216void AssemblerX86::movzx(Type SrcTy, GPRRegister dst, GPRRegister src) {
Jan Voung8acded02014-09-22 18:02:25 -0700217 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung39d4aca2014-10-15 15:16:54 -0700218 bool ByteSized = isByteSizedType(SrcTy);
219 assert(ByteSized || SrcTy == IceType_i16);
Jan Voung8acded02014-09-22 18:02:25 -0700220 EmitUint8(0x0F);
Jan Voung39d4aca2014-10-15 15:16:54 -0700221 EmitUint8(ByteSized ? 0xB6 : 0xB7);
Jan Voung8acded02014-09-22 18:02:25 -0700222 EmitRegisterOperand(dst, src);
223}
224
Jan Voung39d4aca2014-10-15 15:16:54 -0700225void AssemblerX86::movzx(Type SrcTy, GPRRegister dst, const Address &src) {
Jan Voung8acded02014-09-22 18:02:25 -0700226 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung39d4aca2014-10-15 15:16:54 -0700227 bool ByteSized = isByteSizedType(SrcTy);
228 assert(ByteSized || SrcTy == IceType_i16);
Jan Voung8acded02014-09-22 18:02:25 -0700229 EmitUint8(0x0F);
Jan Voung39d4aca2014-10-15 15:16:54 -0700230 EmitUint8(ByteSized ? 0xB6 : 0xB7);
Jan Voung8acded02014-09-22 18:02:25 -0700231 EmitOperand(dst, src);
232}
233
Jan Voung39d4aca2014-10-15 15:16:54 -0700234void AssemblerX86::movsx(Type SrcTy, GPRRegister dst, GPRRegister src) {
Jan Voung8acded02014-09-22 18:02:25 -0700235 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung39d4aca2014-10-15 15:16:54 -0700236 bool ByteSized = isByteSizedType(SrcTy);
237 assert(ByteSized || SrcTy == IceType_i16);
Jan Voung8acded02014-09-22 18:02:25 -0700238 EmitUint8(0x0F);
Jan Voung39d4aca2014-10-15 15:16:54 -0700239 EmitUint8(ByteSized ? 0xBE : 0xBF);
Jan Voung8acded02014-09-22 18:02:25 -0700240 EmitRegisterOperand(dst, src);
241}
242
Jan Voung39d4aca2014-10-15 15:16:54 -0700243void AssemblerX86::movsx(Type SrcTy, GPRRegister dst, const Address &src) {
Jan Voung8acded02014-09-22 18:02:25 -0700244 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung39d4aca2014-10-15 15:16:54 -0700245 bool ByteSized = isByteSizedType(SrcTy);
246 assert(ByteSized || SrcTy == IceType_i16);
Jan Voung8acded02014-09-22 18:02:25 -0700247 EmitUint8(0x0F);
Jan Voung39d4aca2014-10-15 15:16:54 -0700248 EmitUint8(ByteSized ? 0xBE : 0xBF);
Jan Voung8acded02014-09-22 18:02:25 -0700249 EmitOperand(dst, src);
250}
251
Jan Voung3b43b892014-09-24 13:32:39 -0700252void AssemblerX86::lea(Type Ty, GPRRegister dst, const Address &src) {
Jan Voung8acded02014-09-22 18:02:25 -0700253 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung3b43b892014-09-24 13:32:39 -0700254 assert(Ty == IceType_i16 || Ty == IceType_i32);
255 if (Ty == IceType_i16)
256 EmitOperandSizeOverride();
Jan Voung8acded02014-09-22 18:02:25 -0700257 EmitUint8(0x8D);
258 EmitOperand(dst, src);
259}
260
261void AssemblerX86::cmov(CondX86::BrCond cond, GPRRegister dst,
262 GPRRegister src) {
263 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
264 EmitUint8(0x0F);
265 EmitUint8(0x40 + cond);
266 EmitRegisterOperand(dst, src);
267}
268
269void AssemblerX86::rep_movsb() {
270 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
271 EmitUint8(0xF3);
272 EmitUint8(0xA4);
273}
274
Jan Voung479e5632014-10-08 21:05:27 -0700275void AssemblerX86::movss(Type Ty, XmmRegister dst, const Address &src) {
Jan Voung8acded02014-09-22 18:02:25 -0700276 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung479e5632014-10-08 21:05:27 -0700277 EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
Jan Voung8acded02014-09-22 18:02:25 -0700278 EmitUint8(0x0F);
279 EmitUint8(0x10);
280 EmitOperand(dst, src);
281}
282
Jan Voung479e5632014-10-08 21:05:27 -0700283void AssemblerX86::movss(Type Ty, const Address &dst, XmmRegister src) {
Jan Voung8acded02014-09-22 18:02:25 -0700284 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung479e5632014-10-08 21:05:27 -0700285 EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
Jan Voung8acded02014-09-22 18:02:25 -0700286 EmitUint8(0x0F);
287 EmitUint8(0x11);
288 EmitOperand(src, dst);
289}
290
Jan Voung479e5632014-10-08 21:05:27 -0700291void AssemblerX86::movss(Type Ty, XmmRegister dst, XmmRegister src) {
Jan Voung8acded02014-09-22 18:02:25 -0700292 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung479e5632014-10-08 21:05:27 -0700293 EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
Jan Voung8acded02014-09-22 18:02:25 -0700294 EmitUint8(0x0F);
295 EmitUint8(0x11);
296 EmitXmmRegisterOperand(src, dst);
297}
298
299void AssemblerX86::movd(XmmRegister dst, GPRRegister src) {
300 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
301 EmitUint8(0x66);
302 EmitUint8(0x0F);
303 EmitUint8(0x6E);
Jan Voung3b43b892014-09-24 13:32:39 -0700304 EmitRegisterOperand(dst, src);
305}
306
307void AssemblerX86::movd(XmmRegister dst, const Address &src) {
308 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
309 EmitUint8(0x66);
310 EmitUint8(0x0F);
311 EmitUint8(0x6E);
312 EmitOperand(dst, src);
Jan Voung8acded02014-09-22 18:02:25 -0700313}
314
315void AssemblerX86::movd(GPRRegister dst, XmmRegister src) {
316 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
317 EmitUint8(0x66);
318 EmitUint8(0x0F);
319 EmitUint8(0x7E);
Jan Voung3b43b892014-09-24 13:32:39 -0700320 EmitRegisterOperand(src, dst);
321}
322
323void AssemblerX86::movd(const Address &dst, XmmRegister src) {
324 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
325 EmitUint8(0x66);
326 EmitUint8(0x0F);
327 EmitUint8(0x7E);
328 EmitOperand(src, dst);
Jan Voung8acded02014-09-22 18:02:25 -0700329}
330
Jan Vounge4dc61b2014-10-06 08:53:52 -0700331void AssemblerX86::movq(XmmRegister dst, XmmRegister src) {
332 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
333 EmitUint8(0xF3);
334 EmitUint8(0x0F);
335 EmitUint8(0x7E);
336 EmitRegisterOperand(dst, src);
337}
338
Jan Voung8acded02014-09-22 18:02:25 -0700339void AssemblerX86::movq(const Address &dst, XmmRegister src) {
340 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
341 EmitUint8(0x66);
342 EmitUint8(0x0F);
343 EmitUint8(0xD6);
Jan Vounge4dc61b2014-10-06 08:53:52 -0700344 EmitOperand(src, dst);
Jan Voung8acded02014-09-22 18:02:25 -0700345}
346
347void AssemblerX86::movq(XmmRegister dst, const Address &src) {
348 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
349 EmitUint8(0xF3);
350 EmitUint8(0x0F);
351 EmitUint8(0x7E);
Jan Vounge4dc61b2014-10-06 08:53:52 -0700352 EmitOperand(dst, src);
Jan Voung8acded02014-09-22 18:02:25 -0700353}
354
355void AssemblerX86::addss(Type Ty, XmmRegister dst, XmmRegister src) {
356 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung3a569182014-09-29 10:16:01 -0700357 EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
Jan Voung8acded02014-09-22 18:02:25 -0700358 EmitUint8(0x0F);
359 EmitUint8(0x58);
360 EmitXmmRegisterOperand(dst, src);
361}
362
363void AssemblerX86::addss(Type Ty, XmmRegister dst, const Address &src) {
364 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung3a569182014-09-29 10:16:01 -0700365 EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
Jan Voung8acded02014-09-22 18:02:25 -0700366 EmitUint8(0x0F);
367 EmitUint8(0x58);
368 EmitOperand(dst, src);
369}
370
371void AssemblerX86::subss(Type Ty, XmmRegister dst, XmmRegister src) {
372 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung3a569182014-09-29 10:16:01 -0700373 EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
Jan Voung8acded02014-09-22 18:02:25 -0700374 EmitUint8(0x0F);
375 EmitUint8(0x5C);
376 EmitXmmRegisterOperand(dst, src);
377}
378
379void AssemblerX86::subss(Type Ty, XmmRegister dst, const Address &src) {
380 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung3a569182014-09-29 10:16:01 -0700381 EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
Jan Voung8acded02014-09-22 18:02:25 -0700382 EmitUint8(0x0F);
383 EmitUint8(0x5C);
384 EmitOperand(dst, src);
385}
386
387void AssemblerX86::mulss(Type Ty, XmmRegister dst, XmmRegister src) {
388 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung3a569182014-09-29 10:16:01 -0700389 EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
Jan Voung8acded02014-09-22 18:02:25 -0700390 EmitUint8(0x0F);
391 EmitUint8(0x59);
392 EmitXmmRegisterOperand(dst, src);
393}
394
395void AssemblerX86::mulss(Type Ty, XmmRegister dst, const Address &src) {
396 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung3a569182014-09-29 10:16:01 -0700397 EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
Jan Voung8acded02014-09-22 18:02:25 -0700398 EmitUint8(0x0F);
399 EmitUint8(0x59);
400 EmitOperand(dst, src);
401}
402
403void AssemblerX86::divss(Type Ty, XmmRegister dst, XmmRegister src) {
404 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung3a569182014-09-29 10:16:01 -0700405 EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
Jan Voung8acded02014-09-22 18:02:25 -0700406 EmitUint8(0x0F);
407 EmitUint8(0x5E);
408 EmitXmmRegisterOperand(dst, src);
409}
410
411void AssemblerX86::divss(Type Ty, XmmRegister dst, const Address &src) {
412 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung3a569182014-09-29 10:16:01 -0700413 EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
Jan Voung8acded02014-09-22 18:02:25 -0700414 EmitUint8(0x0F);
415 EmitUint8(0x5E);
416 EmitOperand(dst, src);
417}
418
Jan Voung479e5632014-10-08 21:05:27 -0700419void AssemblerX86::fld(Type Ty, const Address &src) {
Jan Voung8acded02014-09-22 18:02:25 -0700420 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung479e5632014-10-08 21:05:27 -0700421 EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xD9 : 0xDD);
Jan Voung8acded02014-09-22 18:02:25 -0700422 EmitOperand(0, src);
423}
424
Jan Voung479e5632014-10-08 21:05:27 -0700425void AssemblerX86::fstp(Type Ty, const Address &dst) {
Jan Voung8acded02014-09-22 18:02:25 -0700426 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung479e5632014-10-08 21:05:27 -0700427 EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xD9 : 0xDD);
Jan Voung8acded02014-09-22 18:02:25 -0700428 EmitOperand(3, dst);
429}
430
Jan Voung479e5632014-10-08 21:05:27 -0700431void AssemblerX86::fstp(X87STRegister st) {
Jan Voung8acded02014-09-22 18:02:25 -0700432 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung479e5632014-10-08 21:05:27 -0700433 EmitUint8(0xDD);
434 EmitUint8(0xD8 + st);
Jan Voung8acded02014-09-22 18:02:25 -0700435}
436
437void AssemblerX86::movaps(XmmRegister dst, XmmRegister src) {
438 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
439 EmitUint8(0x0F);
440 EmitUint8(0x28);
441 EmitXmmRegisterOperand(dst, src);
442}
443
Jan Vounge4dc61b2014-10-06 08:53:52 -0700444void AssemblerX86::movups(XmmRegister dst, XmmRegister src) {
445 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
446 EmitUint8(0x0F);
447 EmitUint8(0x10);
448 EmitRegisterOperand(dst, src);
449}
450
Jan Voung8acded02014-09-22 18:02:25 -0700451void AssemblerX86::movups(XmmRegister dst, const Address &src) {
452 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
453 EmitUint8(0x0F);
454 EmitUint8(0x10);
455 EmitOperand(dst, src);
456}
457
458void AssemblerX86::movups(const Address &dst, XmmRegister src) {
459 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
460 EmitUint8(0x0F);
461 EmitUint8(0x11);
462 EmitOperand(src, dst);
463}
464
465void AssemblerX86::padd(Type Ty, XmmRegister dst, XmmRegister src) {
466 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
467 EmitUint8(0x66);
468 EmitUint8(0x0F);
Jan Voung3a569182014-09-29 10:16:01 -0700469 if (isByteSizedArithType(Ty)) {
Jan Voung8acded02014-09-22 18:02:25 -0700470 EmitUint8(0xFC);
471 } else if (Ty == IceType_i16) {
472 EmitUint8(0xFD);
473 } else {
474 EmitUint8(0xFE);
475 }
476 EmitXmmRegisterOperand(dst, src);
477}
478
479void AssemblerX86::padd(Type Ty, XmmRegister dst, const Address &src) {
480 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
481 EmitUint8(0x66);
482 EmitUint8(0x0F);
Jan Voung3a569182014-09-29 10:16:01 -0700483 if (isByteSizedArithType(Ty)) {
Jan Voung8acded02014-09-22 18:02:25 -0700484 EmitUint8(0xFC);
485 } else if (Ty == IceType_i16) {
486 EmitUint8(0xFD);
487 } else {
488 EmitUint8(0xFE);
489 }
490 EmitOperand(dst, src);
491}
492
493void AssemblerX86::pand(Type /* Ty */, XmmRegister dst, XmmRegister src) {
494 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
495 EmitUint8(0x66);
496 EmitUint8(0x0F);
497 EmitUint8(0xDB);
498 EmitXmmRegisterOperand(dst, src);
499}
500
501void AssemblerX86::pand(Type /* Ty */, XmmRegister dst, const Address &src) {
502 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
503 EmitUint8(0x66);
504 EmitUint8(0x0F);
505 EmitUint8(0xDB);
506 EmitOperand(dst, src);
507}
508
509void AssemblerX86::pandn(Type /* Ty */, XmmRegister dst, XmmRegister src) {
510 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
511 EmitUint8(0x66);
512 EmitUint8(0x0F);
513 EmitUint8(0xDF);
514 EmitXmmRegisterOperand(dst, src);
515}
516
517void AssemblerX86::pandn(Type /* Ty */, XmmRegister dst, const Address &src) {
518 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
519 EmitUint8(0x66);
520 EmitUint8(0x0F);
521 EmitUint8(0xDF);
522 EmitOperand(dst, src);
523}
524
Jan Voung8bcca042014-10-03 21:58:02 -0700525void AssemblerX86::pmull(Type Ty, XmmRegister dst, XmmRegister src) {
526 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
527 EmitUint8(0x66);
528 EmitUint8(0x0F);
529 if (Ty == IceType_i16) {
530 EmitUint8(0xD5);
531 } else {
532 assert(Ty == IceType_i32);
533 EmitUint8(0x38);
534 EmitUint8(0x40);
535 }
536 EmitXmmRegisterOperand(dst, src);
537}
538
539void AssemblerX86::pmull(Type Ty, XmmRegister dst, const Address &src) {
540 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
541 EmitUint8(0x66);
542 EmitUint8(0x0F);
543 if (Ty == IceType_i16) {
544 EmitUint8(0xD5);
545 } else {
546 assert(Ty == IceType_i32);
547 EmitUint8(0x38);
548 EmitUint8(0x40);
549 }
550 EmitOperand(dst, src);
551}
552
Jan Voung8acded02014-09-22 18:02:25 -0700553void AssemblerX86::pmuludq(Type /* Ty */, XmmRegister dst, XmmRegister src) {
554 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
555 EmitUint8(0x66);
556 EmitUint8(0x0F);
557 EmitUint8(0xF4);
558 EmitXmmRegisterOperand(dst, src);
559}
560
561void AssemblerX86::pmuludq(Type /* Ty */, XmmRegister dst, const Address &src) {
562 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
563 EmitUint8(0x66);
564 EmitUint8(0x0F);
565 EmitUint8(0xF4);
566 EmitOperand(dst, src);
567}
568
569void AssemblerX86::por(Type /* Ty */, XmmRegister dst, XmmRegister src) {
570 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
571 EmitUint8(0x66);
572 EmitUint8(0x0F);
573 EmitUint8(0xEB);
574 EmitXmmRegisterOperand(dst, src);
575}
576
577void AssemblerX86::por(Type /* Ty */, XmmRegister dst, const Address &src) {
578 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
579 EmitUint8(0x66);
580 EmitUint8(0x0F);
581 EmitUint8(0xEB);
582 EmitOperand(dst, src);
583}
584
585void AssemblerX86::psub(Type Ty, XmmRegister dst, XmmRegister src) {
586 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
587 EmitUint8(0x66);
588 EmitUint8(0x0F);
Jan Voung3a569182014-09-29 10:16:01 -0700589 if (isByteSizedArithType(Ty)) {
Jan Voung8acded02014-09-22 18:02:25 -0700590 EmitUint8(0xF8);
591 } else if (Ty == IceType_i16) {
592 EmitUint8(0xF9);
593 } else {
594 EmitUint8(0xFA);
595 }
596 EmitXmmRegisterOperand(dst, src);
597}
598
599void AssemblerX86::psub(Type Ty, XmmRegister dst, const Address &src) {
600 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
601 EmitUint8(0x66);
602 EmitUint8(0x0F);
Jan Voung3a569182014-09-29 10:16:01 -0700603 if (isByteSizedArithType(Ty)) {
Jan Voung8acded02014-09-22 18:02:25 -0700604 EmitUint8(0xF8);
605 } else if (Ty == IceType_i16) {
606 EmitUint8(0xF9);
607 } else {
608 EmitUint8(0xFA);
609 }
610 EmitOperand(dst, src);
611}
612
613void AssemblerX86::pxor(Type /* Ty */, XmmRegister dst, XmmRegister src) {
614 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
615 EmitUint8(0x66);
616 EmitUint8(0x0F);
617 EmitUint8(0xEF);
618 EmitXmmRegisterOperand(dst, src);
619}
620
621void AssemblerX86::pxor(Type /* Ty */, XmmRegister dst, const Address &src) {
622 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
623 EmitUint8(0x66);
624 EmitUint8(0x0F);
625 EmitUint8(0xEF);
626 EmitOperand(dst, src);
627}
628
Jan Voung8bcca042014-10-03 21:58:02 -0700629void AssemblerX86::psll(Type Ty, XmmRegister dst, XmmRegister src) {
630 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
631 EmitUint8(0x66);
632 EmitUint8(0x0F);
633 if (Ty == IceType_i16) {
634 EmitUint8(0xF1);
635 } else {
636 assert(Ty == IceType_i32);
637 EmitUint8(0xF2);
638 }
639 EmitXmmRegisterOperand(dst, src);
640}
641
642void AssemblerX86::psll(Type Ty, XmmRegister dst, const Address &src) {
643 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
644 EmitUint8(0x66);
645 EmitUint8(0x0F);
646 if (Ty == IceType_i16) {
647 EmitUint8(0xF1);
648 } else {
649 assert(Ty == IceType_i32);
650 EmitUint8(0xF2);
651 }
652 EmitOperand(dst, src);
653}
654
655void AssemblerX86::psll(Type Ty, XmmRegister dst, const Immediate &imm) {
656 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
657 assert(imm.is_int8());
658 EmitUint8(0x66);
659 EmitUint8(0x0F);
660 if (Ty == IceType_i16) {
661 EmitUint8(0x71);
662 } else {
663 assert(Ty == IceType_i32);
664 EmitUint8(0x72);
665 }
666 EmitRegisterOperand(6, dst);
667 EmitUint8(imm.value() & 0xFF);
668}
669
670void AssemblerX86::psra(Type Ty, XmmRegister dst, XmmRegister src) {
671 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
672 EmitUint8(0x66);
673 EmitUint8(0x0F);
674 if (Ty == IceType_i16) {
675 EmitUint8(0xE1);
676 } else {
677 assert(Ty == IceType_i32);
678 EmitUint8(0xE2);
679 }
680 EmitXmmRegisterOperand(dst, src);
681}
682
683void AssemblerX86::psra(Type Ty, XmmRegister dst, const Address &src) {
684 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
685 EmitUint8(0x66);
686 EmitUint8(0x0F);
687 if (Ty == IceType_i16) {
688 EmitUint8(0xE1);
689 } else {
690 assert(Ty == IceType_i32);
691 EmitUint8(0xE2);
692 }
693 EmitOperand(dst, src);
694}
695
696void AssemblerX86::psra(Type Ty, XmmRegister dst, const Immediate &imm) {
697 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
698 assert(imm.is_int8());
699 EmitUint8(0x66);
700 EmitUint8(0x0F);
701 if (Ty == IceType_i16) {
702 EmitUint8(0x71);
703 } else {
704 assert(Ty == IceType_i32);
705 EmitUint8(0x72);
706 }
707 EmitRegisterOperand(4, dst);
708 EmitUint8(imm.value() & 0xFF);
709}
710
Jan Voung8acded02014-09-22 18:02:25 -0700711// {add,sub,mul,div}ps are given a Ty parameter for consistency with
712// {add,sub,mul,div}ss. In the future, when the PNaCl ABI allows
713// addpd, etc., we can use the Ty parameter to decide on adding
714// a 0x66 prefix.
715void AssemblerX86::addps(Type /* Ty */, XmmRegister dst, XmmRegister src) {
716 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
717 EmitUint8(0x0F);
718 EmitUint8(0x58);
719 EmitXmmRegisterOperand(dst, src);
720}
721
722void AssemblerX86::addps(Type /* Ty */, XmmRegister dst, const Address &src) {
723 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
724 EmitUint8(0x0F);
725 EmitUint8(0x58);
726 EmitOperand(dst, src);
727}
728
729void AssemblerX86::subps(Type /* Ty */, XmmRegister dst, XmmRegister src) {
730 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
731 EmitUint8(0x0F);
732 EmitUint8(0x5C);
733 EmitXmmRegisterOperand(dst, src);
734}
735
736void AssemblerX86::subps(Type /* Ty */, XmmRegister dst, const Address &src) {
737 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
738 EmitUint8(0x0F);
739 EmitUint8(0x5C);
740 EmitOperand(dst, src);
741}
742
743void AssemblerX86::divps(Type /* Ty */, XmmRegister dst, XmmRegister src) {
744 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
745 EmitUint8(0x0F);
746 EmitUint8(0x5E);
747 EmitXmmRegisterOperand(dst, src);
748}
749
750void AssemblerX86::divps(Type /* Ty */, XmmRegister dst, const Address &src) {
751 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
752 EmitUint8(0x0F);
753 EmitUint8(0x5E);
754 EmitOperand(dst, src);
755}
756
757void AssemblerX86::mulps(Type /* Ty */, XmmRegister dst, XmmRegister src) {
758 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
759 EmitUint8(0x0F);
760 EmitUint8(0x59);
761 EmitXmmRegisterOperand(dst, src);
762}
763
764void AssemblerX86::mulps(Type /* Ty */, XmmRegister dst, const Address &src) {
765 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
766 EmitUint8(0x0F);
767 EmitUint8(0x59);
768 EmitOperand(dst, src);
769}
770
771void AssemblerX86::minps(XmmRegister dst, XmmRegister src) {
772 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
773 EmitUint8(0x0F);
774 EmitUint8(0x5D);
775 EmitXmmRegisterOperand(dst, src);
776}
777
778void AssemblerX86::maxps(XmmRegister dst, XmmRegister src) {
779 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
780 EmitUint8(0x0F);
781 EmitUint8(0x5F);
782 EmitXmmRegisterOperand(dst, src);
783}
784
785void AssemblerX86::andps(XmmRegister dst, XmmRegister src) {
786 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
787 EmitUint8(0x0F);
788 EmitUint8(0x54);
789 EmitXmmRegisterOperand(dst, src);
790}
791
792void AssemblerX86::andps(XmmRegister dst, const Address &src) {
793 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
794 EmitUint8(0x0F);
795 EmitUint8(0x54);
796 EmitOperand(dst, src);
797}
798
799void AssemblerX86::orps(XmmRegister dst, XmmRegister src) {
800 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
801 EmitUint8(0x0F);
802 EmitUint8(0x56);
803 EmitXmmRegisterOperand(dst, src);
804}
805
Jan Voungd026c442014-10-13 14:06:50 -0700806void AssemblerX86::blendvps(Type /* Ty */, XmmRegister dst, XmmRegister src) {
807 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
808 EmitUint8(0x66);
809 EmitUint8(0x0F);
810 EmitUint8(0x38);
811 EmitUint8(0x14);
812 EmitXmmRegisterOperand(dst, src);
813}
814
815void AssemblerX86::blendvps(Type /* Ty */, XmmRegister dst,
816 const Address &src) {
817 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
818 EmitUint8(0x66);
819 EmitUint8(0x0F);
820 EmitUint8(0x38);
821 EmitUint8(0x14);
822 EmitOperand(dst, src);
823}
824
825void AssemblerX86::pblendvb(Type /* Ty */, XmmRegister dst, XmmRegister src) {
826 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
827 EmitUint8(0x66);
828 EmitUint8(0x0F);
829 EmitUint8(0x38);
830 EmitUint8(0x10);
831 EmitXmmRegisterOperand(dst, src);
832}
833
834void AssemblerX86::pblendvb(Type /* Ty */, XmmRegister dst,
835 const Address &src) {
836 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
837 EmitUint8(0x66);
838 EmitUint8(0x0F);
839 EmitUint8(0x38);
840 EmitUint8(0x10);
841 EmitOperand(dst, src);
842}
843
Jan Voung8acded02014-09-22 18:02:25 -0700844void AssemblerX86::cmpps(XmmRegister dst, XmmRegister src,
845 CondX86::CmppsCond CmpCondition) {
846 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
847 EmitUint8(0x0F);
848 EmitUint8(0xC2);
849 EmitXmmRegisterOperand(dst, src);
850 EmitUint8(CmpCondition);
851}
852
853void AssemblerX86::cmpps(XmmRegister dst, const Address &src,
854 CondX86::CmppsCond CmpCondition) {
855 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
856 EmitUint8(0x0F);
857 EmitUint8(0xC2);
858 EmitOperand(dst, src);
859 EmitUint8(CmpCondition);
860}
861
862void AssemblerX86::sqrtps(XmmRegister dst) {
863 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
864 EmitUint8(0x0F);
865 EmitUint8(0x51);
866 EmitXmmRegisterOperand(dst, dst);
867}
868
869void AssemblerX86::rsqrtps(XmmRegister dst) {
870 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
871 EmitUint8(0x0F);
872 EmitUint8(0x52);
873 EmitXmmRegisterOperand(dst, dst);
874}
875
876void AssemblerX86::reciprocalps(XmmRegister dst) {
877 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
878 EmitUint8(0x0F);
879 EmitUint8(0x53);
880 EmitXmmRegisterOperand(dst, dst);
881}
882
883void AssemblerX86::movhlps(XmmRegister dst, XmmRegister src) {
884 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
885 EmitUint8(0x0F);
886 EmitUint8(0x12);
887 EmitXmmRegisterOperand(dst, src);
888}
889
890void AssemblerX86::movlhps(XmmRegister dst, XmmRegister src) {
891 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
892 EmitUint8(0x0F);
893 EmitUint8(0x16);
894 EmitXmmRegisterOperand(dst, src);
895}
896
897void AssemblerX86::unpcklps(XmmRegister dst, XmmRegister src) {
898 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
899 EmitUint8(0x0F);
900 EmitUint8(0x14);
901 EmitXmmRegisterOperand(dst, src);
902}
903
904void AssemblerX86::unpckhps(XmmRegister dst, XmmRegister src) {
905 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
906 EmitUint8(0x0F);
907 EmitUint8(0x15);
908 EmitXmmRegisterOperand(dst, src);
909}
910
911void AssemblerX86::unpcklpd(XmmRegister dst, XmmRegister src) {
912 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
913 EmitUint8(0x66);
914 EmitUint8(0x0F);
915 EmitUint8(0x14);
916 EmitXmmRegisterOperand(dst, src);
917}
918
919void AssemblerX86::unpckhpd(XmmRegister dst, XmmRegister src) {
920 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
921 EmitUint8(0x66);
922 EmitUint8(0x0F);
923 EmitUint8(0x15);
924 EmitXmmRegisterOperand(dst, src);
925}
926
927void AssemblerX86::set1ps(XmmRegister dst, GPRRegister tmp1,
928 const Immediate &imm) {
929 // Load 32-bit immediate value into tmp1.
Jan Voungfe14fb82014-10-13 15:56:32 -0700930 mov(IceType_i32, tmp1, imm);
Jan Voung8acded02014-09-22 18:02:25 -0700931 // Move value from tmp1 into dst.
932 movd(dst, tmp1);
933 // Broadcast low lane into other three lanes.
934 shufps(dst, dst, Immediate(0x0));
935}
936
937void AssemblerX86::shufps(XmmRegister dst, XmmRegister src,
938 const Immediate &imm) {
939 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
940 EmitUint8(0x0F);
941 EmitUint8(0xC6);
942 EmitXmmRegisterOperand(dst, src);
943 assert(imm.is_uint8());
944 EmitUint8(imm.value());
945}
946
Jan Voung962befa2014-10-15 09:32:58 -0700947void AssemblerX86::pshufd(Type /* Ty */, XmmRegister dst, XmmRegister src,
948 const Immediate &imm) {
949 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
950 EmitUint8(0x66);
951 EmitUint8(0x0F);
952 EmitUint8(0x70);
953 EmitXmmRegisterOperand(dst, src);
954 assert(imm.is_uint8());
955 EmitUint8(imm.value());
956}
957
958void AssemblerX86::pshufd(Type /* Ty */, XmmRegister dst, const Address &src,
959 const Immediate &imm) {
960 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
961 EmitUint8(0x66);
962 EmitUint8(0x0F);
963 EmitUint8(0x70);
964 EmitOperand(dst, src);
965 assert(imm.is_uint8());
966 EmitUint8(imm.value());
967}
968
969void AssemblerX86::shufps(Type /* Ty */, XmmRegister dst, XmmRegister src,
970 const Immediate &imm) {
971 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
972 EmitUint8(0x0F);
973 EmitUint8(0xC6);
974 EmitXmmRegisterOperand(dst, src);
975 assert(imm.is_uint8());
976 EmitUint8(imm.value());
977}
978
979void AssemblerX86::shufps(Type /* Ty */, XmmRegister dst, const Address &src,
980 const Immediate &imm) {
981 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
982 EmitUint8(0x0F);
983 EmitUint8(0xC6);
984 EmitOperand(dst, src);
985 assert(imm.is_uint8());
986 EmitUint8(imm.value());
987}
988
Jan Voung8acded02014-09-22 18:02:25 -0700989void AssemblerX86::minpd(XmmRegister dst, XmmRegister src) {
990 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
991 EmitUint8(0x66);
992 EmitUint8(0x0F);
993 EmitUint8(0x5D);
994 EmitXmmRegisterOperand(dst, src);
995}
996
997void AssemblerX86::maxpd(XmmRegister dst, XmmRegister src) {
998 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
999 EmitUint8(0x66);
1000 EmitUint8(0x0F);
1001 EmitUint8(0x5F);
1002 EmitXmmRegisterOperand(dst, src);
1003}
1004
1005void AssemblerX86::sqrtpd(XmmRegister dst) {
1006 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1007 EmitUint8(0x66);
1008 EmitUint8(0x0F);
1009 EmitUint8(0x51);
1010 EmitXmmRegisterOperand(dst, dst);
1011}
1012
Jan Voung8acded02014-09-22 18:02:25 -07001013void AssemblerX86::shufpd(XmmRegister dst, XmmRegister src,
1014 const Immediate &imm) {
1015 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1016 EmitUint8(0x66);
1017 EmitUint8(0x0F);
1018 EmitUint8(0xC6);
1019 EmitXmmRegisterOperand(dst, src);
1020 assert(imm.is_uint8());
1021 EmitUint8(imm.value());
1022}
1023
Jan Voung699bf022014-10-08 13:52:10 -07001024void AssemblerX86::cvtdq2ps(Type /* Ignore */, XmmRegister dst,
1025 XmmRegister src) {
Jan Voung8acded02014-09-22 18:02:25 -07001026 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung8acded02014-09-22 18:02:25 -07001027 EmitUint8(0x0F);
Jan Voung699bf022014-10-08 13:52:10 -07001028 EmitUint8(0x5B);
Jan Voung8acded02014-09-22 18:02:25 -07001029 EmitXmmRegisterOperand(dst, src);
1030}
1031
Jan Voung699bf022014-10-08 13:52:10 -07001032void AssemblerX86::cvtdq2ps(Type /* Ignore */, XmmRegister dst,
1033 const Address &src) {
1034 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1035 EmitUint8(0x0F);
1036 EmitUint8(0x5B);
1037 EmitOperand(dst, src);
1038}
1039
1040void AssemblerX86::cvttps2dq(Type /* Ignore */, XmmRegister dst,
1041 XmmRegister src) {
Jan Voung8acded02014-09-22 18:02:25 -07001042 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1043 EmitUint8(0xF3);
1044 EmitUint8(0x0F);
Jan Voung699bf022014-10-08 13:52:10 -07001045 EmitUint8(0x5B);
1046 EmitXmmRegisterOperand(dst, src);
1047}
1048
1049void AssemblerX86::cvttps2dq(Type /* Ignore */, XmmRegister dst,
1050 const Address &src) {
1051 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1052 EmitUint8(0xF3);
1053 EmitUint8(0x0F);
1054 EmitUint8(0x5B);
1055 EmitOperand(dst, src);
1056}
1057
1058void AssemblerX86::cvtsi2ss(Type DestTy, XmmRegister dst, GPRRegister src) {
1059 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1060 EmitUint8(isFloat32Asserting32Or64(DestTy) ? 0xF3 : 0xF2);
1061 EmitUint8(0x0F);
1062 EmitUint8(0x2A);
1063 EmitRegisterOperand(dst, src);
1064}
1065
1066void AssemblerX86::cvtsi2ss(Type DestTy, XmmRegister dst, const Address &src) {
1067 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1068 EmitUint8(isFloat32Asserting32Or64(DestTy) ? 0xF3 : 0xF2);
1069 EmitUint8(0x0F);
1070 EmitUint8(0x2A);
1071 EmitOperand(dst, src);
1072}
1073
1074void AssemblerX86::cvtfloat2float(Type SrcTy, XmmRegister dst,
1075 XmmRegister src) {
1076 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1077 // ss2sd or sd2ss
1078 EmitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
1079 EmitUint8(0x0F);
Jan Voung8acded02014-09-22 18:02:25 -07001080 EmitUint8(0x5A);
1081 EmitXmmRegisterOperand(dst, src);
1082}
1083
Jan Voung699bf022014-10-08 13:52:10 -07001084void AssemblerX86::cvtfloat2float(Type SrcTy, XmmRegister dst,
1085 const Address &src) {
Jan Voung8acded02014-09-22 18:02:25 -07001086 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung699bf022014-10-08 13:52:10 -07001087 EmitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
Jan Voung8acded02014-09-22 18:02:25 -07001088 EmitUint8(0x0F);
1089 EmitUint8(0x5A);
Jan Voung699bf022014-10-08 13:52:10 -07001090 EmitOperand(dst, src);
1091}
1092
1093void AssemblerX86::cvttss2si(Type SrcTy, GPRRegister dst, XmmRegister src) {
1094 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1095 EmitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
1096 EmitUint8(0x0F);
1097 EmitUint8(0x2C);
Jan Voung8acded02014-09-22 18:02:25 -07001098 EmitXmmRegisterOperand(dst, src);
1099}
1100
Jan Voung699bf022014-10-08 13:52:10 -07001101void AssemblerX86::cvttss2si(Type SrcTy, GPRRegister dst, const Address &src) {
Jan Voung8acded02014-09-22 18:02:25 -07001102 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung699bf022014-10-08 13:52:10 -07001103 EmitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
Jan Voung8acded02014-09-22 18:02:25 -07001104 EmitUint8(0x0F);
Jan Voung699bf022014-10-08 13:52:10 -07001105 EmitUint8(0x2C);
1106 EmitOperand(dst, src);
Jan Voung8acded02014-09-22 18:02:25 -07001107}
1108
1109void AssemblerX86::ucomiss(Type Ty, XmmRegister a, XmmRegister b) {
1110 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1111 if (Ty == IceType_f64)
1112 EmitUint8(0x66);
1113 EmitUint8(0x0F);
1114 EmitUint8(0x2E);
1115 EmitXmmRegisterOperand(a, b);
1116}
1117
1118void AssemblerX86::ucomiss(Type Ty, XmmRegister a, const Address &b) {
1119 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1120 if (Ty == IceType_f64)
1121 EmitUint8(0x66);
1122 EmitUint8(0x0F);
1123 EmitUint8(0x2E);
1124 EmitOperand(a, b);
1125}
1126
1127void AssemblerX86::movmskpd(GPRRegister dst, XmmRegister src) {
1128 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1129 EmitUint8(0x66);
1130 EmitUint8(0x0F);
1131 EmitUint8(0x50);
1132 EmitXmmRegisterOperand(dst, src);
1133}
1134
1135void AssemblerX86::movmskps(GPRRegister dst, XmmRegister src) {
1136 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1137 EmitUint8(0x0F);
1138 EmitUint8(0x50);
1139 EmitXmmRegisterOperand(dst, src);
1140}
1141
1142void AssemblerX86::sqrtss(Type Ty, XmmRegister dst, const Address &src) {
1143 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung3a569182014-09-29 10:16:01 -07001144 EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
Jan Voung8acded02014-09-22 18:02:25 -07001145 EmitUint8(0x0F);
1146 EmitUint8(0x51);
1147 EmitOperand(dst, src);
1148}
1149
1150void AssemblerX86::sqrtss(Type Ty, XmmRegister dst, XmmRegister src) {
1151 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung3a569182014-09-29 10:16:01 -07001152 EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
Jan Voung8acded02014-09-22 18:02:25 -07001153 EmitUint8(0x0F);
1154 EmitUint8(0x51);
1155 EmitXmmRegisterOperand(dst, src);
1156}
1157
1158void AssemblerX86::xorpd(XmmRegister dst, const Address &src) {
1159 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1160 EmitUint8(0x66);
1161 EmitUint8(0x0F);
1162 EmitUint8(0x57);
1163 EmitOperand(dst, src);
1164}
1165
1166void AssemblerX86::xorpd(XmmRegister dst, XmmRegister src) {
1167 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1168 EmitUint8(0x66);
1169 EmitUint8(0x0F);
1170 EmitUint8(0x57);
1171 EmitXmmRegisterOperand(dst, src);
1172}
1173
1174void AssemblerX86::orpd(XmmRegister dst, XmmRegister src) {
1175 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1176 EmitUint8(0x66);
1177 EmitUint8(0x0F);
1178 EmitUint8(0x56);
1179 EmitXmmRegisterOperand(dst, src);
1180}
1181
1182void AssemblerX86::xorps(XmmRegister dst, const Address &src) {
1183 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1184 EmitUint8(0x0F);
1185 EmitUint8(0x57);
1186 EmitOperand(dst, src);
1187}
1188
1189void AssemblerX86::xorps(XmmRegister dst, XmmRegister src) {
1190 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1191 EmitUint8(0x0F);
1192 EmitUint8(0x57);
1193 EmitXmmRegisterOperand(dst, src);
1194}
1195
1196void AssemblerX86::andpd(XmmRegister dst, const Address &src) {
1197 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1198 EmitUint8(0x66);
1199 EmitUint8(0x0F);
1200 EmitUint8(0x54);
1201 EmitOperand(dst, src);
1202}
1203
1204void AssemblerX86::andpd(XmmRegister dst, XmmRegister src) {
1205 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1206 EmitUint8(0x66);
1207 EmitUint8(0x0F);
1208 EmitUint8(0x54);
1209 EmitXmmRegisterOperand(dst, src);
1210}
1211
Jan Voung962befa2014-10-15 09:32:58 -07001212void AssemblerX86::insertps(Type Ty, XmmRegister dst, XmmRegister src,
1213 const Immediate &imm) {
Jan Voung8acded02014-09-22 18:02:25 -07001214 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung962befa2014-10-15 09:32:58 -07001215 assert(imm.is_uint8());
1216 assert(isVectorFloatingType(Ty));
1217 (void)Ty;
Jan Voung8acded02014-09-22 18:02:25 -07001218 EmitUint8(0x66);
1219 EmitUint8(0x0F);
1220 EmitUint8(0x3A);
Jan Voung962befa2014-10-15 09:32:58 -07001221 EmitUint8(0x21);
1222 EmitXmmRegisterOperand(dst, src);
Jan Voung8acded02014-09-22 18:02:25 -07001223 EmitUint8(imm.value());
1224}
1225
Jan Voung962befa2014-10-15 09:32:58 -07001226void AssemblerX86::insertps(Type Ty, XmmRegister dst, const Address &src,
1227 const Immediate &imm) {
1228 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1229 assert(imm.is_uint8());
1230 assert(isVectorFloatingType(Ty));
1231 (void)Ty;
1232 EmitUint8(0x66);
1233 EmitUint8(0x0F);
1234 EmitUint8(0x3A);
1235 EmitUint8(0x21);
1236 EmitOperand(dst, src);
1237 EmitUint8(imm.value());
1238}
1239
1240void AssemblerX86::pinsr(Type Ty, XmmRegister dst, GPRRegister src,
1241 const Immediate &imm) {
1242 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1243 assert(imm.is_uint8());
1244 if (Ty == IceType_i16) {
1245 EmitUint8(0x66);
1246 EmitUint8(0x0F);
1247 EmitUint8(0xC4);
1248 EmitXmmRegisterOperand(dst, XmmRegister(src));
1249 EmitUint8(imm.value());
1250 } else {
1251 EmitUint8(0x66);
1252 EmitUint8(0x0F);
1253 EmitUint8(0x3A);
1254 EmitUint8(isByteSizedType(Ty) ? 0x20 : 0x22);
1255 EmitXmmRegisterOperand(dst, XmmRegister(src));
1256 EmitUint8(imm.value());
1257 }
1258}
1259
1260void AssemblerX86::pinsr(Type Ty, XmmRegister dst, const Address &src,
1261 const Immediate &imm) {
1262 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1263 assert(imm.is_uint8());
1264 if (Ty == IceType_i16) {
1265 EmitUint8(0x66);
1266 EmitUint8(0x0F);
1267 EmitUint8(0xC4);
1268 EmitOperand(dst, src);
1269 EmitUint8(imm.value());
1270 } else {
1271 EmitUint8(0x66);
1272 EmitUint8(0x0F);
1273 EmitUint8(0x3A);
1274 EmitUint8(isByteSizedType(Ty) ? 0x20 : 0x22);
1275 EmitOperand(dst, src);
1276 EmitUint8(imm.value());
1277 }
1278}
1279
1280void AssemblerX86::pextr(Type Ty, GPRRegister dst, XmmRegister src,
1281 const Immediate &imm) {
1282 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1283 assert(imm.is_uint8());
1284 if (Ty == IceType_i16) {
1285 EmitUint8(0x66);
1286 EmitUint8(0x0F);
1287 EmitUint8(0xC5);
1288 EmitXmmRegisterOperand(XmmRegister(dst), src);
1289 EmitUint8(imm.value());
1290 } else {
1291 EmitUint8(0x66);
1292 EmitUint8(0x0F);
1293 EmitUint8(0x3A);
1294 EmitUint8(isByteSizedType(Ty) ? 0x14 : 0x16);
1295 // SSE 4.1 versions are "MRI" because dst can be mem, while
1296 // pextrw (SSE2) is RMI because dst must be reg.
1297 EmitXmmRegisterOperand(src, XmmRegister(dst));
1298 EmitUint8(imm.value());
1299 }
1300}
1301
Jan Voung8acded02014-09-22 18:02:25 -07001302void AssemblerX86::pmovsxdq(XmmRegister dst, XmmRegister src) {
1303 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1304 EmitUint8(0x66);
1305 EmitUint8(0x0F);
1306 EmitUint8(0x38);
1307 EmitUint8(0x25);
1308 EmitXmmRegisterOperand(dst, src);
1309}
1310
Jan Voung0ac50dc2014-09-30 08:36:06 -07001311void AssemblerX86::pcmpeq(Type Ty, XmmRegister dst, XmmRegister src) {
Jan Voung8acded02014-09-22 18:02:25 -07001312 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1313 EmitUint8(0x66);
1314 EmitUint8(0x0F);
Jan Voung0ac50dc2014-09-30 08:36:06 -07001315 if (isByteSizedArithType(Ty)) {
1316 EmitUint8(0x74);
1317 } else if (Ty == IceType_i16) {
1318 EmitUint8(0x75);
1319 } else {
1320 EmitUint8(0x76);
1321 }
Jan Voung8acded02014-09-22 18:02:25 -07001322 EmitXmmRegisterOperand(dst, src);
1323}
1324
Jan Voung0ac50dc2014-09-30 08:36:06 -07001325void AssemblerX86::pcmpeq(Type Ty, XmmRegister dst, const Address &src) {
1326 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1327 EmitUint8(0x66);
1328 EmitUint8(0x0F);
1329 if (isByteSizedArithType(Ty)) {
1330 EmitUint8(0x74);
1331 } else if (Ty == IceType_i16) {
1332 EmitUint8(0x75);
1333 } else {
1334 EmitUint8(0x76);
1335 }
1336 EmitOperand(dst, src);
1337}
1338
1339void AssemblerX86::pcmpgt(Type Ty, XmmRegister dst, XmmRegister src) {
1340 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1341 EmitUint8(0x66);
1342 EmitUint8(0x0F);
1343 if (isByteSizedArithType(Ty)) {
1344 EmitUint8(0x64);
1345 } else if (Ty == IceType_i16) {
1346 EmitUint8(0x65);
1347 } else {
1348 EmitUint8(0x66);
1349 }
1350 EmitXmmRegisterOperand(dst, src);
1351}
1352
1353void AssemblerX86::pcmpgt(Type Ty, XmmRegister dst, const Address &src) {
1354 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1355 EmitUint8(0x66);
1356 EmitUint8(0x0F);
1357 if (isByteSizedArithType(Ty)) {
1358 EmitUint8(0x64);
1359 } else if (Ty == IceType_i16) {
1360 EmitUint8(0x65);
1361 } else {
1362 EmitUint8(0x66);
1363 }
1364 EmitOperand(dst, src);
1365}
1366
Jan Voung8acded02014-09-22 18:02:25 -07001367void AssemblerX86::roundsd(XmmRegister dst, XmmRegister src,
1368 RoundingMode mode) {
1369 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1370 EmitUint8(0x66);
1371 EmitUint8(0x0F);
1372 EmitUint8(0x3A);
1373 EmitUint8(0x0B);
1374 EmitXmmRegisterOperand(dst, src);
1375 // Mask precision exeption.
1376 EmitUint8(static_cast<uint8_t>(mode) | 0x8);
1377}
1378
Jan Voung8acded02014-09-22 18:02:25 -07001379void AssemblerX86::fnstcw(const Address &dst) {
1380 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1381 EmitUint8(0xD9);
1382 EmitOperand(7, dst);
1383}
1384
1385void AssemblerX86::fldcw(const Address &src) {
1386 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1387 EmitUint8(0xD9);
1388 EmitOperand(5, src);
1389}
1390
1391void AssemblerX86::fistpl(const Address &dst) {
1392 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1393 EmitUint8(0xDF);
1394 EmitOperand(7, dst);
1395}
1396
1397void AssemblerX86::fistps(const Address &dst) {
1398 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1399 EmitUint8(0xDB);
1400 EmitOperand(3, dst);
1401}
1402
1403void AssemblerX86::fildl(const Address &src) {
1404 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1405 EmitUint8(0xDF);
1406 EmitOperand(5, src);
1407}
1408
1409void AssemblerX86::filds(const Address &src) {
1410 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1411 EmitUint8(0xDB);
1412 EmitOperand(0, src);
1413}
1414
1415void AssemblerX86::fincstp() {
1416 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1417 EmitUint8(0xD9);
1418 EmitUint8(0xF7);
1419}
1420
Jan Vounge4dc61b2014-10-06 08:53:52 -07001421void AssemblerX86::cmp(Type Ty, GPRRegister reg, const Immediate &imm) {
Jan Voung8acded02014-09-22 18:02:25 -07001422 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Vounge4dc61b2014-10-06 08:53:52 -07001423 if (isByteSizedType(Ty)) {
1424 EmitComplexI8(7, Operand(reg), imm);
1425 return;
1426 }
1427 if (Ty == IceType_i16)
1428 EmitOperandSizeOverride();
1429 EmitComplex(Ty, 7, Operand(reg), imm);
Jan Voung8acded02014-09-22 18:02:25 -07001430}
1431
Jan Vounge4dc61b2014-10-06 08:53:52 -07001432void AssemblerX86::cmp(Type Ty, GPRRegister reg0, GPRRegister reg1) {
Jan Voung8acded02014-09-22 18:02:25 -07001433 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Vounge4dc61b2014-10-06 08:53:52 -07001434 if (Ty == IceType_i16)
1435 EmitOperandSizeOverride();
1436 if (isByteSizedType(Ty))
1437 EmitUint8(0x3A);
1438 else
1439 EmitUint8(0x3B);
1440 EmitRegisterOperand(reg0, reg1);
Jan Voung8acded02014-09-22 18:02:25 -07001441}
1442
Jan Vounge4dc61b2014-10-06 08:53:52 -07001443void AssemblerX86::cmp(Type Ty, GPRRegister reg, const Address &address) {
Jan Voung8acded02014-09-22 18:02:25 -07001444 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Vounge4dc61b2014-10-06 08:53:52 -07001445 if (Ty == IceType_i16)
1446 EmitOperandSizeOverride();
1447 if (isByteSizedType(Ty))
1448 EmitUint8(0x3A);
1449 else
1450 EmitUint8(0x3B);
Jan Voung8acded02014-09-22 18:02:25 -07001451 EmitOperand(reg, address);
1452}
1453
Jan Vounge4dc61b2014-10-06 08:53:52 -07001454void AssemblerX86::cmp(Type Ty, const Address &address, GPRRegister reg) {
Jan Voung8acded02014-09-22 18:02:25 -07001455 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Vounge4dc61b2014-10-06 08:53:52 -07001456 if (Ty == IceType_i16)
1457 EmitOperandSizeOverride();
1458 if (isByteSizedType(Ty))
1459 EmitUint8(0x38);
1460 else
1461 EmitUint8(0x39);
Jan Voung8acded02014-09-22 18:02:25 -07001462 EmitOperand(reg, address);
1463}
1464
Jan Vounge4dc61b2014-10-06 08:53:52 -07001465void AssemblerX86::cmp(Type Ty, const Address &address, const Immediate &imm) {
Jan Voung8acded02014-09-22 18:02:25 -07001466 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Vounge4dc61b2014-10-06 08:53:52 -07001467 if (isByteSizedType(Ty)) {
1468 EmitComplexI8(7, address, imm);
1469 return;
1470 }
1471 if (Ty == IceType_i16)
1472 EmitOperandSizeOverride();
1473 EmitComplex(Ty, 7, address, imm);
Jan Voung8acded02014-09-22 18:02:25 -07001474}
1475
Jan Vounge4dc61b2014-10-06 08:53:52 -07001476void AssemblerX86::test(Type Ty, GPRRegister reg1, GPRRegister reg2) {
Jan Voung8acded02014-09-22 18:02:25 -07001477 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Vounge4dc61b2014-10-06 08:53:52 -07001478 if (Ty == IceType_i16)
1479 EmitOperandSizeOverride();
1480 if (isByteSizedType(Ty))
1481 EmitUint8(0x84);
1482 else
1483 EmitUint8(0x85);
Jan Voung8acded02014-09-22 18:02:25 -07001484 EmitRegisterOperand(reg1, reg2);
1485}
1486
Jan Vounge4dc61b2014-10-06 08:53:52 -07001487void AssemblerX86::test(Type Ty, const Address &addr, GPRRegister reg) {
1488 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1489 if (Ty == IceType_i16)
1490 EmitOperandSizeOverride();
1491 if (isByteSizedType(Ty))
1492 EmitUint8(0x84);
1493 else
1494 EmitUint8(0x85);
1495 EmitOperand(reg, addr);
1496}
1497
1498void AssemblerX86::test(Type Ty, GPRRegister reg, const Immediate &immediate) {
Jan Voung8acded02014-09-22 18:02:25 -07001499 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1500 // For registers that have a byte variant (EAX, EBX, ECX, and EDX)
1501 // we only test the byte register to keep the encoding short.
Jan Vounge4dc61b2014-10-06 08:53:52 -07001502 // This is legal even if the register had high bits set since
1503 // this only sets flags registers based on the "AND" of the two operands,
1504 // and the immediate had zeros at those high bits.
Jan Voung8acded02014-09-22 18:02:25 -07001505 if (immediate.is_uint8() && reg < 4) {
1506 // Use zero-extended 8-bit immediate.
1507 if (reg == RegX8632::Encoded_Reg_eax) {
1508 EmitUint8(0xA8);
1509 } else {
1510 EmitUint8(0xF6);
1511 EmitUint8(0xC0 + reg);
1512 }
1513 EmitUint8(immediate.value() & 0xFF);
1514 } else if (reg == RegX8632::Encoded_Reg_eax) {
1515 // Use short form if the destination is EAX.
Jan Vounge4dc61b2014-10-06 08:53:52 -07001516 if (Ty == IceType_i16)
1517 EmitOperandSizeOverride();
Jan Voung8acded02014-09-22 18:02:25 -07001518 EmitUint8(0xA9);
Jan Vounge4dc61b2014-10-06 08:53:52 -07001519 EmitImmediate(Ty, immediate);
Jan Voung8acded02014-09-22 18:02:25 -07001520 } else {
Jan Vounge4dc61b2014-10-06 08:53:52 -07001521 if (Ty == IceType_i16)
1522 EmitOperandSizeOverride();
Jan Voung8acded02014-09-22 18:02:25 -07001523 EmitUint8(0xF7);
Jan Vounge4dc61b2014-10-06 08:53:52 -07001524 EmitRegisterOperand(0, reg);
1525 EmitImmediate(Ty, immediate);
1526 }
1527}
1528
1529void AssemblerX86::test(Type Ty, const Address &addr,
1530 const Immediate &immediate) {
1531 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1532 // If the immediate is short, we only test the byte addr to keep the
1533 // encoding short.
1534 if (immediate.is_uint8()) {
1535 // Use zero-extended 8-bit immediate.
1536 EmitUint8(0xF6);
1537 EmitOperand(0, addr);
1538 EmitUint8(immediate.value() & 0xFF);
1539 } else {
1540 if (Ty == IceType_i16)
1541 EmitOperandSizeOverride();
1542 EmitUint8(0xF7);
1543 EmitOperand(0, addr);
1544 EmitImmediate(Ty, immediate);
Jan Voung8acded02014-09-22 18:02:25 -07001545 }
1546}
1547
Jan Voungaf2780c2014-09-26 11:14:30 -07001548void AssemblerX86::And(Type Ty, GPRRegister dst, GPRRegister src) {
Jan Voung8acded02014-09-22 18:02:25 -07001549 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voungaf2780c2014-09-26 11:14:30 -07001550 if (Ty == IceType_i16)
1551 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07001552 if (isByteSizedType(Ty))
Jan Voungaf2780c2014-09-26 11:14:30 -07001553 EmitUint8(0x22);
1554 else
1555 EmitUint8(0x23);
1556 EmitRegisterOperand(dst, src);
Jan Voung8acded02014-09-22 18:02:25 -07001557}
1558
Jan Voungaf2780c2014-09-26 11:14:30 -07001559void AssemblerX86::And(Type Ty, GPRRegister dst, const Address &address) {
Jan Voung8acded02014-09-22 18:02:25 -07001560 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voungaf2780c2014-09-26 11:14:30 -07001561 if (Ty == IceType_i16)
1562 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07001563 if (isByteSizedType(Ty))
Jan Voungaf2780c2014-09-26 11:14:30 -07001564 EmitUint8(0x22);
1565 else
1566 EmitUint8(0x23);
1567 EmitOperand(dst, address);
1568}
1569
1570void AssemblerX86::And(Type Ty, GPRRegister dst, const Immediate &imm) {
1571 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung3a569182014-09-29 10:16:01 -07001572 if (isByteSizedType(Ty)) {
Jan Voungaf2780c2014-09-26 11:14:30 -07001573 EmitComplexI8(4, Operand(dst), imm);
1574 return;
1575 }
1576 if (Ty == IceType_i16)
1577 EmitOperandSizeOverride();
Jim Stichnoth94c4c8e2014-09-28 20:30:21 -07001578 EmitComplex(Ty, 4, Operand(dst), imm);
Jan Voung8acded02014-09-22 18:02:25 -07001579}
1580
Jan Voungaf2780c2014-09-26 11:14:30 -07001581void AssemblerX86::Or(Type Ty, GPRRegister dst, GPRRegister src) {
Jan Voung8acded02014-09-22 18:02:25 -07001582 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voungaf2780c2014-09-26 11:14:30 -07001583 if (Ty == IceType_i16)
1584 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07001585 if (isByteSizedType(Ty))
Jan Voungaf2780c2014-09-26 11:14:30 -07001586 EmitUint8(0x0A);
1587 else
1588 EmitUint8(0x0B);
1589 EmitRegisterOperand(dst, src);
1590}
1591
1592void AssemblerX86::Or(Type Ty, GPRRegister dst, const Address &address) {
1593 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1594 if (Ty == IceType_i16)
1595 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07001596 if (isByteSizedType(Ty))
Jan Voungaf2780c2014-09-26 11:14:30 -07001597 EmitUint8(0x0A);
1598 else
1599 EmitUint8(0x0B);
Jan Voung8acded02014-09-22 18:02:25 -07001600 EmitOperand(dst, address);
1601}
1602
Jan Voungaf2780c2014-09-26 11:14:30 -07001603void AssemblerX86::Or(Type Ty, GPRRegister dst, const Immediate &imm) {
Jan Voung8acded02014-09-22 18:02:25 -07001604 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung3a569182014-09-29 10:16:01 -07001605 if (isByteSizedType(Ty)) {
Jan Voungaf2780c2014-09-26 11:14:30 -07001606 EmitComplexI8(1, Operand(dst), imm);
1607 return;
1608 }
1609 if (Ty == IceType_i16)
1610 EmitOperandSizeOverride();
Jim Stichnoth94c4c8e2014-09-28 20:30:21 -07001611 EmitComplex(Ty, 1, Operand(dst), imm);
Jan Voung8acded02014-09-22 18:02:25 -07001612}
1613
Jan Voungaf2780c2014-09-26 11:14:30 -07001614void AssemblerX86::Xor(Type Ty, GPRRegister dst, GPRRegister src) {
Jan Voung8acded02014-09-22 18:02:25 -07001615 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voungaf2780c2014-09-26 11:14:30 -07001616 if (Ty == IceType_i16)
1617 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07001618 if (isByteSizedType(Ty))
Jan Voungaf2780c2014-09-26 11:14:30 -07001619 EmitUint8(0x32);
1620 else
1621 EmitUint8(0x33);
1622 EmitRegisterOperand(dst, src);
1623}
1624
1625void AssemblerX86::Xor(Type Ty, GPRRegister dst, const Address &address) {
1626 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1627 if (Ty == IceType_i16)
1628 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07001629 if (isByteSizedType(Ty))
Jan Voungaf2780c2014-09-26 11:14:30 -07001630 EmitUint8(0x32);
1631 else
1632 EmitUint8(0x33);
Jan Voung8acded02014-09-22 18:02:25 -07001633 EmitOperand(dst, address);
1634}
1635
Jan Voungaf2780c2014-09-26 11:14:30 -07001636void AssemblerX86::Xor(Type Ty, GPRRegister dst, const Immediate &imm) {
Jan Voung8acded02014-09-22 18:02:25 -07001637 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung3a569182014-09-29 10:16:01 -07001638 if (isByteSizedType(Ty)) {
Jan Voungaf2780c2014-09-26 11:14:30 -07001639 EmitComplexI8(6, Operand(dst), imm);
1640 return;
1641 }
1642 if (Ty == IceType_i16)
1643 EmitOperandSizeOverride();
Jim Stichnoth94c4c8e2014-09-28 20:30:21 -07001644 EmitComplex(Ty, 6, Operand(dst), imm);
Jan Voung8acded02014-09-22 18:02:25 -07001645}
1646
Jan Voungaf2780c2014-09-26 11:14:30 -07001647void AssemblerX86::add(Type Ty, GPRRegister dst, GPRRegister src) {
Jan Voung8acded02014-09-22 18:02:25 -07001648 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voungaf2780c2014-09-26 11:14:30 -07001649 if (Ty == IceType_i16)
1650 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07001651 if (isByteSizedArithType(Ty))
Jan Voungaf2780c2014-09-26 11:14:30 -07001652 EmitUint8(0x02);
1653 else
1654 EmitUint8(0x03);
1655 EmitRegisterOperand(dst, src);
Jan Voung8acded02014-09-22 18:02:25 -07001656}
1657
Jan Voungaf2780c2014-09-26 11:14:30 -07001658void AssemblerX86::add(Type Ty, GPRRegister reg, const Address &address) {
Jan Voung8acded02014-09-22 18:02:25 -07001659 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voungaf2780c2014-09-26 11:14:30 -07001660 if (Ty == IceType_i16)
1661 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07001662 if (isByteSizedArithType(Ty))
Jan Voungaf2780c2014-09-26 11:14:30 -07001663 EmitUint8(0x02);
1664 else
1665 EmitUint8(0x03);
1666 EmitOperand(reg, address);
1667}
1668
1669void AssemblerX86::add(Type Ty, GPRRegister reg, const Immediate &imm) {
1670 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung3a569182014-09-29 10:16:01 -07001671 if (isByteSizedArithType(Ty)) {
Jan Voungaf2780c2014-09-26 11:14:30 -07001672 EmitComplexI8(0, Operand(reg), imm);
1673 return;
1674 }
1675 if (Ty == IceType_i16)
1676 EmitOperandSizeOverride();
Jim Stichnoth94c4c8e2014-09-28 20:30:21 -07001677 EmitComplex(Ty, 0, Operand(reg), imm);
Jan Voung8acded02014-09-22 18:02:25 -07001678}
1679
Jan Voungaf2780c2014-09-26 11:14:30 -07001680void AssemblerX86::adc(Type Ty, GPRRegister dst, GPRRegister src) {
Jan Voung8acded02014-09-22 18:02:25 -07001681 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voungaf2780c2014-09-26 11:14:30 -07001682 if (Ty == IceType_i16)
1683 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07001684 if (isByteSizedArithType(Ty))
Jan Voungaf2780c2014-09-26 11:14:30 -07001685 EmitUint8(0x12);
1686 else
1687 EmitUint8(0x13);
1688 EmitRegisterOperand(dst, src);
Jan Voung8acded02014-09-22 18:02:25 -07001689}
1690
Jan Voungaf2780c2014-09-26 11:14:30 -07001691void AssemblerX86::adc(Type Ty, GPRRegister dst, const Address &address) {
Jan Voung8acded02014-09-22 18:02:25 -07001692 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voungaf2780c2014-09-26 11:14:30 -07001693 if (Ty == IceType_i16)
1694 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07001695 if (isByteSizedArithType(Ty))
Jan Voungaf2780c2014-09-26 11:14:30 -07001696 EmitUint8(0x12);
1697 else
1698 EmitUint8(0x13);
Jan Voung8acded02014-09-22 18:02:25 -07001699 EmitOperand(dst, address);
1700}
1701
Jan Voungaf2780c2014-09-26 11:14:30 -07001702void AssemblerX86::adc(Type Ty, GPRRegister reg, const Immediate &imm) {
Jan Voung8acded02014-09-22 18:02:25 -07001703 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung3a569182014-09-29 10:16:01 -07001704 if (isByteSizedArithType(Ty)) {
Jan Voungaf2780c2014-09-26 11:14:30 -07001705 EmitComplexI8(2, Operand(reg), imm);
1706 return;
1707 }
1708 if (Ty == IceType_i16)
1709 EmitOperandSizeOverride();
Jim Stichnoth94c4c8e2014-09-28 20:30:21 -07001710 EmitComplex(Ty, 2, Operand(reg), imm);
Jan Voungaf2780c2014-09-26 11:14:30 -07001711}
1712
1713void AssemblerX86::sub(Type Ty, GPRRegister dst, GPRRegister src) {
1714 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1715 if (Ty == IceType_i16)
1716 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07001717 if (isByteSizedArithType(Ty))
Jan Voungaf2780c2014-09-26 11:14:30 -07001718 EmitUint8(0x2A);
1719 else
1720 EmitUint8(0x2B);
1721 EmitRegisterOperand(dst, src);
1722}
1723
1724void AssemblerX86::sub(Type Ty, GPRRegister reg, const Address &address) {
1725 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1726 if (Ty == IceType_i16)
1727 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07001728 if (isByteSizedArithType(Ty))
Jan Voungaf2780c2014-09-26 11:14:30 -07001729 EmitUint8(0x2A);
1730 else
1731 EmitUint8(0x2B);
Jan Voung8acded02014-09-22 18:02:25 -07001732 EmitOperand(reg, address);
1733}
1734
Jan Voungaf2780c2014-09-26 11:14:30 -07001735void AssemblerX86::sub(Type Ty, GPRRegister reg, const Immediate &imm) {
Jan Voung8acded02014-09-22 18:02:25 -07001736 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung3a569182014-09-29 10:16:01 -07001737 if (isByteSizedArithType(Ty)) {
Jan Voungaf2780c2014-09-26 11:14:30 -07001738 EmitComplexI8(5, Operand(reg), imm);
1739 return;
1740 }
1741 if (Ty == IceType_i16)
1742 EmitOperandSizeOverride();
Jim Stichnoth94c4c8e2014-09-28 20:30:21 -07001743 EmitComplex(Ty, 5, Operand(reg), imm);
Jan Voung8acded02014-09-22 18:02:25 -07001744}
1745
Jan Voungaf2780c2014-09-26 11:14:30 -07001746void AssemblerX86::sbb(Type Ty, GPRRegister dst, GPRRegister src) {
Jan Voung8acded02014-09-22 18:02:25 -07001747 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voungaf2780c2014-09-26 11:14:30 -07001748 if (Ty == IceType_i16)
1749 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07001750 if (isByteSizedArithType(Ty))
Jan Voungaf2780c2014-09-26 11:14:30 -07001751 EmitUint8(0x1A);
1752 else
1753 EmitUint8(0x1B);
1754 EmitRegisterOperand(dst, src);
Jan Voung8acded02014-09-22 18:02:25 -07001755}
1756
Jan Voungaf2780c2014-09-26 11:14:30 -07001757void AssemblerX86::sbb(Type Ty, GPRRegister dst, const Address &address) {
Jan Voung8acded02014-09-22 18:02:25 -07001758 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voungaf2780c2014-09-26 11:14:30 -07001759 if (Ty == IceType_i16)
1760 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07001761 if (isByteSizedArithType(Ty))
Jan Voungaf2780c2014-09-26 11:14:30 -07001762 EmitUint8(0x1A);
1763 else
1764 EmitUint8(0x1B);
1765 EmitOperand(dst, address);
1766}
1767
1768void AssemblerX86::sbb(Type Ty, GPRRegister reg, const Immediate &imm) {
1769 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung3a569182014-09-29 10:16:01 -07001770 if (isByteSizedArithType(Ty)) {
Jan Voungaf2780c2014-09-26 11:14:30 -07001771 EmitComplexI8(3, Operand(reg), imm);
1772 return;
1773 }
1774 if (Ty == IceType_i16)
1775 EmitOperandSizeOverride();
Jim Stichnoth94c4c8e2014-09-28 20:30:21 -07001776 EmitComplex(Ty, 3, Operand(reg), imm);
Jan Voung8acded02014-09-22 18:02:25 -07001777}
1778
Jan Voung03532e52014-09-23 13:32:18 -07001779void AssemblerX86::cbw() {
1780 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1781 EmitOperandSizeOverride();
1782 EmitUint8(0x98);
1783}
1784
1785void AssemblerX86::cwd() {
1786 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1787 EmitOperandSizeOverride();
1788 EmitUint8(0x99);
1789}
1790
Jan Voung8acded02014-09-22 18:02:25 -07001791void AssemblerX86::cdq() {
1792 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1793 EmitUint8(0x99);
1794}
1795
Jan Voungaf2780c2014-09-26 11:14:30 -07001796void AssemblerX86::div(Type Ty, GPRRegister reg) {
Jan Voung8acded02014-09-22 18:02:25 -07001797 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voungaf2780c2014-09-26 11:14:30 -07001798 if (Ty == IceType_i16)
1799 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07001800 if (isByteSizedArithType(Ty))
Jan Voungaf2780c2014-09-26 11:14:30 -07001801 EmitUint8(0xF6);
1802 else
1803 EmitUint8(0xF7);
1804 EmitRegisterOperand(6, reg);
1805}
1806
1807void AssemblerX86::div(Type Ty, const Address &addr) {
1808 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1809 if (Ty == IceType_i16)
1810 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07001811 if (isByteSizedArithType(Ty))
Jan Voungaf2780c2014-09-26 11:14:30 -07001812 EmitUint8(0xF6);
1813 else
1814 EmitUint8(0xF7);
1815 EmitOperand(6, addr);
1816}
1817
1818void AssemblerX86::idiv(Type Ty, GPRRegister reg) {
1819 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1820 if (Ty == IceType_i16)
1821 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07001822 if (isByteSizedArithType(Ty))
Jan Voungaf2780c2014-09-26 11:14:30 -07001823 EmitUint8(0xF6);
1824 else
1825 EmitUint8(0xF7);
1826 EmitRegisterOperand(7, reg);
1827}
1828
1829void AssemblerX86::idiv(Type Ty, const Address &addr) {
1830 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1831 if (Ty == IceType_i16)
1832 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07001833 if (isByteSizedArithType(Ty))
Jan Voungaf2780c2014-09-26 11:14:30 -07001834 EmitUint8(0xF6);
1835 else
1836 EmitUint8(0xF7);
1837 EmitOperand(7, addr);
Jan Voung8acded02014-09-22 18:02:25 -07001838}
1839
Jan Voung0ac50dc2014-09-30 08:36:06 -07001840void AssemblerX86::imul(Type Ty, GPRRegister dst, GPRRegister src) {
Jan Voung8acded02014-09-22 18:02:25 -07001841 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung0ac50dc2014-09-30 08:36:06 -07001842 assert(Ty == IceType_i16 || Ty == IceType_i32);
1843 if (Ty == IceType_i16)
1844 EmitOperandSizeOverride();
Jan Voung8acded02014-09-22 18:02:25 -07001845 EmitUint8(0x0F);
1846 EmitUint8(0xAF);
Jan Voung0ac50dc2014-09-30 08:36:06 -07001847 EmitRegisterOperand(dst, src);
Jan Voung8acded02014-09-22 18:02:25 -07001848}
1849
Jan Voung0ac50dc2014-09-30 08:36:06 -07001850void AssemblerX86::imul(Type Ty, GPRRegister reg, const Address &address) {
Jan Voung8acded02014-09-22 18:02:25 -07001851 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung0ac50dc2014-09-30 08:36:06 -07001852 assert(Ty == IceType_i16 || Ty == IceType_i32);
1853 if (Ty == IceType_i16)
1854 EmitOperandSizeOverride();
Jan Voung8acded02014-09-22 18:02:25 -07001855 EmitUint8(0x0F);
1856 EmitUint8(0xAF);
1857 EmitOperand(reg, address);
1858}
1859
Jan Voung0ac50dc2014-09-30 08:36:06 -07001860void AssemblerX86::imul(Type Ty, GPRRegister reg, const Immediate &imm) {
Jan Voung8acded02014-09-22 18:02:25 -07001861 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung0ac50dc2014-09-30 08:36:06 -07001862 assert(Ty == IceType_i16 || Ty == IceType_i32);
1863 if (Ty == IceType_i16)
1864 EmitOperandSizeOverride();
1865 if (imm.is_int8()) {
1866 EmitUint8(0x6B);
1867 EmitRegisterOperand(reg, reg);
1868 EmitUint8(imm.value() & 0xFF);
1869 } else {
1870 EmitUint8(0x69);
1871 EmitRegisterOperand(reg, reg);
1872 EmitImmediate(Ty, imm);
1873 }
Jan Voung8acded02014-09-22 18:02:25 -07001874}
1875
Jan Voung0ac50dc2014-09-30 08:36:06 -07001876void AssemblerX86::imul(Type Ty, GPRRegister reg) {
Jan Voung8acded02014-09-22 18:02:25 -07001877 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung0ac50dc2014-09-30 08:36:06 -07001878 if (Ty == IceType_i16)
1879 EmitOperandSizeOverride();
1880 if (isByteSizedArithType(Ty))
1881 EmitUint8(0xF6);
1882 else
1883 EmitUint8(0xF7);
1884 EmitRegisterOperand(5, reg);
1885}
1886
1887void AssemblerX86::imul(Type Ty, const Address &address) {
1888 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1889 if (Ty == IceType_i16)
1890 EmitOperandSizeOverride();
1891 if (isByteSizedArithType(Ty))
1892 EmitUint8(0xF6);
1893 else
1894 EmitUint8(0xF7);
Jan Voung8acded02014-09-22 18:02:25 -07001895 EmitOperand(5, address);
1896}
1897
Jan Voungaf2780c2014-09-26 11:14:30 -07001898void AssemblerX86::mul(Type Ty, GPRRegister reg) {
Jan Voung8acded02014-09-22 18:02:25 -07001899 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voungaf2780c2014-09-26 11:14:30 -07001900 if (Ty == IceType_i16)
1901 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07001902 if (isByteSizedArithType(Ty))
Jan Voungaf2780c2014-09-26 11:14:30 -07001903 EmitUint8(0xF6);
1904 else
1905 EmitUint8(0xF7);
1906 EmitRegisterOperand(4, reg);
Jan Voung8acded02014-09-22 18:02:25 -07001907}
1908
Jan Voungaf2780c2014-09-26 11:14:30 -07001909void AssemblerX86::mul(Type Ty, const Address &address) {
Jan Voung8acded02014-09-22 18:02:25 -07001910 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voungaf2780c2014-09-26 11:14:30 -07001911 if (Ty == IceType_i16)
1912 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07001913 if (isByteSizedArithType(Ty))
Jan Voungaf2780c2014-09-26 11:14:30 -07001914 EmitUint8(0xF6);
1915 else
1916 EmitUint8(0xF7);
Jan Voung8acded02014-09-22 18:02:25 -07001917 EmitOperand(4, address);
1918}
1919
Jan Voung8acded02014-09-22 18:02:25 -07001920void AssemblerX86::incl(GPRRegister reg) {
1921 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1922 EmitUint8(0x40 + reg);
1923}
1924
1925void AssemblerX86::incl(const Address &address) {
1926 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1927 EmitUint8(0xFF);
1928 EmitOperand(0, address);
1929}
1930
1931void AssemblerX86::decl(GPRRegister reg) {
1932 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1933 EmitUint8(0x48 + reg);
1934}
1935
1936void AssemblerX86::decl(const Address &address) {
1937 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1938 EmitUint8(0xFF);
1939 EmitOperand(1, address);
1940}
1941
Jan Voung8bcca042014-10-03 21:58:02 -07001942void AssemblerX86::rol(Type Ty, GPRRegister reg, const Immediate &imm) {
1943 EmitGenericShift(0, Ty, reg, imm);
Jan Voung8acded02014-09-22 18:02:25 -07001944}
1945
Jan Voung8bcca042014-10-03 21:58:02 -07001946void AssemblerX86::rol(Type Ty, GPRRegister operand, GPRRegister shifter) {
1947 EmitGenericShift(0, Ty, Operand(operand), shifter);
Jan Voung8acded02014-09-22 18:02:25 -07001948}
1949
Jan Voung8bcca042014-10-03 21:58:02 -07001950void AssemblerX86::rol(Type Ty, const Address &operand, GPRRegister shifter) {
1951 EmitGenericShift(0, Ty, operand, shifter);
Jan Voung8acded02014-09-22 18:02:25 -07001952}
1953
Jan Voung8bcca042014-10-03 21:58:02 -07001954void AssemblerX86::shl(Type Ty, GPRRegister reg, const Immediate &imm) {
1955 EmitGenericShift(4, Ty, reg, imm);
Jan Voung8acded02014-09-22 18:02:25 -07001956}
1957
Jan Voung8bcca042014-10-03 21:58:02 -07001958void AssemblerX86::shl(Type Ty, GPRRegister operand, GPRRegister shifter) {
1959 EmitGenericShift(4, Ty, Operand(operand), shifter);
Jan Voung8acded02014-09-22 18:02:25 -07001960}
1961
Jan Voung8bcca042014-10-03 21:58:02 -07001962void AssemblerX86::shl(Type Ty, const Address &operand, GPRRegister shifter) {
1963 EmitGenericShift(4, Ty, operand, shifter);
Jan Voung8acded02014-09-22 18:02:25 -07001964}
1965
Jan Voung8bcca042014-10-03 21:58:02 -07001966void AssemblerX86::shr(Type Ty, GPRRegister reg, const Immediate &imm) {
1967 EmitGenericShift(5, Ty, reg, imm);
Jan Voung8acded02014-09-22 18:02:25 -07001968}
1969
Jan Voung8bcca042014-10-03 21:58:02 -07001970void AssemblerX86::shr(Type Ty, GPRRegister operand, GPRRegister shifter) {
1971 EmitGenericShift(5, Ty, Operand(operand), shifter);
1972}
1973
1974void AssemblerX86::shr(Type Ty, const Address &operand, GPRRegister shifter) {
1975 EmitGenericShift(5, Ty, operand, shifter);
1976}
1977
1978void AssemblerX86::sar(Type Ty, GPRRegister reg, const Immediate &imm) {
1979 EmitGenericShift(7, Ty, reg, imm);
1980}
1981
1982void AssemblerX86::sar(Type Ty, GPRRegister operand, GPRRegister shifter) {
1983 EmitGenericShift(7, Ty, Operand(operand), shifter);
1984}
1985
1986void AssemblerX86::sar(Type Ty, const Address &address, GPRRegister shifter) {
1987 EmitGenericShift(7, Ty, address, shifter);
Jan Voung8acded02014-09-22 18:02:25 -07001988}
1989
Jan Voung962befa2014-10-15 09:32:58 -07001990void AssemblerX86::shld(Type Ty, GPRRegister dst, GPRRegister src) {
Jan Voung8acded02014-09-22 18:02:25 -07001991 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung962befa2014-10-15 09:32:58 -07001992 assert(Ty == IceType_i16 || Ty == IceType_i32);
1993 if (Ty == IceType_i16)
1994 EmitOperandSizeOverride();
Jan Voung8acded02014-09-22 18:02:25 -07001995 EmitUint8(0x0F);
1996 EmitUint8(0xA5);
1997 EmitRegisterOperand(src, dst);
1998}
1999
Jan Voung962befa2014-10-15 09:32:58 -07002000void AssemblerX86::shld(Type Ty, GPRRegister dst, GPRRegister src,
Jan Voung8acded02014-09-22 18:02:25 -07002001 const Immediate &imm) {
2002 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung962befa2014-10-15 09:32:58 -07002003 assert(Ty == IceType_i16 || Ty == IceType_i32);
Jan Voung8acded02014-09-22 18:02:25 -07002004 assert(imm.is_int8());
Jan Voung962befa2014-10-15 09:32:58 -07002005 if (Ty == IceType_i16)
2006 EmitOperandSizeOverride();
Jan Voung8acded02014-09-22 18:02:25 -07002007 EmitUint8(0x0F);
2008 EmitUint8(0xA4);
2009 EmitRegisterOperand(src, dst);
2010 EmitUint8(imm.value() & 0xFF);
2011}
2012
Jan Voung962befa2014-10-15 09:32:58 -07002013void AssemblerX86::shld(Type Ty, const Address &operand, GPRRegister src) {
Jan Voung8acded02014-09-22 18:02:25 -07002014 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung962befa2014-10-15 09:32:58 -07002015 assert(Ty == IceType_i16 || Ty == IceType_i32);
2016 if (Ty == IceType_i16)
2017 EmitOperandSizeOverride();
Jan Voung8acded02014-09-22 18:02:25 -07002018 EmitUint8(0x0F);
2019 EmitUint8(0xA5);
Jan Voung962befa2014-10-15 09:32:58 -07002020 EmitOperand(src, operand);
Jan Voung8acded02014-09-22 18:02:25 -07002021}
2022
Jan Voung962befa2014-10-15 09:32:58 -07002023void AssemblerX86::shrd(Type Ty, GPRRegister dst, GPRRegister src) {
Jan Voung8acded02014-09-22 18:02:25 -07002024 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung962befa2014-10-15 09:32:58 -07002025 assert(Ty == IceType_i16 || Ty == IceType_i32);
2026 if (Ty == IceType_i16)
2027 EmitOperandSizeOverride();
Jan Voung8acded02014-09-22 18:02:25 -07002028 EmitUint8(0x0F);
2029 EmitUint8(0xAD);
2030 EmitRegisterOperand(src, dst);
2031}
2032
Jan Voung962befa2014-10-15 09:32:58 -07002033void AssemblerX86::shrd(Type Ty, GPRRegister dst, GPRRegister src,
Jan Voung8acded02014-09-22 18:02:25 -07002034 const Immediate &imm) {
2035 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung962befa2014-10-15 09:32:58 -07002036 assert(Ty == IceType_i16 || Ty == IceType_i32);
Jan Voung8acded02014-09-22 18:02:25 -07002037 assert(imm.is_int8());
Jan Voung962befa2014-10-15 09:32:58 -07002038 if (Ty == IceType_i16)
2039 EmitOperandSizeOverride();
Jan Voung8acded02014-09-22 18:02:25 -07002040 EmitUint8(0x0F);
2041 EmitUint8(0xAC);
2042 EmitRegisterOperand(src, dst);
2043 EmitUint8(imm.value() & 0xFF);
2044}
2045
Jan Voung962befa2014-10-15 09:32:58 -07002046void AssemblerX86::shrd(Type Ty, const Address &dst, GPRRegister src) {
Jan Voung8acded02014-09-22 18:02:25 -07002047 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung962befa2014-10-15 09:32:58 -07002048 assert(Ty == IceType_i16 || Ty == IceType_i32);
2049 if (Ty == IceType_i16)
2050 EmitOperandSizeOverride();
Jan Voung8acded02014-09-22 18:02:25 -07002051 EmitUint8(0x0F);
2052 EmitUint8(0xAD);
Jan Voung962befa2014-10-15 09:32:58 -07002053 EmitOperand(src, dst);
Jan Voung8acded02014-09-22 18:02:25 -07002054}
2055
Jan Voung3b43b892014-09-24 13:32:39 -07002056void AssemblerX86::neg(Type Ty, GPRRegister reg) {
Jan Voung8acded02014-09-22 18:02:25 -07002057 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung3b43b892014-09-24 13:32:39 -07002058 if (Ty == IceType_i16)
2059 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07002060 if (isByteSizedArithType(Ty))
Jan Voung3b43b892014-09-24 13:32:39 -07002061 EmitUint8(0xF6);
2062 else
2063 EmitUint8(0xF7);
2064 EmitRegisterOperand(3, reg);
2065}
2066
2067void AssemblerX86::neg(Type Ty, const Address &addr) {
2068 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2069 if (Ty == IceType_i16)
2070 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07002071 if (isByteSizedArithType(Ty))
Jan Voung3b43b892014-09-24 13:32:39 -07002072 EmitUint8(0xF6);
2073 else
2074 EmitUint8(0xF7);
2075 EmitOperand(3, addr);
Jan Voung8acded02014-09-22 18:02:25 -07002076}
2077
2078void AssemblerX86::notl(GPRRegister reg) {
2079 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2080 EmitUint8(0xF7);
2081 EmitUint8(0xD0 | reg);
2082}
2083
Jan Voung3b43b892014-09-24 13:32:39 -07002084void AssemblerX86::bswap(Type Ty, GPRRegister reg) {
Jan Voung8acded02014-09-22 18:02:25 -07002085 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Jan Voung3b43b892014-09-24 13:32:39 -07002086 assert(Ty == IceType_i32);
Jim Stichnoth9c234e22014-10-01 09:28:21 -07002087 (void)Ty;
Jan Voung3b43b892014-09-24 13:32:39 -07002088 EmitUint8(0x0F);
2089 EmitUint8(0xC8 | reg);
2090}
2091
2092void AssemblerX86::bsf(Type Ty, GPRRegister dst, GPRRegister src) {
2093 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2094 assert(Ty == IceType_i16 || Ty == IceType_i32);
2095 if (Ty == IceType_i16)
2096 EmitOperandSizeOverride();
2097 EmitUint8(0x0F);
2098 EmitUint8(0xBC);
2099 EmitRegisterOperand(dst, src);
2100}
2101
2102void AssemblerX86::bsf(Type Ty, GPRRegister dst, const Address &src) {
2103 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2104 assert(Ty == IceType_i16 || Ty == IceType_i32);
2105 if (Ty == IceType_i16)
2106 EmitOperandSizeOverride();
2107 EmitUint8(0x0F);
2108 EmitUint8(0xBC);
2109 EmitOperand(dst, src);
2110}
2111
2112void AssemblerX86::bsr(Type Ty, GPRRegister dst, GPRRegister src) {
2113 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2114 assert(Ty == IceType_i16 || Ty == IceType_i32);
2115 if (Ty == IceType_i16)
2116 EmitOperandSizeOverride();
Jan Voung8acded02014-09-22 18:02:25 -07002117 EmitUint8(0x0F);
2118 EmitUint8(0xBD);
2119 EmitRegisterOperand(dst, src);
2120}
2121
Jan Voung3b43b892014-09-24 13:32:39 -07002122void AssemblerX86::bsr(Type Ty, GPRRegister dst, const Address &src) {
2123 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2124 assert(Ty == IceType_i16 || Ty == IceType_i32);
2125 if (Ty == IceType_i16)
2126 EmitOperandSizeOverride();
2127 EmitUint8(0x0F);
2128 EmitUint8(0xBD);
2129 EmitOperand(dst, src);
2130}
2131
Jan Voung8acded02014-09-22 18:02:25 -07002132void AssemblerX86::bt(GPRRegister base, GPRRegister offset) {
2133 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2134 EmitUint8(0x0F);
2135 EmitUint8(0xA3);
2136 EmitRegisterOperand(offset, base);
2137}
2138
2139void AssemblerX86::ret() {
2140 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2141 EmitUint8(0xC3);
2142}
2143
2144void AssemblerX86::ret(const Immediate &imm) {
2145 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2146 EmitUint8(0xC2);
2147 assert(imm.is_uint16());
2148 EmitUint8(imm.value() & 0xFF);
2149 EmitUint8((imm.value() >> 8) & 0xFF);
2150}
2151
2152void AssemblerX86::nop(int size) {
2153 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2154 // There are nops up to size 15, but for now just provide up to size 8.
2155 assert(0 < size && size <= MAX_NOP_SIZE);
2156 switch (size) {
2157 case 1:
2158 EmitUint8(0x90);
2159 break;
2160 case 2:
2161 EmitUint8(0x66);
2162 EmitUint8(0x90);
2163 break;
2164 case 3:
2165 EmitUint8(0x0F);
2166 EmitUint8(0x1F);
2167 EmitUint8(0x00);
2168 break;
2169 case 4:
2170 EmitUint8(0x0F);
2171 EmitUint8(0x1F);
2172 EmitUint8(0x40);
2173 EmitUint8(0x00);
2174 break;
2175 case 5:
2176 EmitUint8(0x0F);
2177 EmitUint8(0x1F);
2178 EmitUint8(0x44);
2179 EmitUint8(0x00);
2180 EmitUint8(0x00);
2181 break;
2182 case 6:
2183 EmitUint8(0x66);
2184 EmitUint8(0x0F);
2185 EmitUint8(0x1F);
2186 EmitUint8(0x44);
2187 EmitUint8(0x00);
2188 EmitUint8(0x00);
2189 break;
2190 case 7:
2191 EmitUint8(0x0F);
2192 EmitUint8(0x1F);
2193 EmitUint8(0x80);
2194 EmitUint8(0x00);
2195 EmitUint8(0x00);
2196 EmitUint8(0x00);
2197 EmitUint8(0x00);
2198 break;
2199 case 8:
2200 EmitUint8(0x0F);
2201 EmitUint8(0x1F);
2202 EmitUint8(0x84);
2203 EmitUint8(0x00);
2204 EmitUint8(0x00);
2205 EmitUint8(0x00);
2206 EmitUint8(0x00);
2207 EmitUint8(0x00);
2208 break;
2209 default:
2210 llvm_unreachable("Unimplemented");
2211 }
2212}
2213
2214void AssemblerX86::int3() {
2215 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2216 EmitUint8(0xCC);
2217}
2218
2219void AssemblerX86::hlt() {
2220 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2221 EmitUint8(0xF4);
2222}
2223
Jan Vounge4dc61b2014-10-06 08:53:52 -07002224void AssemblerX86::ud2() {
2225 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2226 EmitUint8(0x0F);
2227 EmitUint8(0x0B);
2228}
2229
Jan Voung8acded02014-09-22 18:02:25 -07002230void AssemblerX86::j(CondX86::BrCond condition, Label *label, bool near) {
2231 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2232 if (label->IsBound()) {
2233 static const int kShortSize = 2;
2234 static const int kLongSize = 6;
2235 intptr_t offset = label->Position() - buffer_.Size();
2236 assert(offset <= 0);
2237 if (Utils::IsInt(8, offset - kShortSize)) {
2238 EmitUint8(0x70 + condition);
2239 EmitUint8((offset - kShortSize) & 0xFF);
2240 } else {
2241 EmitUint8(0x0F);
2242 EmitUint8(0x80 + condition);
2243 EmitInt32(offset - kLongSize);
2244 }
2245 } else if (near) {
2246 EmitUint8(0x70 + condition);
2247 EmitNearLabelLink(label);
2248 } else {
2249 EmitUint8(0x0F);
2250 EmitUint8(0x80 + condition);
2251 EmitLabelLink(label);
2252 }
2253}
2254
2255void AssemblerX86::j(CondX86::BrCond condition,
2256 const ConstantRelocatable *label) {
2257 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2258 EmitUint8(0x0F);
2259 EmitUint8(0x80 + condition);
Jan Voungec270732015-01-12 17:00:22 -08002260 EmitFixup(this->createFixup(llvm::ELF::R_386_PC32, label));
Jan Voung8acded02014-09-22 18:02:25 -07002261 EmitInt32(-4);
2262}
2263
2264void AssemblerX86::jmp(GPRRegister reg) {
2265 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2266 EmitUint8(0xFF);
2267 EmitRegisterOperand(4, reg);
2268}
2269
2270void AssemblerX86::jmp(Label *label, bool near) {
2271 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2272 if (label->IsBound()) {
2273 static const int kShortSize = 2;
2274 static const int kLongSize = 5;
2275 intptr_t offset = label->Position() - buffer_.Size();
2276 assert(offset <= 0);
2277 if (Utils::IsInt(8, offset - kShortSize)) {
2278 EmitUint8(0xEB);
2279 EmitUint8((offset - kShortSize) & 0xFF);
2280 } else {
2281 EmitUint8(0xE9);
2282 EmitInt32(offset - kLongSize);
2283 }
2284 } else if (near) {
2285 EmitUint8(0xEB);
2286 EmitNearLabelLink(label);
2287 } else {
2288 EmitUint8(0xE9);
2289 EmitLabelLink(label);
2290 }
2291}
2292
2293void AssemblerX86::jmp(const ConstantRelocatable *label) {
2294 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2295 EmitUint8(0xE9);
Jan Voungec270732015-01-12 17:00:22 -08002296 EmitFixup(this->createFixup(llvm::ELF::R_386_PC32, label));
Jan Voung8acded02014-09-22 18:02:25 -07002297 EmitInt32(-4);
2298}
2299
Jan Voungaf2780c2014-09-26 11:14:30 -07002300void AssemblerX86::mfence() {
2301 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2302 EmitUint8(0x0F);
2303 EmitUint8(0xAE);
2304 EmitUint8(0xF0);
2305}
2306
Jan Voung8acded02014-09-22 18:02:25 -07002307void AssemblerX86::lock() {
2308 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2309 EmitUint8(0xF0);
2310}
2311
Jan Voung03532e52014-09-23 13:32:18 -07002312void AssemblerX86::cmpxchg(Type Ty, const Address &address, GPRRegister reg) {
2313 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2314 if (Ty == IceType_i16)
2315 EmitOperandSizeOverride();
2316 EmitUint8(0x0F);
Jan Voung3a569182014-09-29 10:16:01 -07002317 if (isByteSizedArithType(Ty))
Jan Voung03532e52014-09-23 13:32:18 -07002318 EmitUint8(0xB0);
2319 else
2320 EmitUint8(0xB1);
2321 EmitOperand(reg, address);
2322}
2323
2324void AssemblerX86::cmpxchg8b(const Address &address) {
Jan Voung8acded02014-09-22 18:02:25 -07002325 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2326 EmitUint8(0x0F);
Jan Voung03532e52014-09-23 13:32:18 -07002327 EmitUint8(0xC7);
2328 EmitOperand(1, address);
2329}
2330
2331void AssemblerX86::xadd(Type Ty, const Address &addr, GPRRegister reg) {
2332 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2333 if (Ty == IceType_i16)
2334 EmitOperandSizeOverride();
2335 EmitUint8(0x0F);
Jan Voung3a569182014-09-29 10:16:01 -07002336 if (isByteSizedArithType(Ty))
Jan Voung03532e52014-09-23 13:32:18 -07002337 EmitUint8(0xC0);
2338 else
2339 EmitUint8(0xC1);
2340 EmitOperand(reg, addr);
2341}
2342
2343void AssemblerX86::xchg(Type Ty, const Address &addr, GPRRegister reg) {
2344 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2345 if (Ty == IceType_i16)
2346 EmitOperandSizeOverride();
Jan Voung3a569182014-09-29 10:16:01 -07002347 if (isByteSizedArithType(Ty))
Jan Voung03532e52014-09-23 13:32:18 -07002348 EmitUint8(0x86);
2349 else
2350 EmitUint8(0x87);
2351 EmitOperand(reg, addr);
Jan Voung8acded02014-09-22 18:02:25 -07002352}
2353
Jan Voungf76fd372014-10-16 15:39:22 -07002354void AssemblerX86::EmitSegmentOverride(uint8_t prefix) {
2355 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2356 EmitUint8(prefix);
2357}
2358
Jan Voung8acded02014-09-22 18:02:25 -07002359void AssemblerX86::Align(intptr_t alignment, intptr_t offset) {
2360 assert(llvm::isPowerOf2_32(alignment));
2361 intptr_t pos = offset + buffer_.GetPosition();
2362 intptr_t mod = pos & (alignment - 1);
2363 if (mod == 0) {
2364 return;
2365 }
2366 intptr_t bytes_needed = alignment - mod;
2367 while (bytes_needed > MAX_NOP_SIZE) {
2368 nop(MAX_NOP_SIZE);
2369 bytes_needed -= MAX_NOP_SIZE;
2370 }
2371 if (bytes_needed) {
2372 nop(bytes_needed);
2373 }
2374 assert(((offset + buffer_.GetPosition()) & (alignment - 1)) == 0);
2375}
2376
2377void AssemblerX86::Bind(Label *label) {
2378 intptr_t bound = buffer_.Size();
2379 assert(!label->IsBound()); // Labels can only be bound once.
2380 while (label->IsLinked()) {
2381 intptr_t position = label->LinkPosition();
2382 intptr_t next = buffer_.Load<int32_t>(position);
2383 buffer_.Store<int32_t>(position, bound - (position + 4));
2384 label->position_ = next;
2385 }
2386 while (label->HasNear()) {
2387 intptr_t position = label->NearPosition();
2388 intptr_t offset = bound - (position + 1);
2389 assert(Utils::IsInt(8, offset));
2390 buffer_.Store<int8_t>(position, offset);
2391 }
2392 label->BindTo(bound);
2393}
2394
2395void AssemblerX86::EmitOperand(int rm, const Operand &operand) {
2396 assert(rm >= 0 && rm < 8);
2397 const intptr_t length = operand.length_;
2398 assert(length > 0);
2399 // Emit the ModRM byte updated with the given RM value.
2400 assert((operand.encoding_[0] & 0x38) == 0);
2401 EmitUint8(operand.encoding_[0] + (rm << 3));
2402 if (operand.fixup()) {
2403 EmitFixup(operand.fixup());
2404 }
2405 // Emit the rest of the encoded operand.
2406 for (intptr_t i = 1; i < length; i++) {
2407 EmitUint8(operand.encoding_[i]);
2408 }
2409}
2410
Jim Stichnoth94c4c8e2014-09-28 20:30:21 -07002411void AssemblerX86::EmitImmediate(Type Ty, const Immediate &imm) {
Jan Voungfe14fb82014-10-13 15:56:32 -07002412 if (Ty == IceType_i16) {
2413 assert(!imm.fixup());
Jim Stichnoth94c4c8e2014-09-28 20:30:21 -07002414 EmitInt16(imm.value());
Jan Voungfe14fb82014-10-13 15:56:32 -07002415 } else {
2416 if (imm.fixup()) {
2417 EmitFixup(imm.fixup());
2418 }
Jim Stichnoth94c4c8e2014-09-28 20:30:21 -07002419 EmitInt32(imm.value());
Jan Voungfe14fb82014-10-13 15:56:32 -07002420 }
Jan Voung8acded02014-09-22 18:02:25 -07002421}
2422
2423void AssemblerX86::EmitComplexI8(int rm, const Operand &operand,
2424 const Immediate &immediate) {
2425 assert(rm >= 0 && rm < 8);
2426 assert(immediate.is_int8());
2427 if (operand.IsRegister(RegX8632::Encoded_Reg_eax)) {
2428 // Use short form if the destination is al.
2429 EmitUint8(0x04 + (rm << 3));
2430 EmitUint8(immediate.value() & 0xFF);
2431 } else {
2432 // Use sign-extended 8-bit immediate.
2433 EmitUint8(0x80);
2434 EmitOperand(rm, operand);
2435 EmitUint8(immediate.value() & 0xFF);
2436 }
2437}
2438
Jim Stichnoth94c4c8e2014-09-28 20:30:21 -07002439void AssemblerX86::EmitComplex(Type Ty, int rm, const Operand &operand,
Jan Voung8acded02014-09-22 18:02:25 -07002440 const Immediate &immediate) {
2441 assert(rm >= 0 && rm < 8);
2442 if (immediate.is_int8()) {
2443 // Use sign-extended 8-bit immediate.
2444 EmitUint8(0x83);
2445 EmitOperand(rm, operand);
2446 EmitUint8(immediate.value() & 0xFF);
2447 } else if (operand.IsRegister(RegX8632::Encoded_Reg_eax)) {
2448 // Use short form if the destination is eax.
2449 EmitUint8(0x05 + (rm << 3));
Jim Stichnoth94c4c8e2014-09-28 20:30:21 -07002450 EmitImmediate(Ty, immediate);
Jan Voung8acded02014-09-22 18:02:25 -07002451 } else {
2452 EmitUint8(0x81);
2453 EmitOperand(rm, operand);
Jim Stichnoth94c4c8e2014-09-28 20:30:21 -07002454 EmitImmediate(Ty, immediate);
Jan Voung8acded02014-09-22 18:02:25 -07002455 }
2456}
2457
2458void AssemblerX86::EmitLabel(Label *label, intptr_t instruction_size) {
2459 if (label->IsBound()) {
2460 intptr_t offset = label->Position() - buffer_.Size();
2461 assert(offset <= 0);
2462 EmitInt32(offset - instruction_size);
2463 } else {
2464 EmitLabelLink(label);
2465 }
2466}
2467
2468void AssemblerX86::EmitLabelLink(Label *label) {
2469 assert(!label->IsBound());
2470 intptr_t position = buffer_.Size();
2471 EmitInt32(label->position_);
2472 label->LinkTo(position);
2473}
2474
2475void AssemblerX86::EmitNearLabelLink(Label *label) {
2476 assert(!label->IsBound());
2477 intptr_t position = buffer_.Size();
2478 EmitUint8(0);
2479 label->NearLinkTo(position);
2480}
2481
Jan Voung8bcca042014-10-03 21:58:02 -07002482void AssemblerX86::EmitGenericShift(int rm, Type Ty, GPRRegister reg,
Jan Voung8acded02014-09-22 18:02:25 -07002483 const Immediate &imm) {
2484 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2485 assert(imm.is_int8());
Jan Voung8bcca042014-10-03 21:58:02 -07002486 if (Ty == IceType_i16)
2487 EmitOperandSizeOverride();
Jan Voung8acded02014-09-22 18:02:25 -07002488 if (imm.value() == 1) {
Jan Voung8bcca042014-10-03 21:58:02 -07002489 EmitUint8(isByteSizedArithType(Ty) ? 0xD0 : 0xD1);
Jan Voung8acded02014-09-22 18:02:25 -07002490 EmitOperand(rm, Operand(reg));
2491 } else {
Jan Voung8bcca042014-10-03 21:58:02 -07002492 EmitUint8(isByteSizedArithType(Ty) ? 0xC0 : 0xC1);
Jan Voung8acded02014-09-22 18:02:25 -07002493 EmitOperand(rm, Operand(reg));
2494 EmitUint8(imm.value() & 0xFF);
2495 }
2496}
2497
Jan Voung8bcca042014-10-03 21:58:02 -07002498void AssemblerX86::EmitGenericShift(int rm, Type Ty, const Operand &operand,
Jan Voung8acded02014-09-22 18:02:25 -07002499 GPRRegister shifter) {
2500 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2501 assert(shifter == RegX8632::Encoded_Reg_ecx);
Jim Stichnoth9c234e22014-10-01 09:28:21 -07002502 (void)shifter;
Jan Voung8bcca042014-10-03 21:58:02 -07002503 if (Ty == IceType_i16)
2504 EmitOperandSizeOverride();
2505 EmitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3);
2506 EmitOperand(rm, operand);
Jan Voung8acded02014-09-22 18:02:25 -07002507}
2508
2509} // end of namespace x86
2510} // end of namespace Ice