blob: 90170ceed5c7dd53786585c6825db025d159de0d [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070016
Ian Rogers2c8f6532011-09-02 17:16:34 -070017#include "assembler_x86.h"
18
Elliott Hughes1aa246d2012-12-13 09:29:36 -080019#include "base/casts.h"
Ian Rogers166db042013-07-26 12:05:57 -070020#include "entrypoints/quick/quick_entrypoints.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070021#include "memory_region.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070022#include "thread.h"
Tong Shen547cdfd2014-08-05 01:54:19 -070023#include "utils/dwarf_cfi.h"
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070024
Carl Shapiro6b6b5f02011-06-21 15:05:09 -070025namespace art {
Ian Rogers2c8f6532011-09-02 17:16:34 -070026namespace x86 {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070027
Ian Rogersb033c752011-07-20 12:22:35 -070028std::ostream& operator<<(std::ostream& os, const XmmRegister& reg) {
29 return os << "XMM" << static_cast<int>(reg);
30}
31
32std::ostream& operator<<(std::ostream& os, const X87Register& reg) {
33 return os << "ST" << static_cast<int>(reg);
34}
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070035
Ian Rogers2c8f6532011-09-02 17:16:34 -070036void X86Assembler::call(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070037 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
38 EmitUint8(0xFF);
39 EmitRegisterOperand(2, reg);
40}
41
42
Ian Rogers2c8f6532011-09-02 17:16:34 -070043void X86Assembler::call(const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070044 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
45 EmitUint8(0xFF);
46 EmitOperand(2, address);
47}
48
49
Ian Rogers2c8f6532011-09-02 17:16:34 -070050void X86Assembler::call(Label* label) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070051 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
52 EmitUint8(0xE8);
53 static const int kSize = 5;
Nicolas Geoffray1cf95282014-12-12 19:22:03 +000054 // Offset by one because we already have emitted the opcode.
55 EmitLabel(label, kSize - 1);
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070056}
57
58
Nicolas Geoffray8ccc3f52014-03-19 10:34:11 +000059void X86Assembler::call(const ExternalLabel& label) {
60 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
61 intptr_t call_start = buffer_.GetPosition();
62 EmitUint8(0xE8);
63 EmitInt32(label.address());
64 static const intptr_t kCallExternalLabelSize = 5;
65 DCHECK_EQ((buffer_.GetPosition() - call_start), kCallExternalLabelSize);
66}
67
68
Ian Rogers2c8f6532011-09-02 17:16:34 -070069void X86Assembler::pushl(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070070 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
71 EmitUint8(0x50 + reg);
72}
73
74
Ian Rogers2c8f6532011-09-02 17:16:34 -070075void X86Assembler::pushl(const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070076 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
77 EmitUint8(0xFF);
78 EmitOperand(6, address);
79}
80
81
Ian Rogers2c8f6532011-09-02 17:16:34 -070082void X86Assembler::pushl(const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070083 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Ian Rogers44fb0d02012-03-23 16:46:24 -070084 if (imm.is_int8()) {
85 EmitUint8(0x6A);
86 EmitUint8(imm.value() & 0xFF);
87 } else {
88 EmitUint8(0x68);
89 EmitImmediate(imm);
90 }
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070091}
92
93
Ian Rogers2c8f6532011-09-02 17:16:34 -070094void X86Assembler::popl(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070095 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
96 EmitUint8(0x58 + reg);
97}
98
99
Ian Rogers2c8f6532011-09-02 17:16:34 -0700100void X86Assembler::popl(const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700101 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
102 EmitUint8(0x8F);
103 EmitOperand(0, address);
104}
105
106
Ian Rogers2c8f6532011-09-02 17:16:34 -0700107void X86Assembler::movl(Register dst, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700108 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
109 EmitUint8(0xB8 + dst);
110 EmitImmediate(imm);
111}
112
113
Ian Rogers2c8f6532011-09-02 17:16:34 -0700114void X86Assembler::movl(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700115 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
116 EmitUint8(0x89);
117 EmitRegisterOperand(src, dst);
118}
119
120
Ian Rogers2c8f6532011-09-02 17:16:34 -0700121void X86Assembler::movl(Register dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700122 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
123 EmitUint8(0x8B);
124 EmitOperand(dst, src);
125}
126
127
Ian Rogers2c8f6532011-09-02 17:16:34 -0700128void X86Assembler::movl(const Address& dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700129 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
130 EmitUint8(0x89);
131 EmitOperand(src, dst);
132}
133
134
Ian Rogers2c8f6532011-09-02 17:16:34 -0700135void X86Assembler::movl(const Address& dst, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700136 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
137 EmitUint8(0xC7);
138 EmitOperand(0, dst);
139 EmitImmediate(imm);
140}
141
Ian Rogersbdb03912011-09-14 00:55:44 -0700142void X86Assembler::movl(const Address& dst, Label* lbl) {
143 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
144 EmitUint8(0xC7);
145 EmitOperand(0, dst);
146 EmitLabel(lbl, dst.length_ + 5);
147}
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700148
Ian Rogers2c8f6532011-09-02 17:16:34 -0700149void X86Assembler::movzxb(Register dst, ByteRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700150 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
151 EmitUint8(0x0F);
152 EmitUint8(0xB6);
153 EmitRegisterOperand(dst, src);
154}
155
156
Ian Rogers2c8f6532011-09-02 17:16:34 -0700157void X86Assembler::movzxb(Register dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700158 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
159 EmitUint8(0x0F);
160 EmitUint8(0xB6);
161 EmitOperand(dst, src);
162}
163
164
Ian Rogers2c8f6532011-09-02 17:16:34 -0700165void X86Assembler::movsxb(Register dst, ByteRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700166 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
167 EmitUint8(0x0F);
168 EmitUint8(0xBE);
169 EmitRegisterOperand(dst, src);
170}
171
172
Ian Rogers2c8f6532011-09-02 17:16:34 -0700173void X86Assembler::movsxb(Register dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700174 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
175 EmitUint8(0x0F);
176 EmitUint8(0xBE);
177 EmitOperand(dst, src);
178}
179
180
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700181void X86Assembler::movb(Register /*dst*/, const Address& /*src*/) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700182 LOG(FATAL) << "Use movzxb or movsxb instead.";
183}
184
185
Ian Rogers2c8f6532011-09-02 17:16:34 -0700186void X86Assembler::movb(const Address& dst, ByteRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700187 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
188 EmitUint8(0x88);
189 EmitOperand(src, dst);
190}
191
192
Ian Rogers2c8f6532011-09-02 17:16:34 -0700193void X86Assembler::movb(const Address& dst, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700194 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
195 EmitUint8(0xC6);
196 EmitOperand(EAX, dst);
197 CHECK(imm.is_int8());
198 EmitUint8(imm.value() & 0xFF);
199}
200
201
Ian Rogers2c8f6532011-09-02 17:16:34 -0700202void X86Assembler::movzxw(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700203 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
204 EmitUint8(0x0F);
205 EmitUint8(0xB7);
206 EmitRegisterOperand(dst, src);
207}
208
209
Ian Rogers2c8f6532011-09-02 17:16:34 -0700210void X86Assembler::movzxw(Register dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700211 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
212 EmitUint8(0x0F);
213 EmitUint8(0xB7);
214 EmitOperand(dst, src);
215}
216
217
Ian Rogers2c8f6532011-09-02 17:16:34 -0700218void X86Assembler::movsxw(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700219 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
220 EmitUint8(0x0F);
221 EmitUint8(0xBF);
222 EmitRegisterOperand(dst, src);
223}
224
225
Ian Rogers2c8f6532011-09-02 17:16:34 -0700226void X86Assembler::movsxw(Register dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700227 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
228 EmitUint8(0x0F);
229 EmitUint8(0xBF);
230 EmitOperand(dst, src);
231}
232
233
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700234void X86Assembler::movw(Register /*dst*/, const Address& /*src*/) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700235 LOG(FATAL) << "Use movzxw or movsxw instead.";
236}
237
238
Ian Rogers2c8f6532011-09-02 17:16:34 -0700239void X86Assembler::movw(const Address& dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700240 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
241 EmitOperandSizeOverride();
242 EmitUint8(0x89);
243 EmitOperand(src, dst);
244}
245
246
Nicolas Geoffray26a25ef2014-09-30 13:54:09 +0100247void X86Assembler::movw(const Address& dst, const Immediate& imm) {
248 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
249 EmitOperandSizeOverride();
250 EmitUint8(0xC7);
251 EmitOperand(0, dst);
Nicolas Geoffrayb6e72062014-10-07 14:54:48 +0100252 CHECK(imm.is_uint16() || imm.is_int16());
Nicolas Geoffray26a25ef2014-09-30 13:54:09 +0100253 EmitUint8(imm.value() & 0xFF);
254 EmitUint8(imm.value() >> 8);
255}
256
257
Ian Rogers2c8f6532011-09-02 17:16:34 -0700258void X86Assembler::leal(Register dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700259 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
260 EmitUint8(0x8D);
261 EmitOperand(dst, src);
262}
263
264
Ian Rogers2c8f6532011-09-02 17:16:34 -0700265void X86Assembler::cmovl(Condition condition, Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700266 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
267 EmitUint8(0x0F);
Ian Rogersb033c752011-07-20 12:22:35 -0700268 EmitUint8(0x40 + condition);
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700269 EmitRegisterOperand(dst, src);
270}
271
272
Nicolas Geoffray5b4b8982014-12-18 17:45:56 +0000273void X86Assembler::setb(Condition condition, Register dst) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700274 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
275 EmitUint8(0x0F);
Ian Rogersb033c752011-07-20 12:22:35 -0700276 EmitUint8(0x90 + condition);
Nicolas Geoffray5b4b8982014-12-18 17:45:56 +0000277 EmitOperand(0, Operand(dst));
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700278}
279
280
Nicolas Geoffray7fb49da2014-10-06 09:12:41 +0100281void X86Assembler::movaps(XmmRegister dst, XmmRegister src) {
282 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
283 EmitUint8(0x0F);
284 EmitUint8(0x28);
285 EmitXmmRegisterOperand(dst, src);
286}
287
288
Ian Rogers2c8f6532011-09-02 17:16:34 -0700289void X86Assembler::movss(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700290 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
291 EmitUint8(0xF3);
292 EmitUint8(0x0F);
293 EmitUint8(0x10);
294 EmitOperand(dst, src);
295}
296
297
Ian Rogers2c8f6532011-09-02 17:16:34 -0700298void X86Assembler::movss(const Address& dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700299 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
300 EmitUint8(0xF3);
301 EmitUint8(0x0F);
302 EmitUint8(0x11);
303 EmitOperand(src, dst);
304}
305
306
Ian Rogers2c8f6532011-09-02 17:16:34 -0700307void X86Assembler::movss(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700308 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
309 EmitUint8(0xF3);
310 EmitUint8(0x0F);
311 EmitUint8(0x11);
312 EmitXmmRegisterOperand(src, dst);
313}
314
315
Ian Rogers2c8f6532011-09-02 17:16:34 -0700316void X86Assembler::movd(XmmRegister dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700317 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
318 EmitUint8(0x66);
319 EmitUint8(0x0F);
320 EmitUint8(0x6E);
321 EmitOperand(dst, Operand(src));
322}
323
324
Ian Rogers2c8f6532011-09-02 17:16:34 -0700325void X86Assembler::movd(Register dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700326 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
327 EmitUint8(0x66);
328 EmitUint8(0x0F);
329 EmitUint8(0x7E);
330 EmitOperand(src, Operand(dst));
331}
332
333
Ian Rogers2c8f6532011-09-02 17:16:34 -0700334void X86Assembler::addss(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700335 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
336 EmitUint8(0xF3);
337 EmitUint8(0x0F);
338 EmitUint8(0x58);
339 EmitXmmRegisterOperand(dst, src);
340}
341
342
Ian Rogers2c8f6532011-09-02 17:16:34 -0700343void X86Assembler::addss(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700344 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
345 EmitUint8(0xF3);
346 EmitUint8(0x0F);
347 EmitUint8(0x58);
348 EmitOperand(dst, src);
349}
350
351
Ian Rogers2c8f6532011-09-02 17:16:34 -0700352void X86Assembler::subss(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700353 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
354 EmitUint8(0xF3);
355 EmitUint8(0x0F);
356 EmitUint8(0x5C);
357 EmitXmmRegisterOperand(dst, src);
358}
359
360
Ian Rogers2c8f6532011-09-02 17:16:34 -0700361void X86Assembler::subss(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700362 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
363 EmitUint8(0xF3);
364 EmitUint8(0x0F);
365 EmitUint8(0x5C);
366 EmitOperand(dst, src);
367}
368
369
Ian Rogers2c8f6532011-09-02 17:16:34 -0700370void X86Assembler::mulss(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700371 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
372 EmitUint8(0xF3);
373 EmitUint8(0x0F);
374 EmitUint8(0x59);
375 EmitXmmRegisterOperand(dst, src);
376}
377
378
Ian Rogers2c8f6532011-09-02 17:16:34 -0700379void X86Assembler::mulss(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700380 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
381 EmitUint8(0xF3);
382 EmitUint8(0x0F);
383 EmitUint8(0x59);
384 EmitOperand(dst, src);
385}
386
387
Ian Rogers2c8f6532011-09-02 17:16:34 -0700388void X86Assembler::divss(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700389 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
390 EmitUint8(0xF3);
391 EmitUint8(0x0F);
392 EmitUint8(0x5E);
393 EmitXmmRegisterOperand(dst, src);
394}
395
396
Ian Rogers2c8f6532011-09-02 17:16:34 -0700397void X86Assembler::divss(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700398 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
399 EmitUint8(0xF3);
400 EmitUint8(0x0F);
401 EmitUint8(0x5E);
402 EmitOperand(dst, src);
403}
404
405
Ian Rogers2c8f6532011-09-02 17:16:34 -0700406void X86Assembler::flds(const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700407 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
408 EmitUint8(0xD9);
409 EmitOperand(0, src);
410}
411
412
Mark Mendell24f2dfa2015-01-14 19:51:45 -0500413void X86Assembler::fsts(const Address& dst) {
414 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
415 EmitUint8(0xD9);
416 EmitOperand(2, dst);
417}
418
419
Ian Rogers2c8f6532011-09-02 17:16:34 -0700420void X86Assembler::fstps(const Address& dst) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700421 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
422 EmitUint8(0xD9);
423 EmitOperand(3, dst);
424}
425
426
Ian Rogers2c8f6532011-09-02 17:16:34 -0700427void X86Assembler::movsd(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700428 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
429 EmitUint8(0xF2);
430 EmitUint8(0x0F);
431 EmitUint8(0x10);
432 EmitOperand(dst, src);
433}
434
435
Ian Rogers2c8f6532011-09-02 17:16:34 -0700436void X86Assembler::movsd(const Address& dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700437 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
438 EmitUint8(0xF2);
439 EmitUint8(0x0F);
440 EmitUint8(0x11);
441 EmitOperand(src, dst);
442}
443
444
Ian Rogers2c8f6532011-09-02 17:16:34 -0700445void X86Assembler::movsd(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700446 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
447 EmitUint8(0xF2);
448 EmitUint8(0x0F);
449 EmitUint8(0x11);
450 EmitXmmRegisterOperand(src, dst);
451}
452
453
Nicolas Geoffray234d69d2015-03-09 10:28:50 +0000454void X86Assembler::movhpd(XmmRegister dst, const Address& src) {
455 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
456 EmitUint8(0x66);
457 EmitUint8(0x0F);
458 EmitUint8(0x16);
459 EmitOperand(dst, src);
460}
461
462
463void X86Assembler::movhpd(const Address& dst, XmmRegister src) {
464 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
465 EmitUint8(0x66);
466 EmitUint8(0x0F);
467 EmitUint8(0x17);
468 EmitOperand(src, dst);
469}
470
471
472void X86Assembler::psrldq(XmmRegister reg, const Immediate& shift_count) {
473 DCHECK(shift_count.is_uint8());
474
475 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
476 EmitUint8(0x66);
477 EmitUint8(0x0F);
478 EmitUint8(0x73);
479 EmitXmmRegisterOperand(3, reg);
480 EmitUint8(shift_count.value());
481}
482
483
Calin Juravle52c48962014-12-16 17:02:57 +0000484void X86Assembler::psrlq(XmmRegister reg, const Immediate& shift_count) {
485 DCHECK(shift_count.is_uint8());
486
487 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
488 EmitUint8(0x66);
489 EmitUint8(0x0F);
490 EmitUint8(0x73);
491 EmitXmmRegisterOperand(2, reg);
492 EmitUint8(shift_count.value());
493}
494
495
496void X86Assembler::punpckldq(XmmRegister dst, XmmRegister src) {
497 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
498 EmitUint8(0x66);
499 EmitUint8(0x0F);
500 EmitUint8(0x62);
501 EmitXmmRegisterOperand(dst, src);
502}
503
504
Ian Rogers2c8f6532011-09-02 17:16:34 -0700505void X86Assembler::addsd(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700506 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
507 EmitUint8(0xF2);
508 EmitUint8(0x0F);
509 EmitUint8(0x58);
510 EmitXmmRegisterOperand(dst, src);
511}
512
513
Ian Rogers2c8f6532011-09-02 17:16:34 -0700514void X86Assembler::addsd(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700515 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
516 EmitUint8(0xF2);
517 EmitUint8(0x0F);
518 EmitUint8(0x58);
519 EmitOperand(dst, src);
520}
521
522
Ian Rogers2c8f6532011-09-02 17:16:34 -0700523void X86Assembler::subsd(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700524 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
525 EmitUint8(0xF2);
526 EmitUint8(0x0F);
527 EmitUint8(0x5C);
528 EmitXmmRegisterOperand(dst, src);
529}
530
531
Ian Rogers2c8f6532011-09-02 17:16:34 -0700532void X86Assembler::subsd(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700533 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
534 EmitUint8(0xF2);
535 EmitUint8(0x0F);
536 EmitUint8(0x5C);
537 EmitOperand(dst, src);
538}
539
540
Ian Rogers2c8f6532011-09-02 17:16:34 -0700541void X86Assembler::mulsd(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700542 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
543 EmitUint8(0xF2);
544 EmitUint8(0x0F);
545 EmitUint8(0x59);
546 EmitXmmRegisterOperand(dst, src);
547}
548
549
Ian Rogers2c8f6532011-09-02 17:16:34 -0700550void X86Assembler::mulsd(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700551 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
552 EmitUint8(0xF2);
553 EmitUint8(0x0F);
554 EmitUint8(0x59);
555 EmitOperand(dst, src);
556}
557
558
Ian Rogers2c8f6532011-09-02 17:16:34 -0700559void X86Assembler::divsd(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700560 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
561 EmitUint8(0xF2);
562 EmitUint8(0x0F);
563 EmitUint8(0x5E);
564 EmitXmmRegisterOperand(dst, src);
565}
566
567
Ian Rogers2c8f6532011-09-02 17:16:34 -0700568void X86Assembler::divsd(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700569 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
570 EmitUint8(0xF2);
571 EmitUint8(0x0F);
572 EmitUint8(0x5E);
573 EmitOperand(dst, src);
574}
575
576
Ian Rogers2c8f6532011-09-02 17:16:34 -0700577void X86Assembler::cvtsi2ss(XmmRegister dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700578 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
579 EmitUint8(0xF3);
580 EmitUint8(0x0F);
581 EmitUint8(0x2A);
582 EmitOperand(dst, Operand(src));
583}
584
585
Ian Rogers2c8f6532011-09-02 17:16:34 -0700586void X86Assembler::cvtsi2sd(XmmRegister dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700587 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
588 EmitUint8(0xF2);
589 EmitUint8(0x0F);
590 EmitUint8(0x2A);
591 EmitOperand(dst, Operand(src));
592}
593
594
Ian Rogers2c8f6532011-09-02 17:16:34 -0700595void X86Assembler::cvtss2si(Register dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700596 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
597 EmitUint8(0xF3);
598 EmitUint8(0x0F);
599 EmitUint8(0x2D);
600 EmitXmmRegisterOperand(dst, src);
601}
602
603
Ian Rogers2c8f6532011-09-02 17:16:34 -0700604void X86Assembler::cvtss2sd(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700605 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
606 EmitUint8(0xF3);
607 EmitUint8(0x0F);
608 EmitUint8(0x5A);
609 EmitXmmRegisterOperand(dst, src);
610}
611
612
Ian Rogers2c8f6532011-09-02 17:16:34 -0700613void X86Assembler::cvtsd2si(Register dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700614 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
615 EmitUint8(0xF2);
616 EmitUint8(0x0F);
617 EmitUint8(0x2D);
618 EmitXmmRegisterOperand(dst, src);
619}
620
621
Ian Rogers2c8f6532011-09-02 17:16:34 -0700622void X86Assembler::cvttss2si(Register dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700623 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
624 EmitUint8(0xF3);
625 EmitUint8(0x0F);
626 EmitUint8(0x2C);
627 EmitXmmRegisterOperand(dst, src);
628}
629
630
Ian Rogers2c8f6532011-09-02 17:16:34 -0700631void X86Assembler::cvttsd2si(Register dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700632 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
633 EmitUint8(0xF2);
634 EmitUint8(0x0F);
635 EmitUint8(0x2C);
636 EmitXmmRegisterOperand(dst, src);
637}
638
639
Ian Rogers2c8f6532011-09-02 17:16:34 -0700640void X86Assembler::cvtsd2ss(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700641 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
642 EmitUint8(0xF2);
643 EmitUint8(0x0F);
644 EmitUint8(0x5A);
645 EmitXmmRegisterOperand(dst, src);
646}
647
648
Ian Rogers2c8f6532011-09-02 17:16:34 -0700649void X86Assembler::cvtdq2pd(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700650 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
651 EmitUint8(0xF3);
652 EmitUint8(0x0F);
653 EmitUint8(0xE6);
654 EmitXmmRegisterOperand(dst, src);
655}
656
657
Ian Rogers2c8f6532011-09-02 17:16:34 -0700658void X86Assembler::comiss(XmmRegister a, XmmRegister b) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700659 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
660 EmitUint8(0x0F);
661 EmitUint8(0x2F);
662 EmitXmmRegisterOperand(a, b);
663}
664
665
Ian Rogers2c8f6532011-09-02 17:16:34 -0700666void X86Assembler::comisd(XmmRegister a, XmmRegister b) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700667 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
668 EmitUint8(0x66);
669 EmitUint8(0x0F);
670 EmitUint8(0x2F);
671 EmitXmmRegisterOperand(a, b);
672}
673
674
Calin Juravleddb7df22014-11-25 20:56:51 +0000675void X86Assembler::ucomiss(XmmRegister a, XmmRegister b) {
676 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
677 EmitUint8(0x0F);
678 EmitUint8(0x2E);
679 EmitXmmRegisterOperand(a, b);
680}
681
682
683void X86Assembler::ucomisd(XmmRegister a, XmmRegister b) {
684 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
685 EmitUint8(0x66);
686 EmitUint8(0x0F);
687 EmitUint8(0x2E);
688 EmitXmmRegisterOperand(a, b);
689}
690
691
Ian Rogers2c8f6532011-09-02 17:16:34 -0700692void X86Assembler::sqrtsd(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700693 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
694 EmitUint8(0xF2);
695 EmitUint8(0x0F);
696 EmitUint8(0x51);
697 EmitXmmRegisterOperand(dst, src);
698}
699
700
Ian Rogers2c8f6532011-09-02 17:16:34 -0700701void X86Assembler::sqrtss(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700702 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
703 EmitUint8(0xF3);
704 EmitUint8(0x0F);
705 EmitUint8(0x51);
706 EmitXmmRegisterOperand(dst, src);
707}
708
709
Ian Rogers2c8f6532011-09-02 17:16:34 -0700710void X86Assembler::xorpd(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700711 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
712 EmitUint8(0x66);
713 EmitUint8(0x0F);
714 EmitUint8(0x57);
715 EmitOperand(dst, src);
716}
717
718
Ian Rogers2c8f6532011-09-02 17:16:34 -0700719void X86Assembler::xorpd(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700720 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
721 EmitUint8(0x66);
722 EmitUint8(0x0F);
723 EmitUint8(0x57);
724 EmitXmmRegisterOperand(dst, src);
725}
726
727
Ian Rogers2c8f6532011-09-02 17:16:34 -0700728void X86Assembler::xorps(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700729 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
730 EmitUint8(0x0F);
731 EmitUint8(0x57);
732 EmitOperand(dst, src);
733}
734
735
Ian Rogers2c8f6532011-09-02 17:16:34 -0700736void X86Assembler::xorps(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700737 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
738 EmitUint8(0x0F);
739 EmitUint8(0x57);
740 EmitXmmRegisterOperand(dst, src);
741}
742
743
Ian Rogers2c8f6532011-09-02 17:16:34 -0700744void X86Assembler::andpd(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700745 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
746 EmitUint8(0x66);
747 EmitUint8(0x0F);
748 EmitUint8(0x54);
749 EmitOperand(dst, src);
750}
751
752
Ian Rogers2c8f6532011-09-02 17:16:34 -0700753void X86Assembler::fldl(const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700754 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
755 EmitUint8(0xDD);
756 EmitOperand(0, src);
757}
758
759
Mark Mendell24f2dfa2015-01-14 19:51:45 -0500760void X86Assembler::fstl(const Address& dst) {
761 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
762 EmitUint8(0xDD);
763 EmitOperand(2, dst);
764}
765
766
Ian Rogers2c8f6532011-09-02 17:16:34 -0700767void X86Assembler::fstpl(const Address& dst) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700768 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
769 EmitUint8(0xDD);
770 EmitOperand(3, dst);
771}
772
773
Mark Mendell24f2dfa2015-01-14 19:51:45 -0500774void X86Assembler::fstsw() {
775 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
776 EmitUint8(0x9B);
777 EmitUint8(0xDF);
778 EmitUint8(0xE0);
779}
780
781
Ian Rogers2c8f6532011-09-02 17:16:34 -0700782void X86Assembler::fnstcw(const Address& dst) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700783 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
784 EmitUint8(0xD9);
785 EmitOperand(7, dst);
786}
787
788
Ian Rogers2c8f6532011-09-02 17:16:34 -0700789void X86Assembler::fldcw(const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700790 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
791 EmitUint8(0xD9);
792 EmitOperand(5, src);
793}
794
795
Ian Rogers2c8f6532011-09-02 17:16:34 -0700796void X86Assembler::fistpl(const Address& dst) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700797 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
798 EmitUint8(0xDF);
799 EmitOperand(7, dst);
800}
801
802
Ian Rogers2c8f6532011-09-02 17:16:34 -0700803void X86Assembler::fistps(const Address& dst) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700804 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
805 EmitUint8(0xDB);
806 EmitOperand(3, dst);
807}
808
809
Ian Rogers2c8f6532011-09-02 17:16:34 -0700810void X86Assembler::fildl(const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700811 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
812 EmitUint8(0xDF);
813 EmitOperand(5, src);
814}
815
816
Ian Rogers2c8f6532011-09-02 17:16:34 -0700817void X86Assembler::fincstp() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700818 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
819 EmitUint8(0xD9);
820 EmitUint8(0xF7);
821}
822
823
Ian Rogers2c8f6532011-09-02 17:16:34 -0700824void X86Assembler::ffree(const Immediate& index) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700825 CHECK_LT(index.value(), 7);
826 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
827 EmitUint8(0xDD);
828 EmitUint8(0xC0 + index.value());
829}
830
831
Ian Rogers2c8f6532011-09-02 17:16:34 -0700832void X86Assembler::fsin() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700833 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
834 EmitUint8(0xD9);
835 EmitUint8(0xFE);
836}
837
838
Ian Rogers2c8f6532011-09-02 17:16:34 -0700839void X86Assembler::fcos() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700840 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
841 EmitUint8(0xD9);
842 EmitUint8(0xFF);
843}
844
845
Ian Rogers2c8f6532011-09-02 17:16:34 -0700846void X86Assembler::fptan() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700847 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
848 EmitUint8(0xD9);
849 EmitUint8(0xF2);
850}
851
852
Mark Mendell24f2dfa2015-01-14 19:51:45 -0500853void X86Assembler::fucompp() {
854 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
855 EmitUint8(0xDA);
856 EmitUint8(0xE9);
857}
858
859
860void X86Assembler::fprem() {
861 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
862 EmitUint8(0xD9);
863 EmitUint8(0xF8);
864}
865
866
Ian Rogers2c8f6532011-09-02 17:16:34 -0700867void X86Assembler::xchgl(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700868 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
869 EmitUint8(0x87);
870 EmitRegisterOperand(dst, src);
871}
872
Nicolas Geoffray3c049742014-09-24 18:10:46 +0100873
Ian Rogers7caad772012-03-30 01:07:54 -0700874void X86Assembler::xchgl(Register reg, const Address& address) {
875 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
876 EmitUint8(0x87);
877 EmitOperand(reg, address);
878}
879
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700880
Nicolas Geoffray3c049742014-09-24 18:10:46 +0100881void X86Assembler::cmpw(const Address& address, const Immediate& imm) {
882 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
883 EmitUint8(0x66);
884 EmitComplex(7, address, imm);
885}
886
887
Ian Rogers2c8f6532011-09-02 17:16:34 -0700888void X86Assembler::cmpl(Register reg, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700889 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
890 EmitComplex(7, Operand(reg), imm);
891}
892
893
Ian Rogers2c8f6532011-09-02 17:16:34 -0700894void X86Assembler::cmpl(Register reg0, Register reg1) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700895 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
896 EmitUint8(0x3B);
897 EmitOperand(reg0, Operand(reg1));
898}
899
900
Ian Rogers2c8f6532011-09-02 17:16:34 -0700901void X86Assembler::cmpl(Register reg, const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700902 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
903 EmitUint8(0x3B);
904 EmitOperand(reg, address);
905}
906
907
Ian Rogers2c8f6532011-09-02 17:16:34 -0700908void X86Assembler::addl(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700909 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
910 EmitUint8(0x03);
911 EmitRegisterOperand(dst, src);
912}
913
914
Ian Rogers2c8f6532011-09-02 17:16:34 -0700915void X86Assembler::addl(Register reg, const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700916 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
917 EmitUint8(0x03);
918 EmitOperand(reg, address);
919}
920
921
Ian Rogers2c8f6532011-09-02 17:16:34 -0700922void X86Assembler::cmpl(const Address& address, Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700923 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
924 EmitUint8(0x39);
925 EmitOperand(reg, address);
926}
927
928
Ian Rogers2c8f6532011-09-02 17:16:34 -0700929void X86Assembler::cmpl(const Address& address, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700930 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
931 EmitComplex(7, address, imm);
932}
933
934
Ian Rogers2c8f6532011-09-02 17:16:34 -0700935void X86Assembler::testl(Register reg1, Register reg2) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700936 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
937 EmitUint8(0x85);
938 EmitRegisterOperand(reg1, reg2);
939}
940
941
Nicolas Geoffrayf12feb82014-07-17 18:32:41 +0100942void X86Assembler::testl(Register reg, const Address& address) {
943 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
944 EmitUint8(0x85);
945 EmitOperand(reg, address);
946}
947
948
Ian Rogers2c8f6532011-09-02 17:16:34 -0700949void X86Assembler::testl(Register reg, const Immediate& immediate) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700950 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
951 // For registers that have a byte variant (EAX, EBX, ECX, and EDX)
952 // we only test the byte register to keep the encoding short.
953 if (immediate.is_uint8() && reg < 4) {
954 // Use zero-extended 8-bit immediate.
955 if (reg == EAX) {
956 EmitUint8(0xA8);
957 } else {
958 EmitUint8(0xF6);
959 EmitUint8(0xC0 + reg);
960 }
961 EmitUint8(immediate.value() & 0xFF);
962 } else if (reg == EAX) {
963 // Use short form if the destination is EAX.
964 EmitUint8(0xA9);
965 EmitImmediate(immediate);
966 } else {
967 EmitUint8(0xF7);
968 EmitOperand(0, Operand(reg));
969 EmitImmediate(immediate);
970 }
971}
972
973
Ian Rogers2c8f6532011-09-02 17:16:34 -0700974void X86Assembler::andl(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700975 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
976 EmitUint8(0x23);
977 EmitOperand(dst, Operand(src));
978}
979
980
Nicolas Geoffray9574c4b2014-11-12 13:19:37 +0000981void X86Assembler::andl(Register reg, const Address& address) {
982 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
983 EmitUint8(0x23);
984 EmitOperand(reg, address);
985}
986
987
Ian Rogers2c8f6532011-09-02 17:16:34 -0700988void X86Assembler::andl(Register dst, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700989 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
990 EmitComplex(4, Operand(dst), imm);
991}
992
993
Ian Rogers2c8f6532011-09-02 17:16:34 -0700994void X86Assembler::orl(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700995 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
996 EmitUint8(0x0B);
997 EmitOperand(dst, Operand(src));
998}
999
1000
Nicolas Geoffray9574c4b2014-11-12 13:19:37 +00001001void X86Assembler::orl(Register reg, const Address& address) {
1002 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1003 EmitUint8(0x0B);
1004 EmitOperand(reg, address);
1005}
1006
1007
Ian Rogers2c8f6532011-09-02 17:16:34 -07001008void X86Assembler::orl(Register dst, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001009 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1010 EmitComplex(1, Operand(dst), imm);
1011}
1012
1013
Ian Rogers2c8f6532011-09-02 17:16:34 -07001014void X86Assembler::xorl(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001015 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1016 EmitUint8(0x33);
1017 EmitOperand(dst, Operand(src));
1018}
1019
Nicolas Geoffray9574c4b2014-11-12 13:19:37 +00001020
1021void X86Assembler::xorl(Register reg, const Address& address) {
1022 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1023 EmitUint8(0x33);
1024 EmitOperand(reg, address);
1025}
1026
1027
Nicolas Geoffrayb55f8352014-04-07 15:26:35 +01001028void X86Assembler::xorl(Register dst, const Immediate& imm) {
1029 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1030 EmitComplex(6, Operand(dst), imm);
1031}
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001032
Nicolas Geoffray9574c4b2014-11-12 13:19:37 +00001033
Ian Rogers2c8f6532011-09-02 17:16:34 -07001034void X86Assembler::addl(Register reg, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001035 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1036 EmitComplex(0, Operand(reg), imm);
1037}
1038
1039
Ian Rogers2c8f6532011-09-02 17:16:34 -07001040void X86Assembler::addl(const Address& address, Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001041 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1042 EmitUint8(0x01);
1043 EmitOperand(reg, address);
1044}
1045
1046
Ian Rogers2c8f6532011-09-02 17:16:34 -07001047void X86Assembler::addl(const Address& address, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001048 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1049 EmitComplex(0, address, imm);
1050}
1051
1052
Ian Rogers2c8f6532011-09-02 17:16:34 -07001053void X86Assembler::adcl(Register reg, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001054 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1055 EmitComplex(2, Operand(reg), imm);
1056}
1057
1058
Ian Rogers2c8f6532011-09-02 17:16:34 -07001059void X86Assembler::adcl(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001060 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1061 EmitUint8(0x13);
1062 EmitOperand(dst, Operand(src));
1063}
1064
1065
Ian Rogers2c8f6532011-09-02 17:16:34 -07001066void X86Assembler::adcl(Register dst, const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001067 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1068 EmitUint8(0x13);
1069 EmitOperand(dst, address);
1070}
1071
1072
Ian Rogers2c8f6532011-09-02 17:16:34 -07001073void X86Assembler::subl(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001074 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1075 EmitUint8(0x2B);
1076 EmitOperand(dst, Operand(src));
1077}
1078
1079
Ian Rogers2c8f6532011-09-02 17:16:34 -07001080void X86Assembler::subl(Register reg, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001081 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1082 EmitComplex(5, Operand(reg), imm);
1083}
1084
1085
Ian Rogers2c8f6532011-09-02 17:16:34 -07001086void X86Assembler::subl(Register reg, const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001087 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1088 EmitUint8(0x2B);
1089 EmitOperand(reg, address);
1090}
1091
1092
Ian Rogers2c8f6532011-09-02 17:16:34 -07001093void X86Assembler::cdq() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001094 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1095 EmitUint8(0x99);
1096}
1097
1098
Ian Rogers2c8f6532011-09-02 17:16:34 -07001099void X86Assembler::idivl(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001100 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1101 EmitUint8(0xF7);
1102 EmitUint8(0xF8 | reg);
1103}
1104
1105
Ian Rogers2c8f6532011-09-02 17:16:34 -07001106void X86Assembler::imull(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001107 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1108 EmitUint8(0x0F);
1109 EmitUint8(0xAF);
1110 EmitOperand(dst, Operand(src));
1111}
1112
1113
Ian Rogers2c8f6532011-09-02 17:16:34 -07001114void X86Assembler::imull(Register reg, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001115 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1116 EmitUint8(0x69);
1117 EmitOperand(reg, Operand(reg));
1118 EmitImmediate(imm);
1119}
1120
1121
Ian Rogers2c8f6532011-09-02 17:16:34 -07001122void X86Assembler::imull(Register reg, const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001123 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1124 EmitUint8(0x0F);
1125 EmitUint8(0xAF);
1126 EmitOperand(reg, address);
1127}
1128
1129
Ian Rogers2c8f6532011-09-02 17:16:34 -07001130void X86Assembler::imull(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001131 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1132 EmitUint8(0xF7);
1133 EmitOperand(5, Operand(reg));
1134}
1135
1136
Ian Rogers2c8f6532011-09-02 17:16:34 -07001137void X86Assembler::imull(const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001138 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1139 EmitUint8(0xF7);
1140 EmitOperand(5, address);
1141}
1142
1143
Ian Rogers2c8f6532011-09-02 17:16:34 -07001144void X86Assembler::mull(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001145 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1146 EmitUint8(0xF7);
1147 EmitOperand(4, Operand(reg));
1148}
1149
1150
Ian Rogers2c8f6532011-09-02 17:16:34 -07001151void X86Assembler::mull(const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001152 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1153 EmitUint8(0xF7);
1154 EmitOperand(4, address);
1155}
1156
1157
Ian Rogers2c8f6532011-09-02 17:16:34 -07001158void X86Assembler::sbbl(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001159 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1160 EmitUint8(0x1B);
1161 EmitOperand(dst, Operand(src));
1162}
1163
1164
Ian Rogers2c8f6532011-09-02 17:16:34 -07001165void X86Assembler::sbbl(Register reg, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001166 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1167 EmitComplex(3, Operand(reg), imm);
1168}
1169
1170
Ian Rogers2c8f6532011-09-02 17:16:34 -07001171void X86Assembler::sbbl(Register dst, const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001172 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1173 EmitUint8(0x1B);
1174 EmitOperand(dst, address);
1175}
1176
1177
Ian Rogers2c8f6532011-09-02 17:16:34 -07001178void X86Assembler::incl(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001179 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1180 EmitUint8(0x40 + reg);
1181}
1182
1183
Ian Rogers2c8f6532011-09-02 17:16:34 -07001184void X86Assembler::incl(const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001185 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1186 EmitUint8(0xFF);
1187 EmitOperand(0, address);
1188}
1189
1190
Ian Rogers2c8f6532011-09-02 17:16:34 -07001191void X86Assembler::decl(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001192 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1193 EmitUint8(0x48 + reg);
1194}
1195
1196
Ian Rogers2c8f6532011-09-02 17:16:34 -07001197void X86Assembler::decl(const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001198 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1199 EmitUint8(0xFF);
1200 EmitOperand(1, address);
1201}
1202
1203
Ian Rogers2c8f6532011-09-02 17:16:34 -07001204void X86Assembler::shll(Register reg, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001205 EmitGenericShift(4, reg, imm);
1206}
1207
1208
Ian Rogers2c8f6532011-09-02 17:16:34 -07001209void X86Assembler::shll(Register operand, Register shifter) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001210 EmitGenericShift(4, operand, shifter);
1211}
1212
1213
Ian Rogers2c8f6532011-09-02 17:16:34 -07001214void X86Assembler::shrl(Register reg, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001215 EmitGenericShift(5, reg, imm);
1216}
1217
1218
Ian Rogers2c8f6532011-09-02 17:16:34 -07001219void X86Assembler::shrl(Register operand, Register shifter) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001220 EmitGenericShift(5, operand, shifter);
1221}
1222
1223
Ian Rogers2c8f6532011-09-02 17:16:34 -07001224void X86Assembler::sarl(Register reg, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001225 EmitGenericShift(7, reg, imm);
1226}
1227
1228
Ian Rogers2c8f6532011-09-02 17:16:34 -07001229void X86Assembler::sarl(Register operand, Register shifter) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001230 EmitGenericShift(7, operand, shifter);
1231}
1232
1233
Calin Juravle9aec02f2014-11-18 23:06:35 +00001234void X86Assembler::shld(Register dst, Register src, Register shifter) {
1235 DCHECK_EQ(ECX, shifter);
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001236 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1237 EmitUint8(0x0F);
1238 EmitUint8(0xA5);
1239 EmitRegisterOperand(src, dst);
1240}
1241
1242
Calin Juravle9aec02f2014-11-18 23:06:35 +00001243void X86Assembler::shrd(Register dst, Register src, Register shifter) {
1244 DCHECK_EQ(ECX, shifter);
1245 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1246 EmitUint8(0x0F);
1247 EmitUint8(0xAD);
1248 EmitRegisterOperand(src, dst);
1249}
1250
1251
Ian Rogers2c8f6532011-09-02 17:16:34 -07001252void X86Assembler::negl(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001253 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1254 EmitUint8(0xF7);
1255 EmitOperand(3, Operand(reg));
1256}
1257
1258
Ian Rogers2c8f6532011-09-02 17:16:34 -07001259void X86Assembler::notl(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001260 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1261 EmitUint8(0xF7);
1262 EmitUint8(0xD0 | reg);
1263}
1264
1265
Ian Rogers2c8f6532011-09-02 17:16:34 -07001266void X86Assembler::enter(const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001267 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1268 EmitUint8(0xC8);
1269 CHECK(imm.is_uint16());
1270 EmitUint8(imm.value() & 0xFF);
1271 EmitUint8((imm.value() >> 8) & 0xFF);
1272 EmitUint8(0x00);
1273}
1274
1275
Ian Rogers2c8f6532011-09-02 17:16:34 -07001276void X86Assembler::leave() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001277 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1278 EmitUint8(0xC9);
1279}
1280
1281
Ian Rogers2c8f6532011-09-02 17:16:34 -07001282void X86Assembler::ret() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001283 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1284 EmitUint8(0xC3);
1285}
1286
1287
Ian Rogers2c8f6532011-09-02 17:16:34 -07001288void X86Assembler::ret(const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001289 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1290 EmitUint8(0xC2);
1291 CHECK(imm.is_uint16());
1292 EmitUint8(imm.value() & 0xFF);
1293 EmitUint8((imm.value() >> 8) & 0xFF);
1294}
1295
1296
1297
Ian Rogers2c8f6532011-09-02 17:16:34 -07001298void X86Assembler::nop() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001299 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1300 EmitUint8(0x90);
1301}
1302
1303
Ian Rogers2c8f6532011-09-02 17:16:34 -07001304void X86Assembler::int3() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001305 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1306 EmitUint8(0xCC);
1307}
1308
1309
Ian Rogers2c8f6532011-09-02 17:16:34 -07001310void X86Assembler::hlt() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001311 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1312 EmitUint8(0xF4);
1313}
1314
1315
Ian Rogers2c8f6532011-09-02 17:16:34 -07001316void X86Assembler::j(Condition condition, Label* label) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001317 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1318 if (label->IsBound()) {
1319 static const int kShortSize = 2;
1320 static const int kLongSize = 6;
1321 int offset = label->Position() - buffer_.Size();
1322 CHECK_LE(offset, 0);
Andreas Gampeab1eb0d2015-02-13 19:23:55 -08001323 if (IsInt<8>(offset - kShortSize)) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001324 EmitUint8(0x70 + condition);
1325 EmitUint8((offset - kShortSize) & 0xFF);
1326 } else {
1327 EmitUint8(0x0F);
1328 EmitUint8(0x80 + condition);
1329 EmitInt32(offset - kLongSize);
1330 }
1331 } else {
1332 EmitUint8(0x0F);
1333 EmitUint8(0x80 + condition);
1334 EmitLabelLink(label);
1335 }
1336}
1337
1338
Ian Rogers2c8f6532011-09-02 17:16:34 -07001339void X86Assembler::jmp(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001340 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1341 EmitUint8(0xFF);
1342 EmitRegisterOperand(4, reg);
1343}
1344
Ian Rogers7caad772012-03-30 01:07:54 -07001345void X86Assembler::jmp(const Address& address) {
1346 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1347 EmitUint8(0xFF);
1348 EmitOperand(4, address);
1349}
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001350
Ian Rogers2c8f6532011-09-02 17:16:34 -07001351void X86Assembler::jmp(Label* label) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001352 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1353 if (label->IsBound()) {
1354 static const int kShortSize = 2;
1355 static const int kLongSize = 5;
1356 int offset = label->Position() - buffer_.Size();
1357 CHECK_LE(offset, 0);
Andreas Gampeab1eb0d2015-02-13 19:23:55 -08001358 if (IsInt<8>(offset - kShortSize)) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001359 EmitUint8(0xEB);
1360 EmitUint8((offset - kShortSize) & 0xFF);
1361 } else {
1362 EmitUint8(0xE9);
1363 EmitInt32(offset - kLongSize);
1364 }
1365 } else {
1366 EmitUint8(0xE9);
1367 EmitLabelLink(label);
1368 }
1369}
1370
1371
Ian Rogers2c8f6532011-09-02 17:16:34 -07001372X86Assembler* X86Assembler::lock() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001373 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1374 EmitUint8(0xF0);
Ian Rogers0d666d82011-08-14 16:03:46 -07001375 return this;
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001376}
1377
1378
Ian Rogers2c8f6532011-09-02 17:16:34 -07001379void X86Assembler::cmpxchgl(const Address& address, Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001380 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1381 EmitUint8(0x0F);
1382 EmitUint8(0xB1);
1383 EmitOperand(reg, address);
1384}
1385
Elliott Hughes79ab9e32012-03-12 15:41:35 -07001386void X86Assembler::mfence() {
1387 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1388 EmitUint8(0x0F);
1389 EmitUint8(0xAE);
1390 EmitUint8(0xF0);
1391}
1392
Ian Rogers2c8f6532011-09-02 17:16:34 -07001393X86Assembler* X86Assembler::fs() {
Ian Rogersb033c752011-07-20 12:22:35 -07001394 // TODO: fs is a prefix and not an instruction
1395 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1396 EmitUint8(0x64);
Ian Rogers0d666d82011-08-14 16:03:46 -07001397 return this;
Ian Rogersb033c752011-07-20 12:22:35 -07001398}
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001399
Ian Rogersbefbd572014-03-06 01:13:39 -08001400X86Assembler* X86Assembler::gs() {
1401 // TODO: fs is a prefix and not an instruction
1402 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1403 EmitUint8(0x65);
1404 return this;
1405}
1406
Ian Rogers2c8f6532011-09-02 17:16:34 -07001407void X86Assembler::AddImmediate(Register reg, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001408 int value = imm.value();
1409 if (value > 0) {
1410 if (value == 1) {
1411 incl(reg);
1412 } else if (value != 0) {
1413 addl(reg, imm);
1414 }
1415 } else if (value < 0) {
1416 value = -value;
1417 if (value == 1) {
1418 decl(reg);
1419 } else if (value != 0) {
1420 subl(reg, Immediate(value));
1421 }
1422 }
1423}
1424
1425
Roland Levillain647b9ed2014-11-27 12:06:00 +00001426void X86Assembler::LoadLongConstant(XmmRegister dst, int64_t value) {
1427 // TODO: Need to have a code constants table.
1428 pushl(Immediate(High32Bits(value)));
1429 pushl(Immediate(Low32Bits(value)));
1430 movsd(dst, Address(ESP, 0));
1431 addl(ESP, Immediate(2 * sizeof(int32_t)));
1432}
1433
1434
Ian Rogers2c8f6532011-09-02 17:16:34 -07001435void X86Assembler::LoadDoubleConstant(XmmRegister dst, double value) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001436 // TODO: Need to have a code constants table.
1437 int64_t constant = bit_cast<int64_t, double>(value);
Roland Levillain647b9ed2014-11-27 12:06:00 +00001438 LoadLongConstant(dst, constant);
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001439}
1440
1441
Ian Rogers2c8f6532011-09-02 17:16:34 -07001442void X86Assembler::Align(int alignment, int offset) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001443 CHECK(IsPowerOfTwo(alignment));
1444 // Emit nop instruction until the real position is aligned.
1445 while (((offset + buffer_.GetPosition()) & (alignment-1)) != 0) {
1446 nop();
1447 }
1448}
1449
1450
Ian Rogers2c8f6532011-09-02 17:16:34 -07001451void X86Assembler::Bind(Label* label) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001452 int bound = buffer_.Size();
1453 CHECK(!label->IsBound()); // Labels can only be bound once.
1454 while (label->IsLinked()) {
1455 int position = label->LinkPosition();
1456 int next = buffer_.Load<int32_t>(position);
1457 buffer_.Store<int32_t>(position, bound - (position + 4));
1458 label->position_ = next;
1459 }
1460 label->BindTo(bound);
1461}
1462
1463
Ian Rogers44fb0d02012-03-23 16:46:24 -07001464void X86Assembler::EmitOperand(int reg_or_opcode, const Operand& operand) {
1465 CHECK_GE(reg_or_opcode, 0);
1466 CHECK_LT(reg_or_opcode, 8);
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001467 const int length = operand.length_;
1468 CHECK_GT(length, 0);
Ian Rogers44fb0d02012-03-23 16:46:24 -07001469 // Emit the ModRM byte updated with the given reg value.
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001470 CHECK_EQ(operand.encoding_[0] & 0x38, 0);
Ian Rogers44fb0d02012-03-23 16:46:24 -07001471 EmitUint8(operand.encoding_[0] + (reg_or_opcode << 3));
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001472 // Emit the rest of the encoded operand.
1473 for (int i = 1; i < length; i++) {
1474 EmitUint8(operand.encoding_[i]);
1475 }
1476}
1477
1478
Ian Rogers2c8f6532011-09-02 17:16:34 -07001479void X86Assembler::EmitImmediate(const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001480 EmitInt32(imm.value());
1481}
1482
1483
Ian Rogers44fb0d02012-03-23 16:46:24 -07001484void X86Assembler::EmitComplex(int reg_or_opcode,
Ian Rogers2c8f6532011-09-02 17:16:34 -07001485 const Operand& operand,
1486 const Immediate& immediate) {
Ian Rogers44fb0d02012-03-23 16:46:24 -07001487 CHECK_GE(reg_or_opcode, 0);
1488 CHECK_LT(reg_or_opcode, 8);
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001489 if (immediate.is_int8()) {
1490 // Use sign-extended 8-bit immediate.
1491 EmitUint8(0x83);
Ian Rogers44fb0d02012-03-23 16:46:24 -07001492 EmitOperand(reg_or_opcode, operand);
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001493 EmitUint8(immediate.value() & 0xFF);
1494 } else if (operand.IsRegister(EAX)) {
1495 // Use short form if the destination is eax.
Ian Rogers44fb0d02012-03-23 16:46:24 -07001496 EmitUint8(0x05 + (reg_or_opcode << 3));
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001497 EmitImmediate(immediate);
1498 } else {
1499 EmitUint8(0x81);
Ian Rogers44fb0d02012-03-23 16:46:24 -07001500 EmitOperand(reg_or_opcode, operand);
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001501 EmitImmediate(immediate);
1502 }
1503}
1504
1505
Ian Rogers2c8f6532011-09-02 17:16:34 -07001506void X86Assembler::EmitLabel(Label* label, int instruction_size) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001507 if (label->IsBound()) {
1508 int offset = label->Position() - buffer_.Size();
1509 CHECK_LE(offset, 0);
1510 EmitInt32(offset - instruction_size);
1511 } else {
1512 EmitLabelLink(label);
1513 }
1514}
1515
1516
Ian Rogers2c8f6532011-09-02 17:16:34 -07001517void X86Assembler::EmitLabelLink(Label* label) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001518 CHECK(!label->IsBound());
1519 int position = buffer_.Size();
1520 EmitInt32(label->position_);
1521 label->LinkTo(position);
1522}
1523
1524
Ian Rogers44fb0d02012-03-23 16:46:24 -07001525void X86Assembler::EmitGenericShift(int reg_or_opcode,
Ian Rogers2c8f6532011-09-02 17:16:34 -07001526 Register reg,
1527 const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001528 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1529 CHECK(imm.is_int8());
1530 if (imm.value() == 1) {
1531 EmitUint8(0xD1);
Ian Rogers44fb0d02012-03-23 16:46:24 -07001532 EmitOperand(reg_or_opcode, Operand(reg));
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001533 } else {
1534 EmitUint8(0xC1);
Ian Rogers44fb0d02012-03-23 16:46:24 -07001535 EmitOperand(reg_or_opcode, Operand(reg));
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001536 EmitUint8(imm.value() & 0xFF);
1537 }
1538}
1539
1540
Ian Rogers44fb0d02012-03-23 16:46:24 -07001541void X86Assembler::EmitGenericShift(int reg_or_opcode,
Ian Rogers2c8f6532011-09-02 17:16:34 -07001542 Register operand,
1543 Register shifter) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001544 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1545 CHECK_EQ(shifter, ECX);
1546 EmitUint8(0xD3);
Ian Rogers44fb0d02012-03-23 16:46:24 -07001547 EmitOperand(reg_or_opcode, Operand(operand));
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001548}
1549
Tong Shen547cdfd2014-08-05 01:54:19 -07001550void X86Assembler::InitializeFrameDescriptionEntry() {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001551 WriteFDEHeader(&cfi_info_, false /* is_64bit */);
Tong Shen547cdfd2014-08-05 01:54:19 -07001552}
1553
1554void X86Assembler::FinalizeFrameDescriptionEntry() {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001555 WriteFDEAddressRange(&cfi_info_, buffer_.Size(), false /* is_64bit */);
Tong Shen547cdfd2014-08-05 01:54:19 -07001556 PadCFI(&cfi_info_);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001557 WriteCFILength(&cfi_info_, false /* is_64bit */);
Tong Shen547cdfd2014-08-05 01:54:19 -07001558}
1559
Ian Rogers790a6b72014-04-01 10:36:00 -07001560constexpr size_t kFramePointerSize = 4;
1561
Ian Rogers2c8f6532011-09-02 17:16:34 -07001562void X86Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg,
Ian Rogersb5d09b22012-03-06 22:14:17 -08001563 const std::vector<ManagedRegister>& spill_regs,
Dmitry Petrochenkofca82202014-03-21 11:21:37 +07001564 const ManagedRegisterEntrySpills& entry_spills) {
Tong Shen547cdfd2014-08-05 01:54:19 -07001565 cfi_cfa_offset_ = kFramePointerSize; // Only return address on stack
1566 cfi_pc_ = buffer_.Size(); // Nothing emitted yet
1567 DCHECK_EQ(cfi_pc_, 0U);
1568
1569 uint32_t reg_offset = 1;
Elliott Hughes06b37d92011-10-16 11:51:29 -07001570 CHECK_ALIGNED(frame_size, kStackAlignment);
Mark P Mendell966c3ae2015-01-27 15:45:27 +00001571 int gpr_count = 0;
jeffhao703f2cd2012-07-13 17:25:52 -07001572 for (int i = spill_regs.size() - 1; i >= 0; --i) {
Mark P Mendell966c3ae2015-01-27 15:45:27 +00001573 x86::X86ManagedRegister spill = spill_regs.at(i).AsX86();
1574 DCHECK(spill.IsCpuRegister());
1575 pushl(spill.AsCpuRegister());
1576 gpr_count++;
Tong Shen547cdfd2014-08-05 01:54:19 -07001577
1578 // DW_CFA_advance_loc
1579 DW_CFA_advance_loc(&cfi_info_, buffer_.Size() - cfi_pc_);
1580 cfi_pc_ = buffer_.Size();
1581 // DW_CFA_def_cfa_offset
1582 cfi_cfa_offset_ += kFramePointerSize;
1583 DW_CFA_def_cfa_offset(&cfi_info_, cfi_cfa_offset_);
1584 // DW_CFA_offset reg offset
1585 reg_offset++;
1586 DW_CFA_offset(&cfi_info_, spill_regs.at(i).AsX86().DWARFRegId(), reg_offset);
jeffhao703f2cd2012-07-13 17:25:52 -07001587 }
Tong Shen547cdfd2014-08-05 01:54:19 -07001588
Ian Rogersb033c752011-07-20 12:22:35 -07001589 // return address then method on stack
Mark P Mendell966c3ae2015-01-27 15:45:27 +00001590 int32_t adjust = frame_size - (gpr_count * kFramePointerSize) -
Tong Shen547cdfd2014-08-05 01:54:19 -07001591 sizeof(StackReference<mirror::ArtMethod>) /*method*/ -
1592 kFramePointerSize /*return address*/;
1593 addl(ESP, Immediate(-adjust));
1594 // DW_CFA_advance_loc
1595 DW_CFA_advance_loc(&cfi_info_, buffer_.Size() - cfi_pc_);
1596 cfi_pc_ = buffer_.Size();
1597 // DW_CFA_def_cfa_offset
1598 cfi_cfa_offset_ += adjust;
1599 DW_CFA_def_cfa_offset(&cfi_info_, cfi_cfa_offset_);
1600
Ian Rogers2c8f6532011-09-02 17:16:34 -07001601 pushl(method_reg.AsX86().AsCpuRegister());
Tong Shen547cdfd2014-08-05 01:54:19 -07001602 // DW_CFA_advance_loc
1603 DW_CFA_advance_loc(&cfi_info_, buffer_.Size() - cfi_pc_);
1604 cfi_pc_ = buffer_.Size();
1605 // DW_CFA_def_cfa_offset
1606 cfi_cfa_offset_ += kFramePointerSize;
1607 DW_CFA_def_cfa_offset(&cfi_info_, cfi_cfa_offset_);
1608
Ian Rogersb5d09b22012-03-06 22:14:17 -08001609 for (size_t i = 0; i < entry_spills.size(); ++i) {
Mark P Mendell966c3ae2015-01-27 15:45:27 +00001610 ManagedRegisterSpill spill = entry_spills.at(i);
1611 if (spill.AsX86().IsCpuRegister()) {
1612 movl(Address(ESP, frame_size + spill.getSpillOffset()), spill.AsX86().AsCpuRegister());
1613 } else {
1614 DCHECK(spill.AsX86().IsXmmRegister());
1615 if (spill.getSize() == 8) {
1616 movsd(Address(ESP, frame_size + spill.getSpillOffset()), spill.AsX86().AsXmmRegister());
1617 } else {
1618 CHECK_EQ(spill.getSize(), 4);
1619 movss(Address(ESP, frame_size + spill.getSpillOffset()), spill.AsX86().AsXmmRegister());
1620 }
1621 }
Ian Rogersb5d09b22012-03-06 22:14:17 -08001622 }
Ian Rogersb033c752011-07-20 12:22:35 -07001623}
1624
Ian Rogers2c8f6532011-09-02 17:16:34 -07001625void X86Assembler::RemoveFrame(size_t frame_size,
Ian Rogers0d666d82011-08-14 16:03:46 -07001626 const std::vector<ManagedRegister>& spill_regs) {
Elliott Hughes06b37d92011-10-16 11:51:29 -07001627 CHECK_ALIGNED(frame_size, kStackAlignment);
Andreas Gampecf4035a2014-05-28 22:43:01 -07001628 addl(ESP, Immediate(frame_size - (spill_regs.size() * kFramePointerSize) -
1629 sizeof(StackReference<mirror::ArtMethod>)));
jeffhao703f2cd2012-07-13 17:25:52 -07001630 for (size_t i = 0; i < spill_regs.size(); ++i) {
Mark P Mendell966c3ae2015-01-27 15:45:27 +00001631 x86::X86ManagedRegister spill = spill_regs.at(i).AsX86();
1632 DCHECK(spill.IsCpuRegister());
1633 popl(spill.AsCpuRegister());
jeffhao703f2cd2012-07-13 17:25:52 -07001634 }
Ian Rogersb033c752011-07-20 12:22:35 -07001635 ret();
1636}
1637
Ian Rogers2c8f6532011-09-02 17:16:34 -07001638void X86Assembler::IncreaseFrameSize(size_t adjust) {
Elliott Hughes06b37d92011-10-16 11:51:29 -07001639 CHECK_ALIGNED(adjust, kStackAlignment);
Ian Rogersb033c752011-07-20 12:22:35 -07001640 addl(ESP, Immediate(-adjust));
Tong Shen547cdfd2014-08-05 01:54:19 -07001641 // DW_CFA_advance_loc
1642 DW_CFA_advance_loc(&cfi_info_, buffer_.Size() - cfi_pc_);
1643 cfi_pc_ = buffer_.Size();
1644 // DW_CFA_def_cfa_offset
1645 cfi_cfa_offset_ += adjust;
1646 DW_CFA_def_cfa_offset(&cfi_info_, cfi_cfa_offset_);
Ian Rogersb033c752011-07-20 12:22:35 -07001647}
1648
Ian Rogers2c8f6532011-09-02 17:16:34 -07001649void X86Assembler::DecreaseFrameSize(size_t adjust) {
Elliott Hughes06b37d92011-10-16 11:51:29 -07001650 CHECK_ALIGNED(adjust, kStackAlignment);
Ian Rogersb033c752011-07-20 12:22:35 -07001651 addl(ESP, Immediate(adjust));
1652}
1653
Ian Rogers2c8f6532011-09-02 17:16:34 -07001654void X86Assembler::Store(FrameOffset offs, ManagedRegister msrc, size_t size) {
1655 X86ManagedRegister src = msrc.AsX86();
Ian Rogers45a76cb2011-07-21 22:00:15 -07001656 if (src.IsNoRegister()) {
1657 CHECK_EQ(0u, size);
1658 } else if (src.IsCpuRegister()) {
Ian Rogersb033c752011-07-20 12:22:35 -07001659 CHECK_EQ(4u, size);
1660 movl(Address(ESP, offs), src.AsCpuRegister());
Ian Rogers9b269d22011-09-04 14:06:05 -07001661 } else if (src.IsRegisterPair()) {
1662 CHECK_EQ(8u, size);
1663 movl(Address(ESP, offs), src.AsRegisterPairLow());
1664 movl(Address(ESP, FrameOffset(offs.Int32Value()+4)),
1665 src.AsRegisterPairHigh());
Ian Rogers45a76cb2011-07-21 22:00:15 -07001666 } else if (src.IsX87Register()) {
1667 if (size == 4) {
1668 fstps(Address(ESP, offs));
1669 } else {
1670 fstpl(Address(ESP, offs));
1671 }
1672 } else {
1673 CHECK(src.IsXmmRegister());
Ian Rogersb033c752011-07-20 12:22:35 -07001674 if (size == 4) {
1675 movss(Address(ESP, offs), src.AsXmmRegister());
1676 } else {
1677 movsd(Address(ESP, offs), src.AsXmmRegister());
1678 }
1679 }
1680}
1681
Ian Rogers2c8f6532011-09-02 17:16:34 -07001682void X86Assembler::StoreRef(FrameOffset dest, ManagedRegister msrc) {
1683 X86ManagedRegister src = msrc.AsX86();
Ian Rogersb033c752011-07-20 12:22:35 -07001684 CHECK(src.IsCpuRegister());
1685 movl(Address(ESP, dest), src.AsCpuRegister());
1686}
1687
Ian Rogers2c8f6532011-09-02 17:16:34 -07001688void X86Assembler::StoreRawPtr(FrameOffset dest, ManagedRegister msrc) {
1689 X86ManagedRegister src = msrc.AsX86();
Ian Rogersdf20fe02011-07-20 20:34:16 -07001690 CHECK(src.IsCpuRegister());
1691 movl(Address(ESP, dest), src.AsCpuRegister());
1692}
1693
Ian Rogers2c8f6532011-09-02 17:16:34 -07001694void X86Assembler::StoreImmediateToFrame(FrameOffset dest, uint32_t imm,
1695 ManagedRegister) {
Ian Rogersb033c752011-07-20 12:22:35 -07001696 movl(Address(ESP, dest), Immediate(imm));
1697}
1698
Ian Rogersdd7624d2014-03-14 17:43:00 -07001699void X86Assembler::StoreImmediateToThread32(ThreadOffset<4> dest, uint32_t imm,
Ian Rogers2c8f6532011-09-02 17:16:34 -07001700 ManagedRegister) {
Ian Rogers0d666d82011-08-14 16:03:46 -07001701 fs()->movl(Address::Absolute(dest), Immediate(imm));
Ian Rogersb033c752011-07-20 12:22:35 -07001702}
1703
Ian Rogersdd7624d2014-03-14 17:43:00 -07001704void X86Assembler::StoreStackOffsetToThread32(ThreadOffset<4> thr_offs,
Ian Rogers2c8f6532011-09-02 17:16:34 -07001705 FrameOffset fr_offs,
1706 ManagedRegister mscratch) {
1707 X86ManagedRegister scratch = mscratch.AsX86();
1708 CHECK(scratch.IsCpuRegister());
1709 leal(scratch.AsCpuRegister(), Address(ESP, fr_offs));
1710 fs()->movl(Address::Absolute(thr_offs), scratch.AsCpuRegister());
1711}
1712
Ian Rogersdd7624d2014-03-14 17:43:00 -07001713void X86Assembler::StoreStackPointerToThread32(ThreadOffset<4> thr_offs) {
Ian Rogers2c8f6532011-09-02 17:16:34 -07001714 fs()->movl(Address::Absolute(thr_offs), ESP);
1715}
1716
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001717void X86Assembler::StoreSpanning(FrameOffset /*dst*/, ManagedRegister /*src*/,
1718 FrameOffset /*in_off*/, ManagedRegister /*scratch*/) {
Ian Rogers2c8f6532011-09-02 17:16:34 -07001719 UNIMPLEMENTED(FATAL); // this case only currently exists for ARM
1720}
1721
1722void X86Assembler::Load(ManagedRegister mdest, FrameOffset src, size_t size) {
1723 X86ManagedRegister dest = mdest.AsX86();
Ian Rogers45a76cb2011-07-21 22:00:15 -07001724 if (dest.IsNoRegister()) {
1725 CHECK_EQ(0u, size);
1726 } else if (dest.IsCpuRegister()) {
Ian Rogersb033c752011-07-20 12:22:35 -07001727 CHECK_EQ(4u, size);
1728 movl(dest.AsCpuRegister(), Address(ESP, src));
Ian Rogers9b269d22011-09-04 14:06:05 -07001729 } else if (dest.IsRegisterPair()) {
1730 CHECK_EQ(8u, size);
1731 movl(dest.AsRegisterPairLow(), Address(ESP, src));
1732 movl(dest.AsRegisterPairHigh(), Address(ESP, FrameOffset(src.Int32Value()+4)));
Ian Rogers45a76cb2011-07-21 22:00:15 -07001733 } else if (dest.IsX87Register()) {
1734 if (size == 4) {
1735 flds(Address(ESP, src));
1736 } else {
1737 fldl(Address(ESP, src));
1738 }
Ian Rogersb033c752011-07-20 12:22:35 -07001739 } else {
Ian Rogers45a76cb2011-07-21 22:00:15 -07001740 CHECK(dest.IsXmmRegister());
1741 if (size == 4) {
1742 movss(dest.AsXmmRegister(), Address(ESP, src));
1743 } else {
1744 movsd(dest.AsXmmRegister(), Address(ESP, src));
1745 }
Ian Rogersb033c752011-07-20 12:22:35 -07001746 }
1747}
1748
Ian Rogersdd7624d2014-03-14 17:43:00 -07001749void X86Assembler::LoadFromThread32(ManagedRegister mdest, ThreadOffset<4> src, size_t size) {
Ian Rogers5a7a74a2011-09-26 16:32:29 -07001750 X86ManagedRegister dest = mdest.AsX86();
1751 if (dest.IsNoRegister()) {
1752 CHECK_EQ(0u, size);
1753 } else if (dest.IsCpuRegister()) {
1754 CHECK_EQ(4u, size);
1755 fs()->movl(dest.AsCpuRegister(), Address::Absolute(src));
1756 } else if (dest.IsRegisterPair()) {
1757 CHECK_EQ(8u, size);
1758 fs()->movl(dest.AsRegisterPairLow(), Address::Absolute(src));
Ian Rogersdd7624d2014-03-14 17:43:00 -07001759 fs()->movl(dest.AsRegisterPairHigh(), Address::Absolute(ThreadOffset<4>(src.Int32Value()+4)));
Ian Rogers5a7a74a2011-09-26 16:32:29 -07001760 } else if (dest.IsX87Register()) {
1761 if (size == 4) {
1762 fs()->flds(Address::Absolute(src));
1763 } else {
1764 fs()->fldl(Address::Absolute(src));
1765 }
1766 } else {
1767 CHECK(dest.IsXmmRegister());
1768 if (size == 4) {
1769 fs()->movss(dest.AsXmmRegister(), Address::Absolute(src));
1770 } else {
1771 fs()->movsd(dest.AsXmmRegister(), Address::Absolute(src));
1772 }
1773 }
1774}
1775
Ian Rogers2c8f6532011-09-02 17:16:34 -07001776void X86Assembler::LoadRef(ManagedRegister mdest, FrameOffset src) {
1777 X86ManagedRegister dest = mdest.AsX86();
Ian Rogersb033c752011-07-20 12:22:35 -07001778 CHECK(dest.IsCpuRegister());
1779 movl(dest.AsCpuRegister(), Address(ESP, src));
1780}
1781
Ian Rogers2c8f6532011-09-02 17:16:34 -07001782void X86Assembler::LoadRef(ManagedRegister mdest, ManagedRegister base,
1783 MemberOffset offs) {
1784 X86ManagedRegister dest = mdest.AsX86();
Ian Rogersb033c752011-07-20 12:22:35 -07001785 CHECK(dest.IsCpuRegister() && dest.IsCpuRegister());
Ian Rogers2c8f6532011-09-02 17:16:34 -07001786 movl(dest.AsCpuRegister(), Address(base.AsX86().AsCpuRegister(), offs));
Hiroshi Yamauchie63a7452014-02-27 14:44:36 -08001787 if (kPoisonHeapReferences) {
1788 negl(dest.AsCpuRegister());
1789 }
Ian Rogersb033c752011-07-20 12:22:35 -07001790}
1791
Ian Rogers2c8f6532011-09-02 17:16:34 -07001792void X86Assembler::LoadRawPtr(ManagedRegister mdest, ManagedRegister base,
1793 Offset offs) {
1794 X86ManagedRegister dest = mdest.AsX86();
Ian Rogersa04d3972011-08-17 11:33:44 -07001795 CHECK(dest.IsCpuRegister() && dest.IsCpuRegister());
Ian Rogers2c8f6532011-09-02 17:16:34 -07001796 movl(dest.AsCpuRegister(), Address(base.AsX86().AsCpuRegister(), offs));
Ian Rogersa04d3972011-08-17 11:33:44 -07001797}
1798
Ian Rogersdd7624d2014-03-14 17:43:00 -07001799void X86Assembler::LoadRawPtrFromThread32(ManagedRegister mdest,
1800 ThreadOffset<4> offs) {
Ian Rogers2c8f6532011-09-02 17:16:34 -07001801 X86ManagedRegister dest = mdest.AsX86();
Ian Rogersb033c752011-07-20 12:22:35 -07001802 CHECK(dest.IsCpuRegister());
Ian Rogers0d666d82011-08-14 16:03:46 -07001803 fs()->movl(dest.AsCpuRegister(), Address::Absolute(offs));
Ian Rogersb033c752011-07-20 12:22:35 -07001804}
1805
jeffhao58136ca2012-05-24 13:40:11 -07001806void X86Assembler::SignExtend(ManagedRegister mreg, size_t size) {
1807 X86ManagedRegister reg = mreg.AsX86();
1808 CHECK(size == 1 || size == 2) << size;
1809 CHECK(reg.IsCpuRegister()) << reg;
1810 if (size == 1) {
1811 movsxb(reg.AsCpuRegister(), reg.AsByteRegister());
1812 } else {
1813 movsxw(reg.AsCpuRegister(), reg.AsCpuRegister());
1814 }
1815}
1816
jeffhaocee4d0c2012-06-15 14:42:01 -07001817void X86Assembler::ZeroExtend(ManagedRegister mreg, size_t size) {
1818 X86ManagedRegister reg = mreg.AsX86();
1819 CHECK(size == 1 || size == 2) << size;
1820 CHECK(reg.IsCpuRegister()) << reg;
1821 if (size == 1) {
1822 movzxb(reg.AsCpuRegister(), reg.AsByteRegister());
1823 } else {
1824 movzxw(reg.AsCpuRegister(), reg.AsCpuRegister());
1825 }
1826}
1827
Ian Rogersb5d09b22012-03-06 22:14:17 -08001828void X86Assembler::Move(ManagedRegister mdest, ManagedRegister msrc, size_t size) {
Ian Rogers2c8f6532011-09-02 17:16:34 -07001829 X86ManagedRegister dest = mdest.AsX86();
1830 X86ManagedRegister src = msrc.AsX86();
Ian Rogersb033c752011-07-20 12:22:35 -07001831 if (!dest.Equals(src)) {
1832 if (dest.IsCpuRegister() && src.IsCpuRegister()) {
1833 movl(dest.AsCpuRegister(), src.AsCpuRegister());
Ian Rogersb5d09b22012-03-06 22:14:17 -08001834 } else if (src.IsX87Register() && dest.IsXmmRegister()) {
1835 // Pass via stack and pop X87 register
1836 subl(ESP, Immediate(16));
1837 if (size == 4) {
1838 CHECK_EQ(src.AsX87Register(), ST0);
1839 fstps(Address(ESP, 0));
1840 movss(dest.AsXmmRegister(), Address(ESP, 0));
1841 } else {
1842 CHECK_EQ(src.AsX87Register(), ST0);
1843 fstpl(Address(ESP, 0));
1844 movsd(dest.AsXmmRegister(), Address(ESP, 0));
1845 }
1846 addl(ESP, Immediate(16));
Ian Rogersb033c752011-07-20 12:22:35 -07001847 } else {
1848 // TODO: x87, SSE
Ian Rogers2c8f6532011-09-02 17:16:34 -07001849 UNIMPLEMENTED(FATAL) << ": Move " << dest << ", " << src;
Ian Rogersb033c752011-07-20 12:22:35 -07001850 }
1851 }
1852}
1853
Ian Rogers2c8f6532011-09-02 17:16:34 -07001854void X86Assembler::CopyRef(FrameOffset dest, FrameOffset src,
1855 ManagedRegister mscratch) {
1856 X86ManagedRegister scratch = mscratch.AsX86();
1857 CHECK(scratch.IsCpuRegister());
1858 movl(scratch.AsCpuRegister(), Address(ESP, src));
1859 movl(Address(ESP, dest), scratch.AsCpuRegister());
1860}
1861
Ian Rogersdd7624d2014-03-14 17:43:00 -07001862void X86Assembler::CopyRawPtrFromThread32(FrameOffset fr_offs,
1863 ThreadOffset<4> thr_offs,
Ian Rogers2c8f6532011-09-02 17:16:34 -07001864 ManagedRegister mscratch) {
1865 X86ManagedRegister scratch = mscratch.AsX86();
1866 CHECK(scratch.IsCpuRegister());
1867 fs()->movl(scratch.AsCpuRegister(), Address::Absolute(thr_offs));
1868 Store(fr_offs, scratch, 4);
1869}
1870
Ian Rogersdd7624d2014-03-14 17:43:00 -07001871void X86Assembler::CopyRawPtrToThread32(ThreadOffset<4> thr_offs,
Ian Rogers2c8f6532011-09-02 17:16:34 -07001872 FrameOffset fr_offs,
1873 ManagedRegister mscratch) {
1874 X86ManagedRegister scratch = mscratch.AsX86();
1875 CHECK(scratch.IsCpuRegister());
1876 Load(scratch, fr_offs, 4);
1877 fs()->movl(Address::Absolute(thr_offs), scratch.AsCpuRegister());
1878}
1879
1880void X86Assembler::Copy(FrameOffset dest, FrameOffset src,
1881 ManagedRegister mscratch,
1882 size_t size) {
1883 X86ManagedRegister scratch = mscratch.AsX86();
Ian Rogersb033c752011-07-20 12:22:35 -07001884 if (scratch.IsCpuRegister() && size == 8) {
1885 Load(scratch, src, 4);
1886 Store(dest, scratch, 4);
1887 Load(scratch, FrameOffset(src.Int32Value() + 4), 4);
1888 Store(FrameOffset(dest.Int32Value() + 4), scratch, 4);
1889 } else {
1890 Load(scratch, src, size);
1891 Store(dest, scratch, size);
1892 }
1893}
1894
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001895void X86Assembler::Copy(FrameOffset /*dst*/, ManagedRegister /*src_base*/, Offset /*src_offset*/,
1896 ManagedRegister /*scratch*/, size_t /*size*/) {
Ian Rogersdc51b792011-09-22 20:41:37 -07001897 UNIMPLEMENTED(FATAL);
1898}
1899
Ian Rogers5a7a74a2011-09-26 16:32:29 -07001900void X86Assembler::Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src,
1901 ManagedRegister scratch, size_t size) {
1902 CHECK(scratch.IsNoRegister());
1903 CHECK_EQ(size, 4u);
1904 pushl(Address(ESP, src));
1905 popl(Address(dest_base.AsX86().AsCpuRegister(), dest_offset));
1906}
1907
Ian Rogersdc51b792011-09-22 20:41:37 -07001908void X86Assembler::Copy(FrameOffset dest, FrameOffset src_base, Offset src_offset,
1909 ManagedRegister mscratch, size_t size) {
1910 Register scratch = mscratch.AsX86().AsCpuRegister();
1911 CHECK_EQ(size, 4u);
1912 movl(scratch, Address(ESP, src_base));
1913 movl(scratch, Address(scratch, src_offset));
1914 movl(Address(ESP, dest), scratch);
1915}
1916
Ian Rogers5a7a74a2011-09-26 16:32:29 -07001917void X86Assembler::Copy(ManagedRegister dest, Offset dest_offset,
1918 ManagedRegister src, Offset src_offset,
1919 ManagedRegister scratch, size_t size) {
Ian Rogersdc51b792011-09-22 20:41:37 -07001920 CHECK_EQ(size, 4u);
Ian Rogers5a7a74a2011-09-26 16:32:29 -07001921 CHECK(scratch.IsNoRegister());
1922 pushl(Address(src.AsX86().AsCpuRegister(), src_offset));
1923 popl(Address(dest.AsX86().AsCpuRegister(), dest_offset));
1924}
1925
1926void X86Assembler::Copy(FrameOffset dest, Offset dest_offset, FrameOffset src, Offset src_offset,
1927 ManagedRegister mscratch, size_t size) {
1928 Register scratch = mscratch.AsX86().AsCpuRegister();
1929 CHECK_EQ(size, 4u);
1930 CHECK_EQ(dest.Int32Value(), src.Int32Value());
1931 movl(scratch, Address(ESP, src));
1932 pushl(Address(scratch, src_offset));
Ian Rogersdc51b792011-09-22 20:41:37 -07001933 popl(Address(scratch, dest_offset));
1934}
1935
Ian Rogerse5de95b2011-09-18 20:31:38 -07001936void X86Assembler::MemoryBarrier(ManagedRegister) {
Elliott Hughes79ab9e32012-03-12 15:41:35 -07001937 mfence();
Ian Rogerse5de95b2011-09-18 20:31:38 -07001938}
1939
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001940void X86Assembler::CreateHandleScopeEntry(ManagedRegister mout_reg,
1941 FrameOffset handle_scope_offset,
Ian Rogers2c8f6532011-09-02 17:16:34 -07001942 ManagedRegister min_reg, bool null_allowed) {
1943 X86ManagedRegister out_reg = mout_reg.AsX86();
1944 X86ManagedRegister in_reg = min_reg.AsX86();
Ian Rogersb033c752011-07-20 12:22:35 -07001945 CHECK(in_reg.IsCpuRegister());
1946 CHECK(out_reg.IsCpuRegister());
Ian Rogers408f79a2011-08-23 18:22:33 -07001947 VerifyObject(in_reg, null_allowed);
Ian Rogersb033c752011-07-20 12:22:35 -07001948 if (null_allowed) {
1949 Label null_arg;
1950 if (!out_reg.Equals(in_reg)) {
1951 xorl(out_reg.AsCpuRegister(), out_reg.AsCpuRegister());
1952 }
1953 testl(in_reg.AsCpuRegister(), in_reg.AsCpuRegister());
Elliott Hughes18c07532011-08-18 15:50:51 -07001954 j(kZero, &null_arg);
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001955 leal(out_reg.AsCpuRegister(), Address(ESP, handle_scope_offset));
Ian Rogersb033c752011-07-20 12:22:35 -07001956 Bind(&null_arg);
1957 } else {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001958 leal(out_reg.AsCpuRegister(), Address(ESP, handle_scope_offset));
Ian Rogersb033c752011-07-20 12:22:35 -07001959 }
1960}
1961
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001962void X86Assembler::CreateHandleScopeEntry(FrameOffset out_off,
1963 FrameOffset handle_scope_offset,
Ian Rogers2c8f6532011-09-02 17:16:34 -07001964 ManagedRegister mscratch,
1965 bool null_allowed) {
1966 X86ManagedRegister scratch = mscratch.AsX86();
Ian Rogersb033c752011-07-20 12:22:35 -07001967 CHECK(scratch.IsCpuRegister());
1968 if (null_allowed) {
1969 Label null_arg;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001970 movl(scratch.AsCpuRegister(), Address(ESP, handle_scope_offset));
Ian Rogersb033c752011-07-20 12:22:35 -07001971 testl(scratch.AsCpuRegister(), scratch.AsCpuRegister());
Elliott Hughes18c07532011-08-18 15:50:51 -07001972 j(kZero, &null_arg);
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001973 leal(scratch.AsCpuRegister(), Address(ESP, handle_scope_offset));
Ian Rogersb033c752011-07-20 12:22:35 -07001974 Bind(&null_arg);
1975 } else {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001976 leal(scratch.AsCpuRegister(), Address(ESP, handle_scope_offset));
Ian Rogersb033c752011-07-20 12:22:35 -07001977 }
1978 Store(out_off, scratch, 4);
1979}
1980
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001981// Given a handle scope entry, load the associated reference.
1982void X86Assembler::LoadReferenceFromHandleScope(ManagedRegister mout_reg,
Ian Rogers2c8f6532011-09-02 17:16:34 -07001983 ManagedRegister min_reg) {
1984 X86ManagedRegister out_reg = mout_reg.AsX86();
1985 X86ManagedRegister in_reg = min_reg.AsX86();
Ian Rogersb033c752011-07-20 12:22:35 -07001986 CHECK(out_reg.IsCpuRegister());
1987 CHECK(in_reg.IsCpuRegister());
1988 Label null_arg;
1989 if (!out_reg.Equals(in_reg)) {
1990 xorl(out_reg.AsCpuRegister(), out_reg.AsCpuRegister());
1991 }
1992 testl(in_reg.AsCpuRegister(), in_reg.AsCpuRegister());
Elliott Hughes18c07532011-08-18 15:50:51 -07001993 j(kZero, &null_arg);
Ian Rogersb033c752011-07-20 12:22:35 -07001994 movl(out_reg.AsCpuRegister(), Address(in_reg.AsCpuRegister(), 0));
1995 Bind(&null_arg);
1996}
1997
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001998void X86Assembler::VerifyObject(ManagedRegister /*src*/, bool /*could_be_null*/) {
Ian Rogersb033c752011-07-20 12:22:35 -07001999 // TODO: not validating references
2000}
2001
Elliott Hughes1bac54f2012-03-16 12:48:31 -07002002void X86Assembler::VerifyObject(FrameOffset /*src*/, bool /*could_be_null*/) {
Ian Rogersb033c752011-07-20 12:22:35 -07002003 // TODO: not validating references
2004}
2005
Ian Rogers2c8f6532011-09-02 17:16:34 -07002006void X86Assembler::Call(ManagedRegister mbase, Offset offset, ManagedRegister) {
2007 X86ManagedRegister base = mbase.AsX86();
Ian Rogersb033c752011-07-20 12:22:35 -07002008 CHECK(base.IsCpuRegister());
Ian Rogersdf20fe02011-07-20 20:34:16 -07002009 call(Address(base.AsCpuRegister(), offset.Int32Value()));
Ian Rogersb033c752011-07-20 12:22:35 -07002010 // TODO: place reference map on call
2011}
2012
Ian Rogers67375ac2011-09-14 00:55:44 -07002013void X86Assembler::Call(FrameOffset base, Offset offset, ManagedRegister mscratch) {
2014 Register scratch = mscratch.AsX86().AsCpuRegister();
2015 movl(scratch, Address(ESP, base));
2016 call(Address(scratch, offset));
Carl Shapiroe2d373e2011-07-25 15:20:06 -07002017}
2018
Ian Rogersdd7624d2014-03-14 17:43:00 -07002019void X86Assembler::CallFromThread32(ThreadOffset<4> offset, ManagedRegister /*mscratch*/) {
Ian Rogersbdb03912011-09-14 00:55:44 -07002020 fs()->call(Address::Absolute(offset));
Shih-wei Liao668512a2011-09-01 14:18:34 -07002021}
2022
Ian Rogers2c8f6532011-09-02 17:16:34 -07002023void X86Assembler::GetCurrentThread(ManagedRegister tr) {
2024 fs()->movl(tr.AsX86().AsCpuRegister(),
Ian Rogersdd7624d2014-03-14 17:43:00 -07002025 Address::Absolute(Thread::SelfOffset<4>()));
Shih-wei Liao668512a2011-09-01 14:18:34 -07002026}
2027
Ian Rogers2c8f6532011-09-02 17:16:34 -07002028void X86Assembler::GetCurrentThread(FrameOffset offset,
2029 ManagedRegister mscratch) {
2030 X86ManagedRegister scratch = mscratch.AsX86();
Ian Rogersdd7624d2014-03-14 17:43:00 -07002031 fs()->movl(scratch.AsCpuRegister(), Address::Absolute(Thread::SelfOffset<4>()));
Shih-wei Liao668512a2011-09-01 14:18:34 -07002032 movl(Address(ESP, offset), scratch.AsCpuRegister());
2033}
2034
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002035void X86Assembler::ExceptionPoll(ManagedRegister /*scratch*/, size_t stack_adjust) {
2036 X86ExceptionSlowPath* slow = new X86ExceptionSlowPath(stack_adjust);
Ian Rogers45a76cb2011-07-21 22:00:15 -07002037 buffer_.EnqueueSlowPath(slow);
Ian Rogersdd7624d2014-03-14 17:43:00 -07002038 fs()->cmpl(Address::Absolute(Thread::ExceptionOffset<4>()), Immediate(0));
Elliott Hughes18c07532011-08-18 15:50:51 -07002039 j(kNotEqual, slow->Entry());
Ian Rogers45a76cb2011-07-21 22:00:15 -07002040}
Ian Rogers0d666d82011-08-14 16:03:46 -07002041
Ian Rogers2c8f6532011-09-02 17:16:34 -07002042void X86ExceptionSlowPath::Emit(Assembler *sasm) {
2043 X86Assembler* sp_asm = down_cast<X86Assembler*>(sasm);
Ian Rogers0d666d82011-08-14 16:03:46 -07002044#define __ sp_asm->
2045 __ Bind(&entry_);
Elliott Hughes20cde902011-10-04 17:37:27 -07002046 // Note: the return value is dead
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002047 if (stack_adjust_ != 0) { // Fix up the frame.
2048 __ DecreaseFrameSize(stack_adjust_);
2049 }
Ian Rogers67375ac2011-09-14 00:55:44 -07002050 // Pass exception as argument in EAX
Ian Rogersdd7624d2014-03-14 17:43:00 -07002051 __ fs()->movl(EAX, Address::Absolute(Thread::ExceptionOffset<4>()));
2052 __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(4, pDeliverException)));
Ian Rogers67375ac2011-09-14 00:55:44 -07002053 // this call should never return
2054 __ int3();
Ian Rogers0d666d82011-08-14 16:03:46 -07002055#undef __
Ian Rogers45a76cb2011-07-21 22:00:15 -07002056}
2057
Ian Rogers2c8f6532011-09-02 17:16:34 -07002058} // namespace x86
Ian Rogersb033c752011-07-20 12:22:35 -07002059} // namespace art