blob: 168a19644981172fc3268d9e87c38aa2dc13a177 [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright (c) 1994-2006 Sun Microsystems Inc.
2// All Rights Reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions
6// are met:
7//
8// - Redistributions of source code must retain the above copyright notice,
9// this list of conditions and the following disclaimer.
10//
11// - Redistribution in binary form must reproduce the above copyright
12// notice, this list of conditions and the following disclaimer in the
13// documentation and/or other materials provided with the
14// distribution.
15//
16// - Neither the name of Sun Microsystems or the names of contributors may
17// be used to endorse or promote products derived from this software without
18// specific prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31// OF THE POSSIBILITY OF SUCH DAMAGE.
32
33// The original source code covered by the above license above has been modified
34// significantly by Google Inc.
Ben Murdoch3ef787d2012-04-12 10:51:47 +010035// Copyright 2012 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +000036
Emily Bernierd0a1eb72015-03-24 16:35:39 -040037#include "src/ia32/assembler-ia32.h"
38
39#if V8_OS_MACOSX
40#include <sys/sysctl.h>
41#endif
Steve Blocka7e24c12009-10-30 11:49:00 +000042
Ben Murdochb8a8cc12014-11-26 15:28:44 +000043#if V8_TARGET_ARCH_IA32
Leon Clarkef7060e22010-06-03 12:02:55 +010044
Ben Murdochb8a8cc12014-11-26 15:28:44 +000045#include "src/base/bits.h"
46#include "src/base/cpu.h"
47#include "src/disassembler.h"
48#include "src/macro-assembler.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040049#include "src/v8.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000050
51namespace v8 {
52namespace internal {
53
54// -----------------------------------------------------------------------------
55// Implementation of CpuFeatures
56
Emily Bernierd0a1eb72015-03-24 16:35:39 -040057namespace {
58
59bool EnableAVX() {
60#if V8_OS_MACOSX
61 // Mac OS X 10.9 has a bug where AVX transitions were indeed being caused by
62 // ISRs, so we detect Mac OS X 10.9 here and disable AVX in that case.
63 char buffer[128];
64 size_t buffer_size = arraysize(buffer);
65 int ctl_name[] = { CTL_KERN , KERN_OSRELEASE };
66 if (sysctl(ctl_name, 2, buffer, &buffer_size, nullptr, 0) != 0) {
67 V8_Fatal(__FILE__, __LINE__, "V8 failed to get kernel version");
68 }
69 // The buffer now contains a string of the form XX.YY.ZZ, where
70 // XX is the major kernel version component. 13.x.x (Mavericks) is
71 // affected by this bug, so disable AVX there.
72 if (memcmp(buffer, "13.", 3) == 0) return false;
73#endif // V8_OS_MACOSX
74 return FLAG_enable_avx;
75}
76
77} // namespace
78
79
Ben Murdochb8a8cc12014-11-26 15:28:44 +000080void CpuFeatures::ProbeImpl(bool cross_compile) {
81 base::CPU cpu;
82 CHECK(cpu.has_sse2()); // SSE2 support is mandatory.
83 CHECK(cpu.has_cmov()); // CMOV support is mandatory.
Steve Blocka7e24c12009-10-30 11:49:00 +000084
Ben Murdochb8a8cc12014-11-26 15:28:44 +000085 // Only use statically determined features for cross compile (snapshot).
86 if (cross_compile) return;
Steve Blocka7e24c12009-10-30 11:49:00 +000087
Ben Murdochb8a8cc12014-11-26 15:28:44 +000088 if (cpu.has_sse41() && FLAG_enable_sse4_1) supported_ |= 1u << SSE4_1;
89 if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040090 if (cpu.has_avx() && EnableAVX()) supported_ |= 1u << AVX;
91 if (cpu.has_fma3() && FLAG_enable_fma3) supported_ |= 1u << FMA3;
Steve Blocka7e24c12009-10-30 11:49:00 +000092}
93
94
Ben Murdochb8a8cc12014-11-26 15:28:44 +000095void CpuFeatures::PrintTarget() { }
Emily Bernierd0a1eb72015-03-24 16:35:39 -040096void CpuFeatures::PrintFeatures() {
97 printf("SSE3=%d SSE4_1=%d AVX=%d FMA3=%d\n", CpuFeatures::IsSupported(SSE3),
98 CpuFeatures::IsSupported(SSE4_1), CpuFeatures::IsSupported(AVX),
99 CpuFeatures::IsSupported(FMA3));
100}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000101
102
Steve Blocka7e24c12009-10-30 11:49:00 +0000103// -----------------------------------------------------------------------------
104// Implementation of Displacement
105
106void Displacement::init(Label* L, Type type) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000107 DCHECK(!L->is_bound());
Steve Blocka7e24c12009-10-30 11:49:00 +0000108 int next = 0;
109 if (L->is_linked()) {
110 next = L->pos();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000111 DCHECK(next > 0); // Displacements must be at positions > 0
Steve Blocka7e24c12009-10-30 11:49:00 +0000112 }
113 // Ensure that we _never_ overflow the next field.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000114 DCHECK(NextField::is_valid(Assembler::kMaximalBufferSize));
Steve Blocka7e24c12009-10-30 11:49:00 +0000115 data_ = NextField::encode(next) | TypeField::encode(type);
116}
117
118
119// -----------------------------------------------------------------------------
120// Implementation of RelocInfo
121
122
123const int RelocInfo::kApplyMask =
124 RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY |
Ben Murdochbb769b22010-08-11 14:56:33 +0100125 1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE |
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000126 1 << RelocInfo::DEBUG_BREAK_SLOT | 1 << RelocInfo::CODE_AGE_SEQUENCE;
Steve Blocka7e24c12009-10-30 11:49:00 +0000127
128
Leon Clarkef7060e22010-06-03 12:02:55 +0100129bool RelocInfo::IsCodedSpecially() {
130 // The deserializer needs to know whether a pointer is specially coded. Being
131 // specially coded on IA32 means that it is a relative address, as used by
132 // branch instructions. These are also the ones that need changing when a
133 // code object moves.
134 return (1 << rmode_) & kApplyMask;
135}
136
137
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000138bool RelocInfo::IsInConstantPool() {
139 return false;
140}
141
142
Steve Blocka7e24c12009-10-30 11:49:00 +0000143void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
144 // Patch the code at the current address with the supplied instructions.
145 for (int i = 0; i < instruction_count; i++) {
146 *(pc_ + i) = *(instructions + i);
147 }
148
149 // Indicate that code has changed.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000150 CpuFeatures::FlushICache(pc_, instruction_count);
Steve Blocka7e24c12009-10-30 11:49:00 +0000151}
152
153
154// Patch the code at the current PC with a call to the target address.
155// Additional guard int3 instructions can be added if required.
156void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
157 // Call instruction takes up 5 bytes and int3 takes up one byte.
158 static const int kCallCodeSize = 5;
159 int code_size = kCallCodeSize + guard_bytes;
160
161 // Create a code patcher.
162 CodePatcher patcher(pc_, code_size);
163
164 // Add a label for checking the size of the code used for returning.
165#ifdef DEBUG
166 Label check_codesize;
167 patcher.masm()->bind(&check_codesize);
168#endif
169
170 // Patch the code.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000171 patcher.masm()->call(target, RelocInfo::NONE32);
Steve Blocka7e24c12009-10-30 11:49:00 +0000172
173 // Check that the size of the code generated is as expected.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000174 DCHECK_EQ(kCallCodeSize,
Steve Blocka7e24c12009-10-30 11:49:00 +0000175 patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
176
177 // Add the requested number of int3 instructions after the call.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000178 DCHECK_GE(guard_bytes, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +0000179 for (int i = 0; i < guard_bytes; i++) {
180 patcher.masm()->int3();
181 }
182}
183
184
185// -----------------------------------------------------------------------------
186// Implementation of Operand
187
188Operand::Operand(Register base, int32_t disp, RelocInfo::Mode rmode) {
189 // [base + disp/r]
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000190 if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000191 // [base]
192 set_modrm(0, base);
193 if (base.is(esp)) set_sib(times_1, esp, base);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000194 } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000195 // [base + disp8]
196 set_modrm(1, base);
197 if (base.is(esp)) set_sib(times_1, esp, base);
198 set_disp8(disp);
199 } else {
200 // [base + disp/r]
201 set_modrm(2, base);
202 if (base.is(esp)) set_sib(times_1, esp, base);
203 set_dispr(disp, rmode);
204 }
205}
206
207
208Operand::Operand(Register base,
209 Register index,
210 ScaleFactor scale,
211 int32_t disp,
212 RelocInfo::Mode rmode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000213 DCHECK(!index.is(esp)); // illegal addressing mode
Steve Blocka7e24c12009-10-30 11:49:00 +0000214 // [base + index*scale + disp/r]
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000215 if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000216 // [base + index*scale]
217 set_modrm(0, esp);
218 set_sib(scale, index, base);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000219 } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000220 // [base + index*scale + disp8]
221 set_modrm(1, esp);
222 set_sib(scale, index, base);
223 set_disp8(disp);
224 } else {
225 // [base + index*scale + disp/r]
226 set_modrm(2, esp);
227 set_sib(scale, index, base);
228 set_dispr(disp, rmode);
229 }
230}
231
232
233Operand::Operand(Register index,
234 ScaleFactor scale,
235 int32_t disp,
236 RelocInfo::Mode rmode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000237 DCHECK(!index.is(esp)); // illegal addressing mode
Steve Blocka7e24c12009-10-30 11:49:00 +0000238 // [index*scale + disp/r]
239 set_modrm(0, esp);
240 set_sib(scale, index, ebp);
241 set_dispr(disp, rmode);
242}
243
244
245bool Operand::is_reg(Register reg) const {
246 return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only.
247 && ((buf_[0] & 0x07) == reg.code()); // register codes match.
248}
249
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100250
251bool Operand::is_reg_only() const {
252 return (buf_[0] & 0xF8) == 0xC0; // Addressing mode is register only.
253}
254
255
256Register Operand::reg() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000257 DCHECK(is_reg_only());
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100258 return Register::from_code(buf_[0] & 0x07);
259}
260
261
Steve Blocka7e24c12009-10-30 11:49:00 +0000262// -----------------------------------------------------------------------------
Andrei Popescu31002712010-02-23 13:46:05 +0000263// Implementation of Assembler.
Steve Blocka7e24c12009-10-30 11:49:00 +0000264
265// Emit a single byte. Must always be inlined.
266#define EMIT(x) \
267 *pc_++ = (x)
268
269
270#ifdef GENERATED_CODE_COVERAGE
271static void InitCoverageLog();
272#endif
273
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000274Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
275 : AssemblerBase(isolate, buffer, buffer_size),
276 positions_recorder_(this) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000277 // Clear the buffer in debug mode unless it was provided by the
278 // caller in which case we can't be sure it's okay to overwrite
279 // existing code in it; see CodePatcher::CodePatcher(...).
280#ifdef DEBUG
281 if (own_buffer_) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000282 memset(buffer_, 0xCC, buffer_size_); // int3
Steve Blocka7e24c12009-10-30 11:49:00 +0000283 }
284#endif
285
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000286 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000287
Steve Blocka7e24c12009-10-30 11:49:00 +0000288#ifdef GENERATED_CODE_COVERAGE
289 InitCoverageLog();
290#endif
291}
292
293
Steve Blocka7e24c12009-10-30 11:49:00 +0000294void Assembler::GetCode(CodeDesc* desc) {
Andrei Popescu31002712010-02-23 13:46:05 +0000295 // Finalize code (at this point overflow() may be true, but the gap ensures
296 // that we are still not overlapping instructions and relocation info).
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000297 DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100298 // Set up code descriptor.
Steve Blocka7e24c12009-10-30 11:49:00 +0000299 desc->buffer = buffer_;
300 desc->buffer_size = buffer_size_;
301 desc->instr_size = pc_offset();
302 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
303 desc->origin = this;
Steve Blocka7e24c12009-10-30 11:49:00 +0000304}
305
306
307void Assembler::Align(int m) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000308 DCHECK(base::bits::IsPowerOfTwo32(m));
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100309 int mask = m - 1;
310 int addr = pc_offset();
311 Nop((m - (addr & mask)) & mask);
312}
313
314
315bool Assembler::IsNop(Address addr) {
316 Address a = addr;
317 while (*a == 0x66) a++;
318 if (*a == 0x90) return true;
319 if (a[0] == 0xf && a[1] == 0x1f) return true;
320 return false;
321}
322
323
324void Assembler::Nop(int bytes) {
325 EnsureSpace ensure_space(this);
326
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100327 // Multi byte nops from http://support.amd.com/us/Processor_TechDocs/40546.pdf
328 while (bytes > 0) {
329 switch (bytes) {
330 case 2:
331 EMIT(0x66);
332 case 1:
333 EMIT(0x90);
334 return;
335 case 3:
336 EMIT(0xf);
337 EMIT(0x1f);
338 EMIT(0);
339 return;
340 case 4:
341 EMIT(0xf);
342 EMIT(0x1f);
343 EMIT(0x40);
344 EMIT(0);
345 return;
346 case 6:
347 EMIT(0x66);
348 case 5:
349 EMIT(0xf);
350 EMIT(0x1f);
351 EMIT(0x44);
352 EMIT(0);
353 EMIT(0);
354 return;
355 case 7:
356 EMIT(0xf);
357 EMIT(0x1f);
358 EMIT(0x80);
359 EMIT(0);
360 EMIT(0);
361 EMIT(0);
362 EMIT(0);
363 return;
364 default:
365 case 11:
366 EMIT(0x66);
367 bytes--;
368 case 10:
369 EMIT(0x66);
370 bytes--;
371 case 9:
372 EMIT(0x66);
373 bytes--;
374 case 8:
375 EMIT(0xf);
376 EMIT(0x1f);
377 EMIT(0x84);
378 EMIT(0);
379 EMIT(0);
380 EMIT(0);
381 EMIT(0);
382 EMIT(0);
383 bytes -= 8;
384 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000385 }
386}
387
388
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100389void Assembler::CodeTargetAlign() {
390 Align(16); // Preferred alignment of jump targets on ia32.
391}
392
393
Steve Blocka7e24c12009-10-30 11:49:00 +0000394void Assembler::cpuid() {
Steve Blocka7e24c12009-10-30 11:49:00 +0000395 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000396 EMIT(0x0F);
397 EMIT(0xA2);
398}
399
400
401void Assembler::pushad() {
402 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000403 EMIT(0x60);
404}
405
406
407void Assembler::popad() {
408 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000409 EMIT(0x61);
410}
411
412
413void Assembler::pushfd() {
414 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000415 EMIT(0x9C);
416}
417
418
419void Assembler::popfd() {
420 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000421 EMIT(0x9D);
422}
423
424
425void Assembler::push(const Immediate& x) {
426 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000427 if (x.is_int8()) {
428 EMIT(0x6a);
429 EMIT(x.x_);
430 } else {
431 EMIT(0x68);
432 emit(x);
433 }
434}
435
436
Ben Murdochb0fe1622011-05-05 13:52:32 +0100437void Assembler::push_imm32(int32_t imm32) {
438 EnsureSpace ensure_space(this);
439 EMIT(0x68);
440 emit(imm32);
441}
442
443
Steve Blocka7e24c12009-10-30 11:49:00 +0000444void Assembler::push(Register src) {
445 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000446 EMIT(0x50 | src.code());
447}
448
449
450void Assembler::push(const Operand& src) {
451 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000452 EMIT(0xFF);
453 emit_operand(esi, src);
454}
455
456
457void Assembler::pop(Register dst) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000458 DCHECK(reloc_info_writer.last_pc() != NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +0000459 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000460 EMIT(0x58 | dst.code());
461}
462
463
464void Assembler::pop(const Operand& dst) {
465 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000466 EMIT(0x8F);
467 emit_operand(eax, dst);
468}
469
470
471void Assembler::enter(const Immediate& size) {
472 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000473 EMIT(0xC8);
474 emit_w(size);
475 EMIT(0);
476}
477
478
479void Assembler::leave() {
480 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000481 EMIT(0xC9);
482}
483
484
485void Assembler::mov_b(Register dst, const Operand& src) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100486 CHECK(dst.is_byte_register());
Steve Blocka7e24c12009-10-30 11:49:00 +0000487 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000488 EMIT(0x8A);
489 emit_operand(dst, src);
490}
491
492
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400493void Assembler::mov_b(const Operand& dst, const Immediate& src) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000494 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000495 EMIT(0xC6);
496 emit_operand(eax, dst);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400497 EMIT(static_cast<int8_t>(src.x_));
Steve Blocka7e24c12009-10-30 11:49:00 +0000498}
499
500
501void Assembler::mov_b(const Operand& dst, Register src) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100502 CHECK(src.is_byte_register());
Steve Blocka7e24c12009-10-30 11:49:00 +0000503 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000504 EMIT(0x88);
505 emit_operand(src, dst);
506}
507
508
509void Assembler::mov_w(Register dst, const Operand& src) {
510 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000511 EMIT(0x66);
512 EMIT(0x8B);
513 emit_operand(dst, src);
514}
515
516
517void Assembler::mov_w(const Operand& dst, Register src) {
518 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000519 EMIT(0x66);
520 EMIT(0x89);
521 emit_operand(src, dst);
522}
523
524
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400525void Assembler::mov_w(const Operand& dst, const Immediate& src) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000526 EnsureSpace ensure_space(this);
527 EMIT(0x66);
528 EMIT(0xC7);
529 emit_operand(eax, dst);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400530 EMIT(static_cast<int8_t>(src.x_ & 0xff));
531 EMIT(static_cast<int8_t>(src.x_ >> 8));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000532}
533
534
Steve Blocka7e24c12009-10-30 11:49:00 +0000535void Assembler::mov(Register dst, int32_t imm32) {
536 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000537 EMIT(0xB8 | dst.code());
538 emit(imm32);
539}
540
541
542void Assembler::mov(Register dst, const Immediate& x) {
543 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000544 EMIT(0xB8 | dst.code());
545 emit(x);
546}
547
548
549void Assembler::mov(Register dst, Handle<Object> handle) {
550 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000551 EMIT(0xB8 | dst.code());
552 emit(handle);
553}
554
555
556void Assembler::mov(Register dst, const Operand& src) {
557 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000558 EMIT(0x8B);
559 emit_operand(dst, src);
560}
561
562
563void Assembler::mov(Register dst, Register src) {
564 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000565 EMIT(0x89);
566 EMIT(0xC0 | src.code() << 3 | dst.code());
567}
568
569
570void Assembler::mov(const Operand& dst, const Immediate& x) {
571 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000572 EMIT(0xC7);
573 emit_operand(eax, dst);
574 emit(x);
575}
576
577
578void Assembler::mov(const Operand& dst, Handle<Object> handle) {
579 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000580 EMIT(0xC7);
581 emit_operand(eax, dst);
582 emit(handle);
583}
584
585
586void Assembler::mov(const Operand& dst, Register src) {
587 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000588 EMIT(0x89);
589 emit_operand(src, dst);
590}
591
592
593void Assembler::movsx_b(Register dst, const Operand& src) {
594 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000595 EMIT(0x0F);
596 EMIT(0xBE);
597 emit_operand(dst, src);
598}
599
600
601void Assembler::movsx_w(Register dst, const Operand& src) {
602 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000603 EMIT(0x0F);
604 EMIT(0xBF);
605 emit_operand(dst, src);
606}
607
608
609void Assembler::movzx_b(Register dst, const Operand& src) {
610 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000611 EMIT(0x0F);
612 EMIT(0xB6);
613 emit_operand(dst, src);
614}
615
616
617void Assembler::movzx_w(Register dst, const Operand& src) {
618 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000619 EMIT(0x0F);
620 EMIT(0xB7);
621 emit_operand(dst, src);
622}
623
624
Steve Blocka7e24c12009-10-30 11:49:00 +0000625void Assembler::cmov(Condition cc, Register dst, const Operand& src) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000626 EnsureSpace ensure_space(this);
Andrei Popescu31002712010-02-23 13:46:05 +0000627 // Opcode: 0f 40 + cc /r.
Steve Blocka7e24c12009-10-30 11:49:00 +0000628 EMIT(0x0F);
629 EMIT(0x40 + cc);
630 emit_operand(dst, src);
631}
632
633
Steve Block6ded16b2010-05-10 14:33:55 +0100634void Assembler::cld() {
635 EnsureSpace ensure_space(this);
Steve Block6ded16b2010-05-10 14:33:55 +0100636 EMIT(0xFC);
637}
638
639
Leon Clarkee46be812010-01-19 14:06:41 +0000640void Assembler::rep_movs() {
641 EnsureSpace ensure_space(this);
Leon Clarkee46be812010-01-19 14:06:41 +0000642 EMIT(0xF3);
643 EMIT(0xA5);
644}
645
646
Steve Block6ded16b2010-05-10 14:33:55 +0100647void Assembler::rep_stos() {
648 EnsureSpace ensure_space(this);
Steve Block6ded16b2010-05-10 14:33:55 +0100649 EMIT(0xF3);
650 EMIT(0xAB);
651}
652
653
Leon Clarkef7060e22010-06-03 12:02:55 +0100654void Assembler::stos() {
655 EnsureSpace ensure_space(this);
Leon Clarkef7060e22010-06-03 12:02:55 +0100656 EMIT(0xAB);
657}
658
659
Steve Blocka7e24c12009-10-30 11:49:00 +0000660void Assembler::xchg(Register dst, Register src) {
661 EnsureSpace ensure_space(this);
Andrei Popescu31002712010-02-23 13:46:05 +0000662 if (src.is(eax) || dst.is(eax)) { // Single-byte encoding.
Steve Blocka7e24c12009-10-30 11:49:00 +0000663 EMIT(0x90 | (src.is(eax) ? dst.code() : src.code()));
664 } else {
665 EMIT(0x87);
666 EMIT(0xC0 | src.code() << 3 | dst.code());
667 }
668}
669
670
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000671void Assembler::xchg(Register dst, const Operand& src) {
672 EnsureSpace ensure_space(this);
673 EMIT(0x87);
674 emit_operand(dst, src);
675}
676
677
Steve Blocka7e24c12009-10-30 11:49:00 +0000678void Assembler::adc(Register dst, int32_t imm32) {
679 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000680 emit_arith(2, Operand(dst), Immediate(imm32));
681}
682
683
684void Assembler::adc(Register dst, const Operand& src) {
685 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000686 EMIT(0x13);
687 emit_operand(dst, src);
688}
689
690
691void Assembler::add(Register dst, const Operand& src) {
692 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000693 EMIT(0x03);
694 emit_operand(dst, src);
695}
696
697
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100698void Assembler::add(const Operand& dst, Register src) {
699 EnsureSpace ensure_space(this);
700 EMIT(0x01);
701 emit_operand(src, dst);
702}
703
704
Steve Blocka7e24c12009-10-30 11:49:00 +0000705void Assembler::add(const Operand& dst, const Immediate& x) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000706 DCHECK(reloc_info_writer.last_pc() != NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +0000707 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000708 emit_arith(0, dst, x);
709}
710
711
712void Assembler::and_(Register dst, int32_t imm32) {
Steve Block59151502010-09-22 15:07:15 +0100713 and_(dst, Immediate(imm32));
714}
715
716
717void Assembler::and_(Register dst, const Immediate& x) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000718 EnsureSpace ensure_space(this);
Steve Block59151502010-09-22 15:07:15 +0100719 emit_arith(4, Operand(dst), x);
Steve Blocka7e24c12009-10-30 11:49:00 +0000720}
721
722
723void Assembler::and_(Register dst, const Operand& src) {
724 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000725 EMIT(0x23);
726 emit_operand(dst, src);
727}
728
729
730void Assembler::and_(const Operand& dst, const Immediate& x) {
731 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000732 emit_arith(4, dst, x);
733}
734
735
736void Assembler::and_(const Operand& dst, Register src) {
737 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000738 EMIT(0x21);
739 emit_operand(src, dst);
740}
741
742
743void Assembler::cmpb(const Operand& op, int8_t imm8) {
744 EnsureSpace ensure_space(this);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100745 if (op.is_reg(eax)) {
746 EMIT(0x3C);
747 } else {
748 EMIT(0x80);
749 emit_operand(edi, op); // edi == 7
750 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000751 EMIT(imm8);
752}
753
754
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100755void Assembler::cmpb(const Operand& op, Register reg) {
756 CHECK(reg.is_byte_register());
Leon Clarked91b9f72010-01-27 17:25:45 +0000757 EnsureSpace ensure_space(this);
Leon Clarked91b9f72010-01-27 17:25:45 +0000758 EMIT(0x38);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100759 emit_operand(reg, op);
Leon Clarked91b9f72010-01-27 17:25:45 +0000760}
761
762
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100763void Assembler::cmpb(Register reg, const Operand& op) {
764 CHECK(reg.is_byte_register());
Leon Clarked91b9f72010-01-27 17:25:45 +0000765 EnsureSpace ensure_space(this);
Leon Clarked91b9f72010-01-27 17:25:45 +0000766 EMIT(0x3A);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100767 emit_operand(reg, op);
Leon Clarked91b9f72010-01-27 17:25:45 +0000768}
769
770
Steve Blocka7e24c12009-10-30 11:49:00 +0000771void Assembler::cmpw(const Operand& op, Immediate imm16) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000772 DCHECK(imm16.is_int16());
Steve Blocka7e24c12009-10-30 11:49:00 +0000773 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000774 EMIT(0x66);
775 EMIT(0x81);
776 emit_operand(edi, op);
777 emit_w(imm16);
778}
779
780
781void Assembler::cmp(Register reg, int32_t imm32) {
782 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000783 emit_arith(7, Operand(reg), Immediate(imm32));
784}
785
786
787void Assembler::cmp(Register reg, Handle<Object> handle) {
788 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000789 emit_arith(7, Operand(reg), Immediate(handle));
790}
791
792
793void Assembler::cmp(Register reg, const Operand& op) {
794 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000795 EMIT(0x3B);
796 emit_operand(reg, op);
797}
798
799
800void Assembler::cmp(const Operand& op, const Immediate& imm) {
801 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000802 emit_arith(7, op, imm);
803}
804
805
806void Assembler::cmp(const Operand& op, Handle<Object> handle) {
807 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000808 emit_arith(7, op, Immediate(handle));
809}
810
811
812void Assembler::cmpb_al(const Operand& op) {
813 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000814 EMIT(0x38); // CMP r/m8, r8
815 emit_operand(eax, op); // eax has same code as register al.
816}
817
818
819void Assembler::cmpw_ax(const Operand& op) {
820 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000821 EMIT(0x66);
822 EMIT(0x39); // CMP r/m16, r16
823 emit_operand(eax, op); // eax has same code as register ax.
824}
825
826
827void Assembler::dec_b(Register dst) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100828 CHECK(dst.is_byte_register());
Steve Blocka7e24c12009-10-30 11:49:00 +0000829 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000830 EMIT(0xFE);
831 EMIT(0xC8 | dst.code());
832}
833
834
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100835void Assembler::dec_b(const Operand& dst) {
836 EnsureSpace ensure_space(this);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100837 EMIT(0xFE);
838 emit_operand(ecx, dst);
839}
840
841
Steve Blocka7e24c12009-10-30 11:49:00 +0000842void Assembler::dec(Register dst) {
843 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000844 EMIT(0x48 | dst.code());
845}
846
847
848void Assembler::dec(const Operand& dst) {
849 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000850 EMIT(0xFF);
851 emit_operand(ecx, dst);
852}
853
854
855void Assembler::cdq() {
856 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000857 EMIT(0x99);
858}
859
860
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000861void Assembler::idiv(const Operand& src) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000862 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000863 EMIT(0xF7);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000864 emit_operand(edi, src);
865}
866
867
868void Assembler::div(const Operand& src) {
869 EnsureSpace ensure_space(this);
870 EMIT(0xF7);
871 emit_operand(esi, src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000872}
873
874
875void Assembler::imul(Register reg) {
876 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000877 EMIT(0xF7);
878 EMIT(0xE8 | reg.code());
879}
880
881
882void Assembler::imul(Register dst, const Operand& src) {
883 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000884 EMIT(0x0F);
885 EMIT(0xAF);
886 emit_operand(dst, src);
887}
888
889
890void Assembler::imul(Register dst, Register src, int32_t imm32) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000891 imul(dst, Operand(src), imm32);
892}
893
894
895void Assembler::imul(Register dst, const Operand& src, int32_t imm32) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000896 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000897 if (is_int8(imm32)) {
898 EMIT(0x6B);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000899 emit_operand(dst, src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000900 EMIT(imm32);
901 } else {
902 EMIT(0x69);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000903 emit_operand(dst, src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000904 emit(imm32);
905 }
906}
907
908
909void Assembler::inc(Register dst) {
910 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000911 EMIT(0x40 | dst.code());
912}
913
914
915void Assembler::inc(const Operand& dst) {
916 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000917 EMIT(0xFF);
918 emit_operand(eax, dst);
919}
920
921
922void Assembler::lea(Register dst, const Operand& src) {
923 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000924 EMIT(0x8D);
925 emit_operand(dst, src);
926}
927
928
929void Assembler::mul(Register src) {
930 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000931 EMIT(0xF7);
932 EMIT(0xE0 | src.code());
933}
934
935
936void Assembler::neg(Register dst) {
937 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000938 EMIT(0xF7);
939 EMIT(0xD8 | dst.code());
940}
941
942
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000943void Assembler::neg(const Operand& dst) {
944 EnsureSpace ensure_space(this);
945 EMIT(0xF7);
946 emit_operand(ebx, dst);
947}
948
949
Steve Blocka7e24c12009-10-30 11:49:00 +0000950void Assembler::not_(Register dst) {
951 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000952 EMIT(0xF7);
953 EMIT(0xD0 | dst.code());
954}
955
956
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000957void Assembler::not_(const Operand& dst) {
958 EnsureSpace ensure_space(this);
959 EMIT(0xF7);
960 emit_operand(edx, dst);
961}
962
963
Steve Blocka7e24c12009-10-30 11:49:00 +0000964void Assembler::or_(Register dst, int32_t imm32) {
965 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000966 emit_arith(1, Operand(dst), Immediate(imm32));
967}
968
969
970void Assembler::or_(Register dst, const Operand& src) {
971 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000972 EMIT(0x0B);
973 emit_operand(dst, src);
974}
975
976
977void Assembler::or_(const Operand& dst, const Immediate& x) {
978 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000979 emit_arith(1, dst, x);
980}
981
982
983void Assembler::or_(const Operand& dst, Register src) {
984 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000985 EMIT(0x09);
986 emit_operand(src, dst);
987}
988
989
990void Assembler::rcl(Register dst, uint8_t imm8) {
991 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000992 DCHECK(is_uint5(imm8)); // illegal shift count
Steve Blocka7e24c12009-10-30 11:49:00 +0000993 if (imm8 == 1) {
994 EMIT(0xD1);
995 EMIT(0xD0 | dst.code());
996 } else {
997 EMIT(0xC1);
998 EMIT(0xD0 | dst.code());
999 EMIT(imm8);
1000 }
1001}
1002
1003
Iain Merrick75681382010-08-19 15:07:18 +01001004void Assembler::rcr(Register dst, uint8_t imm8) {
1005 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001006 DCHECK(is_uint5(imm8)); // illegal shift count
Iain Merrick75681382010-08-19 15:07:18 +01001007 if (imm8 == 1) {
1008 EMIT(0xD1);
1009 EMIT(0xD8 | dst.code());
1010 } else {
1011 EMIT(0xC1);
1012 EMIT(0xD8 | dst.code());
1013 EMIT(imm8);
1014 }
1015}
1016
1017
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001018void Assembler::ror(const Operand& dst, uint8_t imm8) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001019 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001020 DCHECK(is_uint5(imm8)); // illegal shift count
Steve Blocka7e24c12009-10-30 11:49:00 +00001021 if (imm8 == 1) {
1022 EMIT(0xD1);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001023 emit_operand(ecx, dst);
Steve Blocka7e24c12009-10-30 11:49:00 +00001024 } else {
1025 EMIT(0xC1);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001026 emit_operand(ecx, dst);
Steve Blocka7e24c12009-10-30 11:49:00 +00001027 EMIT(imm8);
1028 }
1029}
1030
1031
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001032void Assembler::ror_cl(const Operand& dst) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001033 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001034 EMIT(0xD3);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001035 emit_operand(ecx, dst);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001036}
1037
1038
1039void Assembler::sar(const Operand& dst, uint8_t imm8) {
1040 EnsureSpace ensure_space(this);
1041 DCHECK(is_uint5(imm8)); // illegal shift count
1042 if (imm8 == 1) {
1043 EMIT(0xD1);
1044 emit_operand(edi, dst);
1045 } else {
1046 EMIT(0xC1);
1047 emit_operand(edi, dst);
1048 EMIT(imm8);
1049 }
1050}
1051
1052
1053void Assembler::sar_cl(const Operand& dst) {
1054 EnsureSpace ensure_space(this);
1055 EMIT(0xD3);
1056 emit_operand(edi, dst);
Steve Blocka7e24c12009-10-30 11:49:00 +00001057}
1058
1059
1060void Assembler::sbb(Register dst, const Operand& src) {
1061 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001062 EMIT(0x1B);
1063 emit_operand(dst, src);
1064}
1065
1066
1067void Assembler::shld(Register dst, const Operand& src) {
1068 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001069 EMIT(0x0F);
1070 EMIT(0xA5);
1071 emit_operand(dst, src);
1072}
1073
1074
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001075void Assembler::shl(const Operand& dst, uint8_t imm8) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001076 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001077 DCHECK(is_uint5(imm8)); // illegal shift count
Steve Blocka7e24c12009-10-30 11:49:00 +00001078 if (imm8 == 1) {
1079 EMIT(0xD1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001080 emit_operand(esp, dst);
Steve Blocka7e24c12009-10-30 11:49:00 +00001081 } else {
1082 EMIT(0xC1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001083 emit_operand(esp, dst);
Steve Blocka7e24c12009-10-30 11:49:00 +00001084 EMIT(imm8);
1085 }
1086}
1087
1088
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001089void Assembler::shl_cl(const Operand& dst) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001090 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001091 EMIT(0xD3);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001092 emit_operand(esp, dst);
Steve Blocka7e24c12009-10-30 11:49:00 +00001093}
1094
1095
1096void Assembler::shrd(Register dst, const Operand& src) {
1097 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001098 EMIT(0x0F);
1099 EMIT(0xAD);
1100 emit_operand(dst, src);
1101}
1102
1103
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001104void Assembler::shr(const Operand& dst, uint8_t imm8) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001105 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001106 DCHECK(is_uint5(imm8)); // illegal shift count
Steve Blockd0582a62009-12-15 09:54:21 +00001107 if (imm8 == 1) {
1108 EMIT(0xD1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001109 emit_operand(ebp, dst);
Steve Blockd0582a62009-12-15 09:54:21 +00001110 } else {
1111 EMIT(0xC1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001112 emit_operand(ebp, dst);
Steve Blockd0582a62009-12-15 09:54:21 +00001113 EMIT(imm8);
1114 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001115}
1116
1117
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001118void Assembler::shr_cl(const Operand& dst) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001119 EnsureSpace ensure_space(this);
Steve Blockd0582a62009-12-15 09:54:21 +00001120 EMIT(0xD3);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001121 emit_operand(ebp, dst);
Steve Blocka7e24c12009-10-30 11:49:00 +00001122}
1123
1124
1125void Assembler::sub(const Operand& dst, const Immediate& x) {
1126 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001127 emit_arith(5, dst, x);
1128}
1129
1130
1131void Assembler::sub(Register dst, const Operand& src) {
1132 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001133 EMIT(0x2B);
1134 emit_operand(dst, src);
1135}
1136
1137
1138void Assembler::sub(const Operand& dst, Register src) {
1139 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001140 EMIT(0x29);
1141 emit_operand(src, dst);
1142}
1143
1144
1145void Assembler::test(Register reg, const Immediate& imm) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001146 if (RelocInfo::IsNone(imm.rmode_) && is_uint8(imm.x_)) {
1147 test_b(reg, imm.x_);
1148 return;
Steve Blocka7e24c12009-10-30 11:49:00 +00001149 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001150
1151 EnsureSpace ensure_space(this);
1152 // This is not using emit_arith because test doesn't support
1153 // sign-extension of 8-bit operands.
1154 if (reg.is(eax)) {
1155 EMIT(0xA9);
1156 } else {
1157 EMIT(0xF7);
1158 EMIT(0xC0 | reg.code());
1159 }
1160 emit(imm);
Steve Blocka7e24c12009-10-30 11:49:00 +00001161}
1162
1163
1164void Assembler::test(Register reg, const Operand& op) {
1165 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001166 EMIT(0x85);
1167 emit_operand(reg, op);
1168}
1169
1170
Leon Clarkee46be812010-01-19 14:06:41 +00001171void Assembler::test_b(Register reg, const Operand& op) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001172 CHECK(reg.is_byte_register());
Leon Clarkee46be812010-01-19 14:06:41 +00001173 EnsureSpace ensure_space(this);
Leon Clarkee46be812010-01-19 14:06:41 +00001174 EMIT(0x84);
1175 emit_operand(reg, op);
1176}
1177
1178
Steve Blocka7e24c12009-10-30 11:49:00 +00001179void Assembler::test(const Operand& op, const Immediate& imm) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001180 if (op.is_reg_only()) {
1181 test(op.reg(), imm);
1182 return;
1183 }
1184 if (RelocInfo::IsNone(imm.rmode_) && is_uint8(imm.x_)) {
1185 return test_b(op, imm.x_);
1186 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001187 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001188 EMIT(0xF7);
1189 emit_operand(eax, op);
1190 emit(imm);
1191}
1192
1193
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001194void Assembler::test_b(Register reg, uint8_t imm8) {
1195 EnsureSpace ensure_space(this);
1196 // Only use test against byte for registers that have a byte
1197 // variant: eax, ebx, ecx, and edx.
1198 if (reg.is(eax)) {
1199 EMIT(0xA8);
1200 EMIT(imm8);
1201 } else if (reg.is_byte_register()) {
1202 emit_arith_b(0xF6, 0xC0, reg, imm8);
1203 } else {
1204 EMIT(0xF7);
1205 EMIT(0xC0 | reg.code());
1206 emit(imm8);
1207 }
1208}
1209
1210
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001211void Assembler::test_b(const Operand& op, uint8_t imm8) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001212 if (op.is_reg_only()) {
1213 test_b(op.reg(), imm8);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001214 return;
1215 }
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001216 EnsureSpace ensure_space(this);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001217 EMIT(0xF6);
1218 emit_operand(eax, op);
1219 EMIT(imm8);
1220}
1221
1222
Steve Blocka7e24c12009-10-30 11:49:00 +00001223void Assembler::xor_(Register dst, int32_t imm32) {
1224 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001225 emit_arith(6, Operand(dst), Immediate(imm32));
1226}
1227
1228
1229void Assembler::xor_(Register dst, const Operand& src) {
1230 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001231 EMIT(0x33);
1232 emit_operand(dst, src);
1233}
1234
1235
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001236void Assembler::xor_(const Operand& dst, Register src) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001237 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001238 EMIT(0x31);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001239 emit_operand(src, dst);
Steve Blocka7e24c12009-10-30 11:49:00 +00001240}
1241
1242
1243void Assembler::xor_(const Operand& dst, const Immediate& x) {
1244 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001245 emit_arith(6, dst, x);
1246}
1247
1248
1249void Assembler::bt(const Operand& dst, Register src) {
1250 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001251 EMIT(0x0F);
1252 EMIT(0xA3);
1253 emit_operand(src, dst);
1254}
1255
1256
1257void Assembler::bts(const Operand& dst, Register src) {
1258 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001259 EMIT(0x0F);
1260 EMIT(0xAB);
1261 emit_operand(src, dst);
1262}
1263
1264
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001265void Assembler::bsr(Register dst, const Operand& src) {
1266 EnsureSpace ensure_space(this);
1267 EMIT(0x0F);
1268 EMIT(0xBD);
1269 emit_operand(dst, src);
1270}
1271
1272
Steve Blocka7e24c12009-10-30 11:49:00 +00001273void Assembler::hlt() {
1274 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001275 EMIT(0xF4);
1276}
1277
1278
1279void Assembler::int3() {
1280 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001281 EMIT(0xCC);
1282}
1283
1284
1285void Assembler::nop() {
1286 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001287 EMIT(0x90);
1288}
1289
1290
Steve Blocka7e24c12009-10-30 11:49:00 +00001291void Assembler::ret(int imm16) {
1292 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001293 DCHECK(is_uint16(imm16));
Steve Blocka7e24c12009-10-30 11:49:00 +00001294 if (imm16 == 0) {
1295 EMIT(0xC3);
1296 } else {
1297 EMIT(0xC2);
1298 EMIT(imm16 & 0xFF);
1299 EMIT((imm16 >> 8) & 0xFF);
1300 }
1301}
1302
1303
1304// Labels refer to positions in the (to be) generated code.
1305// There are bound, linked, and unused labels.
1306//
1307// Bound labels refer to known positions in the already
1308// generated code. pos() is the position the label refers to.
1309//
1310// Linked labels refer to unknown positions in the code
1311// to be generated; pos() is the position of the 32bit
1312// Displacement of the last instruction using the label.
1313
1314
1315void Assembler::print(Label* L) {
1316 if (L->is_unused()) {
1317 PrintF("unused label\n");
1318 } else if (L->is_bound()) {
1319 PrintF("bound label to %d\n", L->pos());
1320 } else if (L->is_linked()) {
1321 Label l = *L;
1322 PrintF("unbound label");
1323 while (l.is_linked()) {
1324 Displacement disp = disp_at(&l);
1325 PrintF("@ %d ", l.pos());
1326 disp.print();
1327 PrintF("\n");
1328 disp.next(&l);
1329 }
1330 } else {
1331 PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
1332 }
1333}
1334
1335
1336void Assembler::bind_to(Label* L, int pos) {
1337 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001338 DCHECK(0 <= pos && pos <= pc_offset()); // must have a valid binding position
Steve Blocka7e24c12009-10-30 11:49:00 +00001339 while (L->is_linked()) {
1340 Displacement disp = disp_at(L);
1341 int fixup_pos = L->pos();
1342 if (disp.type() == Displacement::CODE_RELATIVE) {
1343 // Relative to Code* heap object pointer.
1344 long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag);
1345 } else {
1346 if (disp.type() == Displacement::UNCONDITIONAL_JUMP) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001347 DCHECK(byte_at(fixup_pos - 1) == 0xE9); // jmp expected
Steve Blocka7e24c12009-10-30 11:49:00 +00001348 }
Andrei Popescu31002712010-02-23 13:46:05 +00001349 // Relative address, relative to point after address.
Steve Blocka7e24c12009-10-30 11:49:00 +00001350 int imm32 = pos - (fixup_pos + sizeof(int32_t));
1351 long_at_put(fixup_pos, imm32);
1352 }
1353 disp.next(L);
1354 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001355 while (L->is_near_linked()) {
1356 int fixup_pos = L->near_link_pos();
1357 int offset_to_next =
1358 static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001359 DCHECK(offset_to_next <= 0);
Ben Murdoch257744e2011-11-30 15:57:28 +00001360 // Relative address, relative to point after address.
1361 int disp = pos - fixup_pos - sizeof(int8_t);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001362 CHECK(0 <= disp && disp <= 127);
Ben Murdoch257744e2011-11-30 15:57:28 +00001363 set_byte_at(fixup_pos, disp);
1364 if (offset_to_next < 0) {
1365 L->link_to(fixup_pos + offset_to_next, Label::kNear);
1366 } else {
1367 L->UnuseNear();
1368 }
1369 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001370 L->bind_to(pos);
1371}
1372
1373
Steve Blocka7e24c12009-10-30 11:49:00 +00001374void Assembler::bind(Label* L) {
1375 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001376 DCHECK(!L->is_bound()); // label can only be bound once
Steve Blocka7e24c12009-10-30 11:49:00 +00001377 bind_to(L, pc_offset());
1378}
1379
1380
1381void Assembler::call(Label* L) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01001382 positions_recorder()->WriteRecordedPositions();
Steve Blocka7e24c12009-10-30 11:49:00 +00001383 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001384 if (L->is_bound()) {
1385 const int long_size = 5;
1386 int offs = L->pos() - pc_offset();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001387 DCHECK(offs <= 0);
Andrei Popescu31002712010-02-23 13:46:05 +00001388 // 1110 1000 #32-bit disp.
Steve Blocka7e24c12009-10-30 11:49:00 +00001389 EMIT(0xE8);
1390 emit(offs - long_size);
1391 } else {
Andrei Popescu31002712010-02-23 13:46:05 +00001392 // 1110 1000 #32-bit disp.
Steve Blocka7e24c12009-10-30 11:49:00 +00001393 EMIT(0xE8);
1394 emit_disp(L, Displacement::OTHER);
1395 }
1396}
1397
1398
1399void Assembler::call(byte* entry, RelocInfo::Mode rmode) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01001400 positions_recorder()->WriteRecordedPositions();
Steve Blocka7e24c12009-10-30 11:49:00 +00001401 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001402 DCHECK(!RelocInfo::IsCodeTarget(rmode));
Steve Blocka7e24c12009-10-30 11:49:00 +00001403 EMIT(0xE8);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001404 if (RelocInfo::IsRuntimeEntry(rmode)) {
1405 emit(reinterpret_cast<uint32_t>(entry), rmode);
1406 } else {
1407 emit(entry - (pc_ + sizeof(int32_t)), rmode);
1408 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001409}
1410
1411
Ben Murdoch257744e2011-11-30 15:57:28 +00001412int Assembler::CallSize(const Operand& adr) {
1413 // Call size is 1 (opcode) + adr.len_ (operand).
1414 return 1 + adr.len_;
1415}
1416
1417
Steve Blocka7e24c12009-10-30 11:49:00 +00001418void Assembler::call(const Operand& adr) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01001419 positions_recorder()->WriteRecordedPositions();
Steve Blocka7e24c12009-10-30 11:49:00 +00001420 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001421 EMIT(0xFF);
1422 emit_operand(edx, adr);
1423}
1424
1425
Ben Murdoch257744e2011-11-30 15:57:28 +00001426int Assembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) {
1427 return 1 /* EMIT */ + sizeof(uint32_t) /* emit */;
Steve Blocka7e24c12009-10-30 11:49:00 +00001428}
1429
1430
Ben Murdoch257744e2011-11-30 15:57:28 +00001431void Assembler::call(Handle<Code> code,
1432 RelocInfo::Mode rmode,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001433 TypeFeedbackId ast_id) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001434 positions_recorder()->WriteRecordedPositions();
Steve Blocka7e24c12009-10-30 11:49:00 +00001435 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001436 DCHECK(RelocInfo::IsCodeTarget(rmode)
1437 || rmode == RelocInfo::CODE_AGE_SEQUENCE);
Ben Murdoch257744e2011-11-30 15:57:28 +00001438 EMIT(0xE8);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001439 emit(code, rmode, ast_id);
Ben Murdoch257744e2011-11-30 15:57:28 +00001440}
1441
1442
1443void Assembler::jmp(Label* L, Label::Distance distance) {
1444 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001445 if (L->is_bound()) {
1446 const int short_size = 2;
1447 const int long_size = 5;
1448 int offs = L->pos() - pc_offset();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001449 DCHECK(offs <= 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00001450 if (is_int8(offs - short_size)) {
Andrei Popescu31002712010-02-23 13:46:05 +00001451 // 1110 1011 #8-bit disp.
Steve Blocka7e24c12009-10-30 11:49:00 +00001452 EMIT(0xEB);
1453 EMIT((offs - short_size) & 0xFF);
1454 } else {
Andrei Popescu31002712010-02-23 13:46:05 +00001455 // 1110 1001 #32-bit disp.
Steve Blocka7e24c12009-10-30 11:49:00 +00001456 EMIT(0xE9);
1457 emit(offs - long_size);
1458 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001459 } else if (distance == Label::kNear) {
1460 EMIT(0xEB);
1461 emit_near_disp(L);
Steve Blocka7e24c12009-10-30 11:49:00 +00001462 } else {
Andrei Popescu31002712010-02-23 13:46:05 +00001463 // 1110 1001 #32-bit disp.
Steve Blocka7e24c12009-10-30 11:49:00 +00001464 EMIT(0xE9);
1465 emit_disp(L, Displacement::UNCONDITIONAL_JUMP);
1466 }
1467}
1468
1469
1470void Assembler::jmp(byte* entry, RelocInfo::Mode rmode) {
1471 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001472 DCHECK(!RelocInfo::IsCodeTarget(rmode));
Steve Blocka7e24c12009-10-30 11:49:00 +00001473 EMIT(0xE9);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001474 if (RelocInfo::IsRuntimeEntry(rmode)) {
1475 emit(reinterpret_cast<uint32_t>(entry), rmode);
1476 } else {
1477 emit(entry - (pc_ + sizeof(int32_t)), rmode);
1478 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001479}
1480
1481
1482void Assembler::jmp(const Operand& adr) {
1483 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001484 EMIT(0xFF);
1485 emit_operand(esp, adr);
1486}
1487
1488
1489void Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) {
1490 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001491 DCHECK(RelocInfo::IsCodeTarget(rmode));
Steve Blocka7e24c12009-10-30 11:49:00 +00001492 EMIT(0xE9);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001493 emit(code, rmode);
Steve Blocka7e24c12009-10-30 11:49:00 +00001494}
1495
1496
Ben Murdoch257744e2011-11-30 15:57:28 +00001497void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001498 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001499 DCHECK(0 <= cc && static_cast<int>(cc) < 16);
Steve Blocka7e24c12009-10-30 11:49:00 +00001500 if (L->is_bound()) {
1501 const int short_size = 2;
1502 const int long_size = 6;
1503 int offs = L->pos() - pc_offset();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001504 DCHECK(offs <= 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00001505 if (is_int8(offs - short_size)) {
1506 // 0111 tttn #8-bit disp
1507 EMIT(0x70 | cc);
1508 EMIT((offs - short_size) & 0xFF);
1509 } else {
1510 // 0000 1111 1000 tttn #32-bit disp
1511 EMIT(0x0F);
1512 EMIT(0x80 | cc);
1513 emit(offs - long_size);
1514 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001515 } else if (distance == Label::kNear) {
1516 EMIT(0x70 | cc);
1517 emit_near_disp(L);
Steve Blocka7e24c12009-10-30 11:49:00 +00001518 } else {
1519 // 0000 1111 1000 tttn #32-bit disp
1520 // Note: could eliminate cond. jumps to this jump if condition
1521 // is the same however, seems to be rather unlikely case.
1522 EMIT(0x0F);
1523 EMIT(0x80 | cc);
1524 emit_disp(L, Displacement::OTHER);
1525 }
1526}
1527
1528
Ben Murdoch257744e2011-11-30 15:57:28 +00001529void Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001530 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001531 DCHECK((0 <= cc) && (static_cast<int>(cc) < 16));
Andrei Popescu31002712010-02-23 13:46:05 +00001532 // 0000 1111 1000 tttn #32-bit disp.
Steve Blocka7e24c12009-10-30 11:49:00 +00001533 EMIT(0x0F);
1534 EMIT(0x80 | cc);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001535 if (RelocInfo::IsRuntimeEntry(rmode)) {
1536 emit(reinterpret_cast<uint32_t>(entry), rmode);
1537 } else {
1538 emit(entry - (pc_ + sizeof(int32_t)), rmode);
1539 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001540}
1541
1542
Ben Murdoch257744e2011-11-30 15:57:28 +00001543void Assembler::j(Condition cc, Handle<Code> code) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001544 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001545 // 0000 1111 1000 tttn #32-bit disp
1546 EMIT(0x0F);
1547 EMIT(0x80 | cc);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001548 emit(code, RelocInfo::CODE_TARGET);
Steve Blocka7e24c12009-10-30 11:49:00 +00001549}
1550
1551
Andrei Popescu31002712010-02-23 13:46:05 +00001552// FPU instructions.
Steve Blocka7e24c12009-10-30 11:49:00 +00001553
Steve Blocka7e24c12009-10-30 11:49:00 +00001554void Assembler::fld(int i) {
1555 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001556 emit_farith(0xD9, 0xC0, i);
1557}
1558
1559
Andrei Popescu402d9372010-02-26 13:31:12 +00001560void Assembler::fstp(int i) {
1561 EnsureSpace ensure_space(this);
Andrei Popescu402d9372010-02-26 13:31:12 +00001562 emit_farith(0xDD, 0xD8, i);
1563}
1564
1565
Steve Blocka7e24c12009-10-30 11:49:00 +00001566void Assembler::fld1() {
1567 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001568 EMIT(0xD9);
1569 EMIT(0xE8);
1570}
1571
1572
Andrei Popescu402d9372010-02-26 13:31:12 +00001573void Assembler::fldpi() {
1574 EnsureSpace ensure_space(this);
Andrei Popescu402d9372010-02-26 13:31:12 +00001575 EMIT(0xD9);
1576 EMIT(0xEB);
1577}
1578
1579
Steve Blocka7e24c12009-10-30 11:49:00 +00001580void Assembler::fldz() {
1581 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001582 EMIT(0xD9);
1583 EMIT(0xEE);
1584}
1585
1586
Ben Murdochb0fe1622011-05-05 13:52:32 +01001587void Assembler::fldln2() {
1588 EnsureSpace ensure_space(this);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001589 EMIT(0xD9);
1590 EMIT(0xED);
1591}
1592
1593
Steve Blocka7e24c12009-10-30 11:49:00 +00001594void Assembler::fld_s(const Operand& adr) {
1595 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001596 EMIT(0xD9);
1597 emit_operand(eax, adr);
1598}
1599
1600
1601void Assembler::fld_d(const Operand& adr) {
1602 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001603 EMIT(0xDD);
1604 emit_operand(eax, adr);
1605}
1606
1607
1608void Assembler::fstp_s(const Operand& adr) {
1609 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001610 EMIT(0xD9);
1611 emit_operand(ebx, adr);
1612}
1613
1614
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001615void Assembler::fst_s(const Operand& adr) {
1616 EnsureSpace ensure_space(this);
1617 EMIT(0xD9);
1618 emit_operand(edx, adr);
1619}
1620
1621
Steve Blocka7e24c12009-10-30 11:49:00 +00001622void Assembler::fstp_d(const Operand& adr) {
1623 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001624 EMIT(0xDD);
1625 emit_operand(ebx, adr);
1626}
1627
1628
Andrei Popescu402d9372010-02-26 13:31:12 +00001629void Assembler::fst_d(const Operand& adr) {
1630 EnsureSpace ensure_space(this);
Andrei Popescu402d9372010-02-26 13:31:12 +00001631 EMIT(0xDD);
1632 emit_operand(edx, adr);
1633}
1634
1635
Steve Blocka7e24c12009-10-30 11:49:00 +00001636void Assembler::fild_s(const Operand& adr) {
1637 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001638 EMIT(0xDB);
1639 emit_operand(eax, adr);
1640}
1641
1642
1643void Assembler::fild_d(const Operand& adr) {
1644 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001645 EMIT(0xDF);
1646 emit_operand(ebp, adr);
1647}
1648
1649
1650void Assembler::fistp_s(const Operand& adr) {
1651 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001652 EMIT(0xDB);
1653 emit_operand(ebx, adr);
1654}
1655
1656
1657void Assembler::fisttp_s(const Operand& adr) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001658 DCHECK(IsEnabled(SSE3));
Steve Blocka7e24c12009-10-30 11:49:00 +00001659 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001660 EMIT(0xDB);
1661 emit_operand(ecx, adr);
1662}
1663
1664
Leon Clarkee46be812010-01-19 14:06:41 +00001665void Assembler::fisttp_d(const Operand& adr) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001666 DCHECK(IsEnabled(SSE3));
Leon Clarkee46be812010-01-19 14:06:41 +00001667 EnsureSpace ensure_space(this);
Leon Clarkee46be812010-01-19 14:06:41 +00001668 EMIT(0xDD);
1669 emit_operand(ecx, adr);
1670}
1671
1672
Steve Blocka7e24c12009-10-30 11:49:00 +00001673void Assembler::fist_s(const Operand& adr) {
1674 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001675 EMIT(0xDB);
1676 emit_operand(edx, adr);
1677}
1678
1679
1680void Assembler::fistp_d(const Operand& adr) {
1681 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001682 EMIT(0xDF);
1683 emit_operand(edi, adr);
1684}
1685
1686
1687void Assembler::fabs() {
1688 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001689 EMIT(0xD9);
1690 EMIT(0xE1);
1691}
1692
1693
1694void Assembler::fchs() {
1695 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001696 EMIT(0xD9);
1697 EMIT(0xE0);
1698}
1699
1700
1701void Assembler::fcos() {
1702 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001703 EMIT(0xD9);
1704 EMIT(0xFF);
1705}
1706
1707
1708void Assembler::fsin() {
1709 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001710 EMIT(0xD9);
1711 EMIT(0xFE);
1712}
1713
1714
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001715void Assembler::fptan() {
1716 EnsureSpace ensure_space(this);
1717 EMIT(0xD9);
1718 EMIT(0xF2);
1719}
1720
1721
Ben Murdochb0fe1622011-05-05 13:52:32 +01001722void Assembler::fyl2x() {
1723 EnsureSpace ensure_space(this);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001724 EMIT(0xD9);
1725 EMIT(0xF1);
1726}
1727
1728
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001729void Assembler::f2xm1() {
1730 EnsureSpace ensure_space(this);
1731 EMIT(0xD9);
1732 EMIT(0xF0);
1733}
1734
1735
1736void Assembler::fscale() {
1737 EnsureSpace ensure_space(this);
1738 EMIT(0xD9);
1739 EMIT(0xFD);
1740}
1741
1742
1743void Assembler::fninit() {
1744 EnsureSpace ensure_space(this);
1745 EMIT(0xDB);
1746 EMIT(0xE3);
1747}
1748
1749
Steve Blocka7e24c12009-10-30 11:49:00 +00001750void Assembler::fadd(int i) {
1751 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001752 emit_farith(0xDC, 0xC0, i);
1753}
1754
1755
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001756void Assembler::fadd_i(int i) {
1757 EnsureSpace ensure_space(this);
1758 emit_farith(0xD8, 0xC0, i);
1759}
1760
1761
Steve Blocka7e24c12009-10-30 11:49:00 +00001762void Assembler::fsub(int i) {
1763 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001764 emit_farith(0xDC, 0xE8, i);
1765}
1766
1767
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001768void Assembler::fsub_i(int i) {
1769 EnsureSpace ensure_space(this);
1770 emit_farith(0xD8, 0xE0, i);
1771}
1772
1773
Steve Blocka7e24c12009-10-30 11:49:00 +00001774void Assembler::fisub_s(const Operand& adr) {
1775 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001776 EMIT(0xDA);
1777 emit_operand(esp, adr);
1778}
1779
1780
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001781void Assembler::fmul_i(int i) {
1782 EnsureSpace ensure_space(this);
1783 emit_farith(0xD8, 0xC8, i);
1784}
1785
1786
Steve Blocka7e24c12009-10-30 11:49:00 +00001787void Assembler::fmul(int i) {
1788 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001789 emit_farith(0xDC, 0xC8, i);
1790}
1791
1792
1793void Assembler::fdiv(int i) {
1794 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001795 emit_farith(0xDC, 0xF8, i);
1796}
1797
1798
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001799void Assembler::fdiv_i(int i) {
1800 EnsureSpace ensure_space(this);
1801 emit_farith(0xD8, 0xF0, i);
1802}
1803
1804
Steve Blocka7e24c12009-10-30 11:49:00 +00001805void Assembler::faddp(int i) {
1806 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001807 emit_farith(0xDE, 0xC0, i);
1808}
1809
1810
1811void Assembler::fsubp(int i) {
1812 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001813 emit_farith(0xDE, 0xE8, i);
1814}
1815
1816
1817void Assembler::fsubrp(int i) {
1818 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001819 emit_farith(0xDE, 0xE0, i);
1820}
1821
1822
1823void Assembler::fmulp(int i) {
1824 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001825 emit_farith(0xDE, 0xC8, i);
1826}
1827
1828
1829void Assembler::fdivp(int i) {
1830 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001831 emit_farith(0xDE, 0xF8, i);
1832}
1833
1834
1835void Assembler::fprem() {
1836 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001837 EMIT(0xD9);
1838 EMIT(0xF8);
1839}
1840
1841
1842void Assembler::fprem1() {
1843 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001844 EMIT(0xD9);
1845 EMIT(0xF5);
1846}
1847
1848
1849void Assembler::fxch(int i) {
1850 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001851 emit_farith(0xD9, 0xC8, i);
1852}
1853
1854
1855void Assembler::fincstp() {
1856 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001857 EMIT(0xD9);
1858 EMIT(0xF7);
1859}
1860
1861
1862void Assembler::ffree(int i) {
1863 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001864 emit_farith(0xDD, 0xC0, i);
1865}
1866
1867
1868void Assembler::ftst() {
1869 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001870 EMIT(0xD9);
1871 EMIT(0xE4);
1872}
1873
1874
1875void Assembler::fucomp(int i) {
1876 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001877 emit_farith(0xDD, 0xE8, i);
1878}
1879
1880
1881void Assembler::fucompp() {
1882 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001883 EMIT(0xDA);
1884 EMIT(0xE9);
1885}
1886
1887
Steve Block3ce2e202009-11-05 08:53:23 +00001888void Assembler::fucomi(int i) {
1889 EnsureSpace ensure_space(this);
Steve Block3ce2e202009-11-05 08:53:23 +00001890 EMIT(0xDB);
1891 EMIT(0xE8 + i);
1892}
1893
1894
1895void Assembler::fucomip() {
1896 EnsureSpace ensure_space(this);
Steve Block3ce2e202009-11-05 08:53:23 +00001897 EMIT(0xDF);
1898 EMIT(0xE9);
1899}
1900
1901
Steve Blocka7e24c12009-10-30 11:49:00 +00001902void Assembler::fcompp() {
1903 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001904 EMIT(0xDE);
1905 EMIT(0xD9);
1906}
1907
1908
1909void Assembler::fnstsw_ax() {
1910 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001911 EMIT(0xDF);
1912 EMIT(0xE0);
1913}
1914
1915
1916void Assembler::fwait() {
1917 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001918 EMIT(0x9B);
1919}
1920
1921
1922void Assembler::frndint() {
1923 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001924 EMIT(0xD9);
1925 EMIT(0xFC);
1926}
1927
1928
1929void Assembler::fnclex() {
1930 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001931 EMIT(0xDB);
1932 EMIT(0xE2);
1933}
1934
1935
1936void Assembler::sahf() {
1937 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001938 EMIT(0x9E);
1939}
1940
1941
1942void Assembler::setcc(Condition cc, Register reg) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001943 DCHECK(reg.is_byte_register());
Steve Blocka7e24c12009-10-30 11:49:00 +00001944 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001945 EMIT(0x0F);
1946 EMIT(0x90 | cc);
1947 EMIT(0xC0 | reg.code());
1948}
1949
1950
1951void Assembler::cvttss2si(Register dst, const Operand& src) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001952 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001953 EMIT(0xF3);
1954 EMIT(0x0F);
1955 EMIT(0x2C);
1956 emit_operand(dst, src);
1957}
1958
1959
1960void Assembler::cvttsd2si(Register dst, const Operand& src) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001961 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001962 EMIT(0xF2);
1963 EMIT(0x0F);
1964 EMIT(0x2C);
1965 emit_operand(dst, src);
1966}
1967
1968
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001969void Assembler::cvtsd2si(Register dst, XMMRegister src) {
1970 EnsureSpace ensure_space(this);
1971 EMIT(0xF2);
1972 EMIT(0x0F);
1973 EMIT(0x2D);
1974 emit_sse_operand(dst, src);
1975}
1976
1977
Steve Blocka7e24c12009-10-30 11:49:00 +00001978void Assembler::cvtsi2sd(XMMRegister dst, const Operand& src) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001979 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001980 EMIT(0xF2);
1981 EMIT(0x0F);
1982 EMIT(0x2A);
1983 emit_sse_operand(dst, src);
1984}
1985
1986
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001987void Assembler::cvtss2sd(XMMRegister dst, const Operand& src) {
Steve Block6ded16b2010-05-10 14:33:55 +01001988 EnsureSpace ensure_space(this);
Steve Block6ded16b2010-05-10 14:33:55 +01001989 EMIT(0xF3);
1990 EMIT(0x0F);
1991 EMIT(0x5A);
1992 emit_sse_operand(dst, src);
1993}
1994
1995
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001996void Assembler::cvtsd2ss(XMMRegister dst, const Operand& src) {
Steve Block44f0eee2011-05-26 01:26:41 +01001997 EnsureSpace ensure_space(this);
Steve Block44f0eee2011-05-26 01:26:41 +01001998 EMIT(0xF2);
1999 EMIT(0x0F);
2000 EMIT(0x5A);
2001 emit_sse_operand(dst, src);
2002}
2003
2004
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002005void Assembler::addsd(XMMRegister dst, const Operand& src) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002006 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00002007 EMIT(0xF2);
2008 EMIT(0x0F);
2009 EMIT(0x58);
2010 emit_sse_operand(dst, src);
2011}
2012
2013
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002014void Assembler::mulsd(XMMRegister dst, const Operand& src) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002015 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00002016 EMIT(0xF2);
2017 EMIT(0x0F);
2018 EMIT(0x59);
2019 emit_sse_operand(dst, src);
2020}
2021
2022
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002023void Assembler::subsd(XMMRegister dst, const Operand& src) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002024 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00002025 EMIT(0xF2);
2026 EMIT(0x0F);
2027 EMIT(0x5C);
2028 emit_sse_operand(dst, src);
2029}
2030
2031
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002032void Assembler::divsd(XMMRegister dst, const Operand& src) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002033 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00002034 EMIT(0xF2);
2035 EMIT(0x0F);
2036 EMIT(0x5E);
2037 emit_sse_operand(dst, src);
2038}
2039
2040
Leon Clarkee46be812010-01-19 14:06:41 +00002041void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
Leon Clarkee46be812010-01-19 14:06:41 +00002042 EnsureSpace ensure_space(this);
Leon Clarkee46be812010-01-19 14:06:41 +00002043 EMIT(0x66);
2044 EMIT(0x0F);
2045 EMIT(0x57);
2046 emit_sse_operand(dst, src);
2047}
2048
2049
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002050void Assembler::andps(XMMRegister dst, const Operand& src) {
2051 EnsureSpace ensure_space(this);
2052 EMIT(0x0F);
2053 EMIT(0x54);
2054 emit_sse_operand(dst, src);
2055}
2056
2057
2058void Assembler::orps(XMMRegister dst, const Operand& src) {
2059 EnsureSpace ensure_space(this);
2060 EMIT(0x0F);
2061 EMIT(0x56);
2062 emit_sse_operand(dst, src);
2063}
2064
2065
2066void Assembler::xorps(XMMRegister dst, const Operand& src) {
Ben Murdoch257744e2011-11-30 15:57:28 +00002067 EnsureSpace ensure_space(this);
2068 EMIT(0x0F);
2069 EMIT(0x57);
2070 emit_sse_operand(dst, src);
2071}
2072
2073
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002074void Assembler::addps(XMMRegister dst, const Operand& src) {
2075 EnsureSpace ensure_space(this);
2076 EMIT(0x0F);
2077 EMIT(0x58);
2078 emit_sse_operand(dst, src);
2079}
2080
2081
2082void Assembler::subps(XMMRegister dst, const Operand& src) {
2083 EnsureSpace ensure_space(this);
2084 EMIT(0x0F);
2085 EMIT(0x5C);
2086 emit_sse_operand(dst, src);
2087}
2088
2089
2090void Assembler::mulps(XMMRegister dst, const Operand& src) {
2091 EnsureSpace ensure_space(this);
2092 EMIT(0x0F);
2093 EMIT(0x59);
2094 emit_sse_operand(dst, src);
2095}
2096
2097
2098void Assembler::divps(XMMRegister dst, const Operand& src) {
2099 EnsureSpace ensure_space(this);
2100 EMIT(0x0F);
2101 EMIT(0x5E);
2102 emit_sse_operand(dst, src);
2103}
2104
2105
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002106void Assembler::sqrtsd(XMMRegister dst, const Operand& src) {
2107 EnsureSpace ensure_space(this);
2108 EMIT(0xF2);
2109 EMIT(0x0F);
2110 EMIT(0x51);
2111 emit_sse_operand(dst, src);
2112}
2113
2114
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002115void Assembler::andpd(XMMRegister dst, XMMRegister src) {
2116 EnsureSpace ensure_space(this);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002117 EMIT(0x66);
2118 EMIT(0x0F);
2119 EMIT(0x54);
2120 emit_sse_operand(dst, src);
2121}
2122
2123
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002124void Assembler::orpd(XMMRegister dst, XMMRegister src) {
Steve Block6ded16b2010-05-10 14:33:55 +01002125 EnsureSpace ensure_space(this);
Steve Block6ded16b2010-05-10 14:33:55 +01002126 EMIT(0x66);
2127 EMIT(0x0F);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002128 EMIT(0x56);
Steve Block6ded16b2010-05-10 14:33:55 +01002129 emit_sse_operand(dst, src);
2130}
2131
2132
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002133void Assembler::ucomisd(XMMRegister dst, const Operand& src) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002134 EnsureSpace ensure_space(this);
2135 EMIT(0x66);
2136 EMIT(0x0F);
2137 EMIT(0x2E);
2138 emit_sse_operand(dst, src);
2139}
2140
2141
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002142void Assembler::roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002143 DCHECK(IsEnabled(SSE4_1));
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002144 EnsureSpace ensure_space(this);
2145 EMIT(0x66);
2146 EMIT(0x0F);
2147 EMIT(0x3A);
2148 EMIT(0x0B);
2149 emit_sse_operand(dst, src);
2150 // Mask precision exeption.
2151 EMIT(static_cast<byte>(mode) | 0x8);
2152}
2153
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002154
Steve Block6ded16b2010-05-10 14:33:55 +01002155void Assembler::movmskpd(Register dst, XMMRegister src) {
Steve Block6ded16b2010-05-10 14:33:55 +01002156 EnsureSpace ensure_space(this);
Steve Block6ded16b2010-05-10 14:33:55 +01002157 EMIT(0x66);
2158 EMIT(0x0F);
2159 EMIT(0x50);
2160 emit_sse_operand(dst, src);
2161}
2162
2163
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002164void Assembler::movmskps(Register dst, XMMRegister src) {
2165 EnsureSpace ensure_space(this);
2166 EMIT(0x0F);
2167 EMIT(0x50);
2168 emit_sse_operand(dst, src);
2169}
2170
2171
2172void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) {
2173 EnsureSpace ensure_space(this);
2174 EMIT(0x66);
2175 EMIT(0x0F);
2176 EMIT(0x76);
2177 emit_sse_operand(dst, src);
2178}
2179
2180
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002181void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002182 EnsureSpace ensure_space(this);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002183 EMIT(0xF2);
2184 EMIT(0x0F);
2185 EMIT(0xC2);
2186 emit_sse_operand(dst, src);
2187 EMIT(1); // LT == 1
2188}
2189
2190
2191void Assembler::movaps(XMMRegister dst, XMMRegister src) {
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002192 EnsureSpace ensure_space(this);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002193 EMIT(0x0F);
2194 EMIT(0x28);
2195 emit_sse_operand(dst, src);
2196}
2197
2198
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002199void Assembler::shufps(XMMRegister dst, XMMRegister src, byte imm8) {
2200 DCHECK(is_uint8(imm8));
2201 EnsureSpace ensure_space(this);
2202 EMIT(0x0F);
2203 EMIT(0xC6);
2204 emit_sse_operand(dst, src);
2205 EMIT(imm8);
2206}
2207
2208
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002209void Assembler::movdqa(const Operand& dst, XMMRegister src) {
Leon Clarkee46be812010-01-19 14:06:41 +00002210 EnsureSpace ensure_space(this);
Leon Clarkee46be812010-01-19 14:06:41 +00002211 EMIT(0x66);
2212 EMIT(0x0F);
2213 EMIT(0x7F);
2214 emit_sse_operand(src, dst);
2215}
2216
2217
2218void Assembler::movdqa(XMMRegister dst, const Operand& src) {
Leon Clarkee46be812010-01-19 14:06:41 +00002219 EnsureSpace ensure_space(this);
Leon Clarkee46be812010-01-19 14:06:41 +00002220 EMIT(0x66);
2221 EMIT(0x0F);
2222 EMIT(0x6F);
2223 emit_sse_operand(dst, src);
2224}
2225
2226
2227void Assembler::movdqu(const Operand& dst, XMMRegister src ) {
Leon Clarkee46be812010-01-19 14:06:41 +00002228 EnsureSpace ensure_space(this);
Leon Clarkee46be812010-01-19 14:06:41 +00002229 EMIT(0xF3);
2230 EMIT(0x0F);
2231 EMIT(0x7F);
2232 emit_sse_operand(src, dst);
2233}
2234
2235
2236void Assembler::movdqu(XMMRegister dst, const Operand& src) {
Leon Clarkee46be812010-01-19 14:06:41 +00002237 EnsureSpace ensure_space(this);
Leon Clarkee46be812010-01-19 14:06:41 +00002238 EMIT(0xF3);
2239 EMIT(0x0F);
2240 EMIT(0x6F);
2241 emit_sse_operand(dst, src);
2242}
2243
2244
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002245void Assembler::movntdqa(XMMRegister dst, const Operand& src) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002246 DCHECK(IsEnabled(SSE4_1));
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002247 EnsureSpace ensure_space(this);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002248 EMIT(0x66);
2249 EMIT(0x0F);
2250 EMIT(0x38);
2251 EMIT(0x2A);
2252 emit_sse_operand(dst, src);
2253}
2254
2255
2256void Assembler::movntdq(const Operand& dst, XMMRegister src) {
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002257 EnsureSpace ensure_space(this);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002258 EMIT(0x66);
2259 EMIT(0x0F);
2260 EMIT(0xE7);
2261 emit_sse_operand(src, dst);
2262}
2263
2264
2265void Assembler::prefetch(const Operand& src, int level) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002266 DCHECK(is_uint2(level));
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002267 EnsureSpace ensure_space(this);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002268 EMIT(0x0F);
2269 EMIT(0x18);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002270 // Emit hint number in Reg position of RegR/M.
2271 XMMRegister code = XMMRegister::from_code(level);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002272 emit_sse_operand(code, src);
2273}
2274
2275
Steve Blocka7e24c12009-10-30 11:49:00 +00002276void Assembler::movsd(const Operand& dst, XMMRegister src ) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002277 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00002278 EMIT(0xF2); // double
2279 EMIT(0x0F);
2280 EMIT(0x11); // store
2281 emit_sse_operand(src, dst);
2282}
2283
2284
2285void Assembler::movsd(XMMRegister dst, const Operand& src) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002286 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00002287 EMIT(0xF2); // double
2288 EMIT(0x0F);
2289 EMIT(0x10); // load
2290 emit_sse_operand(dst, src);
2291}
2292
Ben Murdochb0fe1622011-05-05 13:52:32 +01002293
Steve Block44f0eee2011-05-26 01:26:41 +01002294void Assembler::movss(const Operand& dst, XMMRegister src ) {
Steve Block44f0eee2011-05-26 01:26:41 +01002295 EnsureSpace ensure_space(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002296 EMIT(0xF3); // float
2297 EMIT(0x0F);
2298 EMIT(0x11); // store
2299 emit_sse_operand(src, dst);
2300}
2301
2302
2303void Assembler::movss(XMMRegister dst, const Operand& src) {
Steve Block44f0eee2011-05-26 01:26:41 +01002304 EnsureSpace ensure_space(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002305 EMIT(0xF3); // float
2306 EMIT(0x0F);
2307 EMIT(0x10); // load
2308 emit_sse_operand(dst, src);
2309}
2310
2311
Steve Block6ded16b2010-05-10 14:33:55 +01002312void Assembler::movd(XMMRegister dst, const Operand& src) {
Steve Block6ded16b2010-05-10 14:33:55 +01002313 EnsureSpace ensure_space(this);
Steve Block6ded16b2010-05-10 14:33:55 +01002314 EMIT(0x66);
2315 EMIT(0x0F);
2316 EMIT(0x6E);
2317 emit_sse_operand(dst, src);
2318}
2319
2320
Ben Murdochb0fe1622011-05-05 13:52:32 +01002321void Assembler::movd(const Operand& dst, XMMRegister src) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01002322 EnsureSpace ensure_space(this);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002323 EMIT(0x66);
2324 EMIT(0x0F);
2325 EMIT(0x7E);
2326 emit_sse_operand(src, dst);
2327}
2328
2329
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002330void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002331 DCHECK(IsEnabled(SSE4_1));
2332 DCHECK(is_uint8(imm8));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002333 EnsureSpace ensure_space(this);
2334 EMIT(0x66);
2335 EMIT(0x0F);
2336 EMIT(0x3A);
2337 EMIT(0x17);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002338 emit_sse_operand(src, dst);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002339 EMIT(imm8);
2340}
2341
2342
Ben Murdochb0fe1622011-05-05 13:52:32 +01002343void Assembler::pand(XMMRegister dst, XMMRegister src) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01002344 EnsureSpace ensure_space(this);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002345 EMIT(0x66);
2346 EMIT(0x0F);
2347 EMIT(0xDB);
2348 emit_sse_operand(dst, src);
2349}
2350
2351
Steve Block6ded16b2010-05-10 14:33:55 +01002352void Assembler::pxor(XMMRegister dst, XMMRegister src) {
Steve Block6ded16b2010-05-10 14:33:55 +01002353 EnsureSpace ensure_space(this);
Steve Block6ded16b2010-05-10 14:33:55 +01002354 EMIT(0x66);
2355 EMIT(0x0F);
2356 EMIT(0xEF);
2357 emit_sse_operand(dst, src);
2358}
2359
2360
Ben Murdochb8e0da22011-05-16 14:20:40 +01002361void Assembler::por(XMMRegister dst, XMMRegister src) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01002362 EnsureSpace ensure_space(this);
Ben Murdochb8e0da22011-05-16 14:20:40 +01002363 EMIT(0x66);
2364 EMIT(0x0F);
2365 EMIT(0xEB);
2366 emit_sse_operand(dst, src);
2367}
2368
2369
Steve Block6ded16b2010-05-10 14:33:55 +01002370void Assembler::ptest(XMMRegister dst, XMMRegister src) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002371 DCHECK(IsEnabled(SSE4_1));
Steve Block6ded16b2010-05-10 14:33:55 +01002372 EnsureSpace ensure_space(this);
Steve Block6ded16b2010-05-10 14:33:55 +01002373 EMIT(0x66);
2374 EMIT(0x0F);
2375 EMIT(0x38);
2376 EMIT(0x17);
2377 emit_sse_operand(dst, src);
2378}
2379
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002380
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002381void Assembler::pslld(XMMRegister reg, int8_t shift) {
2382 EnsureSpace ensure_space(this);
2383 EMIT(0x66);
2384 EMIT(0x0F);
2385 EMIT(0x72);
2386 emit_sse_operand(esi, reg); // esi == 6
2387 EMIT(shift);
2388}
2389
2390
2391void Assembler::psrld(XMMRegister reg, int8_t shift) {
2392 EnsureSpace ensure_space(this);
2393 EMIT(0x66);
2394 EMIT(0x0F);
2395 EMIT(0x72);
2396 emit_sse_operand(edx, reg); // edx == 2
2397 EMIT(shift);
2398}
2399
2400
Ben Murdochb0fe1622011-05-05 13:52:32 +01002401void Assembler::psllq(XMMRegister reg, int8_t shift) {
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002402 EnsureSpace ensure_space(this);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002403 EMIT(0x66);
2404 EMIT(0x0F);
2405 EMIT(0x73);
2406 emit_sse_operand(esi, reg); // esi == 6
Ben Murdochb0fe1622011-05-05 13:52:32 +01002407 EMIT(shift);
2408}
2409
2410
Ben Murdochb8e0da22011-05-16 14:20:40 +01002411void Assembler::psllq(XMMRegister dst, XMMRegister src) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01002412 EnsureSpace ensure_space(this);
Ben Murdochb8e0da22011-05-16 14:20:40 +01002413 EMIT(0x66);
2414 EMIT(0x0F);
2415 EMIT(0xF3);
2416 emit_sse_operand(dst, src);
2417}
2418
2419
2420void Assembler::psrlq(XMMRegister reg, int8_t shift) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01002421 EnsureSpace ensure_space(this);
Ben Murdochb8e0da22011-05-16 14:20:40 +01002422 EMIT(0x66);
2423 EMIT(0x0F);
2424 EMIT(0x73);
2425 emit_sse_operand(edx, reg); // edx == 2
2426 EMIT(shift);
2427}
2428
2429
2430void Assembler::psrlq(XMMRegister dst, XMMRegister src) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01002431 EnsureSpace ensure_space(this);
Ben Murdochb8e0da22011-05-16 14:20:40 +01002432 EMIT(0x66);
2433 EMIT(0x0F);
2434 EMIT(0xD3);
2435 emit_sse_operand(dst, src);
2436}
2437
2438
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002439void Assembler::pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01002440 EnsureSpace ensure_space(this);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002441 EMIT(0x66);
2442 EMIT(0x0F);
2443 EMIT(0x70);
2444 emit_sse_operand(dst, src);
2445 EMIT(shuffle);
2446}
2447
2448
2449void Assembler::pextrd(const Operand& dst, XMMRegister src, int8_t offset) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002450 DCHECK(IsEnabled(SSE4_1));
Ben Murdochb0fe1622011-05-05 13:52:32 +01002451 EnsureSpace ensure_space(this);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002452 EMIT(0x66);
2453 EMIT(0x0F);
2454 EMIT(0x3A);
2455 EMIT(0x16);
2456 emit_sse_operand(src, dst);
2457 EMIT(offset);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002458}
2459
2460
Steve Block1e0659c2011-05-24 12:43:12 +01002461void Assembler::pinsrd(XMMRegister dst, const Operand& src, int8_t offset) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002462 DCHECK(IsEnabled(SSE4_1));
Steve Block1e0659c2011-05-24 12:43:12 +01002463 EnsureSpace ensure_space(this);
Steve Block1e0659c2011-05-24 12:43:12 +01002464 EMIT(0x66);
2465 EMIT(0x0F);
2466 EMIT(0x3A);
2467 EMIT(0x22);
2468 emit_sse_operand(dst, src);
2469 EMIT(offset);
2470}
2471
2472
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002473void Assembler::addss(XMMRegister dst, const Operand& src) {
2474 EnsureSpace ensure_space(this);
2475 EMIT(0xF3);
2476 EMIT(0x0F);
2477 EMIT(0x58);
2478 emit_sse_operand(dst, src);
2479}
2480
2481
2482void Assembler::subss(XMMRegister dst, const Operand& src) {
2483 EnsureSpace ensure_space(this);
2484 EMIT(0xF3);
2485 EMIT(0x0F);
2486 EMIT(0x5C);
2487 emit_sse_operand(dst, src);
2488}
2489
2490
2491void Assembler::mulss(XMMRegister dst, const Operand& src) {
2492 EnsureSpace ensure_space(this);
2493 EMIT(0xF3);
2494 EMIT(0x0F);
2495 EMIT(0x59);
2496 emit_sse_operand(dst, src);
2497}
2498
2499
2500void Assembler::divss(XMMRegister dst, const Operand& src) {
2501 EnsureSpace ensure_space(this);
2502 EMIT(0xF3);
2503 EMIT(0x0F);
2504 EMIT(0x5E);
2505 emit_sse_operand(dst, src);
2506}
2507
2508
2509void Assembler::ucomiss(XMMRegister dst, const Operand& src) {
2510 EnsureSpace ensure_space(this);
2511 EMIT(0x0f);
2512 EMIT(0x2e);
2513 emit_sse_operand(dst, src);
2514}
2515
2516
2517// AVX instructions
2518void Assembler::vfmasd(byte op, XMMRegister dst, XMMRegister src1,
2519 const Operand& src2) {
2520 DCHECK(IsEnabled(FMA3));
2521 EnsureSpace ensure_space(this);
2522 emit_vex_prefix(src1, kLIG, k66, k0F38, kW1);
2523 EMIT(op);
2524 emit_sse_operand(dst, src2);
2525}
2526
2527
2528void Assembler::vfmass(byte op, XMMRegister dst, XMMRegister src1,
2529 const Operand& src2) {
2530 DCHECK(IsEnabled(FMA3));
2531 EnsureSpace ensure_space(this);
2532 emit_vex_prefix(src1, kLIG, k66, k0F38, kW0);
2533 EMIT(op);
2534 emit_sse_operand(dst, src2);
2535}
2536
2537
2538void Assembler::vsd(byte op, XMMRegister dst, XMMRegister src1,
2539 const Operand& src2) {
2540 DCHECK(IsEnabled(AVX));
2541 EnsureSpace ensure_space(this);
2542 emit_vex_prefix(src1, kLIG, kF2, k0F, kWIG);
2543 EMIT(op);
2544 emit_sse_operand(dst, src2);
2545}
2546
2547
Steve Blocka7e24c12009-10-30 11:49:00 +00002548void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
2549 Register ireg = { reg.code() };
2550 emit_operand(ireg, adr);
2551}
2552
2553
2554void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
2555 EMIT(0xC0 | dst.code() << 3 | src.code());
2556}
2557
2558
Steve Block6ded16b2010-05-10 14:33:55 +01002559void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
2560 EMIT(0xC0 | dst.code() << 3 | src.code());
2561}
2562
2563
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002564void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
2565 EMIT(0xC0 | (dst.code() << 3) | src.code());
2566}
2567
2568
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002569void Assembler::emit_vex_prefix(XMMRegister vreg, VectorLength l, SIMDPrefix pp,
2570 LeadingOpcode mm, VexW w) {
2571 if (mm != k0F || w != kW0) {
2572 EMIT(0xc4);
2573 EMIT(0xc0 | mm);
2574 EMIT(w | ((~vreg.code() & 0xf) << 3) | l | pp);
2575 } else {
2576 EMIT(0xc5);
2577 EMIT(((~vreg.code()) << 3) | l | pp);
2578 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002579}
2580
2581
2582void Assembler::RecordJSReturn() {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002583 positions_recorder()->WriteRecordedPositions();
Steve Blocka7e24c12009-10-30 11:49:00 +00002584 EnsureSpace ensure_space(this);
2585 RecordRelocInfo(RelocInfo::JS_RETURN);
2586}
2587
2588
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002589void Assembler::RecordDebugBreakSlot() {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002590 positions_recorder()->WriteRecordedPositions();
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002591 EnsureSpace ensure_space(this);
2592 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
2593}
2594
2595
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002596void Assembler::RecordComment(const char* msg, bool force) {
2597 if (FLAG_code_comments || force) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002598 EnsureSpace ensure_space(this);
2599 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
2600 }
2601}
2602
2603
Steve Blocka7e24c12009-10-30 11:49:00 +00002604void Assembler::GrowBuffer() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002605 DCHECK(buffer_overflow());
Steve Blocka7e24c12009-10-30 11:49:00 +00002606 if (!own_buffer_) FATAL("external code buffer is too small");
2607
Andrei Popescu31002712010-02-23 13:46:05 +00002608 // Compute new buffer size.
Steve Blocka7e24c12009-10-30 11:49:00 +00002609 CodeDesc desc; // the new buffer
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002610 desc.buffer_size = 2 * buffer_size_;
2611
Steve Blocka7e24c12009-10-30 11:49:00 +00002612 // Some internal data structures overflow for very large buffers,
2613 // they must ensure that kMaximalBufferSize is not too large.
2614 if ((desc.buffer_size > kMaximalBufferSize) ||
Steve Block44f0eee2011-05-26 01:26:41 +01002615 (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002616 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
2617 }
2618
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002619 // Set up new buffer.
Steve Blocka7e24c12009-10-30 11:49:00 +00002620 desc.buffer = NewArray<byte>(desc.buffer_size);
2621 desc.instr_size = pc_offset();
2622 desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos());
2623
2624 // Clear the buffer in debug mode. Use 'int3' instructions to make
2625 // sure to get into problems if we ever run uninitialized code.
2626#ifdef DEBUG
2627 memset(desc.buffer, 0xCC, desc.buffer_size);
2628#endif
2629
Andrei Popescu31002712010-02-23 13:46:05 +00002630 // Copy the data.
Steve Blocka7e24c12009-10-30 11:49:00 +00002631 int pc_delta = desc.buffer - buffer_;
2632 int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002633 MemMove(desc.buffer, buffer_, desc.instr_size);
2634 MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(),
2635 desc.reloc_size);
Steve Blocka7e24c12009-10-30 11:49:00 +00002636
Andrei Popescu31002712010-02-23 13:46:05 +00002637 // Switch buffers.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002638 DeleteArray(buffer_);
Steve Blocka7e24c12009-10-30 11:49:00 +00002639 buffer_ = desc.buffer;
2640 buffer_size_ = desc.buffer_size;
2641 pc_ += pc_delta;
Steve Blocka7e24c12009-10-30 11:49:00 +00002642 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
2643 reloc_info_writer.last_pc() + pc_delta);
2644
Andrei Popescu31002712010-02-23 13:46:05 +00002645 // Relocate runtime entries.
Steve Blocka7e24c12009-10-30 11:49:00 +00002646 for (RelocIterator it(desc); !it.done(); it.next()) {
2647 RelocInfo::Mode rmode = it.rinfo()->rmode();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002648 if (rmode == RelocInfo::INTERNAL_REFERENCE) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002649 int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc());
2650 if (*p != 0) { // 0 means uninitialized.
2651 *p += pc_delta;
2652 }
2653 }
2654 }
2655
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002656 DCHECK(!buffer_overflow());
Steve Blocka7e24c12009-10-30 11:49:00 +00002657}
2658
2659
2660void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002661 DCHECK(is_uint8(op1) && is_uint8(op2)); // wrong opcode
2662 DCHECK(is_uint8(imm8));
2663 DCHECK((op1 & 0x01) == 0); // should be 8bit operation
Steve Blocka7e24c12009-10-30 11:49:00 +00002664 EMIT(op1);
2665 EMIT(op2 | dst.code());
2666 EMIT(imm8);
2667}
2668
2669
2670void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002671 DCHECK((0 <= sel) && (sel <= 7));
Steve Blocka7e24c12009-10-30 11:49:00 +00002672 Register ireg = { sel };
2673 if (x.is_int8()) {
2674 EMIT(0x83); // using a sign-extended 8-bit immediate.
2675 emit_operand(ireg, dst);
2676 EMIT(x.x_ & 0xFF);
2677 } else if (dst.is_reg(eax)) {
2678 EMIT((sel << 3) | 0x05); // short form if the destination is eax.
2679 emit(x);
2680 } else {
2681 EMIT(0x81); // using a literal 32-bit immediate.
2682 emit_operand(ireg, dst);
2683 emit(x);
2684 }
2685}
2686
2687
2688void Assembler::emit_operand(Register reg, const Operand& adr) {
2689 const unsigned length = adr.len_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002690 DCHECK(length > 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002691
2692 // Emit updated ModRM byte containing the given register.
2693 pc_[0] = (adr.buf_[0] & ~0x38) | (reg.code() << 3);
2694
2695 // Emit the rest of the encoded operand.
2696 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
2697 pc_ += length;
2698
2699 // Emit relocation information if necessary.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002700 if (length >= sizeof(int32_t) && !RelocInfo::IsNone(adr.rmode_)) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002701 pc_ -= sizeof(int32_t); // pc_ must be *at* disp32
2702 RecordRelocInfo(adr.rmode_);
2703 pc_ += sizeof(int32_t);
2704 }
2705}
2706
2707
2708void Assembler::emit_farith(int b1, int b2, int i) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002709 DCHECK(is_uint8(b1) && is_uint8(b2)); // wrong opcode
2710 DCHECK(0 <= i && i < 8); // illegal stack offset
Steve Blocka7e24c12009-10-30 11:49:00 +00002711 EMIT(b1);
2712 EMIT(b2 + i);
2713}
2714
2715
Ben Murdochb0fe1622011-05-05 13:52:32 +01002716void Assembler::db(uint8_t data) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002717 EnsureSpace ensure_space(this);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002718 EMIT(data);
2719}
2720
2721
2722void Assembler::dd(uint32_t data) {
2723 EnsureSpace ensure_space(this);
2724 emit(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00002725}
2726
2727
2728void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002729 DCHECK(!RelocInfo::IsNone(rmode));
Steve Blocka7e24c12009-10-30 11:49:00 +00002730 // Don't record external references unless the heap will be serialized.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002731 if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
2732 !serializer_enabled() && !emit_debug_code()) {
2733 return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002734 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002735 RelocInfo rinfo(pc_, rmode, data, NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00002736 reloc_info_writer.Write(&rinfo);
2737}
2738
2739
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002740Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
2741 // No out-of-line constant pool support.
2742 DCHECK(!FLAG_enable_ool_constant_pool);
2743 return isolate->factory()->empty_constant_pool_array();
2744}
2745
2746
2747void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
2748 // No out-of-line constant pool support.
2749 DCHECK(!FLAG_enable_ool_constant_pool);
2750 return;
2751}
2752
2753
Steve Blocka7e24c12009-10-30 11:49:00 +00002754#ifdef GENERATED_CODE_COVERAGE
2755static FILE* coverage_log = NULL;
2756
2757
2758static void InitCoverageLog() {
2759 char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
2760 if (file_name != NULL) {
2761 coverage_log = fopen(file_name, "aw+");
2762 }
2763}
2764
2765
2766void LogGeneratedCodeCoverage(const char* file_line) {
2767 const char* return_address = (&file_line)[-1];
2768 char* push_insn = const_cast<char*>(return_address - 12);
2769 push_insn[0] = 0xeb; // Relative branch insn.
2770 push_insn[1] = 13; // Skip over coverage insns.
2771 if (coverage_log != NULL) {
2772 fprintf(coverage_log, "%s\n", file_line);
2773 fflush(coverage_log);
2774 }
2775}
2776
2777#endif
2778
2779} } // namespace v8::internal
Leon Clarkef7060e22010-06-03 12:02:55 +01002780
2781#endif // V8_TARGET_ARCH_IA32