blob: 4c7c4e97e9843f6d680ec31d3ea7d8ce432babad [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;
54 EmitLabel(label, kSize);
55}
56
57
Nicolas Geoffray8ccc3f52014-03-19 10:34:11 +000058void X86Assembler::call(const ExternalLabel& label) {
59 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
60 intptr_t call_start = buffer_.GetPosition();
61 EmitUint8(0xE8);
62 EmitInt32(label.address());
63 static const intptr_t kCallExternalLabelSize = 5;
64 DCHECK_EQ((buffer_.GetPosition() - call_start), kCallExternalLabelSize);
65}
66
67
Ian Rogers2c8f6532011-09-02 17:16:34 -070068void X86Assembler::pushl(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070069 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
70 EmitUint8(0x50 + reg);
71}
72
73
Ian Rogers2c8f6532011-09-02 17:16:34 -070074void X86Assembler::pushl(const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070075 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
76 EmitUint8(0xFF);
77 EmitOperand(6, address);
78}
79
80
Ian Rogers2c8f6532011-09-02 17:16:34 -070081void X86Assembler::pushl(const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070082 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Ian Rogers44fb0d02012-03-23 16:46:24 -070083 if (imm.is_int8()) {
84 EmitUint8(0x6A);
85 EmitUint8(imm.value() & 0xFF);
86 } else {
87 EmitUint8(0x68);
88 EmitImmediate(imm);
89 }
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070090}
91
92
Ian Rogers2c8f6532011-09-02 17:16:34 -070093void X86Assembler::popl(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070094 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
95 EmitUint8(0x58 + reg);
96}
97
98
Ian Rogers2c8f6532011-09-02 17:16:34 -070099void X86Assembler::popl(const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700100 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
101 EmitUint8(0x8F);
102 EmitOperand(0, address);
103}
104
105
Ian Rogers2c8f6532011-09-02 17:16:34 -0700106void X86Assembler::movl(Register dst, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700107 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
108 EmitUint8(0xB8 + dst);
109 EmitImmediate(imm);
110}
111
112
Ian Rogers2c8f6532011-09-02 17:16:34 -0700113void X86Assembler::movl(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700114 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
115 EmitUint8(0x89);
116 EmitRegisterOperand(src, dst);
117}
118
119
Ian Rogers2c8f6532011-09-02 17:16:34 -0700120void X86Assembler::movl(Register dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700121 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
122 EmitUint8(0x8B);
123 EmitOperand(dst, src);
124}
125
126
Ian Rogers2c8f6532011-09-02 17:16:34 -0700127void X86Assembler::movl(const Address& dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700128 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
129 EmitUint8(0x89);
130 EmitOperand(src, dst);
131}
132
133
Ian Rogers2c8f6532011-09-02 17:16:34 -0700134void X86Assembler::movl(const Address& dst, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700135 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
136 EmitUint8(0xC7);
137 EmitOperand(0, dst);
138 EmitImmediate(imm);
139}
140
Ian Rogersbdb03912011-09-14 00:55:44 -0700141void X86Assembler::movl(const Address& dst, Label* lbl) {
142 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
143 EmitUint8(0xC7);
144 EmitOperand(0, dst);
145 EmitLabel(lbl, dst.length_ + 5);
146}
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700147
Ian Rogers2c8f6532011-09-02 17:16:34 -0700148void X86Assembler::movzxb(Register dst, ByteRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700149 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
150 EmitUint8(0x0F);
151 EmitUint8(0xB6);
152 EmitRegisterOperand(dst, src);
153}
154
155
Ian Rogers2c8f6532011-09-02 17:16:34 -0700156void X86Assembler::movzxb(Register dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700157 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
158 EmitUint8(0x0F);
159 EmitUint8(0xB6);
160 EmitOperand(dst, src);
161}
162
163
Ian Rogers2c8f6532011-09-02 17:16:34 -0700164void X86Assembler::movsxb(Register dst, ByteRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700165 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
166 EmitUint8(0x0F);
167 EmitUint8(0xBE);
168 EmitRegisterOperand(dst, src);
169}
170
171
Ian Rogers2c8f6532011-09-02 17:16:34 -0700172void X86Assembler::movsxb(Register dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700173 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
174 EmitUint8(0x0F);
175 EmitUint8(0xBE);
176 EmitOperand(dst, src);
177}
178
179
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700180void X86Assembler::movb(Register /*dst*/, const Address& /*src*/) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700181 LOG(FATAL) << "Use movzxb or movsxb instead.";
182}
183
184
Ian Rogers2c8f6532011-09-02 17:16:34 -0700185void X86Assembler::movb(const Address& dst, ByteRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700186 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
187 EmitUint8(0x88);
188 EmitOperand(src, dst);
189}
190
191
Ian Rogers2c8f6532011-09-02 17:16:34 -0700192void X86Assembler::movb(const Address& dst, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700193 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
194 EmitUint8(0xC6);
195 EmitOperand(EAX, dst);
196 CHECK(imm.is_int8());
197 EmitUint8(imm.value() & 0xFF);
198}
199
200
Ian Rogers2c8f6532011-09-02 17:16:34 -0700201void X86Assembler::movzxw(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700202 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
203 EmitUint8(0x0F);
204 EmitUint8(0xB7);
205 EmitRegisterOperand(dst, src);
206}
207
208
Ian Rogers2c8f6532011-09-02 17:16:34 -0700209void X86Assembler::movzxw(Register dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700210 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
211 EmitUint8(0x0F);
212 EmitUint8(0xB7);
213 EmitOperand(dst, src);
214}
215
216
Ian Rogers2c8f6532011-09-02 17:16:34 -0700217void X86Assembler::movsxw(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700218 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
219 EmitUint8(0x0F);
220 EmitUint8(0xBF);
221 EmitRegisterOperand(dst, src);
222}
223
224
Ian Rogers2c8f6532011-09-02 17:16:34 -0700225void X86Assembler::movsxw(Register dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700226 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
227 EmitUint8(0x0F);
228 EmitUint8(0xBF);
229 EmitOperand(dst, src);
230}
231
232
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700233void X86Assembler::movw(Register /*dst*/, const Address& /*src*/) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700234 LOG(FATAL) << "Use movzxw or movsxw instead.";
235}
236
237
Ian Rogers2c8f6532011-09-02 17:16:34 -0700238void X86Assembler::movw(const Address& dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700239 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
240 EmitOperandSizeOverride();
241 EmitUint8(0x89);
242 EmitOperand(src, dst);
243}
244
245
Nicolas Geoffray26a25ef2014-09-30 13:54:09 +0100246void X86Assembler::movw(const Address& dst, const Immediate& imm) {
247 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
248 EmitOperandSizeOverride();
249 EmitUint8(0xC7);
250 EmitOperand(0, dst);
Nicolas Geoffrayb6e72062014-10-07 14:54:48 +0100251 CHECK(imm.is_uint16() || imm.is_int16());
Nicolas Geoffray26a25ef2014-09-30 13:54:09 +0100252 EmitUint8(imm.value() & 0xFF);
253 EmitUint8(imm.value() >> 8);
254}
255
256
Ian Rogers2c8f6532011-09-02 17:16:34 -0700257void X86Assembler::leal(Register dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700258 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
259 EmitUint8(0x8D);
260 EmitOperand(dst, src);
261}
262
263
Ian Rogers2c8f6532011-09-02 17:16:34 -0700264void X86Assembler::cmovl(Condition condition, Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700265 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
266 EmitUint8(0x0F);
Ian Rogersb033c752011-07-20 12:22:35 -0700267 EmitUint8(0x40 + condition);
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700268 EmitRegisterOperand(dst, src);
269}
270
271
Ian Rogers2c8f6532011-09-02 17:16:34 -0700272void X86Assembler::setb(Condition condition, Register dst) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700273 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
274 EmitUint8(0x0F);
Ian Rogersb033c752011-07-20 12:22:35 -0700275 EmitUint8(0x90 + condition);
276 EmitOperand(0, Operand(dst));
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700277}
278
279
Ian Rogers2c8f6532011-09-02 17:16:34 -0700280void X86Assembler::movss(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700281 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
282 EmitUint8(0xF3);
283 EmitUint8(0x0F);
284 EmitUint8(0x10);
285 EmitOperand(dst, src);
286}
287
288
Ian Rogers2c8f6532011-09-02 17:16:34 -0700289void X86Assembler::movss(const Address& dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700290 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
291 EmitUint8(0xF3);
292 EmitUint8(0x0F);
293 EmitUint8(0x11);
294 EmitOperand(src, dst);
295}
296
297
Ian Rogers2c8f6532011-09-02 17:16:34 -0700298void X86Assembler::movss(XmmRegister 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 EmitXmmRegisterOperand(src, dst);
304}
305
306
Ian Rogers2c8f6532011-09-02 17:16:34 -0700307void X86Assembler::movd(XmmRegister dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700308 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
309 EmitUint8(0x66);
310 EmitUint8(0x0F);
311 EmitUint8(0x6E);
312 EmitOperand(dst, Operand(src));
313}
314
315
Ian Rogers2c8f6532011-09-02 17:16:34 -0700316void X86Assembler::movd(Register dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700317 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
318 EmitUint8(0x66);
319 EmitUint8(0x0F);
320 EmitUint8(0x7E);
321 EmitOperand(src, Operand(dst));
322}
323
324
Ian Rogers2c8f6532011-09-02 17:16:34 -0700325void X86Assembler::addss(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700326 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
327 EmitUint8(0xF3);
328 EmitUint8(0x0F);
329 EmitUint8(0x58);
330 EmitXmmRegisterOperand(dst, src);
331}
332
333
Ian Rogers2c8f6532011-09-02 17:16:34 -0700334void X86Assembler::addss(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700335 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
336 EmitUint8(0xF3);
337 EmitUint8(0x0F);
338 EmitUint8(0x58);
339 EmitOperand(dst, src);
340}
341
342
Ian Rogers2c8f6532011-09-02 17:16:34 -0700343void X86Assembler::subss(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700344 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
345 EmitUint8(0xF3);
346 EmitUint8(0x0F);
347 EmitUint8(0x5C);
348 EmitXmmRegisterOperand(dst, src);
349}
350
351
Ian Rogers2c8f6532011-09-02 17:16:34 -0700352void X86Assembler::subss(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700353 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
354 EmitUint8(0xF3);
355 EmitUint8(0x0F);
356 EmitUint8(0x5C);
357 EmitOperand(dst, src);
358}
359
360
Ian Rogers2c8f6532011-09-02 17:16:34 -0700361void X86Assembler::mulss(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700362 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
363 EmitUint8(0xF3);
364 EmitUint8(0x0F);
365 EmitUint8(0x59);
366 EmitXmmRegisterOperand(dst, src);
367}
368
369
Ian Rogers2c8f6532011-09-02 17:16:34 -0700370void X86Assembler::mulss(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700371 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
372 EmitUint8(0xF3);
373 EmitUint8(0x0F);
374 EmitUint8(0x59);
375 EmitOperand(dst, src);
376}
377
378
Ian Rogers2c8f6532011-09-02 17:16:34 -0700379void X86Assembler::divss(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700380 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
381 EmitUint8(0xF3);
382 EmitUint8(0x0F);
383 EmitUint8(0x5E);
384 EmitXmmRegisterOperand(dst, src);
385}
386
387
Ian Rogers2c8f6532011-09-02 17:16:34 -0700388void X86Assembler::divss(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700389 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
390 EmitUint8(0xF3);
391 EmitUint8(0x0F);
392 EmitUint8(0x5E);
393 EmitOperand(dst, src);
394}
395
396
Ian Rogers2c8f6532011-09-02 17:16:34 -0700397void X86Assembler::flds(const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700398 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
399 EmitUint8(0xD9);
400 EmitOperand(0, src);
401}
402
403
Ian Rogers2c8f6532011-09-02 17:16:34 -0700404void X86Assembler::fstps(const Address& dst) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700405 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
406 EmitUint8(0xD9);
407 EmitOperand(3, dst);
408}
409
410
Ian Rogers2c8f6532011-09-02 17:16:34 -0700411void X86Assembler::movsd(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700412 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
413 EmitUint8(0xF2);
414 EmitUint8(0x0F);
415 EmitUint8(0x10);
416 EmitOperand(dst, src);
417}
418
419
Ian Rogers2c8f6532011-09-02 17:16:34 -0700420void X86Assembler::movsd(const Address& dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700421 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
422 EmitUint8(0xF2);
423 EmitUint8(0x0F);
424 EmitUint8(0x11);
425 EmitOperand(src, dst);
426}
427
428
Ian Rogers2c8f6532011-09-02 17:16:34 -0700429void X86Assembler::movsd(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700430 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
431 EmitUint8(0xF2);
432 EmitUint8(0x0F);
433 EmitUint8(0x11);
434 EmitXmmRegisterOperand(src, dst);
435}
436
437
Ian Rogers2c8f6532011-09-02 17:16:34 -0700438void X86Assembler::addsd(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700439 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
440 EmitUint8(0xF2);
441 EmitUint8(0x0F);
442 EmitUint8(0x58);
443 EmitXmmRegisterOperand(dst, src);
444}
445
446
Ian Rogers2c8f6532011-09-02 17:16:34 -0700447void X86Assembler::addsd(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700448 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
449 EmitUint8(0xF2);
450 EmitUint8(0x0F);
451 EmitUint8(0x58);
452 EmitOperand(dst, src);
453}
454
455
Ian Rogers2c8f6532011-09-02 17:16:34 -0700456void X86Assembler::subsd(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700457 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
458 EmitUint8(0xF2);
459 EmitUint8(0x0F);
460 EmitUint8(0x5C);
461 EmitXmmRegisterOperand(dst, src);
462}
463
464
Ian Rogers2c8f6532011-09-02 17:16:34 -0700465void X86Assembler::subsd(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700466 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
467 EmitUint8(0xF2);
468 EmitUint8(0x0F);
469 EmitUint8(0x5C);
470 EmitOperand(dst, src);
471}
472
473
Ian Rogers2c8f6532011-09-02 17:16:34 -0700474void X86Assembler::mulsd(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700475 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
476 EmitUint8(0xF2);
477 EmitUint8(0x0F);
478 EmitUint8(0x59);
479 EmitXmmRegisterOperand(dst, src);
480}
481
482
Ian Rogers2c8f6532011-09-02 17:16:34 -0700483void X86Assembler::mulsd(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700484 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
485 EmitUint8(0xF2);
486 EmitUint8(0x0F);
487 EmitUint8(0x59);
488 EmitOperand(dst, src);
489}
490
491
Ian Rogers2c8f6532011-09-02 17:16:34 -0700492void X86Assembler::divsd(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700493 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
494 EmitUint8(0xF2);
495 EmitUint8(0x0F);
496 EmitUint8(0x5E);
497 EmitXmmRegisterOperand(dst, src);
498}
499
500
Ian Rogers2c8f6532011-09-02 17:16:34 -0700501void X86Assembler::divsd(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700502 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
503 EmitUint8(0xF2);
504 EmitUint8(0x0F);
505 EmitUint8(0x5E);
506 EmitOperand(dst, src);
507}
508
509
Ian Rogers2c8f6532011-09-02 17:16:34 -0700510void X86Assembler::cvtsi2ss(XmmRegister dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700511 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
512 EmitUint8(0xF3);
513 EmitUint8(0x0F);
514 EmitUint8(0x2A);
515 EmitOperand(dst, Operand(src));
516}
517
518
Ian Rogers2c8f6532011-09-02 17:16:34 -0700519void X86Assembler::cvtsi2sd(XmmRegister dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700520 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
521 EmitUint8(0xF2);
522 EmitUint8(0x0F);
523 EmitUint8(0x2A);
524 EmitOperand(dst, Operand(src));
525}
526
527
Ian Rogers2c8f6532011-09-02 17:16:34 -0700528void X86Assembler::cvtss2si(Register dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700529 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
530 EmitUint8(0xF3);
531 EmitUint8(0x0F);
532 EmitUint8(0x2D);
533 EmitXmmRegisterOperand(dst, src);
534}
535
536
Ian Rogers2c8f6532011-09-02 17:16:34 -0700537void X86Assembler::cvtss2sd(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700538 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
539 EmitUint8(0xF3);
540 EmitUint8(0x0F);
541 EmitUint8(0x5A);
542 EmitXmmRegisterOperand(dst, src);
543}
544
545
Ian Rogers2c8f6532011-09-02 17:16:34 -0700546void X86Assembler::cvtsd2si(Register dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700547 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
548 EmitUint8(0xF2);
549 EmitUint8(0x0F);
550 EmitUint8(0x2D);
551 EmitXmmRegisterOperand(dst, src);
552}
553
554
Ian Rogers2c8f6532011-09-02 17:16:34 -0700555void X86Assembler::cvttss2si(Register dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700556 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
557 EmitUint8(0xF3);
558 EmitUint8(0x0F);
559 EmitUint8(0x2C);
560 EmitXmmRegisterOperand(dst, src);
561}
562
563
Ian Rogers2c8f6532011-09-02 17:16:34 -0700564void X86Assembler::cvttsd2si(Register dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700565 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
566 EmitUint8(0xF2);
567 EmitUint8(0x0F);
568 EmitUint8(0x2C);
569 EmitXmmRegisterOperand(dst, src);
570}
571
572
Ian Rogers2c8f6532011-09-02 17:16:34 -0700573void X86Assembler::cvtsd2ss(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700574 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
575 EmitUint8(0xF2);
576 EmitUint8(0x0F);
577 EmitUint8(0x5A);
578 EmitXmmRegisterOperand(dst, src);
579}
580
581
Ian Rogers2c8f6532011-09-02 17:16:34 -0700582void X86Assembler::cvtdq2pd(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700583 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
584 EmitUint8(0xF3);
585 EmitUint8(0x0F);
586 EmitUint8(0xE6);
587 EmitXmmRegisterOperand(dst, src);
588}
589
590
Ian Rogers2c8f6532011-09-02 17:16:34 -0700591void X86Assembler::comiss(XmmRegister a, XmmRegister b) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700592 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
593 EmitUint8(0x0F);
594 EmitUint8(0x2F);
595 EmitXmmRegisterOperand(a, b);
596}
597
598
Ian Rogers2c8f6532011-09-02 17:16:34 -0700599void X86Assembler::comisd(XmmRegister a, XmmRegister b) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700600 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
601 EmitUint8(0x66);
602 EmitUint8(0x0F);
603 EmitUint8(0x2F);
604 EmitXmmRegisterOperand(a, b);
605}
606
607
Ian Rogers2c8f6532011-09-02 17:16:34 -0700608void X86Assembler::sqrtsd(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700609 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
610 EmitUint8(0xF2);
611 EmitUint8(0x0F);
612 EmitUint8(0x51);
613 EmitXmmRegisterOperand(dst, src);
614}
615
616
Ian Rogers2c8f6532011-09-02 17:16:34 -0700617void X86Assembler::sqrtss(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700618 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
619 EmitUint8(0xF3);
620 EmitUint8(0x0F);
621 EmitUint8(0x51);
622 EmitXmmRegisterOperand(dst, src);
623}
624
625
Ian Rogers2c8f6532011-09-02 17:16:34 -0700626void X86Assembler::xorpd(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700627 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
628 EmitUint8(0x66);
629 EmitUint8(0x0F);
630 EmitUint8(0x57);
631 EmitOperand(dst, src);
632}
633
634
Ian Rogers2c8f6532011-09-02 17:16:34 -0700635void X86Assembler::xorpd(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700636 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
637 EmitUint8(0x66);
638 EmitUint8(0x0F);
639 EmitUint8(0x57);
640 EmitXmmRegisterOperand(dst, src);
641}
642
643
Ian Rogers2c8f6532011-09-02 17:16:34 -0700644void X86Assembler::xorps(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700645 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
646 EmitUint8(0x0F);
647 EmitUint8(0x57);
648 EmitOperand(dst, src);
649}
650
651
Ian Rogers2c8f6532011-09-02 17:16:34 -0700652void X86Assembler::xorps(XmmRegister dst, XmmRegister src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700653 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
654 EmitUint8(0x0F);
655 EmitUint8(0x57);
656 EmitXmmRegisterOperand(dst, src);
657}
658
659
Ian Rogers2c8f6532011-09-02 17:16:34 -0700660void X86Assembler::andpd(XmmRegister dst, const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700661 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
662 EmitUint8(0x66);
663 EmitUint8(0x0F);
664 EmitUint8(0x54);
665 EmitOperand(dst, src);
666}
667
668
Ian Rogers2c8f6532011-09-02 17:16:34 -0700669void X86Assembler::fldl(const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700670 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
671 EmitUint8(0xDD);
672 EmitOperand(0, src);
673}
674
675
Ian Rogers2c8f6532011-09-02 17:16:34 -0700676void X86Assembler::fstpl(const Address& dst) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700677 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
678 EmitUint8(0xDD);
679 EmitOperand(3, dst);
680}
681
682
Ian Rogers2c8f6532011-09-02 17:16:34 -0700683void X86Assembler::fnstcw(const Address& dst) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700684 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
685 EmitUint8(0xD9);
686 EmitOperand(7, dst);
687}
688
689
Ian Rogers2c8f6532011-09-02 17:16:34 -0700690void X86Assembler::fldcw(const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700691 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
692 EmitUint8(0xD9);
693 EmitOperand(5, src);
694}
695
696
Ian Rogers2c8f6532011-09-02 17:16:34 -0700697void X86Assembler::fistpl(const Address& dst) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700698 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
699 EmitUint8(0xDF);
700 EmitOperand(7, dst);
701}
702
703
Ian Rogers2c8f6532011-09-02 17:16:34 -0700704void X86Assembler::fistps(const Address& dst) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700705 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
706 EmitUint8(0xDB);
707 EmitOperand(3, dst);
708}
709
710
Ian Rogers2c8f6532011-09-02 17:16:34 -0700711void X86Assembler::fildl(const Address& src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700712 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
713 EmitUint8(0xDF);
714 EmitOperand(5, src);
715}
716
717
Ian Rogers2c8f6532011-09-02 17:16:34 -0700718void X86Assembler::fincstp() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700719 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
720 EmitUint8(0xD9);
721 EmitUint8(0xF7);
722}
723
724
Ian Rogers2c8f6532011-09-02 17:16:34 -0700725void X86Assembler::ffree(const Immediate& index) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700726 CHECK_LT(index.value(), 7);
727 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
728 EmitUint8(0xDD);
729 EmitUint8(0xC0 + index.value());
730}
731
732
Ian Rogers2c8f6532011-09-02 17:16:34 -0700733void X86Assembler::fsin() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700734 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
735 EmitUint8(0xD9);
736 EmitUint8(0xFE);
737}
738
739
Ian Rogers2c8f6532011-09-02 17:16:34 -0700740void X86Assembler::fcos() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700741 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
742 EmitUint8(0xD9);
743 EmitUint8(0xFF);
744}
745
746
Ian Rogers2c8f6532011-09-02 17:16:34 -0700747void X86Assembler::fptan() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700748 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
749 EmitUint8(0xD9);
750 EmitUint8(0xF2);
751}
752
753
Ian Rogers2c8f6532011-09-02 17:16:34 -0700754void X86Assembler::xchgl(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700755 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
756 EmitUint8(0x87);
757 EmitRegisterOperand(dst, src);
758}
759
Nicolas Geoffray3c049742014-09-24 18:10:46 +0100760
Ian Rogers7caad772012-03-30 01:07:54 -0700761void X86Assembler::xchgl(Register reg, const Address& address) {
762 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
763 EmitUint8(0x87);
764 EmitOperand(reg, address);
765}
766
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700767
Nicolas Geoffray3c049742014-09-24 18:10:46 +0100768void X86Assembler::cmpw(const Address& address, const Immediate& imm) {
769 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
770 EmitUint8(0x66);
771 EmitComplex(7, address, imm);
772}
773
774
Ian Rogers2c8f6532011-09-02 17:16:34 -0700775void X86Assembler::cmpl(Register reg, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700776 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
777 EmitComplex(7, Operand(reg), imm);
778}
779
780
Ian Rogers2c8f6532011-09-02 17:16:34 -0700781void X86Assembler::cmpl(Register reg0, Register reg1) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700782 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
783 EmitUint8(0x3B);
784 EmitOperand(reg0, Operand(reg1));
785}
786
787
Ian Rogers2c8f6532011-09-02 17:16:34 -0700788void X86Assembler::cmpl(Register reg, const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700789 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
790 EmitUint8(0x3B);
791 EmitOperand(reg, address);
792}
793
794
Ian Rogers2c8f6532011-09-02 17:16:34 -0700795void X86Assembler::addl(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700796 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
797 EmitUint8(0x03);
798 EmitRegisterOperand(dst, src);
799}
800
801
Ian Rogers2c8f6532011-09-02 17:16:34 -0700802void X86Assembler::addl(Register reg, const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700803 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
804 EmitUint8(0x03);
805 EmitOperand(reg, address);
806}
807
808
Ian Rogers2c8f6532011-09-02 17:16:34 -0700809void X86Assembler::cmpl(const Address& address, Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700810 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
811 EmitUint8(0x39);
812 EmitOperand(reg, address);
813}
814
815
Ian Rogers2c8f6532011-09-02 17:16:34 -0700816void X86Assembler::cmpl(const Address& address, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700817 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
818 EmitComplex(7, address, imm);
819}
820
821
Ian Rogers2c8f6532011-09-02 17:16:34 -0700822void X86Assembler::testl(Register reg1, Register reg2) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700823 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
824 EmitUint8(0x85);
825 EmitRegisterOperand(reg1, reg2);
826}
827
828
Nicolas Geoffrayf12feb82014-07-17 18:32:41 +0100829void X86Assembler::testl(Register reg, const Address& address) {
830 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
831 EmitUint8(0x85);
832 EmitOperand(reg, address);
833}
834
835
Ian Rogers2c8f6532011-09-02 17:16:34 -0700836void X86Assembler::testl(Register reg, const Immediate& immediate) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700837 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
838 // For registers that have a byte variant (EAX, EBX, ECX, and EDX)
839 // we only test the byte register to keep the encoding short.
840 if (immediate.is_uint8() && reg < 4) {
841 // Use zero-extended 8-bit immediate.
842 if (reg == EAX) {
843 EmitUint8(0xA8);
844 } else {
845 EmitUint8(0xF6);
846 EmitUint8(0xC0 + reg);
847 }
848 EmitUint8(immediate.value() & 0xFF);
849 } else if (reg == EAX) {
850 // Use short form if the destination is EAX.
851 EmitUint8(0xA9);
852 EmitImmediate(immediate);
853 } else {
854 EmitUint8(0xF7);
855 EmitOperand(0, Operand(reg));
856 EmitImmediate(immediate);
857 }
858}
859
860
Ian Rogers2c8f6532011-09-02 17:16:34 -0700861void X86Assembler::andl(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700862 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
863 EmitUint8(0x23);
864 EmitOperand(dst, Operand(src));
865}
866
867
Ian Rogers2c8f6532011-09-02 17:16:34 -0700868void X86Assembler::andl(Register dst, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700869 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
870 EmitComplex(4, Operand(dst), imm);
871}
872
873
Ian Rogers2c8f6532011-09-02 17:16:34 -0700874void X86Assembler::orl(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700875 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
876 EmitUint8(0x0B);
877 EmitOperand(dst, Operand(src));
878}
879
880
Ian Rogers2c8f6532011-09-02 17:16:34 -0700881void X86Assembler::orl(Register dst, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700882 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
883 EmitComplex(1, Operand(dst), imm);
884}
885
886
Ian Rogers2c8f6532011-09-02 17:16:34 -0700887void X86Assembler::xorl(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700888 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
889 EmitUint8(0x33);
890 EmitOperand(dst, Operand(src));
891}
892
Nicolas Geoffrayb55f8352014-04-07 15:26:35 +0100893void X86Assembler::xorl(Register dst, const Immediate& imm) {
894 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
895 EmitComplex(6, Operand(dst), imm);
896}
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700897
Ian Rogers2c8f6532011-09-02 17:16:34 -0700898void X86Assembler::addl(Register reg, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700899 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
900 EmitComplex(0, Operand(reg), imm);
901}
902
903
Ian Rogers2c8f6532011-09-02 17:16:34 -0700904void X86Assembler::addl(const Address& address, Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700905 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
906 EmitUint8(0x01);
907 EmitOperand(reg, address);
908}
909
910
Ian Rogers2c8f6532011-09-02 17:16:34 -0700911void X86Assembler::addl(const Address& address, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700912 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
913 EmitComplex(0, address, imm);
914}
915
916
Ian Rogers2c8f6532011-09-02 17:16:34 -0700917void X86Assembler::adcl(Register reg, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700918 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
919 EmitComplex(2, Operand(reg), imm);
920}
921
922
Ian Rogers2c8f6532011-09-02 17:16:34 -0700923void X86Assembler::adcl(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700924 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
925 EmitUint8(0x13);
926 EmitOperand(dst, Operand(src));
927}
928
929
Ian Rogers2c8f6532011-09-02 17:16:34 -0700930void X86Assembler::adcl(Register dst, const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700931 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
932 EmitUint8(0x13);
933 EmitOperand(dst, address);
934}
935
936
Ian Rogers2c8f6532011-09-02 17:16:34 -0700937void X86Assembler::subl(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700938 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
939 EmitUint8(0x2B);
940 EmitOperand(dst, Operand(src));
941}
942
943
Ian Rogers2c8f6532011-09-02 17:16:34 -0700944void X86Assembler::subl(Register reg, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700945 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
946 EmitComplex(5, Operand(reg), imm);
947}
948
949
Ian Rogers2c8f6532011-09-02 17:16:34 -0700950void X86Assembler::subl(Register reg, const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700951 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
952 EmitUint8(0x2B);
953 EmitOperand(reg, address);
954}
955
956
Ian Rogers2c8f6532011-09-02 17:16:34 -0700957void X86Assembler::cdq() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700958 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
959 EmitUint8(0x99);
960}
961
962
Ian Rogers2c8f6532011-09-02 17:16:34 -0700963void X86Assembler::idivl(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700964 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
965 EmitUint8(0xF7);
966 EmitUint8(0xF8 | reg);
967}
968
969
Ian Rogers2c8f6532011-09-02 17:16:34 -0700970void X86Assembler::imull(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700971 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
972 EmitUint8(0x0F);
973 EmitUint8(0xAF);
974 EmitOperand(dst, Operand(src));
975}
976
977
Ian Rogers2c8f6532011-09-02 17:16:34 -0700978void X86Assembler::imull(Register reg, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700979 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
980 EmitUint8(0x69);
981 EmitOperand(reg, Operand(reg));
982 EmitImmediate(imm);
983}
984
985
Ian Rogers2c8f6532011-09-02 17:16:34 -0700986void X86Assembler::imull(Register reg, const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700987 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
988 EmitUint8(0x0F);
989 EmitUint8(0xAF);
990 EmitOperand(reg, address);
991}
992
993
Ian Rogers2c8f6532011-09-02 17:16:34 -0700994void X86Assembler::imull(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700995 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
996 EmitUint8(0xF7);
997 EmitOperand(5, Operand(reg));
998}
999
1000
Ian Rogers2c8f6532011-09-02 17:16:34 -07001001void X86Assembler::imull(const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001002 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1003 EmitUint8(0xF7);
1004 EmitOperand(5, address);
1005}
1006
1007
Ian Rogers2c8f6532011-09-02 17:16:34 -07001008void X86Assembler::mull(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001009 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1010 EmitUint8(0xF7);
1011 EmitOperand(4, Operand(reg));
1012}
1013
1014
Ian Rogers2c8f6532011-09-02 17:16:34 -07001015void X86Assembler::mull(const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001016 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1017 EmitUint8(0xF7);
1018 EmitOperand(4, address);
1019}
1020
1021
Ian Rogers2c8f6532011-09-02 17:16:34 -07001022void X86Assembler::sbbl(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001023 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1024 EmitUint8(0x1B);
1025 EmitOperand(dst, Operand(src));
1026}
1027
1028
Ian Rogers2c8f6532011-09-02 17:16:34 -07001029void X86Assembler::sbbl(Register reg, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001030 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1031 EmitComplex(3, Operand(reg), imm);
1032}
1033
1034
Ian Rogers2c8f6532011-09-02 17:16:34 -07001035void X86Assembler::sbbl(Register dst, const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001036 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1037 EmitUint8(0x1B);
1038 EmitOperand(dst, address);
1039}
1040
1041
Ian Rogers2c8f6532011-09-02 17:16:34 -07001042void X86Assembler::incl(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001043 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1044 EmitUint8(0x40 + reg);
1045}
1046
1047
Ian Rogers2c8f6532011-09-02 17:16:34 -07001048void X86Assembler::incl(const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001049 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1050 EmitUint8(0xFF);
1051 EmitOperand(0, address);
1052}
1053
1054
Ian Rogers2c8f6532011-09-02 17:16:34 -07001055void X86Assembler::decl(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001056 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1057 EmitUint8(0x48 + reg);
1058}
1059
1060
Ian Rogers2c8f6532011-09-02 17:16:34 -07001061void X86Assembler::decl(const Address& address) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001062 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1063 EmitUint8(0xFF);
1064 EmitOperand(1, address);
1065}
1066
1067
Ian Rogers2c8f6532011-09-02 17:16:34 -07001068void X86Assembler::shll(Register reg, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001069 EmitGenericShift(4, reg, imm);
1070}
1071
1072
Ian Rogers2c8f6532011-09-02 17:16:34 -07001073void X86Assembler::shll(Register operand, Register shifter) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001074 EmitGenericShift(4, operand, shifter);
1075}
1076
1077
Ian Rogers2c8f6532011-09-02 17:16:34 -07001078void X86Assembler::shrl(Register reg, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001079 EmitGenericShift(5, reg, imm);
1080}
1081
1082
Ian Rogers2c8f6532011-09-02 17:16:34 -07001083void X86Assembler::shrl(Register operand, Register shifter) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001084 EmitGenericShift(5, operand, shifter);
1085}
1086
1087
Ian Rogers2c8f6532011-09-02 17:16:34 -07001088void X86Assembler::sarl(Register reg, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001089 EmitGenericShift(7, reg, imm);
1090}
1091
1092
Ian Rogers2c8f6532011-09-02 17:16:34 -07001093void X86Assembler::sarl(Register operand, Register shifter) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001094 EmitGenericShift(7, operand, shifter);
1095}
1096
1097
Ian Rogers2c8f6532011-09-02 17:16:34 -07001098void X86Assembler::shld(Register dst, Register src) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001099 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1100 EmitUint8(0x0F);
1101 EmitUint8(0xA5);
1102 EmitRegisterOperand(src, dst);
1103}
1104
1105
Ian Rogers2c8f6532011-09-02 17:16:34 -07001106void X86Assembler::negl(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001107 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1108 EmitUint8(0xF7);
1109 EmitOperand(3, Operand(reg));
1110}
1111
1112
Ian Rogers2c8f6532011-09-02 17:16:34 -07001113void X86Assembler::notl(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001114 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1115 EmitUint8(0xF7);
1116 EmitUint8(0xD0 | reg);
1117}
1118
1119
Ian Rogers2c8f6532011-09-02 17:16:34 -07001120void X86Assembler::enter(const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001121 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1122 EmitUint8(0xC8);
1123 CHECK(imm.is_uint16());
1124 EmitUint8(imm.value() & 0xFF);
1125 EmitUint8((imm.value() >> 8) & 0xFF);
1126 EmitUint8(0x00);
1127}
1128
1129
Ian Rogers2c8f6532011-09-02 17:16:34 -07001130void X86Assembler::leave() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001131 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1132 EmitUint8(0xC9);
1133}
1134
1135
Ian Rogers2c8f6532011-09-02 17:16:34 -07001136void X86Assembler::ret() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001137 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1138 EmitUint8(0xC3);
1139}
1140
1141
Ian Rogers2c8f6532011-09-02 17:16:34 -07001142void X86Assembler::ret(const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001143 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1144 EmitUint8(0xC2);
1145 CHECK(imm.is_uint16());
1146 EmitUint8(imm.value() & 0xFF);
1147 EmitUint8((imm.value() >> 8) & 0xFF);
1148}
1149
1150
1151
Ian Rogers2c8f6532011-09-02 17:16:34 -07001152void X86Assembler::nop() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001153 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1154 EmitUint8(0x90);
1155}
1156
1157
Ian Rogers2c8f6532011-09-02 17:16:34 -07001158void X86Assembler::int3() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001159 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1160 EmitUint8(0xCC);
1161}
1162
1163
Ian Rogers2c8f6532011-09-02 17:16:34 -07001164void X86Assembler::hlt() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001165 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1166 EmitUint8(0xF4);
1167}
1168
1169
Ian Rogers2c8f6532011-09-02 17:16:34 -07001170void X86Assembler::j(Condition condition, Label* label) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001171 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1172 if (label->IsBound()) {
1173 static const int kShortSize = 2;
1174 static const int kLongSize = 6;
1175 int offset = label->Position() - buffer_.Size();
1176 CHECK_LE(offset, 0);
1177 if (IsInt(8, offset - kShortSize)) {
1178 EmitUint8(0x70 + condition);
1179 EmitUint8((offset - kShortSize) & 0xFF);
1180 } else {
1181 EmitUint8(0x0F);
1182 EmitUint8(0x80 + condition);
1183 EmitInt32(offset - kLongSize);
1184 }
1185 } else {
1186 EmitUint8(0x0F);
1187 EmitUint8(0x80 + condition);
1188 EmitLabelLink(label);
1189 }
1190}
1191
1192
Ian Rogers2c8f6532011-09-02 17:16:34 -07001193void X86Assembler::jmp(Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001194 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1195 EmitUint8(0xFF);
1196 EmitRegisterOperand(4, reg);
1197}
1198
Ian Rogers7caad772012-03-30 01:07:54 -07001199void X86Assembler::jmp(const Address& address) {
1200 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1201 EmitUint8(0xFF);
1202 EmitOperand(4, address);
1203}
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001204
Ian Rogers2c8f6532011-09-02 17:16:34 -07001205void X86Assembler::jmp(Label* label) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001206 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1207 if (label->IsBound()) {
1208 static const int kShortSize = 2;
1209 static const int kLongSize = 5;
1210 int offset = label->Position() - buffer_.Size();
1211 CHECK_LE(offset, 0);
1212 if (IsInt(8, offset - kShortSize)) {
1213 EmitUint8(0xEB);
1214 EmitUint8((offset - kShortSize) & 0xFF);
1215 } else {
1216 EmitUint8(0xE9);
1217 EmitInt32(offset - kLongSize);
1218 }
1219 } else {
1220 EmitUint8(0xE9);
1221 EmitLabelLink(label);
1222 }
1223}
1224
1225
Ian Rogers2c8f6532011-09-02 17:16:34 -07001226X86Assembler* X86Assembler::lock() {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001227 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1228 EmitUint8(0xF0);
Ian Rogers0d666d82011-08-14 16:03:46 -07001229 return this;
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001230}
1231
1232
Ian Rogers2c8f6532011-09-02 17:16:34 -07001233void X86Assembler::cmpxchgl(const Address& address, Register reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001234 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1235 EmitUint8(0x0F);
1236 EmitUint8(0xB1);
1237 EmitOperand(reg, address);
1238}
1239
Elliott Hughes79ab9e32012-03-12 15:41:35 -07001240void X86Assembler::mfence() {
1241 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1242 EmitUint8(0x0F);
1243 EmitUint8(0xAE);
1244 EmitUint8(0xF0);
1245}
1246
Ian Rogers2c8f6532011-09-02 17:16:34 -07001247X86Assembler* X86Assembler::fs() {
Ian Rogersb033c752011-07-20 12:22:35 -07001248 // TODO: fs is a prefix and not an instruction
1249 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1250 EmitUint8(0x64);
Ian Rogers0d666d82011-08-14 16:03:46 -07001251 return this;
Ian Rogersb033c752011-07-20 12:22:35 -07001252}
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001253
Ian Rogersbefbd572014-03-06 01:13:39 -08001254X86Assembler* X86Assembler::gs() {
1255 // TODO: fs is a prefix and not an instruction
1256 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1257 EmitUint8(0x65);
1258 return this;
1259}
1260
Ian Rogers2c8f6532011-09-02 17:16:34 -07001261void X86Assembler::AddImmediate(Register reg, const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001262 int value = imm.value();
1263 if (value > 0) {
1264 if (value == 1) {
1265 incl(reg);
1266 } else if (value != 0) {
1267 addl(reg, imm);
1268 }
1269 } else if (value < 0) {
1270 value = -value;
1271 if (value == 1) {
1272 decl(reg);
1273 } else if (value != 0) {
1274 subl(reg, Immediate(value));
1275 }
1276 }
1277}
1278
1279
Ian Rogers2c8f6532011-09-02 17:16:34 -07001280void X86Assembler::LoadDoubleConstant(XmmRegister dst, double value) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001281 // TODO: Need to have a code constants table.
1282 int64_t constant = bit_cast<int64_t, double>(value);
1283 pushl(Immediate(High32Bits(constant)));
1284 pushl(Immediate(Low32Bits(constant)));
1285 movsd(dst, Address(ESP, 0));
1286 addl(ESP, Immediate(2 * kWordSize));
1287}
1288
1289
Ian Rogers2c8f6532011-09-02 17:16:34 -07001290void X86Assembler::FloatNegate(XmmRegister f) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001291 static const struct {
1292 uint32_t a;
1293 uint32_t b;
1294 uint32_t c;
1295 uint32_t d;
1296 } float_negate_constant __attribute__((aligned(16))) =
1297 { 0x80000000, 0x00000000, 0x80000000, 0x00000000 };
1298 xorps(f, Address::Absolute(reinterpret_cast<uword>(&float_negate_constant)));
1299}
1300
1301
Ian Rogers2c8f6532011-09-02 17:16:34 -07001302void X86Assembler::DoubleNegate(XmmRegister d) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001303 static const struct {
1304 uint64_t a;
1305 uint64_t b;
1306 } double_negate_constant __attribute__((aligned(16))) =
1307 {0x8000000000000000LL, 0x8000000000000000LL};
1308 xorpd(d, Address::Absolute(reinterpret_cast<uword>(&double_negate_constant)));
1309}
1310
1311
Ian Rogers2c8f6532011-09-02 17:16:34 -07001312void X86Assembler::DoubleAbs(XmmRegister reg) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001313 static const struct {
1314 uint64_t a;
1315 uint64_t b;
1316 } double_abs_constant __attribute__((aligned(16))) =
1317 {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL};
1318 andpd(reg, Address::Absolute(reinterpret_cast<uword>(&double_abs_constant)));
1319}
1320
1321
Ian Rogers2c8f6532011-09-02 17:16:34 -07001322void X86Assembler::Align(int alignment, int offset) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001323 CHECK(IsPowerOfTwo(alignment));
1324 // Emit nop instruction until the real position is aligned.
1325 while (((offset + buffer_.GetPosition()) & (alignment-1)) != 0) {
1326 nop();
1327 }
1328}
1329
1330
Ian Rogers2c8f6532011-09-02 17:16:34 -07001331void X86Assembler::Bind(Label* label) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001332 int bound = buffer_.Size();
1333 CHECK(!label->IsBound()); // Labels can only be bound once.
1334 while (label->IsLinked()) {
1335 int position = label->LinkPosition();
1336 int next = buffer_.Load<int32_t>(position);
1337 buffer_.Store<int32_t>(position, bound - (position + 4));
1338 label->position_ = next;
1339 }
1340 label->BindTo(bound);
1341}
1342
1343
Ian Rogers44fb0d02012-03-23 16:46:24 -07001344void X86Assembler::EmitOperand(int reg_or_opcode, const Operand& operand) {
1345 CHECK_GE(reg_or_opcode, 0);
1346 CHECK_LT(reg_or_opcode, 8);
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001347 const int length = operand.length_;
1348 CHECK_GT(length, 0);
Ian Rogers44fb0d02012-03-23 16:46:24 -07001349 // Emit the ModRM byte updated with the given reg value.
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001350 CHECK_EQ(operand.encoding_[0] & 0x38, 0);
Ian Rogers44fb0d02012-03-23 16:46:24 -07001351 EmitUint8(operand.encoding_[0] + (reg_or_opcode << 3));
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001352 // Emit the rest of the encoded operand.
1353 for (int i = 1; i < length; i++) {
1354 EmitUint8(operand.encoding_[i]);
1355 }
1356}
1357
1358
Ian Rogers2c8f6532011-09-02 17:16:34 -07001359void X86Assembler::EmitImmediate(const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001360 EmitInt32(imm.value());
1361}
1362
1363
Ian Rogers44fb0d02012-03-23 16:46:24 -07001364void X86Assembler::EmitComplex(int reg_or_opcode,
Ian Rogers2c8f6532011-09-02 17:16:34 -07001365 const Operand& operand,
1366 const Immediate& immediate) {
Ian Rogers44fb0d02012-03-23 16:46:24 -07001367 CHECK_GE(reg_or_opcode, 0);
1368 CHECK_LT(reg_or_opcode, 8);
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001369 if (immediate.is_int8()) {
1370 // Use sign-extended 8-bit immediate.
1371 EmitUint8(0x83);
Ian Rogers44fb0d02012-03-23 16:46:24 -07001372 EmitOperand(reg_or_opcode, operand);
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001373 EmitUint8(immediate.value() & 0xFF);
1374 } else if (operand.IsRegister(EAX)) {
1375 // Use short form if the destination is eax.
Ian Rogers44fb0d02012-03-23 16:46:24 -07001376 EmitUint8(0x05 + (reg_or_opcode << 3));
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001377 EmitImmediate(immediate);
1378 } else {
1379 EmitUint8(0x81);
Ian Rogers44fb0d02012-03-23 16:46:24 -07001380 EmitOperand(reg_or_opcode, operand);
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001381 EmitImmediate(immediate);
1382 }
1383}
1384
1385
Ian Rogers2c8f6532011-09-02 17:16:34 -07001386void X86Assembler::EmitLabel(Label* label, int instruction_size) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001387 if (label->IsBound()) {
1388 int offset = label->Position() - buffer_.Size();
1389 CHECK_LE(offset, 0);
1390 EmitInt32(offset - instruction_size);
1391 } else {
1392 EmitLabelLink(label);
1393 }
1394}
1395
1396
Ian Rogers2c8f6532011-09-02 17:16:34 -07001397void X86Assembler::EmitLabelLink(Label* label) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001398 CHECK(!label->IsBound());
1399 int position = buffer_.Size();
1400 EmitInt32(label->position_);
1401 label->LinkTo(position);
1402}
1403
1404
Ian Rogers44fb0d02012-03-23 16:46:24 -07001405void X86Assembler::EmitGenericShift(int reg_or_opcode,
Ian Rogers2c8f6532011-09-02 17:16:34 -07001406 Register reg,
1407 const Immediate& imm) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001408 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1409 CHECK(imm.is_int8());
1410 if (imm.value() == 1) {
1411 EmitUint8(0xD1);
Ian Rogers44fb0d02012-03-23 16:46:24 -07001412 EmitOperand(reg_or_opcode, Operand(reg));
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001413 } else {
1414 EmitUint8(0xC1);
Ian Rogers44fb0d02012-03-23 16:46:24 -07001415 EmitOperand(reg_or_opcode, Operand(reg));
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001416 EmitUint8(imm.value() & 0xFF);
1417 }
1418}
1419
1420
Ian Rogers44fb0d02012-03-23 16:46:24 -07001421void X86Assembler::EmitGenericShift(int reg_or_opcode,
Ian Rogers2c8f6532011-09-02 17:16:34 -07001422 Register operand,
1423 Register shifter) {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001424 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1425 CHECK_EQ(shifter, ECX);
1426 EmitUint8(0xD3);
Ian Rogers44fb0d02012-03-23 16:46:24 -07001427 EmitOperand(reg_or_opcode, Operand(operand));
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001428}
1429
Tong Shen547cdfd2014-08-05 01:54:19 -07001430void X86Assembler::InitializeFrameDescriptionEntry() {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001431 WriteFDEHeader(&cfi_info_, false /* is_64bit */);
Tong Shen547cdfd2014-08-05 01:54:19 -07001432}
1433
1434void X86Assembler::FinalizeFrameDescriptionEntry() {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001435 WriteFDEAddressRange(&cfi_info_, buffer_.Size(), false /* is_64bit */);
Tong Shen547cdfd2014-08-05 01:54:19 -07001436 PadCFI(&cfi_info_);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001437 WriteCFILength(&cfi_info_, false /* is_64bit */);
Tong Shen547cdfd2014-08-05 01:54:19 -07001438}
1439
Ian Rogers790a6b72014-04-01 10:36:00 -07001440constexpr size_t kFramePointerSize = 4;
1441
Ian Rogers2c8f6532011-09-02 17:16:34 -07001442void X86Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg,
Ian Rogersb5d09b22012-03-06 22:14:17 -08001443 const std::vector<ManagedRegister>& spill_regs,
Dmitry Petrochenkofca82202014-03-21 11:21:37 +07001444 const ManagedRegisterEntrySpills& entry_spills) {
Tong Shen547cdfd2014-08-05 01:54:19 -07001445 cfi_cfa_offset_ = kFramePointerSize; // Only return address on stack
1446 cfi_pc_ = buffer_.Size(); // Nothing emitted yet
1447 DCHECK_EQ(cfi_pc_, 0U);
1448
1449 uint32_t reg_offset = 1;
Elliott Hughes06b37d92011-10-16 11:51:29 -07001450 CHECK_ALIGNED(frame_size, kStackAlignment);
jeffhao703f2cd2012-07-13 17:25:52 -07001451 for (int i = spill_regs.size() - 1; i >= 0; --i) {
1452 pushl(spill_regs.at(i).AsX86().AsCpuRegister());
Tong Shen547cdfd2014-08-05 01:54:19 -07001453
1454 // DW_CFA_advance_loc
1455 DW_CFA_advance_loc(&cfi_info_, buffer_.Size() - cfi_pc_);
1456 cfi_pc_ = buffer_.Size();
1457 // DW_CFA_def_cfa_offset
1458 cfi_cfa_offset_ += kFramePointerSize;
1459 DW_CFA_def_cfa_offset(&cfi_info_, cfi_cfa_offset_);
1460 // DW_CFA_offset reg offset
1461 reg_offset++;
1462 DW_CFA_offset(&cfi_info_, spill_regs.at(i).AsX86().DWARFRegId(), reg_offset);
jeffhao703f2cd2012-07-13 17:25:52 -07001463 }
Tong Shen547cdfd2014-08-05 01:54:19 -07001464
Ian Rogersb033c752011-07-20 12:22:35 -07001465 // return address then method on stack
Tong Shen547cdfd2014-08-05 01:54:19 -07001466 int32_t adjust = frame_size - (spill_regs.size() * kFramePointerSize) -
1467 sizeof(StackReference<mirror::ArtMethod>) /*method*/ -
1468 kFramePointerSize /*return address*/;
1469 addl(ESP, Immediate(-adjust));
1470 // DW_CFA_advance_loc
1471 DW_CFA_advance_loc(&cfi_info_, buffer_.Size() - cfi_pc_);
1472 cfi_pc_ = buffer_.Size();
1473 // DW_CFA_def_cfa_offset
1474 cfi_cfa_offset_ += adjust;
1475 DW_CFA_def_cfa_offset(&cfi_info_, cfi_cfa_offset_);
1476
Ian Rogers2c8f6532011-09-02 17:16:34 -07001477 pushl(method_reg.AsX86().AsCpuRegister());
Tong Shen547cdfd2014-08-05 01:54:19 -07001478 // DW_CFA_advance_loc
1479 DW_CFA_advance_loc(&cfi_info_, buffer_.Size() - cfi_pc_);
1480 cfi_pc_ = buffer_.Size();
1481 // DW_CFA_def_cfa_offset
1482 cfi_cfa_offset_ += kFramePointerSize;
1483 DW_CFA_def_cfa_offset(&cfi_info_, cfi_cfa_offset_);
1484
Ian Rogersb5d09b22012-03-06 22:14:17 -08001485 for (size_t i = 0; i < entry_spills.size(); ++i) {
Andreas Gampecf4035a2014-05-28 22:43:01 -07001486 movl(Address(ESP, frame_size + sizeof(StackReference<mirror::ArtMethod>) +
1487 (i * kFramePointerSize)),
Ian Rogersb5d09b22012-03-06 22:14:17 -08001488 entry_spills.at(i).AsX86().AsCpuRegister());
1489 }
Ian Rogersb033c752011-07-20 12:22:35 -07001490}
1491
Ian Rogers2c8f6532011-09-02 17:16:34 -07001492void X86Assembler::RemoveFrame(size_t frame_size,
Ian Rogers0d666d82011-08-14 16:03:46 -07001493 const std::vector<ManagedRegister>& spill_regs) {
Elliott Hughes06b37d92011-10-16 11:51:29 -07001494 CHECK_ALIGNED(frame_size, kStackAlignment);
Andreas Gampecf4035a2014-05-28 22:43:01 -07001495 addl(ESP, Immediate(frame_size - (spill_regs.size() * kFramePointerSize) -
1496 sizeof(StackReference<mirror::ArtMethod>)));
jeffhao703f2cd2012-07-13 17:25:52 -07001497 for (size_t i = 0; i < spill_regs.size(); ++i) {
1498 popl(spill_regs.at(i).AsX86().AsCpuRegister());
1499 }
Ian Rogersb033c752011-07-20 12:22:35 -07001500 ret();
1501}
1502
Ian Rogers2c8f6532011-09-02 17:16:34 -07001503void X86Assembler::IncreaseFrameSize(size_t adjust) {
Elliott Hughes06b37d92011-10-16 11:51:29 -07001504 CHECK_ALIGNED(adjust, kStackAlignment);
Ian Rogersb033c752011-07-20 12:22:35 -07001505 addl(ESP, Immediate(-adjust));
Tong Shen547cdfd2014-08-05 01:54:19 -07001506 // DW_CFA_advance_loc
1507 DW_CFA_advance_loc(&cfi_info_, buffer_.Size() - cfi_pc_);
1508 cfi_pc_ = buffer_.Size();
1509 // DW_CFA_def_cfa_offset
1510 cfi_cfa_offset_ += adjust;
1511 DW_CFA_def_cfa_offset(&cfi_info_, cfi_cfa_offset_);
Ian Rogersb033c752011-07-20 12:22:35 -07001512}
1513
Ian Rogers2c8f6532011-09-02 17:16:34 -07001514void X86Assembler::DecreaseFrameSize(size_t adjust) {
Elliott Hughes06b37d92011-10-16 11:51:29 -07001515 CHECK_ALIGNED(adjust, kStackAlignment);
Ian Rogersb033c752011-07-20 12:22:35 -07001516 addl(ESP, Immediate(adjust));
1517}
1518
Ian Rogers2c8f6532011-09-02 17:16:34 -07001519void X86Assembler::Store(FrameOffset offs, ManagedRegister msrc, size_t size) {
1520 X86ManagedRegister src = msrc.AsX86();
Ian Rogers45a76cb2011-07-21 22:00:15 -07001521 if (src.IsNoRegister()) {
1522 CHECK_EQ(0u, size);
1523 } else if (src.IsCpuRegister()) {
Ian Rogersb033c752011-07-20 12:22:35 -07001524 CHECK_EQ(4u, size);
1525 movl(Address(ESP, offs), src.AsCpuRegister());
Ian Rogers9b269d22011-09-04 14:06:05 -07001526 } else if (src.IsRegisterPair()) {
1527 CHECK_EQ(8u, size);
1528 movl(Address(ESP, offs), src.AsRegisterPairLow());
1529 movl(Address(ESP, FrameOffset(offs.Int32Value()+4)),
1530 src.AsRegisterPairHigh());
Ian Rogers45a76cb2011-07-21 22:00:15 -07001531 } else if (src.IsX87Register()) {
1532 if (size == 4) {
1533 fstps(Address(ESP, offs));
1534 } else {
1535 fstpl(Address(ESP, offs));
1536 }
1537 } else {
1538 CHECK(src.IsXmmRegister());
Ian Rogersb033c752011-07-20 12:22:35 -07001539 if (size == 4) {
1540 movss(Address(ESP, offs), src.AsXmmRegister());
1541 } else {
1542 movsd(Address(ESP, offs), src.AsXmmRegister());
1543 }
1544 }
1545}
1546
Ian Rogers2c8f6532011-09-02 17:16:34 -07001547void X86Assembler::StoreRef(FrameOffset dest, ManagedRegister msrc) {
1548 X86ManagedRegister src = msrc.AsX86();
Ian Rogersb033c752011-07-20 12:22:35 -07001549 CHECK(src.IsCpuRegister());
1550 movl(Address(ESP, dest), src.AsCpuRegister());
1551}
1552
Ian Rogers2c8f6532011-09-02 17:16:34 -07001553void X86Assembler::StoreRawPtr(FrameOffset dest, ManagedRegister msrc) {
1554 X86ManagedRegister src = msrc.AsX86();
Ian Rogersdf20fe02011-07-20 20:34:16 -07001555 CHECK(src.IsCpuRegister());
1556 movl(Address(ESP, dest), src.AsCpuRegister());
1557}
1558
Ian Rogers2c8f6532011-09-02 17:16:34 -07001559void X86Assembler::StoreImmediateToFrame(FrameOffset dest, uint32_t imm,
1560 ManagedRegister) {
Ian Rogersb033c752011-07-20 12:22:35 -07001561 movl(Address(ESP, dest), Immediate(imm));
1562}
1563
Ian Rogersdd7624d2014-03-14 17:43:00 -07001564void X86Assembler::StoreImmediateToThread32(ThreadOffset<4> dest, uint32_t imm,
Ian Rogers2c8f6532011-09-02 17:16:34 -07001565 ManagedRegister) {
Ian Rogers0d666d82011-08-14 16:03:46 -07001566 fs()->movl(Address::Absolute(dest), Immediate(imm));
Ian Rogersb033c752011-07-20 12:22:35 -07001567}
1568
Ian Rogersdd7624d2014-03-14 17:43:00 -07001569void X86Assembler::StoreStackOffsetToThread32(ThreadOffset<4> thr_offs,
Ian Rogers2c8f6532011-09-02 17:16:34 -07001570 FrameOffset fr_offs,
1571 ManagedRegister mscratch) {
1572 X86ManagedRegister scratch = mscratch.AsX86();
1573 CHECK(scratch.IsCpuRegister());
1574 leal(scratch.AsCpuRegister(), Address(ESP, fr_offs));
1575 fs()->movl(Address::Absolute(thr_offs), scratch.AsCpuRegister());
1576}
1577
Ian Rogersdd7624d2014-03-14 17:43:00 -07001578void X86Assembler::StoreStackPointerToThread32(ThreadOffset<4> thr_offs) {
Ian Rogers2c8f6532011-09-02 17:16:34 -07001579 fs()->movl(Address::Absolute(thr_offs), ESP);
1580}
1581
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001582void X86Assembler::StoreSpanning(FrameOffset /*dst*/, ManagedRegister /*src*/,
1583 FrameOffset /*in_off*/, ManagedRegister /*scratch*/) {
Ian Rogers2c8f6532011-09-02 17:16:34 -07001584 UNIMPLEMENTED(FATAL); // this case only currently exists for ARM
1585}
1586
1587void X86Assembler::Load(ManagedRegister mdest, FrameOffset src, size_t size) {
1588 X86ManagedRegister dest = mdest.AsX86();
Ian Rogers45a76cb2011-07-21 22:00:15 -07001589 if (dest.IsNoRegister()) {
1590 CHECK_EQ(0u, size);
1591 } else if (dest.IsCpuRegister()) {
Ian Rogersb033c752011-07-20 12:22:35 -07001592 CHECK_EQ(4u, size);
1593 movl(dest.AsCpuRegister(), Address(ESP, src));
Ian Rogers9b269d22011-09-04 14:06:05 -07001594 } else if (dest.IsRegisterPair()) {
1595 CHECK_EQ(8u, size);
1596 movl(dest.AsRegisterPairLow(), Address(ESP, src));
1597 movl(dest.AsRegisterPairHigh(), Address(ESP, FrameOffset(src.Int32Value()+4)));
Ian Rogers45a76cb2011-07-21 22:00:15 -07001598 } else if (dest.IsX87Register()) {
1599 if (size == 4) {
1600 flds(Address(ESP, src));
1601 } else {
1602 fldl(Address(ESP, src));
1603 }
Ian Rogersb033c752011-07-20 12:22:35 -07001604 } else {
Ian Rogers45a76cb2011-07-21 22:00:15 -07001605 CHECK(dest.IsXmmRegister());
1606 if (size == 4) {
1607 movss(dest.AsXmmRegister(), Address(ESP, src));
1608 } else {
1609 movsd(dest.AsXmmRegister(), Address(ESP, src));
1610 }
Ian Rogersb033c752011-07-20 12:22:35 -07001611 }
1612}
1613
Ian Rogersdd7624d2014-03-14 17:43:00 -07001614void X86Assembler::LoadFromThread32(ManagedRegister mdest, ThreadOffset<4> src, size_t size) {
Ian Rogers5a7a74a2011-09-26 16:32:29 -07001615 X86ManagedRegister dest = mdest.AsX86();
1616 if (dest.IsNoRegister()) {
1617 CHECK_EQ(0u, size);
1618 } else if (dest.IsCpuRegister()) {
1619 CHECK_EQ(4u, size);
1620 fs()->movl(dest.AsCpuRegister(), Address::Absolute(src));
1621 } else if (dest.IsRegisterPair()) {
1622 CHECK_EQ(8u, size);
1623 fs()->movl(dest.AsRegisterPairLow(), Address::Absolute(src));
Ian Rogersdd7624d2014-03-14 17:43:00 -07001624 fs()->movl(dest.AsRegisterPairHigh(), Address::Absolute(ThreadOffset<4>(src.Int32Value()+4)));
Ian Rogers5a7a74a2011-09-26 16:32:29 -07001625 } else if (dest.IsX87Register()) {
1626 if (size == 4) {
1627 fs()->flds(Address::Absolute(src));
1628 } else {
1629 fs()->fldl(Address::Absolute(src));
1630 }
1631 } else {
1632 CHECK(dest.IsXmmRegister());
1633 if (size == 4) {
1634 fs()->movss(dest.AsXmmRegister(), Address::Absolute(src));
1635 } else {
1636 fs()->movsd(dest.AsXmmRegister(), Address::Absolute(src));
1637 }
1638 }
1639}
1640
Ian Rogers2c8f6532011-09-02 17:16:34 -07001641void X86Assembler::LoadRef(ManagedRegister mdest, FrameOffset src) {
1642 X86ManagedRegister dest = mdest.AsX86();
Ian Rogersb033c752011-07-20 12:22:35 -07001643 CHECK(dest.IsCpuRegister());
1644 movl(dest.AsCpuRegister(), Address(ESP, src));
1645}
1646
Ian Rogers2c8f6532011-09-02 17:16:34 -07001647void X86Assembler::LoadRef(ManagedRegister mdest, ManagedRegister base,
1648 MemberOffset offs) {
1649 X86ManagedRegister dest = mdest.AsX86();
Ian Rogersb033c752011-07-20 12:22:35 -07001650 CHECK(dest.IsCpuRegister() && dest.IsCpuRegister());
Ian Rogers2c8f6532011-09-02 17:16:34 -07001651 movl(dest.AsCpuRegister(), Address(base.AsX86().AsCpuRegister(), offs));
Hiroshi Yamauchie63a7452014-02-27 14:44:36 -08001652 if (kPoisonHeapReferences) {
1653 negl(dest.AsCpuRegister());
1654 }
Ian Rogersb033c752011-07-20 12:22:35 -07001655}
1656
Ian Rogers2c8f6532011-09-02 17:16:34 -07001657void X86Assembler::LoadRawPtr(ManagedRegister mdest, ManagedRegister base,
1658 Offset offs) {
1659 X86ManagedRegister dest = mdest.AsX86();
Ian Rogersa04d3972011-08-17 11:33:44 -07001660 CHECK(dest.IsCpuRegister() && dest.IsCpuRegister());
Ian Rogers2c8f6532011-09-02 17:16:34 -07001661 movl(dest.AsCpuRegister(), Address(base.AsX86().AsCpuRegister(), offs));
Ian Rogersa04d3972011-08-17 11:33:44 -07001662}
1663
Ian Rogersdd7624d2014-03-14 17:43:00 -07001664void X86Assembler::LoadRawPtrFromThread32(ManagedRegister mdest,
1665 ThreadOffset<4> offs) {
Ian Rogers2c8f6532011-09-02 17:16:34 -07001666 X86ManagedRegister dest = mdest.AsX86();
Ian Rogersb033c752011-07-20 12:22:35 -07001667 CHECK(dest.IsCpuRegister());
Ian Rogers0d666d82011-08-14 16:03:46 -07001668 fs()->movl(dest.AsCpuRegister(), Address::Absolute(offs));
Ian Rogersb033c752011-07-20 12:22:35 -07001669}
1670
jeffhao58136ca2012-05-24 13:40:11 -07001671void X86Assembler::SignExtend(ManagedRegister mreg, size_t size) {
1672 X86ManagedRegister reg = mreg.AsX86();
1673 CHECK(size == 1 || size == 2) << size;
1674 CHECK(reg.IsCpuRegister()) << reg;
1675 if (size == 1) {
1676 movsxb(reg.AsCpuRegister(), reg.AsByteRegister());
1677 } else {
1678 movsxw(reg.AsCpuRegister(), reg.AsCpuRegister());
1679 }
1680}
1681
jeffhaocee4d0c2012-06-15 14:42:01 -07001682void X86Assembler::ZeroExtend(ManagedRegister mreg, size_t size) {
1683 X86ManagedRegister reg = mreg.AsX86();
1684 CHECK(size == 1 || size == 2) << size;
1685 CHECK(reg.IsCpuRegister()) << reg;
1686 if (size == 1) {
1687 movzxb(reg.AsCpuRegister(), reg.AsByteRegister());
1688 } else {
1689 movzxw(reg.AsCpuRegister(), reg.AsCpuRegister());
1690 }
1691}
1692
Ian Rogersb5d09b22012-03-06 22:14:17 -08001693void X86Assembler::Move(ManagedRegister mdest, ManagedRegister msrc, size_t size) {
Ian Rogers2c8f6532011-09-02 17:16:34 -07001694 X86ManagedRegister dest = mdest.AsX86();
1695 X86ManagedRegister src = msrc.AsX86();
Ian Rogersb033c752011-07-20 12:22:35 -07001696 if (!dest.Equals(src)) {
1697 if (dest.IsCpuRegister() && src.IsCpuRegister()) {
1698 movl(dest.AsCpuRegister(), src.AsCpuRegister());
Ian Rogersb5d09b22012-03-06 22:14:17 -08001699 } else if (src.IsX87Register() && dest.IsXmmRegister()) {
1700 // Pass via stack and pop X87 register
1701 subl(ESP, Immediate(16));
1702 if (size == 4) {
1703 CHECK_EQ(src.AsX87Register(), ST0);
1704 fstps(Address(ESP, 0));
1705 movss(dest.AsXmmRegister(), Address(ESP, 0));
1706 } else {
1707 CHECK_EQ(src.AsX87Register(), ST0);
1708 fstpl(Address(ESP, 0));
1709 movsd(dest.AsXmmRegister(), Address(ESP, 0));
1710 }
1711 addl(ESP, Immediate(16));
Ian Rogersb033c752011-07-20 12:22:35 -07001712 } else {
1713 // TODO: x87, SSE
Ian Rogers2c8f6532011-09-02 17:16:34 -07001714 UNIMPLEMENTED(FATAL) << ": Move " << dest << ", " << src;
Ian Rogersb033c752011-07-20 12:22:35 -07001715 }
1716 }
1717}
1718
Ian Rogers2c8f6532011-09-02 17:16:34 -07001719void X86Assembler::CopyRef(FrameOffset dest, FrameOffset src,
1720 ManagedRegister mscratch) {
1721 X86ManagedRegister scratch = mscratch.AsX86();
1722 CHECK(scratch.IsCpuRegister());
1723 movl(scratch.AsCpuRegister(), Address(ESP, src));
1724 movl(Address(ESP, dest), scratch.AsCpuRegister());
1725}
1726
Ian Rogersdd7624d2014-03-14 17:43:00 -07001727void X86Assembler::CopyRawPtrFromThread32(FrameOffset fr_offs,
1728 ThreadOffset<4> thr_offs,
Ian Rogers2c8f6532011-09-02 17:16:34 -07001729 ManagedRegister mscratch) {
1730 X86ManagedRegister scratch = mscratch.AsX86();
1731 CHECK(scratch.IsCpuRegister());
1732 fs()->movl(scratch.AsCpuRegister(), Address::Absolute(thr_offs));
1733 Store(fr_offs, scratch, 4);
1734}
1735
Ian Rogersdd7624d2014-03-14 17:43:00 -07001736void X86Assembler::CopyRawPtrToThread32(ThreadOffset<4> thr_offs,
Ian Rogers2c8f6532011-09-02 17:16:34 -07001737 FrameOffset fr_offs,
1738 ManagedRegister mscratch) {
1739 X86ManagedRegister scratch = mscratch.AsX86();
1740 CHECK(scratch.IsCpuRegister());
1741 Load(scratch, fr_offs, 4);
1742 fs()->movl(Address::Absolute(thr_offs), scratch.AsCpuRegister());
1743}
1744
1745void X86Assembler::Copy(FrameOffset dest, FrameOffset src,
1746 ManagedRegister mscratch,
1747 size_t size) {
1748 X86ManagedRegister scratch = mscratch.AsX86();
Ian Rogersb033c752011-07-20 12:22:35 -07001749 if (scratch.IsCpuRegister() && size == 8) {
1750 Load(scratch, src, 4);
1751 Store(dest, scratch, 4);
1752 Load(scratch, FrameOffset(src.Int32Value() + 4), 4);
1753 Store(FrameOffset(dest.Int32Value() + 4), scratch, 4);
1754 } else {
1755 Load(scratch, src, size);
1756 Store(dest, scratch, size);
1757 }
1758}
1759
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001760void X86Assembler::Copy(FrameOffset /*dst*/, ManagedRegister /*src_base*/, Offset /*src_offset*/,
1761 ManagedRegister /*scratch*/, size_t /*size*/) {
Ian Rogersdc51b792011-09-22 20:41:37 -07001762 UNIMPLEMENTED(FATAL);
1763}
1764
Ian Rogers5a7a74a2011-09-26 16:32:29 -07001765void X86Assembler::Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src,
1766 ManagedRegister scratch, size_t size) {
1767 CHECK(scratch.IsNoRegister());
1768 CHECK_EQ(size, 4u);
1769 pushl(Address(ESP, src));
1770 popl(Address(dest_base.AsX86().AsCpuRegister(), dest_offset));
1771}
1772
Ian Rogersdc51b792011-09-22 20:41:37 -07001773void X86Assembler::Copy(FrameOffset dest, FrameOffset src_base, Offset src_offset,
1774 ManagedRegister mscratch, size_t size) {
1775 Register scratch = mscratch.AsX86().AsCpuRegister();
1776 CHECK_EQ(size, 4u);
1777 movl(scratch, Address(ESP, src_base));
1778 movl(scratch, Address(scratch, src_offset));
1779 movl(Address(ESP, dest), scratch);
1780}
1781
Ian Rogers5a7a74a2011-09-26 16:32:29 -07001782void X86Assembler::Copy(ManagedRegister dest, Offset dest_offset,
1783 ManagedRegister src, Offset src_offset,
1784 ManagedRegister scratch, size_t size) {
Ian Rogersdc51b792011-09-22 20:41:37 -07001785 CHECK_EQ(size, 4u);
Ian Rogers5a7a74a2011-09-26 16:32:29 -07001786 CHECK(scratch.IsNoRegister());
1787 pushl(Address(src.AsX86().AsCpuRegister(), src_offset));
1788 popl(Address(dest.AsX86().AsCpuRegister(), dest_offset));
1789}
1790
1791void X86Assembler::Copy(FrameOffset dest, Offset dest_offset, FrameOffset src, Offset src_offset,
1792 ManagedRegister mscratch, size_t size) {
1793 Register scratch = mscratch.AsX86().AsCpuRegister();
1794 CHECK_EQ(size, 4u);
1795 CHECK_EQ(dest.Int32Value(), src.Int32Value());
1796 movl(scratch, Address(ESP, src));
1797 pushl(Address(scratch, src_offset));
Ian Rogersdc51b792011-09-22 20:41:37 -07001798 popl(Address(scratch, dest_offset));
1799}
1800
Ian Rogerse5de95b2011-09-18 20:31:38 -07001801void X86Assembler::MemoryBarrier(ManagedRegister) {
1802#if ANDROID_SMP != 0
Elliott Hughes79ab9e32012-03-12 15:41:35 -07001803 mfence();
Ian Rogerse5de95b2011-09-18 20:31:38 -07001804#endif
1805}
1806
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001807void X86Assembler::CreateHandleScopeEntry(ManagedRegister mout_reg,
1808 FrameOffset handle_scope_offset,
Ian Rogers2c8f6532011-09-02 17:16:34 -07001809 ManagedRegister min_reg, bool null_allowed) {
1810 X86ManagedRegister out_reg = mout_reg.AsX86();
1811 X86ManagedRegister in_reg = min_reg.AsX86();
Ian Rogersb033c752011-07-20 12:22:35 -07001812 CHECK(in_reg.IsCpuRegister());
1813 CHECK(out_reg.IsCpuRegister());
Ian Rogers408f79a2011-08-23 18:22:33 -07001814 VerifyObject(in_reg, null_allowed);
Ian Rogersb033c752011-07-20 12:22:35 -07001815 if (null_allowed) {
1816 Label null_arg;
1817 if (!out_reg.Equals(in_reg)) {
1818 xorl(out_reg.AsCpuRegister(), out_reg.AsCpuRegister());
1819 }
1820 testl(in_reg.AsCpuRegister(), in_reg.AsCpuRegister());
Elliott Hughes18c07532011-08-18 15:50:51 -07001821 j(kZero, &null_arg);
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001822 leal(out_reg.AsCpuRegister(), Address(ESP, handle_scope_offset));
Ian Rogersb033c752011-07-20 12:22:35 -07001823 Bind(&null_arg);
1824 } else {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001825 leal(out_reg.AsCpuRegister(), Address(ESP, handle_scope_offset));
Ian Rogersb033c752011-07-20 12:22:35 -07001826 }
1827}
1828
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001829void X86Assembler::CreateHandleScopeEntry(FrameOffset out_off,
1830 FrameOffset handle_scope_offset,
Ian Rogers2c8f6532011-09-02 17:16:34 -07001831 ManagedRegister mscratch,
1832 bool null_allowed) {
1833 X86ManagedRegister scratch = mscratch.AsX86();
Ian Rogersb033c752011-07-20 12:22:35 -07001834 CHECK(scratch.IsCpuRegister());
1835 if (null_allowed) {
1836 Label null_arg;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001837 movl(scratch.AsCpuRegister(), Address(ESP, handle_scope_offset));
Ian Rogersb033c752011-07-20 12:22:35 -07001838 testl(scratch.AsCpuRegister(), scratch.AsCpuRegister());
Elliott Hughes18c07532011-08-18 15:50:51 -07001839 j(kZero, &null_arg);
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001840 leal(scratch.AsCpuRegister(), Address(ESP, handle_scope_offset));
Ian Rogersb033c752011-07-20 12:22:35 -07001841 Bind(&null_arg);
1842 } else {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001843 leal(scratch.AsCpuRegister(), Address(ESP, handle_scope_offset));
Ian Rogersb033c752011-07-20 12:22:35 -07001844 }
1845 Store(out_off, scratch, 4);
1846}
1847
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001848// Given a handle scope entry, load the associated reference.
1849void X86Assembler::LoadReferenceFromHandleScope(ManagedRegister mout_reg,
Ian Rogers2c8f6532011-09-02 17:16:34 -07001850 ManagedRegister min_reg) {
1851 X86ManagedRegister out_reg = mout_reg.AsX86();
1852 X86ManagedRegister in_reg = min_reg.AsX86();
Ian Rogersb033c752011-07-20 12:22:35 -07001853 CHECK(out_reg.IsCpuRegister());
1854 CHECK(in_reg.IsCpuRegister());
1855 Label null_arg;
1856 if (!out_reg.Equals(in_reg)) {
1857 xorl(out_reg.AsCpuRegister(), out_reg.AsCpuRegister());
1858 }
1859 testl(in_reg.AsCpuRegister(), in_reg.AsCpuRegister());
Elliott Hughes18c07532011-08-18 15:50:51 -07001860 j(kZero, &null_arg);
Ian Rogersb033c752011-07-20 12:22:35 -07001861 movl(out_reg.AsCpuRegister(), Address(in_reg.AsCpuRegister(), 0));
1862 Bind(&null_arg);
1863}
1864
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001865void X86Assembler::VerifyObject(ManagedRegister /*src*/, bool /*could_be_null*/) {
Ian Rogersb033c752011-07-20 12:22:35 -07001866 // TODO: not validating references
1867}
1868
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001869void X86Assembler::VerifyObject(FrameOffset /*src*/, bool /*could_be_null*/) {
Ian Rogersb033c752011-07-20 12:22:35 -07001870 // TODO: not validating references
1871}
1872
Ian Rogers2c8f6532011-09-02 17:16:34 -07001873void X86Assembler::Call(ManagedRegister mbase, Offset offset, ManagedRegister) {
1874 X86ManagedRegister base = mbase.AsX86();
Ian Rogersb033c752011-07-20 12:22:35 -07001875 CHECK(base.IsCpuRegister());
Ian Rogersdf20fe02011-07-20 20:34:16 -07001876 call(Address(base.AsCpuRegister(), offset.Int32Value()));
Ian Rogersb033c752011-07-20 12:22:35 -07001877 // TODO: place reference map on call
1878}
1879
Ian Rogers67375ac2011-09-14 00:55:44 -07001880void X86Assembler::Call(FrameOffset base, Offset offset, ManagedRegister mscratch) {
1881 Register scratch = mscratch.AsX86().AsCpuRegister();
1882 movl(scratch, Address(ESP, base));
1883 call(Address(scratch, offset));
Carl Shapiroe2d373e2011-07-25 15:20:06 -07001884}
1885
Ian Rogersdd7624d2014-03-14 17:43:00 -07001886void X86Assembler::CallFromThread32(ThreadOffset<4> offset, ManagedRegister /*mscratch*/) {
Ian Rogersbdb03912011-09-14 00:55:44 -07001887 fs()->call(Address::Absolute(offset));
Shih-wei Liao668512a2011-09-01 14:18:34 -07001888}
1889
Ian Rogers2c8f6532011-09-02 17:16:34 -07001890void X86Assembler::GetCurrentThread(ManagedRegister tr) {
1891 fs()->movl(tr.AsX86().AsCpuRegister(),
Ian Rogersdd7624d2014-03-14 17:43:00 -07001892 Address::Absolute(Thread::SelfOffset<4>()));
Shih-wei Liao668512a2011-09-01 14:18:34 -07001893}
1894
Ian Rogers2c8f6532011-09-02 17:16:34 -07001895void X86Assembler::GetCurrentThread(FrameOffset offset,
1896 ManagedRegister mscratch) {
1897 X86ManagedRegister scratch = mscratch.AsX86();
Ian Rogersdd7624d2014-03-14 17:43:00 -07001898 fs()->movl(scratch.AsCpuRegister(), Address::Absolute(Thread::SelfOffset<4>()));
Shih-wei Liao668512a2011-09-01 14:18:34 -07001899 movl(Address(ESP, offset), scratch.AsCpuRegister());
1900}
1901
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001902void X86Assembler::ExceptionPoll(ManagedRegister /*scratch*/, size_t stack_adjust) {
1903 X86ExceptionSlowPath* slow = new X86ExceptionSlowPath(stack_adjust);
Ian Rogers45a76cb2011-07-21 22:00:15 -07001904 buffer_.EnqueueSlowPath(slow);
Ian Rogersdd7624d2014-03-14 17:43:00 -07001905 fs()->cmpl(Address::Absolute(Thread::ExceptionOffset<4>()), Immediate(0));
Elliott Hughes18c07532011-08-18 15:50:51 -07001906 j(kNotEqual, slow->Entry());
Ian Rogers45a76cb2011-07-21 22:00:15 -07001907}
Ian Rogers0d666d82011-08-14 16:03:46 -07001908
Ian Rogers2c8f6532011-09-02 17:16:34 -07001909void X86ExceptionSlowPath::Emit(Assembler *sasm) {
1910 X86Assembler* sp_asm = down_cast<X86Assembler*>(sasm);
Ian Rogers0d666d82011-08-14 16:03:46 -07001911#define __ sp_asm->
1912 __ Bind(&entry_);
Elliott Hughes20cde902011-10-04 17:37:27 -07001913 // Note: the return value is dead
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001914 if (stack_adjust_ != 0) { // Fix up the frame.
1915 __ DecreaseFrameSize(stack_adjust_);
1916 }
Ian Rogers67375ac2011-09-14 00:55:44 -07001917 // Pass exception as argument in EAX
Ian Rogersdd7624d2014-03-14 17:43:00 -07001918 __ fs()->movl(EAX, Address::Absolute(Thread::ExceptionOffset<4>()));
1919 __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(4, pDeliverException)));
Ian Rogers67375ac2011-09-14 00:55:44 -07001920 // this call should never return
1921 __ int3();
Ian Rogers0d666d82011-08-14 16:03:46 -07001922#undef __
Ian Rogers45a76cb2011-07-21 22:00:15 -07001923}
1924
Ian Rogers2c8f6532011-09-02 17:16:34 -07001925} // namespace x86
Ian Rogersb033c752011-07-20 12:22:35 -07001926} // namespace art