blob: d16eea16302347d3891469eb38da820bdcabae57 [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
Ben Murdochb8a8cc12014-11-26 15:28:44 +000037#include "src/v8.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000038
Ben Murdochb8a8cc12014-11-26 15:28:44 +000039#if V8_TARGET_ARCH_IA32
Leon Clarkef7060e22010-06-03 12:02:55 +010040
Ben Murdochb8a8cc12014-11-26 15:28:44 +000041#include "src/base/bits.h"
42#include "src/base/cpu.h"
43#include "src/disassembler.h"
44#include "src/macro-assembler.h"
45#include "src/serialize.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000046
47namespace v8 {
48namespace internal {
49
50// -----------------------------------------------------------------------------
51// Implementation of CpuFeatures
52
Ben Murdochb8a8cc12014-11-26 15:28:44 +000053void CpuFeatures::ProbeImpl(bool cross_compile) {
54 base::CPU cpu;
55 CHECK(cpu.has_sse2()); // SSE2 support is mandatory.
56 CHECK(cpu.has_cmov()); // CMOV support is mandatory.
Steve Blocka7e24c12009-10-30 11:49:00 +000057
Ben Murdochb8a8cc12014-11-26 15:28:44 +000058 // Only use statically determined features for cross compile (snapshot).
59 if (cross_compile) return;
Steve Blocka7e24c12009-10-30 11:49:00 +000060
Ben Murdochb8a8cc12014-11-26 15:28:44 +000061 if (cpu.has_sse41() && FLAG_enable_sse4_1) supported_ |= 1u << SSE4_1;
62 if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3;
Steve Blocka7e24c12009-10-30 11:49:00 +000063}
64
65
Ben Murdochb8a8cc12014-11-26 15:28:44 +000066void CpuFeatures::PrintTarget() { }
67void CpuFeatures::PrintFeatures() { }
68
69
Steve Blocka7e24c12009-10-30 11:49:00 +000070// -----------------------------------------------------------------------------
71// Implementation of Displacement
72
73void Displacement::init(Label* L, Type type) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000074 DCHECK(!L->is_bound());
Steve Blocka7e24c12009-10-30 11:49:00 +000075 int next = 0;
76 if (L->is_linked()) {
77 next = L->pos();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000078 DCHECK(next > 0); // Displacements must be at positions > 0
Steve Blocka7e24c12009-10-30 11:49:00 +000079 }
80 // Ensure that we _never_ overflow the next field.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000081 DCHECK(NextField::is_valid(Assembler::kMaximalBufferSize));
Steve Blocka7e24c12009-10-30 11:49:00 +000082 data_ = NextField::encode(next) | TypeField::encode(type);
83}
84
85
86// -----------------------------------------------------------------------------
87// Implementation of RelocInfo
88
89
90const int RelocInfo::kApplyMask =
91 RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY |
Ben Murdochbb769b22010-08-11 14:56:33 +010092 1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE |
Ben Murdochb8a8cc12014-11-26 15:28:44 +000093 1 << RelocInfo::DEBUG_BREAK_SLOT | 1 << RelocInfo::CODE_AGE_SEQUENCE;
Steve Blocka7e24c12009-10-30 11:49:00 +000094
95
Leon Clarkef7060e22010-06-03 12:02:55 +010096bool RelocInfo::IsCodedSpecially() {
97 // The deserializer needs to know whether a pointer is specially coded. Being
98 // specially coded on IA32 means that it is a relative address, as used by
99 // branch instructions. These are also the ones that need changing when a
100 // code object moves.
101 return (1 << rmode_) & kApplyMask;
102}
103
104
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000105bool RelocInfo::IsInConstantPool() {
106 return false;
107}
108
109
Steve Blocka7e24c12009-10-30 11:49:00 +0000110void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
111 // Patch the code at the current address with the supplied instructions.
112 for (int i = 0; i < instruction_count; i++) {
113 *(pc_ + i) = *(instructions + i);
114 }
115
116 // Indicate that code has changed.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000117 CpuFeatures::FlushICache(pc_, instruction_count);
Steve Blocka7e24c12009-10-30 11:49:00 +0000118}
119
120
121// Patch the code at the current PC with a call to the target address.
122// Additional guard int3 instructions can be added if required.
123void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
124 // Call instruction takes up 5 bytes and int3 takes up one byte.
125 static const int kCallCodeSize = 5;
126 int code_size = kCallCodeSize + guard_bytes;
127
128 // Create a code patcher.
129 CodePatcher patcher(pc_, code_size);
130
131 // Add a label for checking the size of the code used for returning.
132#ifdef DEBUG
133 Label check_codesize;
134 patcher.masm()->bind(&check_codesize);
135#endif
136
137 // Patch the code.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000138 patcher.masm()->call(target, RelocInfo::NONE32);
Steve Blocka7e24c12009-10-30 11:49:00 +0000139
140 // Check that the size of the code generated is as expected.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000141 DCHECK_EQ(kCallCodeSize,
Steve Blocka7e24c12009-10-30 11:49:00 +0000142 patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
143
144 // Add the requested number of int3 instructions after the call.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000145 DCHECK_GE(guard_bytes, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +0000146 for (int i = 0; i < guard_bytes; i++) {
147 patcher.masm()->int3();
148 }
149}
150
151
152// -----------------------------------------------------------------------------
153// Implementation of Operand
154
155Operand::Operand(Register base, int32_t disp, RelocInfo::Mode rmode) {
156 // [base + disp/r]
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000157 if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000158 // [base]
159 set_modrm(0, base);
160 if (base.is(esp)) set_sib(times_1, esp, base);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000161 } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000162 // [base + disp8]
163 set_modrm(1, base);
164 if (base.is(esp)) set_sib(times_1, esp, base);
165 set_disp8(disp);
166 } else {
167 // [base + disp/r]
168 set_modrm(2, base);
169 if (base.is(esp)) set_sib(times_1, esp, base);
170 set_dispr(disp, rmode);
171 }
172}
173
174
175Operand::Operand(Register base,
176 Register index,
177 ScaleFactor scale,
178 int32_t disp,
179 RelocInfo::Mode rmode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000180 DCHECK(!index.is(esp)); // illegal addressing mode
Steve Blocka7e24c12009-10-30 11:49:00 +0000181 // [base + index*scale + disp/r]
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000182 if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000183 // [base + index*scale]
184 set_modrm(0, esp);
185 set_sib(scale, index, base);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000186 } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000187 // [base + index*scale + disp8]
188 set_modrm(1, esp);
189 set_sib(scale, index, base);
190 set_disp8(disp);
191 } else {
192 // [base + index*scale + disp/r]
193 set_modrm(2, esp);
194 set_sib(scale, index, base);
195 set_dispr(disp, rmode);
196 }
197}
198
199
200Operand::Operand(Register index,
201 ScaleFactor scale,
202 int32_t disp,
203 RelocInfo::Mode rmode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000204 DCHECK(!index.is(esp)); // illegal addressing mode
Steve Blocka7e24c12009-10-30 11:49:00 +0000205 // [index*scale + disp/r]
206 set_modrm(0, esp);
207 set_sib(scale, index, ebp);
208 set_dispr(disp, rmode);
209}
210
211
212bool Operand::is_reg(Register reg) const {
213 return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only.
214 && ((buf_[0] & 0x07) == reg.code()); // register codes match.
215}
216
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100217
218bool Operand::is_reg_only() const {
219 return (buf_[0] & 0xF8) == 0xC0; // Addressing mode is register only.
220}
221
222
223Register Operand::reg() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000224 DCHECK(is_reg_only());
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100225 return Register::from_code(buf_[0] & 0x07);
226}
227
228
Steve Blocka7e24c12009-10-30 11:49:00 +0000229// -----------------------------------------------------------------------------
Andrei Popescu31002712010-02-23 13:46:05 +0000230// Implementation of Assembler.
Steve Blocka7e24c12009-10-30 11:49:00 +0000231
232// Emit a single byte. Must always be inlined.
233#define EMIT(x) \
234 *pc_++ = (x)
235
236
237#ifdef GENERATED_CODE_COVERAGE
238static void InitCoverageLog();
239#endif
240
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000241Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
242 : AssemblerBase(isolate, buffer, buffer_size),
243 positions_recorder_(this) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000244 // Clear the buffer in debug mode unless it was provided by the
245 // caller in which case we can't be sure it's okay to overwrite
246 // existing code in it; see CodePatcher::CodePatcher(...).
247#ifdef DEBUG
248 if (own_buffer_) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000249 memset(buffer_, 0xCC, buffer_size_); // int3
Steve Blocka7e24c12009-10-30 11:49:00 +0000250 }
251#endif
252
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000253 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000254
Steve Blocka7e24c12009-10-30 11:49:00 +0000255#ifdef GENERATED_CODE_COVERAGE
256 InitCoverageLog();
257#endif
258}
259
260
Steve Blocka7e24c12009-10-30 11:49:00 +0000261void Assembler::GetCode(CodeDesc* desc) {
Andrei Popescu31002712010-02-23 13:46:05 +0000262 // Finalize code (at this point overflow() may be true, but the gap ensures
263 // that we are still not overlapping instructions and relocation info).
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000264 DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100265 // Set up code descriptor.
Steve Blocka7e24c12009-10-30 11:49:00 +0000266 desc->buffer = buffer_;
267 desc->buffer_size = buffer_size_;
268 desc->instr_size = pc_offset();
269 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
270 desc->origin = this;
Steve Blocka7e24c12009-10-30 11:49:00 +0000271}
272
273
274void Assembler::Align(int m) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000275 DCHECK(base::bits::IsPowerOfTwo32(m));
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100276 int mask = m - 1;
277 int addr = pc_offset();
278 Nop((m - (addr & mask)) & mask);
279}
280
281
282bool Assembler::IsNop(Address addr) {
283 Address a = addr;
284 while (*a == 0x66) a++;
285 if (*a == 0x90) return true;
286 if (a[0] == 0xf && a[1] == 0x1f) return true;
287 return false;
288}
289
290
291void Assembler::Nop(int bytes) {
292 EnsureSpace ensure_space(this);
293
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100294 // Multi byte nops from http://support.amd.com/us/Processor_TechDocs/40546.pdf
295 while (bytes > 0) {
296 switch (bytes) {
297 case 2:
298 EMIT(0x66);
299 case 1:
300 EMIT(0x90);
301 return;
302 case 3:
303 EMIT(0xf);
304 EMIT(0x1f);
305 EMIT(0);
306 return;
307 case 4:
308 EMIT(0xf);
309 EMIT(0x1f);
310 EMIT(0x40);
311 EMIT(0);
312 return;
313 case 6:
314 EMIT(0x66);
315 case 5:
316 EMIT(0xf);
317 EMIT(0x1f);
318 EMIT(0x44);
319 EMIT(0);
320 EMIT(0);
321 return;
322 case 7:
323 EMIT(0xf);
324 EMIT(0x1f);
325 EMIT(0x80);
326 EMIT(0);
327 EMIT(0);
328 EMIT(0);
329 EMIT(0);
330 return;
331 default:
332 case 11:
333 EMIT(0x66);
334 bytes--;
335 case 10:
336 EMIT(0x66);
337 bytes--;
338 case 9:
339 EMIT(0x66);
340 bytes--;
341 case 8:
342 EMIT(0xf);
343 EMIT(0x1f);
344 EMIT(0x84);
345 EMIT(0);
346 EMIT(0);
347 EMIT(0);
348 EMIT(0);
349 EMIT(0);
350 bytes -= 8;
351 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000352 }
353}
354
355
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100356void Assembler::CodeTargetAlign() {
357 Align(16); // Preferred alignment of jump targets on ia32.
358}
359
360
Steve Blocka7e24c12009-10-30 11:49:00 +0000361void Assembler::cpuid() {
Steve Blocka7e24c12009-10-30 11:49:00 +0000362 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000363 EMIT(0x0F);
364 EMIT(0xA2);
365}
366
367
368void Assembler::pushad() {
369 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000370 EMIT(0x60);
371}
372
373
374void Assembler::popad() {
375 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000376 EMIT(0x61);
377}
378
379
380void Assembler::pushfd() {
381 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000382 EMIT(0x9C);
383}
384
385
386void Assembler::popfd() {
387 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000388 EMIT(0x9D);
389}
390
391
392void Assembler::push(const Immediate& x) {
393 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000394 if (x.is_int8()) {
395 EMIT(0x6a);
396 EMIT(x.x_);
397 } else {
398 EMIT(0x68);
399 emit(x);
400 }
401}
402
403
Ben Murdochb0fe1622011-05-05 13:52:32 +0100404void Assembler::push_imm32(int32_t imm32) {
405 EnsureSpace ensure_space(this);
406 EMIT(0x68);
407 emit(imm32);
408}
409
410
Steve Blocka7e24c12009-10-30 11:49:00 +0000411void Assembler::push(Register src) {
412 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000413 EMIT(0x50 | src.code());
414}
415
416
417void Assembler::push(const Operand& src) {
418 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000419 EMIT(0xFF);
420 emit_operand(esi, src);
421}
422
423
424void Assembler::pop(Register dst) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000425 DCHECK(reloc_info_writer.last_pc() != NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +0000426 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000427 EMIT(0x58 | dst.code());
428}
429
430
431void Assembler::pop(const Operand& dst) {
432 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000433 EMIT(0x8F);
434 emit_operand(eax, dst);
435}
436
437
438void Assembler::enter(const Immediate& size) {
439 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000440 EMIT(0xC8);
441 emit_w(size);
442 EMIT(0);
443}
444
445
446void Assembler::leave() {
447 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000448 EMIT(0xC9);
449}
450
451
452void Assembler::mov_b(Register dst, const Operand& src) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100453 CHECK(dst.is_byte_register());
Steve Blocka7e24c12009-10-30 11:49:00 +0000454 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000455 EMIT(0x8A);
456 emit_operand(dst, src);
457}
458
459
460void Assembler::mov_b(const Operand& dst, int8_t imm8) {
461 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000462 EMIT(0xC6);
463 emit_operand(eax, dst);
464 EMIT(imm8);
465}
466
467
468void Assembler::mov_b(const Operand& dst, Register src) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100469 CHECK(src.is_byte_register());
Steve Blocka7e24c12009-10-30 11:49:00 +0000470 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000471 EMIT(0x88);
472 emit_operand(src, dst);
473}
474
475
476void Assembler::mov_w(Register dst, const Operand& src) {
477 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000478 EMIT(0x66);
479 EMIT(0x8B);
480 emit_operand(dst, src);
481}
482
483
484void Assembler::mov_w(const Operand& dst, Register src) {
485 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000486 EMIT(0x66);
487 EMIT(0x89);
488 emit_operand(src, dst);
489}
490
491
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000492void Assembler::mov_w(const Operand& dst, int16_t imm16) {
493 EnsureSpace ensure_space(this);
494 EMIT(0x66);
495 EMIT(0xC7);
496 emit_operand(eax, dst);
497 EMIT(static_cast<int8_t>(imm16 & 0xff));
498 EMIT(static_cast<int8_t>(imm16 >> 8));
499}
500
501
Steve Blocka7e24c12009-10-30 11:49:00 +0000502void Assembler::mov(Register dst, int32_t imm32) {
503 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000504 EMIT(0xB8 | dst.code());
505 emit(imm32);
506}
507
508
509void Assembler::mov(Register dst, const Immediate& x) {
510 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000511 EMIT(0xB8 | dst.code());
512 emit(x);
513}
514
515
516void Assembler::mov(Register dst, Handle<Object> handle) {
517 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000518 EMIT(0xB8 | dst.code());
519 emit(handle);
520}
521
522
523void Assembler::mov(Register dst, const Operand& src) {
524 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000525 EMIT(0x8B);
526 emit_operand(dst, src);
527}
528
529
530void Assembler::mov(Register dst, Register src) {
531 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000532 EMIT(0x89);
533 EMIT(0xC0 | src.code() << 3 | dst.code());
534}
535
536
537void Assembler::mov(const Operand& dst, const Immediate& x) {
538 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000539 EMIT(0xC7);
540 emit_operand(eax, dst);
541 emit(x);
542}
543
544
545void Assembler::mov(const Operand& dst, Handle<Object> handle) {
546 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000547 EMIT(0xC7);
548 emit_operand(eax, dst);
549 emit(handle);
550}
551
552
553void Assembler::mov(const Operand& dst, Register src) {
554 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000555 EMIT(0x89);
556 emit_operand(src, dst);
557}
558
559
560void Assembler::movsx_b(Register dst, const Operand& src) {
561 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000562 EMIT(0x0F);
563 EMIT(0xBE);
564 emit_operand(dst, src);
565}
566
567
568void Assembler::movsx_w(Register dst, const Operand& src) {
569 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000570 EMIT(0x0F);
571 EMIT(0xBF);
572 emit_operand(dst, src);
573}
574
575
576void Assembler::movzx_b(Register dst, const Operand& src) {
577 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000578 EMIT(0x0F);
579 EMIT(0xB6);
580 emit_operand(dst, src);
581}
582
583
584void Assembler::movzx_w(Register dst, const Operand& src) {
585 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000586 EMIT(0x0F);
587 EMIT(0xB7);
588 emit_operand(dst, src);
589}
590
591
Steve Blocka7e24c12009-10-30 11:49:00 +0000592void Assembler::cmov(Condition cc, Register dst, const Operand& src) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000593 EnsureSpace ensure_space(this);
Andrei Popescu31002712010-02-23 13:46:05 +0000594 // Opcode: 0f 40 + cc /r.
Steve Blocka7e24c12009-10-30 11:49:00 +0000595 EMIT(0x0F);
596 EMIT(0x40 + cc);
597 emit_operand(dst, src);
598}
599
600
Steve Block6ded16b2010-05-10 14:33:55 +0100601void Assembler::cld() {
602 EnsureSpace ensure_space(this);
Steve Block6ded16b2010-05-10 14:33:55 +0100603 EMIT(0xFC);
604}
605
606
Leon Clarkee46be812010-01-19 14:06:41 +0000607void Assembler::rep_movs() {
608 EnsureSpace ensure_space(this);
Leon Clarkee46be812010-01-19 14:06:41 +0000609 EMIT(0xF3);
610 EMIT(0xA5);
611}
612
613
Steve Block6ded16b2010-05-10 14:33:55 +0100614void Assembler::rep_stos() {
615 EnsureSpace ensure_space(this);
Steve Block6ded16b2010-05-10 14:33:55 +0100616 EMIT(0xF3);
617 EMIT(0xAB);
618}
619
620
Leon Clarkef7060e22010-06-03 12:02:55 +0100621void Assembler::stos() {
622 EnsureSpace ensure_space(this);
Leon Clarkef7060e22010-06-03 12:02:55 +0100623 EMIT(0xAB);
624}
625
626
Steve Blocka7e24c12009-10-30 11:49:00 +0000627void Assembler::xchg(Register dst, Register src) {
628 EnsureSpace ensure_space(this);
Andrei Popescu31002712010-02-23 13:46:05 +0000629 if (src.is(eax) || dst.is(eax)) { // Single-byte encoding.
Steve Blocka7e24c12009-10-30 11:49:00 +0000630 EMIT(0x90 | (src.is(eax) ? dst.code() : src.code()));
631 } else {
632 EMIT(0x87);
633 EMIT(0xC0 | src.code() << 3 | dst.code());
634 }
635}
636
637
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000638void Assembler::xchg(Register dst, const Operand& src) {
639 EnsureSpace ensure_space(this);
640 EMIT(0x87);
641 emit_operand(dst, src);
642}
643
644
Steve Blocka7e24c12009-10-30 11:49:00 +0000645void Assembler::adc(Register dst, int32_t imm32) {
646 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000647 emit_arith(2, Operand(dst), Immediate(imm32));
648}
649
650
651void Assembler::adc(Register dst, const Operand& src) {
652 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000653 EMIT(0x13);
654 emit_operand(dst, src);
655}
656
657
658void Assembler::add(Register dst, const Operand& src) {
659 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000660 EMIT(0x03);
661 emit_operand(dst, src);
662}
663
664
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100665void Assembler::add(const Operand& dst, Register src) {
666 EnsureSpace ensure_space(this);
667 EMIT(0x01);
668 emit_operand(src, dst);
669}
670
671
Steve Blocka7e24c12009-10-30 11:49:00 +0000672void Assembler::add(const Operand& dst, const Immediate& x) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000673 DCHECK(reloc_info_writer.last_pc() != NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +0000674 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000675 emit_arith(0, dst, x);
676}
677
678
679void Assembler::and_(Register dst, int32_t imm32) {
Steve Block59151502010-09-22 15:07:15 +0100680 and_(dst, Immediate(imm32));
681}
682
683
684void Assembler::and_(Register dst, const Immediate& x) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000685 EnsureSpace ensure_space(this);
Steve Block59151502010-09-22 15:07:15 +0100686 emit_arith(4, Operand(dst), x);
Steve Blocka7e24c12009-10-30 11:49:00 +0000687}
688
689
690void Assembler::and_(Register dst, const Operand& src) {
691 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000692 EMIT(0x23);
693 emit_operand(dst, src);
694}
695
696
697void Assembler::and_(const Operand& dst, const Immediate& x) {
698 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000699 emit_arith(4, dst, x);
700}
701
702
703void Assembler::and_(const Operand& dst, Register src) {
704 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000705 EMIT(0x21);
706 emit_operand(src, dst);
707}
708
709
710void Assembler::cmpb(const Operand& op, int8_t imm8) {
711 EnsureSpace ensure_space(this);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100712 if (op.is_reg(eax)) {
713 EMIT(0x3C);
714 } else {
715 EMIT(0x80);
716 emit_operand(edi, op); // edi == 7
717 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000718 EMIT(imm8);
719}
720
721
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100722void Assembler::cmpb(const Operand& op, Register reg) {
723 CHECK(reg.is_byte_register());
Leon Clarked91b9f72010-01-27 17:25:45 +0000724 EnsureSpace ensure_space(this);
Leon Clarked91b9f72010-01-27 17:25:45 +0000725 EMIT(0x38);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100726 emit_operand(reg, op);
Leon Clarked91b9f72010-01-27 17:25:45 +0000727}
728
729
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100730void Assembler::cmpb(Register reg, const Operand& op) {
731 CHECK(reg.is_byte_register());
Leon Clarked91b9f72010-01-27 17:25:45 +0000732 EnsureSpace ensure_space(this);
Leon Clarked91b9f72010-01-27 17:25:45 +0000733 EMIT(0x3A);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100734 emit_operand(reg, op);
Leon Clarked91b9f72010-01-27 17:25:45 +0000735}
736
737
Steve Blocka7e24c12009-10-30 11:49:00 +0000738void Assembler::cmpw(const Operand& op, Immediate imm16) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000739 DCHECK(imm16.is_int16());
Steve Blocka7e24c12009-10-30 11:49:00 +0000740 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000741 EMIT(0x66);
742 EMIT(0x81);
743 emit_operand(edi, op);
744 emit_w(imm16);
745}
746
747
748void Assembler::cmp(Register reg, int32_t imm32) {
749 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000750 emit_arith(7, Operand(reg), Immediate(imm32));
751}
752
753
754void Assembler::cmp(Register reg, Handle<Object> handle) {
755 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000756 emit_arith(7, Operand(reg), Immediate(handle));
757}
758
759
760void Assembler::cmp(Register reg, const Operand& op) {
761 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000762 EMIT(0x3B);
763 emit_operand(reg, op);
764}
765
766
767void Assembler::cmp(const Operand& op, const Immediate& imm) {
768 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000769 emit_arith(7, op, imm);
770}
771
772
773void Assembler::cmp(const Operand& op, Handle<Object> handle) {
774 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000775 emit_arith(7, op, Immediate(handle));
776}
777
778
779void Assembler::cmpb_al(const Operand& op) {
780 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000781 EMIT(0x38); // CMP r/m8, r8
782 emit_operand(eax, op); // eax has same code as register al.
783}
784
785
786void Assembler::cmpw_ax(const Operand& op) {
787 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000788 EMIT(0x66);
789 EMIT(0x39); // CMP r/m16, r16
790 emit_operand(eax, op); // eax has same code as register ax.
791}
792
793
794void Assembler::dec_b(Register dst) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100795 CHECK(dst.is_byte_register());
Steve Blocka7e24c12009-10-30 11:49:00 +0000796 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000797 EMIT(0xFE);
798 EMIT(0xC8 | dst.code());
799}
800
801
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100802void Assembler::dec_b(const Operand& dst) {
803 EnsureSpace ensure_space(this);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100804 EMIT(0xFE);
805 emit_operand(ecx, dst);
806}
807
808
Steve Blocka7e24c12009-10-30 11:49:00 +0000809void Assembler::dec(Register dst) {
810 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000811 EMIT(0x48 | dst.code());
812}
813
814
815void Assembler::dec(const Operand& dst) {
816 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000817 EMIT(0xFF);
818 emit_operand(ecx, dst);
819}
820
821
822void Assembler::cdq() {
823 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000824 EMIT(0x99);
825}
826
827
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000828void Assembler::idiv(const Operand& src) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000829 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000830 EMIT(0xF7);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000831 emit_operand(edi, src);
832}
833
834
835void Assembler::div(const Operand& src) {
836 EnsureSpace ensure_space(this);
837 EMIT(0xF7);
838 emit_operand(esi, src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000839}
840
841
842void Assembler::imul(Register reg) {
843 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000844 EMIT(0xF7);
845 EMIT(0xE8 | reg.code());
846}
847
848
849void Assembler::imul(Register dst, const Operand& src) {
850 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000851 EMIT(0x0F);
852 EMIT(0xAF);
853 emit_operand(dst, src);
854}
855
856
857void Assembler::imul(Register dst, Register src, int32_t imm32) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000858 imul(dst, Operand(src), imm32);
859}
860
861
862void Assembler::imul(Register dst, const Operand& src, int32_t imm32) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000863 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000864 if (is_int8(imm32)) {
865 EMIT(0x6B);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000866 emit_operand(dst, src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000867 EMIT(imm32);
868 } else {
869 EMIT(0x69);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000870 emit_operand(dst, src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000871 emit(imm32);
872 }
873}
874
875
876void Assembler::inc(Register dst) {
877 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000878 EMIT(0x40 | dst.code());
879}
880
881
882void Assembler::inc(const Operand& dst) {
883 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000884 EMIT(0xFF);
885 emit_operand(eax, dst);
886}
887
888
889void Assembler::lea(Register dst, const Operand& src) {
890 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000891 EMIT(0x8D);
892 emit_operand(dst, src);
893}
894
895
896void Assembler::mul(Register src) {
897 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000898 EMIT(0xF7);
899 EMIT(0xE0 | src.code());
900}
901
902
903void Assembler::neg(Register dst) {
904 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000905 EMIT(0xF7);
906 EMIT(0xD8 | dst.code());
907}
908
909
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000910void Assembler::neg(const Operand& dst) {
911 EnsureSpace ensure_space(this);
912 EMIT(0xF7);
913 emit_operand(ebx, dst);
914}
915
916
Steve Blocka7e24c12009-10-30 11:49:00 +0000917void Assembler::not_(Register dst) {
918 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000919 EMIT(0xF7);
920 EMIT(0xD0 | dst.code());
921}
922
923
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000924void Assembler::not_(const Operand& dst) {
925 EnsureSpace ensure_space(this);
926 EMIT(0xF7);
927 emit_operand(edx, dst);
928}
929
930
Steve Blocka7e24c12009-10-30 11:49:00 +0000931void Assembler::or_(Register dst, int32_t imm32) {
932 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000933 emit_arith(1, Operand(dst), Immediate(imm32));
934}
935
936
937void Assembler::or_(Register dst, const Operand& src) {
938 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000939 EMIT(0x0B);
940 emit_operand(dst, src);
941}
942
943
944void Assembler::or_(const Operand& dst, const Immediate& x) {
945 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000946 emit_arith(1, dst, x);
947}
948
949
950void Assembler::or_(const Operand& dst, Register src) {
951 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000952 EMIT(0x09);
953 emit_operand(src, dst);
954}
955
956
957void Assembler::rcl(Register dst, uint8_t imm8) {
958 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000959 DCHECK(is_uint5(imm8)); // illegal shift count
Steve Blocka7e24c12009-10-30 11:49:00 +0000960 if (imm8 == 1) {
961 EMIT(0xD1);
962 EMIT(0xD0 | dst.code());
963 } else {
964 EMIT(0xC1);
965 EMIT(0xD0 | dst.code());
966 EMIT(imm8);
967 }
968}
969
970
Iain Merrick75681382010-08-19 15:07:18 +0100971void Assembler::rcr(Register dst, uint8_t imm8) {
972 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000973 DCHECK(is_uint5(imm8)); // illegal shift count
Iain Merrick75681382010-08-19 15:07:18 +0100974 if (imm8 == 1) {
975 EMIT(0xD1);
976 EMIT(0xD8 | dst.code());
977 } else {
978 EMIT(0xC1);
979 EMIT(0xD8 | dst.code());
980 EMIT(imm8);
981 }
982}
983
984
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000985void Assembler::ror(Register dst, uint8_t imm8) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000986 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000987 DCHECK(is_uint5(imm8)); // illegal shift count
Steve Blocka7e24c12009-10-30 11:49:00 +0000988 if (imm8 == 1) {
989 EMIT(0xD1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000990 EMIT(0xC8 | dst.code());
Steve Blocka7e24c12009-10-30 11:49:00 +0000991 } else {
992 EMIT(0xC1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000993 EMIT(0xC8 | dst.code());
Steve Blocka7e24c12009-10-30 11:49:00 +0000994 EMIT(imm8);
995 }
996}
997
998
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000999void Assembler::ror_cl(Register dst) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001000 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001001 EMIT(0xD3);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001002 EMIT(0xC8 | dst.code());
1003}
1004
1005
1006void Assembler::sar(const Operand& dst, uint8_t imm8) {
1007 EnsureSpace ensure_space(this);
1008 DCHECK(is_uint5(imm8)); // illegal shift count
1009 if (imm8 == 1) {
1010 EMIT(0xD1);
1011 emit_operand(edi, dst);
1012 } else {
1013 EMIT(0xC1);
1014 emit_operand(edi, dst);
1015 EMIT(imm8);
1016 }
1017}
1018
1019
1020void Assembler::sar_cl(const Operand& dst) {
1021 EnsureSpace ensure_space(this);
1022 EMIT(0xD3);
1023 emit_operand(edi, dst);
Steve Blocka7e24c12009-10-30 11:49:00 +00001024}
1025
1026
1027void Assembler::sbb(Register dst, const Operand& src) {
1028 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001029 EMIT(0x1B);
1030 emit_operand(dst, src);
1031}
1032
1033
1034void Assembler::shld(Register dst, const Operand& src) {
1035 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001036 EMIT(0x0F);
1037 EMIT(0xA5);
1038 emit_operand(dst, src);
1039}
1040
1041
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001042void Assembler::shl(const Operand& dst, uint8_t imm8) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001043 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001044 DCHECK(is_uint5(imm8)); // illegal shift count
Steve Blocka7e24c12009-10-30 11:49:00 +00001045 if (imm8 == 1) {
1046 EMIT(0xD1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001047 emit_operand(esp, dst);
Steve Blocka7e24c12009-10-30 11:49:00 +00001048 } else {
1049 EMIT(0xC1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001050 emit_operand(esp, dst);
Steve Blocka7e24c12009-10-30 11:49:00 +00001051 EMIT(imm8);
1052 }
1053}
1054
1055
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001056void Assembler::shl_cl(const Operand& dst) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001057 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001058 EMIT(0xD3);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001059 emit_operand(esp, dst);
Steve Blocka7e24c12009-10-30 11:49:00 +00001060}
1061
1062
1063void Assembler::shrd(Register dst, const Operand& src) {
1064 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001065 EMIT(0x0F);
1066 EMIT(0xAD);
1067 emit_operand(dst, src);
1068}
1069
1070
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001071void Assembler::shr(const Operand& dst, uint8_t imm8) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001072 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001073 DCHECK(is_uint5(imm8)); // illegal shift count
Steve Blockd0582a62009-12-15 09:54:21 +00001074 if (imm8 == 1) {
1075 EMIT(0xD1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001076 emit_operand(ebp, dst);
Steve Blockd0582a62009-12-15 09:54:21 +00001077 } else {
1078 EMIT(0xC1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001079 emit_operand(ebp, dst);
Steve Blockd0582a62009-12-15 09:54:21 +00001080 EMIT(imm8);
1081 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001082}
1083
1084
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001085void Assembler::shr_cl(const Operand& dst) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001086 EnsureSpace ensure_space(this);
Steve Blockd0582a62009-12-15 09:54:21 +00001087 EMIT(0xD3);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001088 emit_operand(ebp, dst);
Steve Blocka7e24c12009-10-30 11:49:00 +00001089}
1090
1091
1092void Assembler::sub(const Operand& dst, const Immediate& x) {
1093 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001094 emit_arith(5, dst, x);
1095}
1096
1097
1098void Assembler::sub(Register dst, const Operand& src) {
1099 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001100 EMIT(0x2B);
1101 emit_operand(dst, src);
1102}
1103
1104
1105void Assembler::sub(const Operand& dst, Register src) {
1106 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001107 EMIT(0x29);
1108 emit_operand(src, dst);
1109}
1110
1111
1112void Assembler::test(Register reg, const Immediate& imm) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001113 if (RelocInfo::IsNone(imm.rmode_) && is_uint8(imm.x_)) {
1114 test_b(reg, imm.x_);
1115 return;
Steve Blocka7e24c12009-10-30 11:49:00 +00001116 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001117
1118 EnsureSpace ensure_space(this);
1119 // This is not using emit_arith because test doesn't support
1120 // sign-extension of 8-bit operands.
1121 if (reg.is(eax)) {
1122 EMIT(0xA9);
1123 } else {
1124 EMIT(0xF7);
1125 EMIT(0xC0 | reg.code());
1126 }
1127 emit(imm);
Steve Blocka7e24c12009-10-30 11:49:00 +00001128}
1129
1130
1131void Assembler::test(Register reg, const Operand& op) {
1132 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001133 EMIT(0x85);
1134 emit_operand(reg, op);
1135}
1136
1137
Leon Clarkee46be812010-01-19 14:06:41 +00001138void Assembler::test_b(Register reg, const Operand& op) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001139 CHECK(reg.is_byte_register());
Leon Clarkee46be812010-01-19 14:06:41 +00001140 EnsureSpace ensure_space(this);
Leon Clarkee46be812010-01-19 14:06:41 +00001141 EMIT(0x84);
1142 emit_operand(reg, op);
1143}
1144
1145
Steve Blocka7e24c12009-10-30 11:49:00 +00001146void Assembler::test(const Operand& op, const Immediate& imm) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001147 if (op.is_reg_only()) {
1148 test(op.reg(), imm);
1149 return;
1150 }
1151 if (RelocInfo::IsNone(imm.rmode_) && is_uint8(imm.x_)) {
1152 return test_b(op, imm.x_);
1153 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001154 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001155 EMIT(0xF7);
1156 emit_operand(eax, op);
1157 emit(imm);
1158}
1159
1160
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001161void Assembler::test_b(Register reg, uint8_t imm8) {
1162 EnsureSpace ensure_space(this);
1163 // Only use test against byte for registers that have a byte
1164 // variant: eax, ebx, ecx, and edx.
1165 if (reg.is(eax)) {
1166 EMIT(0xA8);
1167 EMIT(imm8);
1168 } else if (reg.is_byte_register()) {
1169 emit_arith_b(0xF6, 0xC0, reg, imm8);
1170 } else {
1171 EMIT(0xF7);
1172 EMIT(0xC0 | reg.code());
1173 emit(imm8);
1174 }
1175}
1176
1177
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001178void Assembler::test_b(const Operand& op, uint8_t imm8) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001179 if (op.is_reg_only()) {
1180 test_b(op.reg(), imm8);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001181 return;
1182 }
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001183 EnsureSpace ensure_space(this);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001184 EMIT(0xF6);
1185 emit_operand(eax, op);
1186 EMIT(imm8);
1187}
1188
1189
Steve Blocka7e24c12009-10-30 11:49:00 +00001190void Assembler::xor_(Register dst, int32_t imm32) {
1191 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001192 emit_arith(6, Operand(dst), Immediate(imm32));
1193}
1194
1195
1196void Assembler::xor_(Register dst, const Operand& src) {
1197 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001198 EMIT(0x33);
1199 emit_operand(dst, src);
1200}
1201
1202
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001203void Assembler::xor_(const Operand& dst, Register src) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001204 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001205 EMIT(0x31);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001206 emit_operand(src, dst);
Steve Blocka7e24c12009-10-30 11:49:00 +00001207}
1208
1209
1210void Assembler::xor_(const Operand& dst, const Immediate& x) {
1211 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001212 emit_arith(6, dst, x);
1213}
1214
1215
1216void Assembler::bt(const Operand& dst, Register src) {
1217 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001218 EMIT(0x0F);
1219 EMIT(0xA3);
1220 emit_operand(src, dst);
1221}
1222
1223
1224void Assembler::bts(const Operand& dst, Register src) {
1225 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001226 EMIT(0x0F);
1227 EMIT(0xAB);
1228 emit_operand(src, dst);
1229}
1230
1231
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001232void Assembler::bsr(Register dst, const Operand& src) {
1233 EnsureSpace ensure_space(this);
1234 EMIT(0x0F);
1235 EMIT(0xBD);
1236 emit_operand(dst, src);
1237}
1238
1239
Steve Blocka7e24c12009-10-30 11:49:00 +00001240void Assembler::hlt() {
1241 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001242 EMIT(0xF4);
1243}
1244
1245
1246void Assembler::int3() {
1247 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001248 EMIT(0xCC);
1249}
1250
1251
1252void Assembler::nop() {
1253 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001254 EMIT(0x90);
1255}
1256
1257
Steve Blocka7e24c12009-10-30 11:49:00 +00001258void Assembler::ret(int imm16) {
1259 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001260 DCHECK(is_uint16(imm16));
Steve Blocka7e24c12009-10-30 11:49:00 +00001261 if (imm16 == 0) {
1262 EMIT(0xC3);
1263 } else {
1264 EMIT(0xC2);
1265 EMIT(imm16 & 0xFF);
1266 EMIT((imm16 >> 8) & 0xFF);
1267 }
1268}
1269
1270
1271// Labels refer to positions in the (to be) generated code.
1272// There are bound, linked, and unused labels.
1273//
1274// Bound labels refer to known positions in the already
1275// generated code. pos() is the position the label refers to.
1276//
1277// Linked labels refer to unknown positions in the code
1278// to be generated; pos() is the position of the 32bit
1279// Displacement of the last instruction using the label.
1280
1281
1282void Assembler::print(Label* L) {
1283 if (L->is_unused()) {
1284 PrintF("unused label\n");
1285 } else if (L->is_bound()) {
1286 PrintF("bound label to %d\n", L->pos());
1287 } else if (L->is_linked()) {
1288 Label l = *L;
1289 PrintF("unbound label");
1290 while (l.is_linked()) {
1291 Displacement disp = disp_at(&l);
1292 PrintF("@ %d ", l.pos());
1293 disp.print();
1294 PrintF("\n");
1295 disp.next(&l);
1296 }
1297 } else {
1298 PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
1299 }
1300}
1301
1302
1303void Assembler::bind_to(Label* L, int pos) {
1304 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001305 DCHECK(0 <= pos && pos <= pc_offset()); // must have a valid binding position
Steve Blocka7e24c12009-10-30 11:49:00 +00001306 while (L->is_linked()) {
1307 Displacement disp = disp_at(L);
1308 int fixup_pos = L->pos();
1309 if (disp.type() == Displacement::CODE_RELATIVE) {
1310 // Relative to Code* heap object pointer.
1311 long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag);
1312 } else {
1313 if (disp.type() == Displacement::UNCONDITIONAL_JUMP) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001314 DCHECK(byte_at(fixup_pos - 1) == 0xE9); // jmp expected
Steve Blocka7e24c12009-10-30 11:49:00 +00001315 }
Andrei Popescu31002712010-02-23 13:46:05 +00001316 // Relative address, relative to point after address.
Steve Blocka7e24c12009-10-30 11:49:00 +00001317 int imm32 = pos - (fixup_pos + sizeof(int32_t));
1318 long_at_put(fixup_pos, imm32);
1319 }
1320 disp.next(L);
1321 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001322 while (L->is_near_linked()) {
1323 int fixup_pos = L->near_link_pos();
1324 int offset_to_next =
1325 static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001326 DCHECK(offset_to_next <= 0);
Ben Murdoch257744e2011-11-30 15:57:28 +00001327 // Relative address, relative to point after address.
1328 int disp = pos - fixup_pos - sizeof(int8_t);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001329 CHECK(0 <= disp && disp <= 127);
Ben Murdoch257744e2011-11-30 15:57:28 +00001330 set_byte_at(fixup_pos, disp);
1331 if (offset_to_next < 0) {
1332 L->link_to(fixup_pos + offset_to_next, Label::kNear);
1333 } else {
1334 L->UnuseNear();
1335 }
1336 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001337 L->bind_to(pos);
1338}
1339
1340
Steve Blocka7e24c12009-10-30 11:49:00 +00001341void Assembler::bind(Label* L) {
1342 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001343 DCHECK(!L->is_bound()); // label can only be bound once
Steve Blocka7e24c12009-10-30 11:49:00 +00001344 bind_to(L, pc_offset());
1345}
1346
1347
1348void Assembler::call(Label* L) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01001349 positions_recorder()->WriteRecordedPositions();
Steve Blocka7e24c12009-10-30 11:49:00 +00001350 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001351 if (L->is_bound()) {
1352 const int long_size = 5;
1353 int offs = L->pos() - pc_offset();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001354 DCHECK(offs <= 0);
Andrei Popescu31002712010-02-23 13:46:05 +00001355 // 1110 1000 #32-bit disp.
Steve Blocka7e24c12009-10-30 11:49:00 +00001356 EMIT(0xE8);
1357 emit(offs - long_size);
1358 } else {
Andrei Popescu31002712010-02-23 13:46:05 +00001359 // 1110 1000 #32-bit disp.
Steve Blocka7e24c12009-10-30 11:49:00 +00001360 EMIT(0xE8);
1361 emit_disp(L, Displacement::OTHER);
1362 }
1363}
1364
1365
1366void Assembler::call(byte* entry, RelocInfo::Mode rmode) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01001367 positions_recorder()->WriteRecordedPositions();
Steve Blocka7e24c12009-10-30 11:49:00 +00001368 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001369 DCHECK(!RelocInfo::IsCodeTarget(rmode));
Steve Blocka7e24c12009-10-30 11:49:00 +00001370 EMIT(0xE8);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001371 if (RelocInfo::IsRuntimeEntry(rmode)) {
1372 emit(reinterpret_cast<uint32_t>(entry), rmode);
1373 } else {
1374 emit(entry - (pc_ + sizeof(int32_t)), rmode);
1375 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001376}
1377
1378
Ben Murdoch257744e2011-11-30 15:57:28 +00001379int Assembler::CallSize(const Operand& adr) {
1380 // Call size is 1 (opcode) + adr.len_ (operand).
1381 return 1 + adr.len_;
1382}
1383
1384
Steve Blocka7e24c12009-10-30 11:49:00 +00001385void Assembler::call(const Operand& adr) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01001386 positions_recorder()->WriteRecordedPositions();
Steve Blocka7e24c12009-10-30 11:49:00 +00001387 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001388 EMIT(0xFF);
1389 emit_operand(edx, adr);
1390}
1391
1392
Ben Murdoch257744e2011-11-30 15:57:28 +00001393int Assembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) {
1394 return 1 /* EMIT */ + sizeof(uint32_t) /* emit */;
Steve Blocka7e24c12009-10-30 11:49:00 +00001395}
1396
1397
Ben Murdoch257744e2011-11-30 15:57:28 +00001398void Assembler::call(Handle<Code> code,
1399 RelocInfo::Mode rmode,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001400 TypeFeedbackId ast_id) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001401 positions_recorder()->WriteRecordedPositions();
Steve Blocka7e24c12009-10-30 11:49:00 +00001402 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001403 DCHECK(RelocInfo::IsCodeTarget(rmode)
1404 || rmode == RelocInfo::CODE_AGE_SEQUENCE);
Ben Murdoch257744e2011-11-30 15:57:28 +00001405 EMIT(0xE8);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001406 emit(code, rmode, ast_id);
Ben Murdoch257744e2011-11-30 15:57:28 +00001407}
1408
1409
1410void Assembler::jmp(Label* L, Label::Distance distance) {
1411 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001412 if (L->is_bound()) {
1413 const int short_size = 2;
1414 const int long_size = 5;
1415 int offs = L->pos() - pc_offset();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001416 DCHECK(offs <= 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00001417 if (is_int8(offs - short_size)) {
Andrei Popescu31002712010-02-23 13:46:05 +00001418 // 1110 1011 #8-bit disp.
Steve Blocka7e24c12009-10-30 11:49:00 +00001419 EMIT(0xEB);
1420 EMIT((offs - short_size) & 0xFF);
1421 } else {
Andrei Popescu31002712010-02-23 13:46:05 +00001422 // 1110 1001 #32-bit disp.
Steve Blocka7e24c12009-10-30 11:49:00 +00001423 EMIT(0xE9);
1424 emit(offs - long_size);
1425 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001426 } else if (distance == Label::kNear) {
1427 EMIT(0xEB);
1428 emit_near_disp(L);
Steve Blocka7e24c12009-10-30 11:49:00 +00001429 } else {
Andrei Popescu31002712010-02-23 13:46:05 +00001430 // 1110 1001 #32-bit disp.
Steve Blocka7e24c12009-10-30 11:49:00 +00001431 EMIT(0xE9);
1432 emit_disp(L, Displacement::UNCONDITIONAL_JUMP);
1433 }
1434}
1435
1436
1437void Assembler::jmp(byte* entry, RelocInfo::Mode rmode) {
1438 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001439 DCHECK(!RelocInfo::IsCodeTarget(rmode));
Steve Blocka7e24c12009-10-30 11:49:00 +00001440 EMIT(0xE9);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001441 if (RelocInfo::IsRuntimeEntry(rmode)) {
1442 emit(reinterpret_cast<uint32_t>(entry), rmode);
1443 } else {
1444 emit(entry - (pc_ + sizeof(int32_t)), rmode);
1445 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001446}
1447
1448
1449void Assembler::jmp(const Operand& adr) {
1450 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001451 EMIT(0xFF);
1452 emit_operand(esp, adr);
1453}
1454
1455
1456void Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) {
1457 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001458 DCHECK(RelocInfo::IsCodeTarget(rmode));
Steve Blocka7e24c12009-10-30 11:49:00 +00001459 EMIT(0xE9);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001460 emit(code, rmode);
Steve Blocka7e24c12009-10-30 11:49:00 +00001461}
1462
1463
Ben Murdoch257744e2011-11-30 15:57:28 +00001464void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001465 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001466 DCHECK(0 <= cc && static_cast<int>(cc) < 16);
Steve Blocka7e24c12009-10-30 11:49:00 +00001467 if (L->is_bound()) {
1468 const int short_size = 2;
1469 const int long_size = 6;
1470 int offs = L->pos() - pc_offset();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001471 DCHECK(offs <= 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00001472 if (is_int8(offs - short_size)) {
1473 // 0111 tttn #8-bit disp
1474 EMIT(0x70 | cc);
1475 EMIT((offs - short_size) & 0xFF);
1476 } else {
1477 // 0000 1111 1000 tttn #32-bit disp
1478 EMIT(0x0F);
1479 EMIT(0x80 | cc);
1480 emit(offs - long_size);
1481 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001482 } else if (distance == Label::kNear) {
1483 EMIT(0x70 | cc);
1484 emit_near_disp(L);
Steve Blocka7e24c12009-10-30 11:49:00 +00001485 } else {
1486 // 0000 1111 1000 tttn #32-bit disp
1487 // Note: could eliminate cond. jumps to this jump if condition
1488 // is the same however, seems to be rather unlikely case.
1489 EMIT(0x0F);
1490 EMIT(0x80 | cc);
1491 emit_disp(L, Displacement::OTHER);
1492 }
1493}
1494
1495
Ben Murdoch257744e2011-11-30 15:57:28 +00001496void Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001497 EnsureSpace ensure_space(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001498 DCHECK((0 <= cc) && (static_cast<int>(cc) < 16));
Andrei Popescu31002712010-02-23 13:46:05 +00001499 // 0000 1111 1000 tttn #32-bit disp.
Steve Blocka7e24c12009-10-30 11:49:00 +00001500 EMIT(0x0F);
1501 EMIT(0x80 | cc);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001502 if (RelocInfo::IsRuntimeEntry(rmode)) {
1503 emit(reinterpret_cast<uint32_t>(entry), rmode);
1504 } else {
1505 emit(entry - (pc_ + sizeof(int32_t)), rmode);
1506 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001507}
1508
1509
Ben Murdoch257744e2011-11-30 15:57:28 +00001510void Assembler::j(Condition cc, Handle<Code> code) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001511 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001512 // 0000 1111 1000 tttn #32-bit disp
1513 EMIT(0x0F);
1514 EMIT(0x80 | cc);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001515 emit(code, RelocInfo::CODE_TARGET);
Steve Blocka7e24c12009-10-30 11:49:00 +00001516}
1517
1518
Andrei Popescu31002712010-02-23 13:46:05 +00001519// FPU instructions.
Steve Blocka7e24c12009-10-30 11:49:00 +00001520
Steve Blocka7e24c12009-10-30 11:49:00 +00001521void Assembler::fld(int i) {
1522 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001523 emit_farith(0xD9, 0xC0, i);
1524}
1525
1526
Andrei Popescu402d9372010-02-26 13:31:12 +00001527void Assembler::fstp(int i) {
1528 EnsureSpace ensure_space(this);
Andrei Popescu402d9372010-02-26 13:31:12 +00001529 emit_farith(0xDD, 0xD8, i);
1530}
1531
1532
Steve Blocka7e24c12009-10-30 11:49:00 +00001533void Assembler::fld1() {
1534 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001535 EMIT(0xD9);
1536 EMIT(0xE8);
1537}
1538
1539
Andrei Popescu402d9372010-02-26 13:31:12 +00001540void Assembler::fldpi() {
1541 EnsureSpace ensure_space(this);
Andrei Popescu402d9372010-02-26 13:31:12 +00001542 EMIT(0xD9);
1543 EMIT(0xEB);
1544}
1545
1546
Steve Blocka7e24c12009-10-30 11:49:00 +00001547void Assembler::fldz() {
1548 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001549 EMIT(0xD9);
1550 EMIT(0xEE);
1551}
1552
1553
Ben Murdochb0fe1622011-05-05 13:52:32 +01001554void Assembler::fldln2() {
1555 EnsureSpace ensure_space(this);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001556 EMIT(0xD9);
1557 EMIT(0xED);
1558}
1559
1560
Steve Blocka7e24c12009-10-30 11:49:00 +00001561void Assembler::fld_s(const Operand& adr) {
1562 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001563 EMIT(0xD9);
1564 emit_operand(eax, adr);
1565}
1566
1567
1568void Assembler::fld_d(const Operand& adr) {
1569 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001570 EMIT(0xDD);
1571 emit_operand(eax, adr);
1572}
1573
1574
1575void Assembler::fstp_s(const Operand& adr) {
1576 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001577 EMIT(0xD9);
1578 emit_operand(ebx, adr);
1579}
1580
1581
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001582void Assembler::fst_s(const Operand& adr) {
1583 EnsureSpace ensure_space(this);
1584 EMIT(0xD9);
1585 emit_operand(edx, adr);
1586}
1587
1588
Steve Blocka7e24c12009-10-30 11:49:00 +00001589void Assembler::fstp_d(const Operand& adr) {
1590 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001591 EMIT(0xDD);
1592 emit_operand(ebx, adr);
1593}
1594
1595
Andrei Popescu402d9372010-02-26 13:31:12 +00001596void Assembler::fst_d(const Operand& adr) {
1597 EnsureSpace ensure_space(this);
Andrei Popescu402d9372010-02-26 13:31:12 +00001598 EMIT(0xDD);
1599 emit_operand(edx, adr);
1600}
1601
1602
Steve Blocka7e24c12009-10-30 11:49:00 +00001603void Assembler::fild_s(const Operand& adr) {
1604 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001605 EMIT(0xDB);
1606 emit_operand(eax, adr);
1607}
1608
1609
1610void Assembler::fild_d(const Operand& adr) {
1611 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001612 EMIT(0xDF);
1613 emit_operand(ebp, adr);
1614}
1615
1616
1617void Assembler::fistp_s(const Operand& adr) {
1618 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001619 EMIT(0xDB);
1620 emit_operand(ebx, adr);
1621}
1622
1623
1624void Assembler::fisttp_s(const Operand& adr) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001625 DCHECK(IsEnabled(SSE3));
Steve Blocka7e24c12009-10-30 11:49:00 +00001626 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001627 EMIT(0xDB);
1628 emit_operand(ecx, adr);
1629}
1630
1631
Leon Clarkee46be812010-01-19 14:06:41 +00001632void Assembler::fisttp_d(const Operand& adr) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001633 DCHECK(IsEnabled(SSE3));
Leon Clarkee46be812010-01-19 14:06:41 +00001634 EnsureSpace ensure_space(this);
Leon Clarkee46be812010-01-19 14:06:41 +00001635 EMIT(0xDD);
1636 emit_operand(ecx, adr);
1637}
1638
1639
Steve Blocka7e24c12009-10-30 11:49:00 +00001640void Assembler::fist_s(const Operand& adr) {
1641 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001642 EMIT(0xDB);
1643 emit_operand(edx, adr);
1644}
1645
1646
1647void Assembler::fistp_d(const Operand& adr) {
1648 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001649 EMIT(0xDF);
1650 emit_operand(edi, adr);
1651}
1652
1653
1654void Assembler::fabs() {
1655 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001656 EMIT(0xD9);
1657 EMIT(0xE1);
1658}
1659
1660
1661void Assembler::fchs() {
1662 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001663 EMIT(0xD9);
1664 EMIT(0xE0);
1665}
1666
1667
1668void Assembler::fcos() {
1669 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001670 EMIT(0xD9);
1671 EMIT(0xFF);
1672}
1673
1674
1675void Assembler::fsin() {
1676 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001677 EMIT(0xD9);
1678 EMIT(0xFE);
1679}
1680
1681
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001682void Assembler::fptan() {
1683 EnsureSpace ensure_space(this);
1684 EMIT(0xD9);
1685 EMIT(0xF2);
1686}
1687
1688
Ben Murdochb0fe1622011-05-05 13:52:32 +01001689void Assembler::fyl2x() {
1690 EnsureSpace ensure_space(this);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001691 EMIT(0xD9);
1692 EMIT(0xF1);
1693}
1694
1695
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001696void Assembler::f2xm1() {
1697 EnsureSpace ensure_space(this);
1698 EMIT(0xD9);
1699 EMIT(0xF0);
1700}
1701
1702
1703void Assembler::fscale() {
1704 EnsureSpace ensure_space(this);
1705 EMIT(0xD9);
1706 EMIT(0xFD);
1707}
1708
1709
1710void Assembler::fninit() {
1711 EnsureSpace ensure_space(this);
1712 EMIT(0xDB);
1713 EMIT(0xE3);
1714}
1715
1716
Steve Blocka7e24c12009-10-30 11:49:00 +00001717void Assembler::fadd(int i) {
1718 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001719 emit_farith(0xDC, 0xC0, i);
1720}
1721
1722
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001723void Assembler::fadd_i(int i) {
1724 EnsureSpace ensure_space(this);
1725 emit_farith(0xD8, 0xC0, i);
1726}
1727
1728
Steve Blocka7e24c12009-10-30 11:49:00 +00001729void Assembler::fsub(int i) {
1730 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001731 emit_farith(0xDC, 0xE8, i);
1732}
1733
1734
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001735void Assembler::fsub_i(int i) {
1736 EnsureSpace ensure_space(this);
1737 emit_farith(0xD8, 0xE0, i);
1738}
1739
1740
Steve Blocka7e24c12009-10-30 11:49:00 +00001741void Assembler::fisub_s(const Operand& adr) {
1742 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001743 EMIT(0xDA);
1744 emit_operand(esp, adr);
1745}
1746
1747
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001748void Assembler::fmul_i(int i) {
1749 EnsureSpace ensure_space(this);
1750 emit_farith(0xD8, 0xC8, i);
1751}
1752
1753
Steve Blocka7e24c12009-10-30 11:49:00 +00001754void Assembler::fmul(int i) {
1755 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001756 emit_farith(0xDC, 0xC8, i);
1757}
1758
1759
1760void Assembler::fdiv(int i) {
1761 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001762 emit_farith(0xDC, 0xF8, i);
1763}
1764
1765
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001766void Assembler::fdiv_i(int i) {
1767 EnsureSpace ensure_space(this);
1768 emit_farith(0xD8, 0xF0, i);
1769}
1770
1771
Steve Blocka7e24c12009-10-30 11:49:00 +00001772void Assembler::faddp(int i) {
1773 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001774 emit_farith(0xDE, 0xC0, i);
1775}
1776
1777
1778void Assembler::fsubp(int i) {
1779 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001780 emit_farith(0xDE, 0xE8, i);
1781}
1782
1783
1784void Assembler::fsubrp(int i) {
1785 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001786 emit_farith(0xDE, 0xE0, i);
1787}
1788
1789
1790void Assembler::fmulp(int i) {
1791 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001792 emit_farith(0xDE, 0xC8, i);
1793}
1794
1795
1796void Assembler::fdivp(int i) {
1797 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001798 emit_farith(0xDE, 0xF8, i);
1799}
1800
1801
1802void Assembler::fprem() {
1803 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001804 EMIT(0xD9);
1805 EMIT(0xF8);
1806}
1807
1808
1809void Assembler::fprem1() {
1810 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001811 EMIT(0xD9);
1812 EMIT(0xF5);
1813}
1814
1815
1816void Assembler::fxch(int i) {
1817 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001818 emit_farith(0xD9, 0xC8, i);
1819}
1820
1821
1822void Assembler::fincstp() {
1823 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001824 EMIT(0xD9);
1825 EMIT(0xF7);
1826}
1827
1828
1829void Assembler::ffree(int i) {
1830 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001831 emit_farith(0xDD, 0xC0, i);
1832}
1833
1834
1835void Assembler::ftst() {
1836 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001837 EMIT(0xD9);
1838 EMIT(0xE4);
1839}
1840
1841
1842void Assembler::fucomp(int i) {
1843 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001844 emit_farith(0xDD, 0xE8, i);
1845}
1846
1847
1848void Assembler::fucompp() {
1849 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001850 EMIT(0xDA);
1851 EMIT(0xE9);
1852}
1853
1854
Steve Block3ce2e202009-11-05 08:53:23 +00001855void Assembler::fucomi(int i) {
1856 EnsureSpace ensure_space(this);
Steve Block3ce2e202009-11-05 08:53:23 +00001857 EMIT(0xDB);
1858 EMIT(0xE8 + i);
1859}
1860
1861
1862void Assembler::fucomip() {
1863 EnsureSpace ensure_space(this);
Steve Block3ce2e202009-11-05 08:53:23 +00001864 EMIT(0xDF);
1865 EMIT(0xE9);
1866}
1867
1868
Steve Blocka7e24c12009-10-30 11:49:00 +00001869void Assembler::fcompp() {
1870 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001871 EMIT(0xDE);
1872 EMIT(0xD9);
1873}
1874
1875
1876void Assembler::fnstsw_ax() {
1877 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001878 EMIT(0xDF);
1879 EMIT(0xE0);
1880}
1881
1882
1883void Assembler::fwait() {
1884 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001885 EMIT(0x9B);
1886}
1887
1888
1889void Assembler::frndint() {
1890 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001891 EMIT(0xD9);
1892 EMIT(0xFC);
1893}
1894
1895
1896void Assembler::fnclex() {
1897 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001898 EMIT(0xDB);
1899 EMIT(0xE2);
1900}
1901
1902
1903void Assembler::sahf() {
1904 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001905 EMIT(0x9E);
1906}
1907
1908
1909void Assembler::setcc(Condition cc, Register reg) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001910 DCHECK(reg.is_byte_register());
Steve Blocka7e24c12009-10-30 11:49:00 +00001911 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001912 EMIT(0x0F);
1913 EMIT(0x90 | cc);
1914 EMIT(0xC0 | reg.code());
1915}
1916
1917
1918void Assembler::cvttss2si(Register dst, const Operand& src) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001919 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001920 EMIT(0xF3);
1921 EMIT(0x0F);
1922 EMIT(0x2C);
1923 emit_operand(dst, src);
1924}
1925
1926
1927void Assembler::cvttsd2si(Register dst, const Operand& src) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001928 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001929 EMIT(0xF2);
1930 EMIT(0x0F);
1931 EMIT(0x2C);
1932 emit_operand(dst, src);
1933}
1934
1935
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001936void Assembler::cvtsd2si(Register dst, XMMRegister src) {
1937 EnsureSpace ensure_space(this);
1938 EMIT(0xF2);
1939 EMIT(0x0F);
1940 EMIT(0x2D);
1941 emit_sse_operand(dst, src);
1942}
1943
1944
Steve Blocka7e24c12009-10-30 11:49:00 +00001945void Assembler::cvtsi2sd(XMMRegister dst, const Operand& src) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001946 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001947 EMIT(0xF2);
1948 EMIT(0x0F);
1949 EMIT(0x2A);
1950 emit_sse_operand(dst, src);
1951}
1952
1953
Steve Block6ded16b2010-05-10 14:33:55 +01001954void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
Steve Block6ded16b2010-05-10 14:33:55 +01001955 EnsureSpace ensure_space(this);
Steve Block6ded16b2010-05-10 14:33:55 +01001956 EMIT(0xF3);
1957 EMIT(0x0F);
1958 EMIT(0x5A);
1959 emit_sse_operand(dst, src);
1960}
1961
1962
Steve Block44f0eee2011-05-26 01:26:41 +01001963void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
Steve Block44f0eee2011-05-26 01:26:41 +01001964 EnsureSpace ensure_space(this);
Steve Block44f0eee2011-05-26 01:26:41 +01001965 EMIT(0xF2);
1966 EMIT(0x0F);
1967 EMIT(0x5A);
1968 emit_sse_operand(dst, src);
1969}
1970
1971
Steve Blocka7e24c12009-10-30 11:49:00 +00001972void Assembler::addsd(XMMRegister dst, XMMRegister src) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001973 EnsureSpace ensure_space(this);
1974 EMIT(0xF2);
1975 EMIT(0x0F);
1976 EMIT(0x58);
1977 emit_sse_operand(dst, src);
1978}
1979
1980
1981void Assembler::addsd(XMMRegister dst, const Operand& src) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001982 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001983 EMIT(0xF2);
1984 EMIT(0x0F);
1985 EMIT(0x58);
1986 emit_sse_operand(dst, src);
1987}
1988
1989
1990void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001991 EnsureSpace ensure_space(this);
1992 EMIT(0xF2);
1993 EMIT(0x0F);
1994 EMIT(0x59);
1995 emit_sse_operand(dst, src);
1996}
1997
1998
1999void Assembler::mulsd(XMMRegister dst, const Operand& src) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002000 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00002001 EMIT(0xF2);
2002 EMIT(0x0F);
2003 EMIT(0x59);
2004 emit_sse_operand(dst, src);
2005}
2006
2007
2008void Assembler::subsd(XMMRegister dst, XMMRegister src) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002009 EnsureSpace ensure_space(this);
2010 EMIT(0xF2);
2011 EMIT(0x0F);
2012 EMIT(0x5C);
2013 emit_sse_operand(dst, src);
2014}
2015
2016
2017void Assembler::subsd(XMMRegister dst, const Operand& src) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002018 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00002019 EMIT(0xF2);
2020 EMIT(0x0F);
2021 EMIT(0x5C);
2022 emit_sse_operand(dst, src);
2023}
2024
2025
2026void Assembler::divsd(XMMRegister dst, XMMRegister src) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002027 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00002028 EMIT(0xF2);
2029 EMIT(0x0F);
2030 EMIT(0x5E);
2031 emit_sse_operand(dst, src);
2032}
2033
2034
Leon Clarkee46be812010-01-19 14:06:41 +00002035void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
Leon Clarkee46be812010-01-19 14:06:41 +00002036 EnsureSpace ensure_space(this);
Leon Clarkee46be812010-01-19 14:06:41 +00002037 EMIT(0x66);
2038 EMIT(0x0F);
2039 EMIT(0x57);
2040 emit_sse_operand(dst, src);
2041}
2042
2043
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002044void Assembler::andps(XMMRegister dst, const Operand& src) {
2045 EnsureSpace ensure_space(this);
2046 EMIT(0x0F);
2047 EMIT(0x54);
2048 emit_sse_operand(dst, src);
2049}
2050
2051
2052void Assembler::orps(XMMRegister dst, const Operand& src) {
2053 EnsureSpace ensure_space(this);
2054 EMIT(0x0F);
2055 EMIT(0x56);
2056 emit_sse_operand(dst, src);
2057}
2058
2059
2060void Assembler::xorps(XMMRegister dst, const Operand& src) {
Ben Murdoch257744e2011-11-30 15:57:28 +00002061 EnsureSpace ensure_space(this);
2062 EMIT(0x0F);
2063 EMIT(0x57);
2064 emit_sse_operand(dst, src);
2065}
2066
2067
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002068void Assembler::addps(XMMRegister dst, const Operand& src) {
2069 EnsureSpace ensure_space(this);
2070 EMIT(0x0F);
2071 EMIT(0x58);
2072 emit_sse_operand(dst, src);
2073}
2074
2075
2076void Assembler::subps(XMMRegister dst, const Operand& src) {
2077 EnsureSpace ensure_space(this);
2078 EMIT(0x0F);
2079 EMIT(0x5C);
2080 emit_sse_operand(dst, src);
2081}
2082
2083
2084void Assembler::mulps(XMMRegister dst, const Operand& src) {
2085 EnsureSpace ensure_space(this);
2086 EMIT(0x0F);
2087 EMIT(0x59);
2088 emit_sse_operand(dst, src);
2089}
2090
2091
2092void Assembler::divps(XMMRegister dst, const Operand& src) {
2093 EnsureSpace ensure_space(this);
2094 EMIT(0x0F);
2095 EMIT(0x5E);
2096 emit_sse_operand(dst, src);
2097}
2098
2099
Steve Block6ded16b2010-05-10 14:33:55 +01002100void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
2101 EnsureSpace ensure_space(this);
Steve Block6ded16b2010-05-10 14:33:55 +01002102 EMIT(0xF2);
2103 EMIT(0x0F);
2104 EMIT(0x51);
2105 emit_sse_operand(dst, src);
2106}
2107
2108
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002109void Assembler::sqrtsd(XMMRegister dst, const Operand& src) {
2110 EnsureSpace ensure_space(this);
2111 EMIT(0xF2);
2112 EMIT(0x0F);
2113 EMIT(0x51);
2114 emit_sse_operand(dst, src);
2115}
2116
2117
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002118void Assembler::andpd(XMMRegister dst, XMMRegister src) {
2119 EnsureSpace ensure_space(this);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002120 EMIT(0x66);
2121 EMIT(0x0F);
2122 EMIT(0x54);
2123 emit_sse_operand(dst, src);
2124}
2125
2126
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002127void Assembler::orpd(XMMRegister dst, XMMRegister src) {
Steve Block6ded16b2010-05-10 14:33:55 +01002128 EnsureSpace ensure_space(this);
Steve Block6ded16b2010-05-10 14:33:55 +01002129 EMIT(0x66);
2130 EMIT(0x0F);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002131 EMIT(0x56);
Steve Block6ded16b2010-05-10 14:33:55 +01002132 emit_sse_operand(dst, src);
2133}
2134
2135
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002136void Assembler::ucomisd(XMMRegister dst, const Operand& src) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002137 EnsureSpace ensure_space(this);
2138 EMIT(0x66);
2139 EMIT(0x0F);
2140 EMIT(0x2E);
2141 emit_sse_operand(dst, src);
2142}
2143
2144
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002145void Assembler::roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002146 DCHECK(IsEnabled(SSE4_1));
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002147 EnsureSpace ensure_space(this);
2148 EMIT(0x66);
2149 EMIT(0x0F);
2150 EMIT(0x3A);
2151 EMIT(0x0B);
2152 emit_sse_operand(dst, src);
2153 // Mask precision exeption.
2154 EMIT(static_cast<byte>(mode) | 0x8);
2155}
2156
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002157
Steve Block6ded16b2010-05-10 14:33:55 +01002158void Assembler::movmskpd(Register dst, XMMRegister src) {
Steve Block6ded16b2010-05-10 14:33:55 +01002159 EnsureSpace ensure_space(this);
Steve Block6ded16b2010-05-10 14:33:55 +01002160 EMIT(0x66);
2161 EMIT(0x0F);
2162 EMIT(0x50);
2163 emit_sse_operand(dst, src);
2164}
2165
2166
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002167void Assembler::movmskps(Register dst, XMMRegister src) {
2168 EnsureSpace ensure_space(this);
2169 EMIT(0x0F);
2170 EMIT(0x50);
2171 emit_sse_operand(dst, src);
2172}
2173
2174
2175void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) {
2176 EnsureSpace ensure_space(this);
2177 EMIT(0x66);
2178 EMIT(0x0F);
2179 EMIT(0x76);
2180 emit_sse_operand(dst, src);
2181}
2182
2183
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002184void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002185 EnsureSpace ensure_space(this);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002186 EMIT(0xF2);
2187 EMIT(0x0F);
2188 EMIT(0xC2);
2189 emit_sse_operand(dst, src);
2190 EMIT(1); // LT == 1
2191}
2192
2193
2194void Assembler::movaps(XMMRegister dst, XMMRegister src) {
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002195 EnsureSpace ensure_space(this);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002196 EMIT(0x0F);
2197 EMIT(0x28);
2198 emit_sse_operand(dst, src);
2199}
2200
2201
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002202void Assembler::shufps(XMMRegister dst, XMMRegister src, byte imm8) {
2203 DCHECK(is_uint8(imm8));
2204 EnsureSpace ensure_space(this);
2205 EMIT(0x0F);
2206 EMIT(0xC6);
2207 emit_sse_operand(dst, src);
2208 EMIT(imm8);
2209}
2210
2211
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002212void Assembler::movdqa(const Operand& dst, XMMRegister src) {
Leon Clarkee46be812010-01-19 14:06:41 +00002213 EnsureSpace ensure_space(this);
Leon Clarkee46be812010-01-19 14:06:41 +00002214 EMIT(0x66);
2215 EMIT(0x0F);
2216 EMIT(0x7F);
2217 emit_sse_operand(src, dst);
2218}
2219
2220
2221void Assembler::movdqa(XMMRegister dst, const Operand& src) {
Leon Clarkee46be812010-01-19 14:06:41 +00002222 EnsureSpace ensure_space(this);
Leon Clarkee46be812010-01-19 14:06:41 +00002223 EMIT(0x66);
2224 EMIT(0x0F);
2225 EMIT(0x6F);
2226 emit_sse_operand(dst, src);
2227}
2228
2229
2230void Assembler::movdqu(const Operand& dst, XMMRegister src ) {
Leon Clarkee46be812010-01-19 14:06:41 +00002231 EnsureSpace ensure_space(this);
Leon Clarkee46be812010-01-19 14:06:41 +00002232 EMIT(0xF3);
2233 EMIT(0x0F);
2234 EMIT(0x7F);
2235 emit_sse_operand(src, dst);
2236}
2237
2238
2239void Assembler::movdqu(XMMRegister dst, const Operand& src) {
Leon Clarkee46be812010-01-19 14:06:41 +00002240 EnsureSpace ensure_space(this);
Leon Clarkee46be812010-01-19 14:06:41 +00002241 EMIT(0xF3);
2242 EMIT(0x0F);
2243 EMIT(0x6F);
2244 emit_sse_operand(dst, src);
2245}
2246
2247
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002248void Assembler::movntdqa(XMMRegister dst, const Operand& src) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002249 DCHECK(IsEnabled(SSE4_1));
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002250 EnsureSpace ensure_space(this);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002251 EMIT(0x66);
2252 EMIT(0x0F);
2253 EMIT(0x38);
2254 EMIT(0x2A);
2255 emit_sse_operand(dst, src);
2256}
2257
2258
2259void Assembler::movntdq(const Operand& dst, XMMRegister src) {
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002260 EnsureSpace ensure_space(this);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002261 EMIT(0x66);
2262 EMIT(0x0F);
2263 EMIT(0xE7);
2264 emit_sse_operand(src, dst);
2265}
2266
2267
2268void Assembler::prefetch(const Operand& src, int level) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002269 DCHECK(is_uint2(level));
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002270 EnsureSpace ensure_space(this);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002271 EMIT(0x0F);
2272 EMIT(0x18);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002273 // Emit hint number in Reg position of RegR/M.
2274 XMMRegister code = XMMRegister::from_code(level);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002275 emit_sse_operand(code, src);
2276}
2277
2278
Steve Blocka7e24c12009-10-30 11:49:00 +00002279void Assembler::movsd(const Operand& dst, XMMRegister src ) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002280 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00002281 EMIT(0xF2); // double
2282 EMIT(0x0F);
2283 EMIT(0x11); // store
2284 emit_sse_operand(src, dst);
2285}
2286
2287
2288void Assembler::movsd(XMMRegister dst, const Operand& src) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002289 EnsureSpace ensure_space(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00002290 EMIT(0xF2); // double
2291 EMIT(0x0F);
2292 EMIT(0x10); // load
2293 emit_sse_operand(dst, src);
2294}
2295
Ben Murdochb0fe1622011-05-05 13:52:32 +01002296
Steve Block44f0eee2011-05-26 01:26:41 +01002297void Assembler::movss(const Operand& dst, XMMRegister src ) {
Steve Block44f0eee2011-05-26 01:26:41 +01002298 EnsureSpace ensure_space(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002299 EMIT(0xF3); // float
2300 EMIT(0x0F);
2301 EMIT(0x11); // store
2302 emit_sse_operand(src, dst);
2303}
2304
2305
2306void Assembler::movss(XMMRegister dst, const Operand& src) {
Steve Block44f0eee2011-05-26 01:26:41 +01002307 EnsureSpace ensure_space(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002308 EMIT(0xF3); // float
2309 EMIT(0x0F);
2310 EMIT(0x10); // load
2311 emit_sse_operand(dst, src);
2312}
2313
2314
Steve Block6ded16b2010-05-10 14:33:55 +01002315void Assembler::movd(XMMRegister dst, const Operand& src) {
Steve Block6ded16b2010-05-10 14:33:55 +01002316 EnsureSpace ensure_space(this);
Steve Block6ded16b2010-05-10 14:33:55 +01002317 EMIT(0x66);
2318 EMIT(0x0F);
2319 EMIT(0x6E);
2320 emit_sse_operand(dst, src);
2321}
2322
2323
Ben Murdochb0fe1622011-05-05 13:52:32 +01002324void Assembler::movd(const Operand& dst, XMMRegister src) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01002325 EnsureSpace ensure_space(this);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002326 EMIT(0x66);
2327 EMIT(0x0F);
2328 EMIT(0x7E);
2329 emit_sse_operand(src, dst);
2330}
2331
2332
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002333void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002334 DCHECK(IsEnabled(SSE4_1));
2335 DCHECK(is_uint8(imm8));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002336 EnsureSpace ensure_space(this);
2337 EMIT(0x66);
2338 EMIT(0x0F);
2339 EMIT(0x3A);
2340 EMIT(0x17);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002341 emit_sse_operand(src, dst);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002342 EMIT(imm8);
2343}
2344
2345
Ben Murdochb0fe1622011-05-05 13:52:32 +01002346void Assembler::pand(XMMRegister dst, XMMRegister src) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01002347 EnsureSpace ensure_space(this);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002348 EMIT(0x66);
2349 EMIT(0x0F);
2350 EMIT(0xDB);
2351 emit_sse_operand(dst, src);
2352}
2353
2354
Steve Block6ded16b2010-05-10 14:33:55 +01002355void Assembler::pxor(XMMRegister dst, XMMRegister src) {
Steve Block6ded16b2010-05-10 14:33:55 +01002356 EnsureSpace ensure_space(this);
Steve Block6ded16b2010-05-10 14:33:55 +01002357 EMIT(0x66);
2358 EMIT(0x0F);
2359 EMIT(0xEF);
2360 emit_sse_operand(dst, src);
2361}
2362
2363
Ben Murdochb8e0da22011-05-16 14:20:40 +01002364void Assembler::por(XMMRegister dst, XMMRegister src) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01002365 EnsureSpace ensure_space(this);
Ben Murdochb8e0da22011-05-16 14:20:40 +01002366 EMIT(0x66);
2367 EMIT(0x0F);
2368 EMIT(0xEB);
2369 emit_sse_operand(dst, src);
2370}
2371
2372
Steve Block6ded16b2010-05-10 14:33:55 +01002373void Assembler::ptest(XMMRegister dst, XMMRegister src) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002374 DCHECK(IsEnabled(SSE4_1));
Steve Block6ded16b2010-05-10 14:33:55 +01002375 EnsureSpace ensure_space(this);
Steve Block6ded16b2010-05-10 14:33:55 +01002376 EMIT(0x66);
2377 EMIT(0x0F);
2378 EMIT(0x38);
2379 EMIT(0x17);
2380 emit_sse_operand(dst, src);
2381}
2382
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002383
Ben Murdochb0fe1622011-05-05 13:52:32 +01002384void Assembler::psllq(XMMRegister reg, int8_t shift) {
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002385 EnsureSpace ensure_space(this);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002386 EMIT(0x66);
2387 EMIT(0x0F);
2388 EMIT(0x73);
2389 emit_sse_operand(esi, reg); // esi == 6
Ben Murdochb0fe1622011-05-05 13:52:32 +01002390 EMIT(shift);
2391}
2392
2393
Ben Murdochb8e0da22011-05-16 14:20:40 +01002394void Assembler::psllq(XMMRegister dst, XMMRegister src) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01002395 EnsureSpace ensure_space(this);
Ben Murdochb8e0da22011-05-16 14:20:40 +01002396 EMIT(0x66);
2397 EMIT(0x0F);
2398 EMIT(0xF3);
2399 emit_sse_operand(dst, src);
2400}
2401
2402
2403void Assembler::psrlq(XMMRegister reg, int8_t shift) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01002404 EnsureSpace ensure_space(this);
Ben Murdochb8e0da22011-05-16 14:20:40 +01002405 EMIT(0x66);
2406 EMIT(0x0F);
2407 EMIT(0x73);
2408 emit_sse_operand(edx, reg); // edx == 2
2409 EMIT(shift);
2410}
2411
2412
2413void Assembler::psrlq(XMMRegister dst, XMMRegister src) {
Ben Murdochb8e0da22011-05-16 14:20:40 +01002414 EnsureSpace ensure_space(this);
Ben Murdochb8e0da22011-05-16 14:20:40 +01002415 EMIT(0x66);
2416 EMIT(0x0F);
2417 EMIT(0xD3);
2418 emit_sse_operand(dst, src);
2419}
2420
2421
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002422void Assembler::pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01002423 EnsureSpace ensure_space(this);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002424 EMIT(0x66);
2425 EMIT(0x0F);
2426 EMIT(0x70);
2427 emit_sse_operand(dst, src);
2428 EMIT(shuffle);
2429}
2430
2431
2432void Assembler::pextrd(const Operand& dst, XMMRegister src, int8_t offset) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002433 DCHECK(IsEnabled(SSE4_1));
Ben Murdochb0fe1622011-05-05 13:52:32 +01002434 EnsureSpace ensure_space(this);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002435 EMIT(0x66);
2436 EMIT(0x0F);
2437 EMIT(0x3A);
2438 EMIT(0x16);
2439 emit_sse_operand(src, dst);
2440 EMIT(offset);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002441}
2442
2443
Steve Block1e0659c2011-05-24 12:43:12 +01002444void Assembler::pinsrd(XMMRegister dst, const Operand& src, int8_t offset) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002445 DCHECK(IsEnabled(SSE4_1));
Steve Block1e0659c2011-05-24 12:43:12 +01002446 EnsureSpace ensure_space(this);
Steve Block1e0659c2011-05-24 12:43:12 +01002447 EMIT(0x66);
2448 EMIT(0x0F);
2449 EMIT(0x3A);
2450 EMIT(0x22);
2451 emit_sse_operand(dst, src);
2452 EMIT(offset);
2453}
2454
2455
Steve Blocka7e24c12009-10-30 11:49:00 +00002456void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
2457 Register ireg = { reg.code() };
2458 emit_operand(ireg, adr);
2459}
2460
2461
2462void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
2463 EMIT(0xC0 | dst.code() << 3 | src.code());
2464}
2465
2466
Steve Block6ded16b2010-05-10 14:33:55 +01002467void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
2468 EMIT(0xC0 | dst.code() << 3 | src.code());
2469}
2470
2471
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002472void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
2473 EMIT(0xC0 | (dst.code() << 3) | src.code());
2474}
2475
2476
Steve Blocka7e24c12009-10-30 11:49:00 +00002477void Assembler::Print() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002478 Disassembler::Decode(isolate(), stdout, buffer_, pc_);
Steve Blocka7e24c12009-10-30 11:49:00 +00002479}
2480
2481
2482void Assembler::RecordJSReturn() {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002483 positions_recorder()->WriteRecordedPositions();
Steve Blocka7e24c12009-10-30 11:49:00 +00002484 EnsureSpace ensure_space(this);
2485 RecordRelocInfo(RelocInfo::JS_RETURN);
2486}
2487
2488
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002489void Assembler::RecordDebugBreakSlot() {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002490 positions_recorder()->WriteRecordedPositions();
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002491 EnsureSpace ensure_space(this);
2492 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
2493}
2494
2495
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002496void Assembler::RecordComment(const char* msg, bool force) {
2497 if (FLAG_code_comments || force) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002498 EnsureSpace ensure_space(this);
2499 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
2500 }
2501}
2502
2503
Steve Blocka7e24c12009-10-30 11:49:00 +00002504void Assembler::GrowBuffer() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002505 DCHECK(buffer_overflow());
Steve Blocka7e24c12009-10-30 11:49:00 +00002506 if (!own_buffer_) FATAL("external code buffer is too small");
2507
Andrei Popescu31002712010-02-23 13:46:05 +00002508 // Compute new buffer size.
Steve Blocka7e24c12009-10-30 11:49:00 +00002509 CodeDesc desc; // the new buffer
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002510 desc.buffer_size = 2 * buffer_size_;
2511
Steve Blocka7e24c12009-10-30 11:49:00 +00002512 // Some internal data structures overflow for very large buffers,
2513 // they must ensure that kMaximalBufferSize is not too large.
2514 if ((desc.buffer_size > kMaximalBufferSize) ||
Steve Block44f0eee2011-05-26 01:26:41 +01002515 (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002516 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
2517 }
2518
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002519 // Set up new buffer.
Steve Blocka7e24c12009-10-30 11:49:00 +00002520 desc.buffer = NewArray<byte>(desc.buffer_size);
2521 desc.instr_size = pc_offset();
2522 desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos());
2523
2524 // Clear the buffer in debug mode. Use 'int3' instructions to make
2525 // sure to get into problems if we ever run uninitialized code.
2526#ifdef DEBUG
2527 memset(desc.buffer, 0xCC, desc.buffer_size);
2528#endif
2529
Andrei Popescu31002712010-02-23 13:46:05 +00002530 // Copy the data.
Steve Blocka7e24c12009-10-30 11:49:00 +00002531 int pc_delta = desc.buffer - buffer_;
2532 int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002533 MemMove(desc.buffer, buffer_, desc.instr_size);
2534 MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(),
2535 desc.reloc_size);
Steve Blocka7e24c12009-10-30 11:49:00 +00002536
Andrei Popescu31002712010-02-23 13:46:05 +00002537 // Switch buffers.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002538 DeleteArray(buffer_);
Steve Blocka7e24c12009-10-30 11:49:00 +00002539 buffer_ = desc.buffer;
2540 buffer_size_ = desc.buffer_size;
2541 pc_ += pc_delta;
Steve Blocka7e24c12009-10-30 11:49:00 +00002542 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
2543 reloc_info_writer.last_pc() + pc_delta);
2544
Andrei Popescu31002712010-02-23 13:46:05 +00002545 // Relocate runtime entries.
Steve Blocka7e24c12009-10-30 11:49:00 +00002546 for (RelocIterator it(desc); !it.done(); it.next()) {
2547 RelocInfo::Mode rmode = it.rinfo()->rmode();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002548 if (rmode == RelocInfo::INTERNAL_REFERENCE) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002549 int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc());
2550 if (*p != 0) { // 0 means uninitialized.
2551 *p += pc_delta;
2552 }
2553 }
2554 }
2555
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002556 DCHECK(!buffer_overflow());
Steve Blocka7e24c12009-10-30 11:49:00 +00002557}
2558
2559
2560void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002561 DCHECK(is_uint8(op1) && is_uint8(op2)); // wrong opcode
2562 DCHECK(is_uint8(imm8));
2563 DCHECK((op1 & 0x01) == 0); // should be 8bit operation
Steve Blocka7e24c12009-10-30 11:49:00 +00002564 EMIT(op1);
2565 EMIT(op2 | dst.code());
2566 EMIT(imm8);
2567}
2568
2569
2570void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002571 DCHECK((0 <= sel) && (sel <= 7));
Steve Blocka7e24c12009-10-30 11:49:00 +00002572 Register ireg = { sel };
2573 if (x.is_int8()) {
2574 EMIT(0x83); // using a sign-extended 8-bit immediate.
2575 emit_operand(ireg, dst);
2576 EMIT(x.x_ & 0xFF);
2577 } else if (dst.is_reg(eax)) {
2578 EMIT((sel << 3) | 0x05); // short form if the destination is eax.
2579 emit(x);
2580 } else {
2581 EMIT(0x81); // using a literal 32-bit immediate.
2582 emit_operand(ireg, dst);
2583 emit(x);
2584 }
2585}
2586
2587
2588void Assembler::emit_operand(Register reg, const Operand& adr) {
2589 const unsigned length = adr.len_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002590 DCHECK(length > 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002591
2592 // Emit updated ModRM byte containing the given register.
2593 pc_[0] = (adr.buf_[0] & ~0x38) | (reg.code() << 3);
2594
2595 // Emit the rest of the encoded operand.
2596 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
2597 pc_ += length;
2598
2599 // Emit relocation information if necessary.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002600 if (length >= sizeof(int32_t) && !RelocInfo::IsNone(adr.rmode_)) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002601 pc_ -= sizeof(int32_t); // pc_ must be *at* disp32
2602 RecordRelocInfo(adr.rmode_);
2603 pc_ += sizeof(int32_t);
2604 }
2605}
2606
2607
2608void Assembler::emit_farith(int b1, int b2, int i) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002609 DCHECK(is_uint8(b1) && is_uint8(b2)); // wrong opcode
2610 DCHECK(0 <= i && i < 8); // illegal stack offset
Steve Blocka7e24c12009-10-30 11:49:00 +00002611 EMIT(b1);
2612 EMIT(b2 + i);
2613}
2614
2615
Ben Murdochb0fe1622011-05-05 13:52:32 +01002616void Assembler::db(uint8_t data) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002617 EnsureSpace ensure_space(this);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002618 EMIT(data);
2619}
2620
2621
2622void Assembler::dd(uint32_t data) {
2623 EnsureSpace ensure_space(this);
2624 emit(data);
Steve Blocka7e24c12009-10-30 11:49:00 +00002625}
2626
2627
2628void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002629 DCHECK(!RelocInfo::IsNone(rmode));
Steve Blocka7e24c12009-10-30 11:49:00 +00002630 // Don't record external references unless the heap will be serialized.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002631 if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
2632 !serializer_enabled() && !emit_debug_code()) {
2633 return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002634 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002635 RelocInfo rinfo(pc_, rmode, data, NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +00002636 reloc_info_writer.Write(&rinfo);
2637}
2638
2639
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002640Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
2641 // No out-of-line constant pool support.
2642 DCHECK(!FLAG_enable_ool_constant_pool);
2643 return isolate->factory()->empty_constant_pool_array();
2644}
2645
2646
2647void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
2648 // No out-of-line constant pool support.
2649 DCHECK(!FLAG_enable_ool_constant_pool);
2650 return;
2651}
2652
2653
Steve Blocka7e24c12009-10-30 11:49:00 +00002654#ifdef GENERATED_CODE_COVERAGE
2655static FILE* coverage_log = NULL;
2656
2657
2658static void InitCoverageLog() {
2659 char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
2660 if (file_name != NULL) {
2661 coverage_log = fopen(file_name, "aw+");
2662 }
2663}
2664
2665
2666void LogGeneratedCodeCoverage(const char* file_line) {
2667 const char* return_address = (&file_line)[-1];
2668 char* push_insn = const_cast<char*>(return_address - 12);
2669 push_insn[0] = 0xeb; // Relative branch insn.
2670 push_insn[1] = 13; // Skip over coverage insns.
2671 if (coverage_log != NULL) {
2672 fprintf(coverage_log, "%s\n", file_line);
2673 fflush(coverage_log);
2674 }
2675}
2676
2677#endif
2678
2679} } // namespace v8::internal
Leon Clarkef7060e22010-06-03 12:02:55 +01002680
2681#endif // V8_TARGET_ARCH_IA32