1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/v8.h" 6 7 #if V8_TARGET_ARCH_X64 8 9 #include "src/base/bits.h" 10 #include "src/macro-assembler.h" 11 #include "src/serialize.h" 12 13 namespace v8 { 14 namespace internal { 15 16 // ----------------------------------------------------------------------------- 17 // Implementation of CpuFeatures 18 19 void CpuFeatures::ProbeImpl(bool cross_compile) { 20 base::CPU cpu; 21 CHECK(cpu.has_sse2()); // SSE2 support is mandatory. 22 CHECK(cpu.has_cmov()); // CMOV support is mandatory. 23 24 // Only use statically determined features for cross compile (snapshot). 25 if (cross_compile) return; 26 27 if (cpu.has_sse41() && FLAG_enable_sse4_1) supported_ |= 1u << SSE4_1; 28 if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3; 29 // SAHF is not generally available in long mode. 30 if (cpu.has_sahf() && FLAG_enable_sahf) supported_|= 1u << SAHF; 31 } 32 33 34 void CpuFeatures::PrintTarget() { } 35 void CpuFeatures::PrintFeatures() { } 36 37 38 // ----------------------------------------------------------------------------- 39 // Implementation of RelocInfo 40 41 // Patch the code at the current PC with a call to the target address. 42 // Additional guard int3 instructions can be added if required. 43 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { 44 int code_size = Assembler::kCallSequenceLength + guard_bytes; 45 46 // Create a code patcher. 47 CodePatcher patcher(pc_, code_size); 48 49 // Add a label for checking the size of the code used for returning. 50 #ifdef DEBUG 51 Label check_codesize; 52 patcher.masm()->bind(&check_codesize); 53 #endif 54 55 // Patch the code. 56 patcher.masm()->movp(kScratchRegister, reinterpret_cast<void*>(target), 57 Assembler::RelocInfoNone()); 58 patcher.masm()->call(kScratchRegister); 59 60 // Check that the size of the code generated is as expected. 61 DCHECK_EQ(Assembler::kCallSequenceLength, 62 patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize)); 63 64 // Add the requested number of int3 instructions after the call. 65 for (int i = 0; i < guard_bytes; i++) { 66 patcher.masm()->int3(); 67 } 68 } 69 70 71 void RelocInfo::PatchCode(byte* instructions, int instruction_count) { 72 // Patch the code at the current address with the supplied instructions. 73 for (int i = 0; i < instruction_count; i++) { 74 *(pc_ + i) = *(instructions + i); 75 } 76 77 // Indicate that code has changed. 78 CpuFeatures::FlushICache(pc_, instruction_count); 79 } 80 81 82 // ----------------------------------------------------------------------------- 83 // Register constants. 84 85 const int 86 Register::kRegisterCodeByAllocationIndex[kMaxNumAllocatableRegisters] = { 87 // rax, rbx, rdx, rcx, rsi, rdi, r8, r9, r11, r14, r15 88 0, 3, 2, 1, 6, 7, 8, 9, 11, 14, 15 89 }; 90 91 const int Register::kAllocationIndexByRegisterCode[kNumRegisters] = { 92 0, 3, 2, 1, -1, -1, 4, 5, 6, 7, -1, 8, -1, -1, 9, 10 93 }; 94 95 96 // ----------------------------------------------------------------------------- 97 // Implementation of Operand 98 99 Operand::Operand(Register base, int32_t disp) : rex_(0) { 100 len_ = 1; 101 if (base.is(rsp) || base.is(r12)) { 102 // SIB byte is needed to encode (rsp + offset) or (r12 + offset). 103 set_sib(times_1, rsp, base); 104 } 105 106 if (disp == 0 && !base.is(rbp) && !base.is(r13)) { 107 set_modrm(0, base); 108 } else if (is_int8(disp)) { 109 set_modrm(1, base); 110 set_disp8(disp); 111 } else { 112 set_modrm(2, base); 113 set_disp32(disp); 114 } 115 } 116 117 118 Operand::Operand(Register base, 119 Register index, 120 ScaleFactor scale, 121 int32_t disp) : rex_(0) { 122 DCHECK(!index.is(rsp)); 123 len_ = 1; 124 set_sib(scale, index, base); 125 if (disp == 0 && !base.is(rbp) && !base.is(r13)) { 126 // This call to set_modrm doesn't overwrite the REX.B (or REX.X) bits 127 // possibly set by set_sib. 128 set_modrm(0, rsp); 129 } else if (is_int8(disp)) { 130 set_modrm(1, rsp); 131 set_disp8(disp); 132 } else { 133 set_modrm(2, rsp); 134 set_disp32(disp); 135 } 136 } 137 138 139 Operand::Operand(Register index, 140 ScaleFactor scale, 141 int32_t disp) : rex_(0) { 142 DCHECK(!index.is(rsp)); 143 len_ = 1; 144 set_modrm(0, rsp); 145 set_sib(scale, index, rbp); 146 set_disp32(disp); 147 } 148 149 150 Operand::Operand(const Operand& operand, int32_t offset) { 151 DCHECK(operand.len_ >= 1); 152 // Operand encodes REX ModR/M [SIB] [Disp]. 153 byte modrm = operand.buf_[0]; 154 DCHECK(modrm < 0xC0); // Disallow mode 3 (register target). 155 bool has_sib = ((modrm & 0x07) == 0x04); 156 byte mode = modrm & 0xC0; 157 int disp_offset = has_sib ? 2 : 1; 158 int base_reg = (has_sib ? operand.buf_[1] : modrm) & 0x07; 159 // Mode 0 with rbp/r13 as ModR/M or SIB base register always has a 32-bit 160 // displacement. 161 bool is_baseless = (mode == 0) && (base_reg == 0x05); // No base or RIP base. 162 int32_t disp_value = 0; 163 if (mode == 0x80 || is_baseless) { 164 // Mode 2 or mode 0 with rbp/r13 as base: Word displacement. 165 disp_value = *bit_cast<const int32_t*>(&operand.buf_[disp_offset]); 166 } else if (mode == 0x40) { 167 // Mode 1: Byte displacement. 168 disp_value = static_cast<signed char>(operand.buf_[disp_offset]); 169 } 170 171 // Write new operand with same registers, but with modified displacement. 172 DCHECK(offset >= 0 ? disp_value + offset > disp_value 173 : disp_value + offset < disp_value); // No overflow. 174 disp_value += offset; 175 rex_ = operand.rex_; 176 if (!is_int8(disp_value) || is_baseless) { 177 // Need 32 bits of displacement, mode 2 or mode 1 with register rbp/r13. 178 buf_[0] = (modrm & 0x3f) | (is_baseless ? 0x00 : 0x80); 179 len_ = disp_offset + 4; 180 Memory::int32_at(&buf_[disp_offset]) = disp_value; 181 } else if (disp_value != 0 || (base_reg == 0x05)) { 182 // Need 8 bits of displacement. 183 buf_[0] = (modrm & 0x3f) | 0x40; // Mode 1. 184 len_ = disp_offset + 1; 185 buf_[disp_offset] = static_cast<byte>(disp_value); 186 } else { 187 // Need no displacement. 188 buf_[0] = (modrm & 0x3f); // Mode 0. 189 len_ = disp_offset; 190 } 191 if (has_sib) { 192 buf_[1] = operand.buf_[1]; 193 } 194 } 195 196 197 bool Operand::AddressUsesRegister(Register reg) const { 198 int code = reg.code(); 199 DCHECK((buf_[0] & 0xC0) != 0xC0); // Always a memory operand. 200 // Start with only low three bits of base register. Initial decoding doesn't 201 // distinguish on the REX.B bit. 202 int base_code = buf_[0] & 0x07; 203 if (base_code == rsp.code()) { 204 // SIB byte present in buf_[1]. 205 // Check the index register from the SIB byte + REX.X prefix. 206 int index_code = ((buf_[1] >> 3) & 0x07) | ((rex_ & 0x02) << 2); 207 // Index code (including REX.X) of 0x04 (rsp) means no index register. 208 if (index_code != rsp.code() && index_code == code) return true; 209 // Add REX.B to get the full base register code. 210 base_code = (buf_[1] & 0x07) | ((rex_ & 0x01) << 3); 211 // A base register of 0x05 (rbp) with mod = 0 means no base register. 212 if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false; 213 return code == base_code; 214 } else { 215 // A base register with low bits of 0x05 (rbp or r13) and mod = 0 means 216 // no base register. 217 if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false; 218 base_code |= ((rex_ & 0x01) << 3); 219 return code == base_code; 220 } 221 } 222 223 224 // ----------------------------------------------------------------------------- 225 // Implementation of Assembler. 226 227 #ifdef GENERATED_CODE_COVERAGE 228 static void InitCoverageLog(); 229 #endif 230 231 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) 232 : AssemblerBase(isolate, buffer, buffer_size), 233 code_targets_(100), 234 positions_recorder_(this) { 235 // Clear the buffer in debug mode unless it was provided by the 236 // caller in which case we can't be sure it's okay to overwrite 237 // existing code in it. 238 #ifdef DEBUG 239 if (own_buffer_) { 240 memset(buffer_, 0xCC, buffer_size_); // int3 241 } 242 #endif 243 244 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); 245 246 247 #ifdef GENERATED_CODE_COVERAGE 248 InitCoverageLog(); 249 #endif 250 } 251 252 253 void Assembler::GetCode(CodeDesc* desc) { 254 // Finalize code (at this point overflow() may be true, but the gap ensures 255 // that we are still not overlapping instructions and relocation info). 256 DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap. 257 // Set up code descriptor. 258 desc->buffer = buffer_; 259 desc->buffer_size = buffer_size_; 260 desc->instr_size = pc_offset(); 261 DCHECK(desc->instr_size > 0); // Zero-size code objects upset the system. 262 desc->reloc_size = 263 static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos()); 264 desc->origin = this; 265 } 266 267 268 void Assembler::Align(int m) { 269 DCHECK(base::bits::IsPowerOfTwo32(m)); 270 int delta = (m - (pc_offset() & (m - 1))) & (m - 1); 271 Nop(delta); 272 } 273 274 275 void Assembler::CodeTargetAlign() { 276 Align(16); // Preferred alignment of jump targets on x64. 277 } 278 279 280 bool Assembler::IsNop(Address addr) { 281 Address a = addr; 282 while (*a == 0x66) a++; 283 if (*a == 0x90) return true; 284 if (a[0] == 0xf && a[1] == 0x1f) return true; 285 return false; 286 } 287 288 289 void Assembler::bind_to(Label* L, int pos) { 290 DCHECK(!L->is_bound()); // Label may only be bound once. 291 DCHECK(0 <= pos && pos <= pc_offset()); // Position must be valid. 292 if (L->is_linked()) { 293 int current = L->pos(); 294 int next = long_at(current); 295 while (next != current) { 296 // Relative address, relative to point after address. 297 int imm32 = pos - (current + sizeof(int32_t)); 298 long_at_put(current, imm32); 299 current = next; 300 next = long_at(next); 301 } 302 // Fix up last fixup on linked list. 303 int last_imm32 = pos - (current + sizeof(int32_t)); 304 long_at_put(current, last_imm32); 305 } 306 while (L->is_near_linked()) { 307 int fixup_pos = L->near_link_pos(); 308 int offset_to_next = 309 static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos))); 310 DCHECK(offset_to_next <= 0); 311 int disp = pos - (fixup_pos + sizeof(int8_t)); 312 CHECK(is_int8(disp)); 313 set_byte_at(fixup_pos, disp); 314 if (offset_to_next < 0) { 315 L->link_to(fixup_pos + offset_to_next, Label::kNear); 316 } else { 317 L->UnuseNear(); 318 } 319 } 320 L->bind_to(pos); 321 } 322 323 324 void Assembler::bind(Label* L) { 325 bind_to(L, pc_offset()); 326 } 327 328 329 void Assembler::GrowBuffer() { 330 DCHECK(buffer_overflow()); 331 if (!own_buffer_) FATAL("external code buffer is too small"); 332 333 // Compute new buffer size. 334 CodeDesc desc; // the new buffer 335 desc.buffer_size = 2 * buffer_size_; 336 337 // Some internal data structures overflow for very large buffers, 338 // they must ensure that kMaximalBufferSize is not too large. 339 if ((desc.buffer_size > kMaximalBufferSize) || 340 (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) { 341 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer"); 342 } 343 344 // Set up new buffer. 345 desc.buffer = NewArray<byte>(desc.buffer_size); 346 desc.instr_size = pc_offset(); 347 desc.reloc_size = 348 static_cast<int>((buffer_ + buffer_size_) - (reloc_info_writer.pos())); 349 350 // Clear the buffer in debug mode. Use 'int3' instructions to make 351 // sure to get into problems if we ever run uninitialized code. 352 #ifdef DEBUG 353 memset(desc.buffer, 0xCC, desc.buffer_size); 354 #endif 355 356 // Copy the data. 357 intptr_t pc_delta = desc.buffer - buffer_; 358 intptr_t rc_delta = (desc.buffer + desc.buffer_size) - 359 (buffer_ + buffer_size_); 360 MemMove(desc.buffer, buffer_, desc.instr_size); 361 MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(), 362 desc.reloc_size); 363 364 // Switch buffers. 365 DeleteArray(buffer_); 366 buffer_ = desc.buffer; 367 buffer_size_ = desc.buffer_size; 368 pc_ += pc_delta; 369 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, 370 reloc_info_writer.last_pc() + pc_delta); 371 372 // Relocate runtime entries. 373 for (RelocIterator it(desc); !it.done(); it.next()) { 374 RelocInfo::Mode rmode = it.rinfo()->rmode(); 375 if (rmode == RelocInfo::INTERNAL_REFERENCE) { 376 intptr_t* p = reinterpret_cast<intptr_t*>(it.rinfo()->pc()); 377 if (*p != 0) { // 0 means uninitialized. 378 *p += pc_delta; 379 } 380 } 381 } 382 383 DCHECK(!buffer_overflow()); 384 } 385 386 387 void Assembler::emit_operand(int code, const Operand& adr) { 388 DCHECK(is_uint3(code)); 389 const unsigned length = adr.len_; 390 DCHECK(length > 0); 391 392 // Emit updated ModR/M byte containing the given register. 393 DCHECK((adr.buf_[0] & 0x38) == 0); 394 pc_[0] = adr.buf_[0] | code << 3; 395 396 // Emit the rest of the encoded operand. 397 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; 398 pc_ += length; 399 } 400 401 402 // Assembler Instruction implementations. 403 404 void Assembler::arithmetic_op(byte opcode, 405 Register reg, 406 const Operand& op, 407 int size) { 408 EnsureSpace ensure_space(this); 409 emit_rex(reg, op, size); 410 emit(opcode); 411 emit_operand(reg, op); 412 } 413 414 415 void Assembler::arithmetic_op(byte opcode, 416 Register reg, 417 Register rm_reg, 418 int size) { 419 EnsureSpace ensure_space(this); 420 DCHECK((opcode & 0xC6) == 2); 421 if (rm_reg.low_bits() == 4) { // Forces SIB byte. 422 // Swap reg and rm_reg and change opcode operand order. 423 emit_rex(rm_reg, reg, size); 424 emit(opcode ^ 0x02); 425 emit_modrm(rm_reg, reg); 426 } else { 427 emit_rex(reg, rm_reg, size); 428 emit(opcode); 429 emit_modrm(reg, rm_reg); 430 } 431 } 432 433 434 void Assembler::arithmetic_op_16(byte opcode, Register reg, Register rm_reg) { 435 EnsureSpace ensure_space(this); 436 DCHECK((opcode & 0xC6) == 2); 437 if (rm_reg.low_bits() == 4) { // Forces SIB byte. 438 // Swap reg and rm_reg and change opcode operand order. 439 emit(0x66); 440 emit_optional_rex_32(rm_reg, reg); 441 emit(opcode ^ 0x02); 442 emit_modrm(rm_reg, reg); 443 } else { 444 emit(0x66); 445 emit_optional_rex_32(reg, rm_reg); 446 emit(opcode); 447 emit_modrm(reg, rm_reg); 448 } 449 } 450 451 452 void Assembler::arithmetic_op_16(byte opcode, 453 Register reg, 454 const Operand& rm_reg) { 455 EnsureSpace ensure_space(this); 456 emit(0x66); 457 emit_optional_rex_32(reg, rm_reg); 458 emit(opcode); 459 emit_operand(reg, rm_reg); 460 } 461 462 463 void Assembler::arithmetic_op_8(byte opcode, Register reg, const Operand& op) { 464 EnsureSpace ensure_space(this); 465 if (!reg.is_byte_register()) { 466 // Register is not one of al, bl, cl, dl. Its encoding needs REX. 467 emit_rex_32(reg); 468 } 469 emit(opcode); 470 emit_operand(reg, op); 471 } 472 473 474 void Assembler::arithmetic_op_8(byte opcode, Register reg, Register rm_reg) { 475 EnsureSpace ensure_space(this); 476 DCHECK((opcode & 0xC6) == 2); 477 if (rm_reg.low_bits() == 4) { // Forces SIB byte. 478 // Swap reg and rm_reg and change opcode operand order. 479 if (!rm_reg.is_byte_register() || !reg.is_byte_register()) { 480 // Register is not one of al, bl, cl, dl. Its encoding needs REX. 481 emit_rex_32(rm_reg, reg); 482 } 483 emit(opcode ^ 0x02); 484 emit_modrm(rm_reg, reg); 485 } else { 486 if (!reg.is_byte_register() || !rm_reg.is_byte_register()) { 487 // Register is not one of al, bl, cl, dl. Its encoding needs REX. 488 emit_rex_32(reg, rm_reg); 489 } 490 emit(opcode); 491 emit_modrm(reg, rm_reg); 492 } 493 } 494 495 496 void Assembler::immediate_arithmetic_op(byte subcode, 497 Register dst, 498 Immediate src, 499 int size) { 500 EnsureSpace ensure_space(this); 501 emit_rex(dst, size); 502 if (is_int8(src.value_)) { 503 emit(0x83); 504 emit_modrm(subcode, dst); 505 emit(src.value_); 506 } else if (dst.is(rax)) { 507 emit(0x05 | (subcode << 3)); 508 emitl(src.value_); 509 } else { 510 emit(0x81); 511 emit_modrm(subcode, dst); 512 emitl(src.value_); 513 } 514 } 515 516 void Assembler::immediate_arithmetic_op(byte subcode, 517 const Operand& dst, 518 Immediate src, 519 int size) { 520 EnsureSpace ensure_space(this); 521 emit_rex(dst, size); 522 if (is_int8(src.value_)) { 523 emit(0x83); 524 emit_operand(subcode, dst); 525 emit(src.value_); 526 } else { 527 emit(0x81); 528 emit_operand(subcode, dst); 529 emitl(src.value_); 530 } 531 } 532 533 534 void Assembler::immediate_arithmetic_op_16(byte subcode, 535 Register dst, 536 Immediate src) { 537 EnsureSpace ensure_space(this); 538 emit(0x66); // Operand size override prefix. 539 emit_optional_rex_32(dst); 540 if (is_int8(src.value_)) { 541 emit(0x83); 542 emit_modrm(subcode, dst); 543 emit(src.value_); 544 } else if (dst.is(rax)) { 545 emit(0x05 | (subcode << 3)); 546 emitw(src.value_); 547 } else { 548 emit(0x81); 549 emit_modrm(subcode, dst); 550 emitw(src.value_); 551 } 552 } 553 554 555 void Assembler::immediate_arithmetic_op_16(byte subcode, 556 const Operand& dst, 557 Immediate src) { 558 EnsureSpace ensure_space(this); 559 emit(0x66); // Operand size override prefix. 560 emit_optional_rex_32(dst); 561 if (is_int8(src.value_)) { 562 emit(0x83); 563 emit_operand(subcode, dst); 564 emit(src.value_); 565 } else { 566 emit(0x81); 567 emit_operand(subcode, dst); 568 emitw(src.value_); 569 } 570 } 571 572 573 void Assembler::immediate_arithmetic_op_8(byte subcode, 574 const Operand& dst, 575 Immediate src) { 576 EnsureSpace ensure_space(this); 577 emit_optional_rex_32(dst); 578 DCHECK(is_int8(src.value_) || is_uint8(src.value_)); 579 emit(0x80); 580 emit_operand(subcode, dst); 581 emit(src.value_); 582 } 583 584 585 void Assembler::immediate_arithmetic_op_8(byte subcode, 586 Register dst, 587 Immediate src) { 588 EnsureSpace ensure_space(this); 589 if (!dst.is_byte_register()) { 590 // Register is not one of al, bl, cl, dl. Its encoding needs REX. 591 emit_rex_32(dst); 592 } 593 DCHECK(is_int8(src.value_) || is_uint8(src.value_)); 594 emit(0x80); 595 emit_modrm(subcode, dst); 596 emit(src.value_); 597 } 598 599 600 void Assembler::shift(Register dst, 601 Immediate shift_amount, 602 int subcode, 603 int size) { 604 EnsureSpace ensure_space(this); 605 DCHECK(size == kInt64Size ? is_uint6(shift_amount.value_) 606 : is_uint5(shift_amount.value_)); 607 if (shift_amount.value_ == 1) { 608 emit_rex(dst, size); 609 emit(0xD1); 610 emit_modrm(subcode, dst); 611 } else { 612 emit_rex(dst, size); 613 emit(0xC1); 614 emit_modrm(subcode, dst); 615 emit(shift_amount.value_); 616 } 617 } 618 619 620 void Assembler::shift(Register dst, int subcode, int size) { 621 EnsureSpace ensure_space(this); 622 emit_rex(dst, size); 623 emit(0xD3); 624 emit_modrm(subcode, dst); 625 } 626 627 628 void Assembler::bt(const Operand& dst, Register src) { 629 EnsureSpace ensure_space(this); 630 emit_rex_64(src, dst); 631 emit(0x0F); 632 emit(0xA3); 633 emit_operand(src, dst); 634 } 635 636 637 void Assembler::bts(const Operand& dst, Register src) { 638 EnsureSpace ensure_space(this); 639 emit_rex_64(src, dst); 640 emit(0x0F); 641 emit(0xAB); 642 emit_operand(src, dst); 643 } 644 645 646 void Assembler::bsrl(Register dst, Register src) { 647 EnsureSpace ensure_space(this); 648 emit_optional_rex_32(dst, src); 649 emit(0x0F); 650 emit(0xBD); 651 emit_modrm(dst, src); 652 } 653 654 655 void Assembler::call(Label* L) { 656 positions_recorder()->WriteRecordedPositions(); 657 EnsureSpace ensure_space(this); 658 // 1110 1000 #32-bit disp. 659 emit(0xE8); 660 if (L->is_bound()) { 661 int offset = L->pos() - pc_offset() - sizeof(int32_t); 662 DCHECK(offset <= 0); 663 emitl(offset); 664 } else if (L->is_linked()) { 665 emitl(L->pos()); 666 L->link_to(pc_offset() - sizeof(int32_t)); 667 } else { 668 DCHECK(L->is_unused()); 669 int32_t current = pc_offset(); 670 emitl(current); 671 L->link_to(current); 672 } 673 } 674 675 676 void Assembler::call(Address entry, RelocInfo::Mode rmode) { 677 DCHECK(RelocInfo::IsRuntimeEntry(rmode)); 678 positions_recorder()->WriteRecordedPositions(); 679 EnsureSpace ensure_space(this); 680 // 1110 1000 #32-bit disp. 681 emit(0xE8); 682 emit_runtime_entry(entry, rmode); 683 } 684 685 686 void Assembler::call(Handle<Code> target, 687 RelocInfo::Mode rmode, 688 TypeFeedbackId ast_id) { 689 positions_recorder()->WriteRecordedPositions(); 690 EnsureSpace ensure_space(this); 691 // 1110 1000 #32-bit disp. 692 emit(0xE8); 693 emit_code_target(target, rmode, ast_id); 694 } 695 696 697 void Assembler::call(Register adr) { 698 positions_recorder()->WriteRecordedPositions(); 699 EnsureSpace ensure_space(this); 700 // Opcode: FF /2 r64. 701 emit_optional_rex_32(adr); 702 emit(0xFF); 703 emit_modrm(0x2, adr); 704 } 705 706 707 void Assembler::call(const Operand& op) { 708 positions_recorder()->WriteRecordedPositions(); 709 EnsureSpace ensure_space(this); 710 // Opcode: FF /2 m64. 711 emit_optional_rex_32(op); 712 emit(0xFF); 713 emit_operand(0x2, op); 714 } 715 716 717 // Calls directly to the given address using a relative offset. 718 // Should only ever be used in Code objects for calls within the 719 // same Code object. Should not be used when generating new code (use labels), 720 // but only when patching existing code. 721 void Assembler::call(Address target) { 722 positions_recorder()->WriteRecordedPositions(); 723 EnsureSpace ensure_space(this); 724 // 1110 1000 #32-bit disp. 725 emit(0xE8); 726 Address source = pc_ + 4; 727 intptr_t displacement = target - source; 728 DCHECK(is_int32(displacement)); 729 emitl(static_cast<int32_t>(displacement)); 730 } 731 732 733 void Assembler::clc() { 734 EnsureSpace ensure_space(this); 735 emit(0xF8); 736 } 737 738 739 void Assembler::cld() { 740 EnsureSpace ensure_space(this); 741 emit(0xFC); 742 } 743 744 745 void Assembler::cdq() { 746 EnsureSpace ensure_space(this); 747 emit(0x99); 748 } 749 750 751 void Assembler::cmovq(Condition cc, Register dst, Register src) { 752 if (cc == always) { 753 movq(dst, src); 754 } else if (cc == never) { 755 return; 756 } 757 // No need to check CpuInfo for CMOV support, it's a required part of the 758 // 64-bit architecture. 759 DCHECK(cc >= 0); // Use mov for unconditional moves. 760 EnsureSpace ensure_space(this); 761 // Opcode: REX.W 0f 40 + cc /r. 762 emit_rex_64(dst, src); 763 emit(0x0f); 764 emit(0x40 + cc); 765 emit_modrm(dst, src); 766 } 767 768 769 void Assembler::cmovq(Condition cc, Register dst, const Operand& src) { 770 if (cc == always) { 771 movq(dst, src); 772 } else if (cc == never) { 773 return; 774 } 775 DCHECK(cc >= 0); 776 EnsureSpace ensure_space(this); 777 // Opcode: REX.W 0f 40 + cc /r. 778 emit_rex_64(dst, src); 779 emit(0x0f); 780 emit(0x40 + cc); 781 emit_operand(dst, src); 782 } 783 784 785 void Assembler::cmovl(Condition cc, Register dst, Register src) { 786 if (cc == always) { 787 movl(dst, src); 788 } else if (cc == never) { 789 return; 790 } 791 DCHECK(cc >= 0); 792 EnsureSpace ensure_space(this); 793 // Opcode: 0f 40 + cc /r. 794 emit_optional_rex_32(dst, src); 795 emit(0x0f); 796 emit(0x40 + cc); 797 emit_modrm(dst, src); 798 } 799 800 801 void Assembler::cmovl(Condition cc, Register dst, const Operand& src) { 802 if (cc == always) { 803 movl(dst, src); 804 } else if (cc == never) { 805 return; 806 } 807 DCHECK(cc >= 0); 808 EnsureSpace ensure_space(this); 809 // Opcode: 0f 40 + cc /r. 810 emit_optional_rex_32(dst, src); 811 emit(0x0f); 812 emit(0x40 + cc); 813 emit_operand(dst, src); 814 } 815 816 817 void Assembler::cmpb_al(Immediate imm8) { 818 DCHECK(is_int8(imm8.value_) || is_uint8(imm8.value_)); 819 EnsureSpace ensure_space(this); 820 emit(0x3c); 821 emit(imm8.value_); 822 } 823 824 825 void Assembler::cpuid() { 826 EnsureSpace ensure_space(this); 827 emit(0x0F); 828 emit(0xA2); 829 } 830 831 832 void Assembler::cqo() { 833 EnsureSpace ensure_space(this); 834 emit_rex_64(); 835 emit(0x99); 836 } 837 838 839 void Assembler::emit_dec(Register dst, int size) { 840 EnsureSpace ensure_space(this); 841 emit_rex(dst, size); 842 emit(0xFF); 843 emit_modrm(0x1, dst); 844 } 845 846 847 void Assembler::emit_dec(const Operand& dst, int size) { 848 EnsureSpace ensure_space(this); 849 emit_rex(dst, size); 850 emit(0xFF); 851 emit_operand(1, dst); 852 } 853 854 855 void Assembler::decb(Register dst) { 856 EnsureSpace ensure_space(this); 857 if (!dst.is_byte_register()) { 858 // Register is not one of al, bl, cl, dl. Its encoding needs REX. 859 emit_rex_32(dst); 860 } 861 emit(0xFE); 862 emit_modrm(0x1, dst); 863 } 864 865 866 void Assembler::decb(const Operand& dst) { 867 EnsureSpace ensure_space(this); 868 emit_optional_rex_32(dst); 869 emit(0xFE); 870 emit_operand(1, dst); 871 } 872 873 874 void Assembler::enter(Immediate size) { 875 EnsureSpace ensure_space(this); 876 emit(0xC8); 877 emitw(size.value_); // 16 bit operand, always. 878 emit(0); 879 } 880 881 882 void Assembler::hlt() { 883 EnsureSpace ensure_space(this); 884 emit(0xF4); 885 } 886 887 888 void Assembler::emit_idiv(Register src, int size) { 889 EnsureSpace ensure_space(this); 890 emit_rex(src, size); 891 emit(0xF7); 892 emit_modrm(0x7, src); 893 } 894 895 896 void Assembler::emit_div(Register src, int size) { 897 EnsureSpace ensure_space(this); 898 emit_rex(src, size); 899 emit(0xF7); 900 emit_modrm(0x6, src); 901 } 902 903 904 void Assembler::emit_imul(Register src, int size) { 905 EnsureSpace ensure_space(this); 906 emit_rex(src, size); 907 emit(0xF7); 908 emit_modrm(0x5, src); 909 } 910 911 912 void Assembler::emit_imul(Register dst, Register src, int size) { 913 EnsureSpace ensure_space(this); 914 emit_rex(dst, src, size); 915 emit(0x0F); 916 emit(0xAF); 917 emit_modrm(dst, src); 918 } 919 920 921 void Assembler::emit_imul(Register dst, const Operand& src, int size) { 922 EnsureSpace ensure_space(this); 923 emit_rex(dst, src, size); 924 emit(0x0F); 925 emit(0xAF); 926 emit_operand(dst, src); 927 } 928 929 930 void Assembler::emit_imul(Register dst, Register src, Immediate imm, int size) { 931 EnsureSpace ensure_space(this); 932 emit_rex(dst, src, size); 933 if (is_int8(imm.value_)) { 934 emit(0x6B); 935 emit_modrm(dst, src); 936 emit(imm.value_); 937 } else { 938 emit(0x69); 939 emit_modrm(dst, src); 940 emitl(imm.value_); 941 } 942 } 943 944 945 void Assembler::emit_inc(Register dst, int size) { 946 EnsureSpace ensure_space(this); 947 emit_rex(dst, size); 948 emit(0xFF); 949 emit_modrm(0x0, dst); 950 } 951 952 953 void Assembler::emit_inc(const Operand& dst, int size) { 954 EnsureSpace ensure_space(this); 955 emit_rex(dst, size); 956 emit(0xFF); 957 emit_operand(0, dst); 958 } 959 960 961 void Assembler::int3() { 962 EnsureSpace ensure_space(this); 963 emit(0xCC); 964 } 965 966 967 void Assembler::j(Condition cc, Label* L, Label::Distance distance) { 968 if (cc == always) { 969 jmp(L); 970 return; 971 } else if (cc == never) { 972 return; 973 } 974 EnsureSpace ensure_space(this); 975 DCHECK(is_uint4(cc)); 976 if (L->is_bound()) { 977 const int short_size = 2; 978 const int long_size = 6; 979 int offs = L->pos() - pc_offset(); 980 DCHECK(offs <= 0); 981 // Determine whether we can use 1-byte offsets for backwards branches, 982 // which have a max range of 128 bytes. 983 984 // We also need to check predictable_code_size() flag here, because on x64, 985 // when the full code generator recompiles code for debugging, some places 986 // need to be padded out to a certain size. The debugger is keeping track of 987 // how often it did this so that it can adjust return addresses on the 988 // stack, but if the size of jump instructions can also change, that's not 989 // enough and the calculated offsets would be incorrect. 990 if (is_int8(offs - short_size) && !predictable_code_size()) { 991 // 0111 tttn #8-bit disp. 992 emit(0x70 | cc); 993 emit((offs - short_size) & 0xFF); 994 } else { 995 // 0000 1111 1000 tttn #32-bit disp. 996 emit(0x0F); 997 emit(0x80 | cc); 998 emitl(offs - long_size); 999 } 1000 } else if (distance == Label::kNear) { 1001 // 0111 tttn #8-bit disp 1002 emit(0x70 | cc); 1003 byte disp = 0x00; 1004 if (L->is_near_linked()) { 1005 int offset = L->near_link_pos() - pc_offset(); 1006 DCHECK(is_int8(offset)); 1007 disp = static_cast<byte>(offset & 0xFF); 1008 } 1009 L->link_to(pc_offset(), Label::kNear); 1010 emit(disp); 1011 } else if (L->is_linked()) { 1012 // 0000 1111 1000 tttn #32-bit disp. 1013 emit(0x0F); 1014 emit(0x80 | cc); 1015 emitl(L->pos()); 1016 L->link_to(pc_offset() - sizeof(int32_t)); 1017 } else { 1018 DCHECK(L->is_unused()); 1019 emit(0x0F); 1020 emit(0x80 | cc); 1021 int32_t current = pc_offset(); 1022 emitl(current); 1023 L->link_to(current); 1024 } 1025 } 1026 1027 1028 void Assembler::j(Condition cc, Address entry, RelocInfo::Mode rmode) { 1029 DCHECK(RelocInfo::IsRuntimeEntry(rmode)); 1030 EnsureSpace ensure_space(this); 1031 DCHECK(is_uint4(cc)); 1032 emit(0x0F); 1033 emit(0x80 | cc); 1034 emit_runtime_entry(entry, rmode); 1035 } 1036 1037 1038 void Assembler::j(Condition cc, 1039 Handle<Code> target, 1040 RelocInfo::Mode rmode) { 1041 EnsureSpace ensure_space(this); 1042 DCHECK(is_uint4(cc)); 1043 // 0000 1111 1000 tttn #32-bit disp. 1044 emit(0x0F); 1045 emit(0x80 | cc); 1046 emit_code_target(target, rmode); 1047 } 1048 1049 1050 void Assembler::jmp(Label* L, Label::Distance distance) { 1051 EnsureSpace ensure_space(this); 1052 const int short_size = sizeof(int8_t); 1053 const int long_size = sizeof(int32_t); 1054 if (L->is_bound()) { 1055 int offs = L->pos() - pc_offset() - 1; 1056 DCHECK(offs <= 0); 1057 if (is_int8(offs - short_size) && !predictable_code_size()) { 1058 // 1110 1011 #8-bit disp. 1059 emit(0xEB); 1060 emit((offs - short_size) & 0xFF); 1061 } else { 1062 // 1110 1001 #32-bit disp. 1063 emit(0xE9); 1064 emitl(offs - long_size); 1065 } 1066 } else if (distance == Label::kNear) { 1067 emit(0xEB); 1068 byte disp = 0x00; 1069 if (L->is_near_linked()) { 1070 int offset = L->near_link_pos() - pc_offset(); 1071 DCHECK(is_int8(offset)); 1072 disp = static_cast<byte>(offset & 0xFF); 1073 } 1074 L->link_to(pc_offset(), Label::kNear); 1075 emit(disp); 1076 } else if (L->is_linked()) { 1077 // 1110 1001 #32-bit disp. 1078 emit(0xE9); 1079 emitl(L->pos()); 1080 L->link_to(pc_offset() - long_size); 1081 } else { 1082 // 1110 1001 #32-bit disp. 1083 DCHECK(L->is_unused()); 1084 emit(0xE9); 1085 int32_t current = pc_offset(); 1086 emitl(current); 1087 L->link_to(current); 1088 } 1089 } 1090 1091 1092 void Assembler::jmp(Handle<Code> target, RelocInfo::Mode rmode) { 1093 EnsureSpace ensure_space(this); 1094 // 1110 1001 #32-bit disp. 1095 emit(0xE9); 1096 emit_code_target(target, rmode); 1097 } 1098 1099 1100 void Assembler::jmp(Address entry, RelocInfo::Mode rmode) { 1101 DCHECK(RelocInfo::IsRuntimeEntry(rmode)); 1102 EnsureSpace ensure_space(this); 1103 DCHECK(RelocInfo::IsRuntimeEntry(rmode)); 1104 emit(0xE9); 1105 emit_runtime_entry(entry, rmode); 1106 } 1107 1108 1109 void Assembler::jmp(Register target) { 1110 EnsureSpace ensure_space(this); 1111 // Opcode FF/4 r64. 1112 emit_optional_rex_32(target); 1113 emit(0xFF); 1114 emit_modrm(0x4, target); 1115 } 1116 1117 1118 void Assembler::jmp(const Operand& src) { 1119 EnsureSpace ensure_space(this); 1120 // Opcode FF/4 m64. 1121 emit_optional_rex_32(src); 1122 emit(0xFF); 1123 emit_operand(0x4, src); 1124 } 1125 1126 1127 void Assembler::emit_lea(Register dst, const Operand& src, int size) { 1128 EnsureSpace ensure_space(this); 1129 emit_rex(dst, src, size); 1130 emit(0x8D); 1131 emit_operand(dst, src); 1132 } 1133 1134 1135 void Assembler::load_rax(void* value, RelocInfo::Mode mode) { 1136 EnsureSpace ensure_space(this); 1137 if (kPointerSize == kInt64Size) { 1138 emit(0x48); // REX.W 1139 emit(0xA1); 1140 emitp(value, mode); 1141 } else { 1142 DCHECK(kPointerSize == kInt32Size); 1143 emit(0xA1); 1144 emitp(value, mode); 1145 // In 64-bit mode, need to zero extend the operand to 8 bytes. 1146 // See 2.2.1.4 in Intel64 and IA32 Architectures Software 1147 // Developer's Manual Volume 2. 1148 emitl(0); 1149 } 1150 } 1151 1152 1153 void Assembler::load_rax(ExternalReference ref) { 1154 load_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE); 1155 } 1156 1157 1158 void Assembler::leave() { 1159 EnsureSpace ensure_space(this); 1160 emit(0xC9); 1161 } 1162 1163 1164 void Assembler::movb(Register dst, const Operand& src) { 1165 EnsureSpace ensure_space(this); 1166 if (!dst.is_byte_register()) { 1167 // Register is not one of al, bl, cl, dl. Its encoding needs REX. 1168 emit_rex_32(dst, src); 1169 } else { 1170 emit_optional_rex_32(dst, src); 1171 } 1172 emit(0x8A); 1173 emit_operand(dst, src); 1174 } 1175 1176 1177 void Assembler::movb(Register dst, Immediate imm) { 1178 EnsureSpace ensure_space(this); 1179 if (!dst.is_byte_register()) { 1180 // Register is not one of al, bl, cl, dl. Its encoding needs REX. 1181 emit_rex_32(dst); 1182 } 1183 emit(0xB0 + dst.low_bits()); 1184 emit(imm.value_); 1185 } 1186 1187 1188 void Assembler::movb(const Operand& dst, Register src) { 1189 EnsureSpace ensure_space(this); 1190 if (!src.is_byte_register()) { 1191 // Register is not one of al, bl, cl, dl. Its encoding needs REX. 1192 emit_rex_32(src, dst); 1193 } else { 1194 emit_optional_rex_32(src, dst); 1195 } 1196 emit(0x88); 1197 emit_operand(src, dst); 1198 } 1199 1200 1201 void Assembler::movb(const Operand& dst, Immediate imm) { 1202 EnsureSpace ensure_space(this); 1203 emit_optional_rex_32(dst); 1204 emit(0xC6); 1205 emit_operand(0x0, dst); 1206 emit(static_cast<byte>(imm.value_)); 1207 } 1208 1209 1210 void Assembler::movw(Register dst, const Operand& src) { 1211 EnsureSpace ensure_space(this); 1212 emit(0x66); 1213 emit_optional_rex_32(dst, src); 1214 emit(0x8B); 1215 emit_operand(dst, src); 1216 } 1217 1218 1219 void Assembler::movw(const Operand& dst, Register src) { 1220 EnsureSpace ensure_space(this); 1221 emit(0x66); 1222 emit_optional_rex_32(src, dst); 1223 emit(0x89); 1224 emit_operand(src, dst); 1225 } 1226 1227 1228 void Assembler::movw(const Operand& dst, Immediate imm) { 1229 EnsureSpace ensure_space(this); 1230 emit(0x66); 1231 emit_optional_rex_32(dst); 1232 emit(0xC7); 1233 emit_operand(0x0, dst); 1234 emit(static_cast<byte>(imm.value_ & 0xff)); 1235 emit(static_cast<byte>(imm.value_ >> 8)); 1236 } 1237 1238 1239 void Assembler::emit_mov(Register dst, const Operand& src, int size) { 1240 EnsureSpace ensure_space(this); 1241 emit_rex(dst, src, size); 1242 emit(0x8B); 1243 emit_operand(dst, src); 1244 } 1245 1246 1247 void Assembler::emit_mov(Register dst, Register src, int size) { 1248 EnsureSpace ensure_space(this); 1249 if (src.low_bits() == 4) { 1250 emit_rex(src, dst, size); 1251 emit(0x89); 1252 emit_modrm(src, dst); 1253 } else { 1254 emit_rex(dst, src, size); 1255 emit(0x8B); 1256 emit_modrm(dst, src); 1257 } 1258 } 1259 1260 1261 void Assembler::emit_mov(const Operand& dst, Register src, int size) { 1262 EnsureSpace ensure_space(this); 1263 emit_rex(src, dst, size); 1264 emit(0x89); 1265 emit_operand(src, dst); 1266 } 1267 1268 1269 void Assembler::emit_mov(Register dst, Immediate value, int size) { 1270 EnsureSpace ensure_space(this); 1271 emit_rex(dst, size); 1272 if (size == kInt64Size) { 1273 emit(0xC7); 1274 emit_modrm(0x0, dst); 1275 } else { 1276 DCHECK(size == kInt32Size); 1277 emit(0xB8 + dst.low_bits()); 1278 } 1279 emit(value); 1280 } 1281 1282 1283 void Assembler::emit_mov(const Operand& dst, Immediate value, int size) { 1284 EnsureSpace ensure_space(this); 1285 emit_rex(dst, size); 1286 emit(0xC7); 1287 emit_operand(0x0, dst); 1288 emit(value); 1289 } 1290 1291 1292 void Assembler::movp(Register dst, void* value, RelocInfo::Mode rmode) { 1293 EnsureSpace ensure_space(this); 1294 emit_rex(dst, kPointerSize); 1295 emit(0xB8 | dst.low_bits()); 1296 emitp(value, rmode); 1297 } 1298 1299 1300 void Assembler::movq(Register dst, int64_t value) { 1301 EnsureSpace ensure_space(this); 1302 emit_rex_64(dst); 1303 emit(0xB8 | dst.low_bits()); 1304 emitq(value); 1305 } 1306 1307 1308 void Assembler::movq(Register dst, uint64_t value) { 1309 movq(dst, static_cast<int64_t>(value)); 1310 } 1311 1312 1313 // Loads the ip-relative location of the src label into the target location 1314 // (as a 32-bit offset sign extended to 64-bit). 1315 void Assembler::movl(const Operand& dst, Label* src) { 1316 EnsureSpace ensure_space(this); 1317 emit_optional_rex_32(dst); 1318 emit(0xC7); 1319 emit_operand(0, dst); 1320 if (src->is_bound()) { 1321 int offset = src->pos() - pc_offset() - sizeof(int32_t); 1322 DCHECK(offset <= 0); 1323 emitl(offset); 1324 } else if (src->is_linked()) { 1325 emitl(src->pos()); 1326 src->link_to(pc_offset() - sizeof(int32_t)); 1327 } else { 1328 DCHECK(src->is_unused()); 1329 int32_t current = pc_offset(); 1330 emitl(current); 1331 src->link_to(current); 1332 } 1333 } 1334 1335 1336 void Assembler::movsxbl(Register dst, const Operand& src) { 1337 EnsureSpace ensure_space(this); 1338 emit_optional_rex_32(dst, src); 1339 emit(0x0F); 1340 emit(0xBE); 1341 emit_operand(dst, src); 1342 } 1343 1344 1345 void Assembler::movsxbq(Register dst, const Operand& src) { 1346 EnsureSpace ensure_space(this); 1347 emit_rex_64(dst, src); 1348 emit(0x0F); 1349 emit(0xBE); 1350 emit_operand(dst, src); 1351 } 1352 1353 1354 void Assembler::movsxwl(Register dst, const Operand& src) { 1355 EnsureSpace ensure_space(this); 1356 emit_optional_rex_32(dst, src); 1357 emit(0x0F); 1358 emit(0xBF); 1359 emit_operand(dst, src); 1360 } 1361 1362 1363 void Assembler::movsxwq(Register dst, const Operand& src) { 1364 EnsureSpace ensure_space(this); 1365 emit_rex_64(dst, src); 1366 emit(0x0F); 1367 emit(0xBF); 1368 emit_operand(dst, src); 1369 } 1370 1371 1372 void Assembler::movsxlq(Register dst, Register src) { 1373 EnsureSpace ensure_space(this); 1374 emit_rex_64(dst, src); 1375 emit(0x63); 1376 emit_modrm(dst, src); 1377 } 1378 1379 1380 void Assembler::movsxlq(Register dst, const Operand& src) { 1381 EnsureSpace ensure_space(this); 1382 emit_rex_64(dst, src); 1383 emit(0x63); 1384 emit_operand(dst, src); 1385 } 1386 1387 1388 void Assembler::emit_movzxb(Register dst, const Operand& src, int size) { 1389 EnsureSpace ensure_space(this); 1390 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore 1391 // there is no need to make this a 64 bit operation. 1392 emit_optional_rex_32(dst, src); 1393 emit(0x0F); 1394 emit(0xB6); 1395 emit_operand(dst, src); 1396 } 1397 1398 1399 void Assembler::emit_movzxb(Register dst, Register src, int size) { 1400 EnsureSpace ensure_space(this); 1401 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore 1402 // there is no need to make this a 64 bit operation. 1403 if (!src.is_byte_register()) { 1404 // Register is not one of al, bl, cl, dl. Its encoding needs REX. 1405 emit_rex_32(dst, src); 1406 } else { 1407 emit_optional_rex_32(dst, src); 1408 } 1409 emit(0x0F); 1410 emit(0xB6); 1411 emit_modrm(dst, src); 1412 } 1413 1414 1415 void Assembler::emit_movzxw(Register dst, const Operand& src, int size) { 1416 EnsureSpace ensure_space(this); 1417 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore 1418 // there is no need to make this a 64 bit operation. 1419 emit_optional_rex_32(dst, src); 1420 emit(0x0F); 1421 emit(0xB7); 1422 emit_operand(dst, src); 1423 } 1424 1425 1426 void Assembler::emit_movzxw(Register dst, Register src, int size) { 1427 EnsureSpace ensure_space(this); 1428 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore 1429 // there is no need to make this a 64 bit operation. 1430 emit_optional_rex_32(dst, src); 1431 emit(0x0F); 1432 emit(0xB7); 1433 emit_modrm(dst, src); 1434 } 1435 1436 1437 void Assembler::repmovsb() { 1438 EnsureSpace ensure_space(this); 1439 emit(0xF3); 1440 emit(0xA4); 1441 } 1442 1443 1444 void Assembler::repmovsw() { 1445 EnsureSpace ensure_space(this); 1446 emit(0x66); // Operand size override. 1447 emit(0xF3); 1448 emit(0xA4); 1449 } 1450 1451 1452 void Assembler::emit_repmovs(int size) { 1453 EnsureSpace ensure_space(this); 1454 emit(0xF3); 1455 emit_rex(size); 1456 emit(0xA5); 1457 } 1458 1459 1460 void Assembler::mul(Register src) { 1461 EnsureSpace ensure_space(this); 1462 emit_rex_64(src); 1463 emit(0xF7); 1464 emit_modrm(0x4, src); 1465 } 1466 1467 1468 void Assembler::emit_neg(Register dst, int size) { 1469 EnsureSpace ensure_space(this); 1470 emit_rex(dst, size); 1471 emit(0xF7); 1472 emit_modrm(0x3, dst); 1473 } 1474 1475 1476 void Assembler::emit_neg(const Operand& dst, int size) { 1477 EnsureSpace ensure_space(this); 1478 emit_rex_64(dst); 1479 emit(0xF7); 1480 emit_operand(3, dst); 1481 } 1482 1483 1484 void Assembler::nop() { 1485 EnsureSpace ensure_space(this); 1486 emit(0x90); 1487 } 1488 1489 1490 void Assembler::emit_not(Register dst, int size) { 1491 EnsureSpace ensure_space(this); 1492 emit_rex(dst, size); 1493 emit(0xF7); 1494 emit_modrm(0x2, dst); 1495 } 1496 1497 1498 void Assembler::emit_not(const Operand& dst, int size) { 1499 EnsureSpace ensure_space(this); 1500 emit_rex(dst, size); 1501 emit(0xF7); 1502 emit_operand(2, dst); 1503 } 1504 1505 1506 void Assembler::Nop(int n) { 1507 // The recommended muti-byte sequences of NOP instructions from the Intel 64 1508 // and IA-32 Architectures Software Developer's Manual. 1509 // 1510 // Length Assembly Byte Sequence 1511 // 2 bytes 66 NOP 66 90H 1512 // 3 bytes NOP DWORD ptr [EAX] 0F 1F 00H 1513 // 4 bytes NOP DWORD ptr [EAX + 00H] 0F 1F 40 00H 1514 // 5 bytes NOP DWORD ptr [EAX + EAX*1 + 00H] 0F 1F 44 00 00H 1515 // 6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H 1516 // 7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H 1517 // 8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H 1518 // 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 66 0F 1F 84 00 00 00 00 1519 // 00000000H] 00H 1520 1521 EnsureSpace ensure_space(this); 1522 while (n > 0) { 1523 switch (n) { 1524 case 2: 1525 emit(0x66); 1526 case 1: 1527 emit(0x90); 1528 return; 1529 case 3: 1530 emit(0x0f); 1531 emit(0x1f); 1532 emit(0x00); 1533 return; 1534 case 4: 1535 emit(0x0f); 1536 emit(0x1f); 1537 emit(0x40); 1538 emit(0x00); 1539 return; 1540 case 6: 1541 emit(0x66); 1542 case 5: 1543 emit(0x0f); 1544 emit(0x1f); 1545 emit(0x44); 1546 emit(0x00); 1547 emit(0x00); 1548 return; 1549 case 7: 1550 emit(0x0f); 1551 emit(0x1f); 1552 emit(0x80); 1553 emit(0x00); 1554 emit(0x00); 1555 emit(0x00); 1556 emit(0x00); 1557 return; 1558 default: 1559 case 11: 1560 emit(0x66); 1561 n--; 1562 case 10: 1563 emit(0x66); 1564 n--; 1565 case 9: 1566 emit(0x66); 1567 n--; 1568 case 8: 1569 emit(0x0f); 1570 emit(0x1f); 1571 emit(0x84); 1572 emit(0x00); 1573 emit(0x00); 1574 emit(0x00); 1575 emit(0x00); 1576 emit(0x00); 1577 n -= 8; 1578 } 1579 } 1580 } 1581 1582 1583 void Assembler::popq(Register dst) { 1584 EnsureSpace ensure_space(this); 1585 emit_optional_rex_32(dst); 1586 emit(0x58 | dst.low_bits()); 1587 } 1588 1589 1590 void Assembler::popq(const Operand& dst) { 1591 EnsureSpace ensure_space(this); 1592 emit_optional_rex_32(dst); 1593 emit(0x8F); 1594 emit_operand(0, dst); 1595 } 1596 1597 1598 void Assembler::popfq() { 1599 EnsureSpace ensure_space(this); 1600 emit(0x9D); 1601 } 1602 1603 1604 void Assembler::pushq(Register src) { 1605 EnsureSpace ensure_space(this); 1606 emit_optional_rex_32(src); 1607 emit(0x50 | src.low_bits()); 1608 } 1609 1610 1611 void Assembler::pushq(const Operand& src) { 1612 EnsureSpace ensure_space(this); 1613 emit_optional_rex_32(src); 1614 emit(0xFF); 1615 emit_operand(6, src); 1616 } 1617 1618 1619 void Assembler::pushq(Immediate value) { 1620 EnsureSpace ensure_space(this); 1621 if (is_int8(value.value_)) { 1622 emit(0x6A); 1623 emit(value.value_); // Emit low byte of value. 1624 } else { 1625 emit(0x68); 1626 emitl(value.value_); 1627 } 1628 } 1629 1630 1631 void Assembler::pushq_imm32(int32_t imm32) { 1632 EnsureSpace ensure_space(this); 1633 emit(0x68); 1634 emitl(imm32); 1635 } 1636 1637 1638 void Assembler::pushfq() { 1639 EnsureSpace ensure_space(this); 1640 emit(0x9C); 1641 } 1642 1643 1644 void Assembler::ret(int imm16) { 1645 EnsureSpace ensure_space(this); 1646 DCHECK(is_uint16(imm16)); 1647 if (imm16 == 0) { 1648 emit(0xC3); 1649 } else { 1650 emit(0xC2); 1651 emit(imm16 & 0xFF); 1652 emit((imm16 >> 8) & 0xFF); 1653 } 1654 } 1655 1656 1657 void Assembler::setcc(Condition cc, Register reg) { 1658 if (cc > last_condition) { 1659 movb(reg, Immediate(cc == always ? 1 : 0)); 1660 return; 1661 } 1662 EnsureSpace ensure_space(this); 1663 DCHECK(is_uint4(cc)); 1664 if (!reg.is_byte_register()) { 1665 // Register is not one of al, bl, cl, dl. Its encoding needs REX. 1666 emit_rex_32(reg); 1667 } 1668 emit(0x0F); 1669 emit(0x90 | cc); 1670 emit_modrm(0x0, reg); 1671 } 1672 1673 1674 void Assembler::shld(Register dst, Register src) { 1675 EnsureSpace ensure_space(this); 1676 emit_rex_64(src, dst); 1677 emit(0x0F); 1678 emit(0xA5); 1679 emit_modrm(src, dst); 1680 } 1681 1682 1683 void Assembler::shrd(Register dst, Register src) { 1684 EnsureSpace ensure_space(this); 1685 emit_rex_64(src, dst); 1686 emit(0x0F); 1687 emit(0xAD); 1688 emit_modrm(src, dst); 1689 } 1690 1691 1692 void Assembler::emit_xchg(Register dst, Register src, int size) { 1693 EnsureSpace ensure_space(this); 1694 if (src.is(rax) || dst.is(rax)) { // Single-byte encoding 1695 Register other = src.is(rax) ? dst : src; 1696 emit_rex(other, size); 1697 emit(0x90 | other.low_bits()); 1698 } else if (dst.low_bits() == 4) { 1699 emit_rex(dst, src, size); 1700 emit(0x87); 1701 emit_modrm(dst, src); 1702 } else { 1703 emit_rex(src, dst, size); 1704 emit(0x87); 1705 emit_modrm(src, dst); 1706 } 1707 } 1708 1709 1710 void Assembler::emit_xchg(Register dst, const Operand& src, int size) { 1711 EnsureSpace ensure_space(this); 1712 emit_rex(dst, src, size); 1713 emit(0x87); 1714 emit_operand(dst, src); 1715 } 1716 1717 1718 void Assembler::store_rax(void* dst, RelocInfo::Mode mode) { 1719 EnsureSpace ensure_space(this); 1720 if (kPointerSize == kInt64Size) { 1721 emit(0x48); // REX.W 1722 emit(0xA3); 1723 emitp(dst, mode); 1724 } else { 1725 DCHECK(kPointerSize == kInt32Size); 1726 emit(0xA3); 1727 emitp(dst, mode); 1728 // In 64-bit mode, need to zero extend the operand to 8 bytes. 1729 // See 2.2.1.4 in Intel64 and IA32 Architectures Software 1730 // Developer's Manual Volume 2. 1731 emitl(0); 1732 } 1733 } 1734 1735 1736 void Assembler::store_rax(ExternalReference ref) { 1737 store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE); 1738 } 1739 1740 1741 void Assembler::testb(Register dst, Register src) { 1742 EnsureSpace ensure_space(this); 1743 if (src.low_bits() == 4) { 1744 emit_rex_32(src, dst); 1745 emit(0x84); 1746 emit_modrm(src, dst); 1747 } else { 1748 if (!dst.is_byte_register() || !src.is_byte_register()) { 1749 // Register is not one of al, bl, cl, dl. Its encoding needs REX. 1750 emit_rex_32(dst, src); 1751 } 1752 emit(0x84); 1753 emit_modrm(dst, src); 1754 } 1755 } 1756 1757 1758 void Assembler::testb(Register reg, Immediate mask) { 1759 DCHECK(is_int8(mask.value_) || is_uint8(mask.value_)); 1760 EnsureSpace ensure_space(this); 1761 if (reg.is(rax)) { 1762 emit(0xA8); 1763 emit(mask.value_); // Low byte emitted. 1764 } else { 1765 if (!reg.is_byte_register()) { 1766 // Register is not one of al, bl, cl, dl. Its encoding needs REX. 1767 emit_rex_32(reg); 1768 } 1769 emit(0xF6); 1770 emit_modrm(0x0, reg); 1771 emit(mask.value_); // Low byte emitted. 1772 } 1773 } 1774 1775 1776 void Assembler::testb(const Operand& op, Immediate mask) { 1777 DCHECK(is_int8(mask.value_) || is_uint8(mask.value_)); 1778 EnsureSpace ensure_space(this); 1779 emit_optional_rex_32(rax, op); 1780 emit(0xF6); 1781 emit_operand(rax, op); // Operation code 0 1782 emit(mask.value_); // Low byte emitted. 1783 } 1784 1785 1786 void Assembler::testb(const Operand& op, Register reg) { 1787 EnsureSpace ensure_space(this); 1788 if (!reg.is_byte_register()) { 1789 // Register is not one of al, bl, cl, dl. Its encoding needs REX. 1790 emit_rex_32(reg, op); 1791 } else { 1792 emit_optional_rex_32(reg, op); 1793 } 1794 emit(0x84); 1795 emit_operand(reg, op); 1796 } 1797 1798 1799 void Assembler::emit_test(Register dst, Register src, int size) { 1800 EnsureSpace ensure_space(this); 1801 if (src.low_bits() == 4) { 1802 emit_rex(src, dst, size); 1803 emit(0x85); 1804 emit_modrm(src, dst); 1805 } else { 1806 emit_rex(dst, src, size); 1807 emit(0x85); 1808 emit_modrm(dst, src); 1809 } 1810 } 1811 1812 1813 void Assembler::emit_test(Register reg, Immediate mask, int size) { 1814 // testl with a mask that fits in the low byte is exactly testb. 1815 if (is_uint8(mask.value_)) { 1816 testb(reg, mask); 1817 return; 1818 } 1819 EnsureSpace ensure_space(this); 1820 if (reg.is(rax)) { 1821 emit_rex(rax, size); 1822 emit(0xA9); 1823 emit(mask); 1824 } else { 1825 emit_rex(reg, size); 1826 emit(0xF7); 1827 emit_modrm(0x0, reg); 1828 emit(mask); 1829 } 1830 } 1831 1832 1833 void Assembler::emit_test(const Operand& op, Immediate mask, int size) { 1834 // testl with a mask that fits in the low byte is exactly testb. 1835 if (is_uint8(mask.value_)) { 1836 testb(op, mask); 1837 return; 1838 } 1839 EnsureSpace ensure_space(this); 1840 emit_rex(rax, op, size); 1841 emit(0xF7); 1842 emit_operand(rax, op); // Operation code 0 1843 emit(mask); 1844 } 1845 1846 1847 void Assembler::emit_test(const Operand& op, Register reg, int size) { 1848 EnsureSpace ensure_space(this); 1849 emit_rex(reg, op, size); 1850 emit(0x85); 1851 emit_operand(reg, op); 1852 } 1853 1854 1855 // FPU instructions. 1856 1857 1858 void Assembler::fld(int i) { 1859 EnsureSpace ensure_space(this); 1860 emit_farith(0xD9, 0xC0, i); 1861 } 1862 1863 1864 void Assembler::fld1() { 1865 EnsureSpace ensure_space(this); 1866 emit(0xD9); 1867 emit(0xE8); 1868 } 1869 1870 1871 void Assembler::fldz() { 1872 EnsureSpace ensure_space(this); 1873 emit(0xD9); 1874 emit(0xEE); 1875 } 1876 1877 1878 void Assembler::fldpi() { 1879 EnsureSpace ensure_space(this); 1880 emit(0xD9); 1881 emit(0xEB); 1882 } 1883 1884 1885 void Assembler::fldln2() { 1886 EnsureSpace ensure_space(this); 1887 emit(0xD9); 1888 emit(0xED); 1889 } 1890 1891 1892 void Assembler::fld_s(const Operand& adr) { 1893 EnsureSpace ensure_space(this); 1894 emit_optional_rex_32(adr); 1895 emit(0xD9); 1896 emit_operand(0, adr); 1897 } 1898 1899 1900 void Assembler::fld_d(const Operand& adr) { 1901 EnsureSpace ensure_space(this); 1902 emit_optional_rex_32(adr); 1903 emit(0xDD); 1904 emit_operand(0, adr); 1905 } 1906 1907 1908 void Assembler::fstp_s(const Operand& adr) { 1909 EnsureSpace ensure_space(this); 1910 emit_optional_rex_32(adr); 1911 emit(0xD9); 1912 emit_operand(3, adr); 1913 } 1914 1915 1916 void Assembler::fstp_d(const Operand& adr) { 1917 EnsureSpace ensure_space(this); 1918 emit_optional_rex_32(adr); 1919 emit(0xDD); 1920 emit_operand(3, adr); 1921 } 1922 1923 1924 void Assembler::fstp(int index) { 1925 DCHECK(is_uint3(index)); 1926 EnsureSpace ensure_space(this); 1927 emit_farith(0xDD, 0xD8, index); 1928 } 1929 1930 1931 void Assembler::fild_s(const Operand& adr) { 1932 EnsureSpace ensure_space(this); 1933 emit_optional_rex_32(adr); 1934 emit(0xDB); 1935 emit_operand(0, adr); 1936 } 1937 1938 1939 void Assembler::fild_d(const Operand& adr) { 1940 EnsureSpace ensure_space(this); 1941 emit_optional_rex_32(adr); 1942 emit(0xDF); 1943 emit_operand(5, adr); 1944 } 1945 1946 1947 void Assembler::fistp_s(const Operand& adr) { 1948 EnsureSpace ensure_space(this); 1949 emit_optional_rex_32(adr); 1950 emit(0xDB); 1951 emit_operand(3, adr); 1952 } 1953 1954 1955 void Assembler::fisttp_s(const Operand& adr) { 1956 DCHECK(IsEnabled(SSE3)); 1957 EnsureSpace ensure_space(this); 1958 emit_optional_rex_32(adr); 1959 emit(0xDB); 1960 emit_operand(1, adr); 1961 } 1962 1963 1964 void Assembler::fisttp_d(const Operand& adr) { 1965 DCHECK(IsEnabled(SSE3)); 1966 EnsureSpace ensure_space(this); 1967 emit_optional_rex_32(adr); 1968 emit(0xDD); 1969 emit_operand(1, adr); 1970 } 1971 1972 1973 void Assembler::fist_s(const Operand& adr) { 1974 EnsureSpace ensure_space(this); 1975 emit_optional_rex_32(adr); 1976 emit(0xDB); 1977 emit_operand(2, adr); 1978 } 1979 1980 1981 void Assembler::fistp_d(const Operand& adr) { 1982 EnsureSpace ensure_space(this); 1983 emit_optional_rex_32(adr); 1984 emit(0xDF); 1985 emit_operand(7, adr); 1986 } 1987 1988 1989 void Assembler::fabs() { 1990 EnsureSpace ensure_space(this); 1991 emit(0xD9); 1992 emit(0xE1); 1993 } 1994 1995 1996 void Assembler::fchs() { 1997 EnsureSpace ensure_space(this); 1998 emit(0xD9); 1999 emit(0xE0); 2000 } 2001 2002 2003 void Assembler::fcos() { 2004 EnsureSpace ensure_space(this); 2005 emit(0xD9); 2006 emit(0xFF); 2007 } 2008 2009 2010 void Assembler::fsin() { 2011 EnsureSpace ensure_space(this); 2012 emit(0xD9); 2013 emit(0xFE); 2014 } 2015 2016 2017 void Assembler::fptan() { 2018 EnsureSpace ensure_space(this); 2019 emit(0xD9); 2020 emit(0xF2); 2021 } 2022 2023 2024 void Assembler::fyl2x() { 2025 EnsureSpace ensure_space(this); 2026 emit(0xD9); 2027 emit(0xF1); 2028 } 2029 2030 2031 void Assembler::f2xm1() { 2032 EnsureSpace ensure_space(this); 2033 emit(0xD9); 2034 emit(0xF0); 2035 } 2036 2037 2038 void Assembler::fscale() { 2039 EnsureSpace ensure_space(this); 2040 emit(0xD9); 2041 emit(0xFD); 2042 } 2043 2044 2045 void Assembler::fninit() { 2046 EnsureSpace ensure_space(this); 2047 emit(0xDB); 2048 emit(0xE3); 2049 } 2050 2051 2052 void Assembler::fadd(int i) { 2053 EnsureSpace ensure_space(this); 2054 emit_farith(0xDC, 0xC0, i); 2055 } 2056 2057 2058 void Assembler::fsub(int i) { 2059 EnsureSpace ensure_space(this); 2060 emit_farith(0xDC, 0xE8, i); 2061 } 2062 2063 2064 void Assembler::fisub_s(const Operand& adr) { 2065 EnsureSpace ensure_space(this); 2066 emit_optional_rex_32(adr); 2067 emit(0xDA); 2068 emit_operand(4, adr); 2069 } 2070 2071 2072 void Assembler::fmul(int i) { 2073 EnsureSpace ensure_space(this); 2074 emit_farith(0xDC, 0xC8, i); 2075 } 2076 2077 2078 void Assembler::fdiv(int i) { 2079 EnsureSpace ensure_space(this); 2080 emit_farith(0xDC, 0xF8, i); 2081 } 2082 2083 2084 void Assembler::faddp(int i) { 2085 EnsureSpace ensure_space(this); 2086 emit_farith(0xDE, 0xC0, i); 2087 } 2088 2089 2090 void Assembler::fsubp(int i) { 2091 EnsureSpace ensure_space(this); 2092 emit_farith(0xDE, 0xE8, i); 2093 } 2094 2095 2096 void Assembler::fsubrp(int i) { 2097 EnsureSpace ensure_space(this); 2098 emit_farith(0xDE, 0xE0, i); 2099 } 2100 2101 2102 void Assembler::fmulp(int i) { 2103 EnsureSpace ensure_space(this); 2104 emit_farith(0xDE, 0xC8, i); 2105 } 2106 2107 2108 void Assembler::fdivp(int i) { 2109 EnsureSpace ensure_space(this); 2110 emit_farith(0xDE, 0xF8, i); 2111 } 2112 2113 2114 void Assembler::fprem() { 2115 EnsureSpace ensure_space(this); 2116 emit(0xD9); 2117 emit(0xF8); 2118 } 2119 2120 2121 void Assembler::fprem1() { 2122 EnsureSpace ensure_space(this); 2123 emit(0xD9); 2124 emit(0xF5); 2125 } 2126 2127 2128 void Assembler::fxch(int i) { 2129 EnsureSpace ensure_space(this); 2130 emit_farith(0xD9, 0xC8, i); 2131 } 2132 2133 2134 void Assembler::fincstp() { 2135 EnsureSpace ensure_space(this); 2136 emit(0xD9); 2137 emit(0xF7); 2138 } 2139 2140 2141 void Assembler::ffree(int i) { 2142 EnsureSpace ensure_space(this); 2143 emit_farith(0xDD, 0xC0, i); 2144 } 2145 2146 2147 void Assembler::ftst() { 2148 EnsureSpace ensure_space(this); 2149 emit(0xD9); 2150 emit(0xE4); 2151 } 2152 2153 2154 void Assembler::fucomp(int i) { 2155 EnsureSpace ensure_space(this); 2156 emit_farith(0xDD, 0xE8, i); 2157 } 2158 2159 2160 void Assembler::fucompp() { 2161 EnsureSpace ensure_space(this); 2162 emit(0xDA); 2163 emit(0xE9); 2164 } 2165 2166 2167 void Assembler::fucomi(int i) { 2168 EnsureSpace ensure_space(this); 2169 emit(0xDB); 2170 emit(0xE8 + i); 2171 } 2172 2173 2174 void Assembler::fucomip() { 2175 EnsureSpace ensure_space(this); 2176 emit(0xDF); 2177 emit(0xE9); 2178 } 2179 2180 2181 void Assembler::fcompp() { 2182 EnsureSpace ensure_space(this); 2183 emit(0xDE); 2184 emit(0xD9); 2185 } 2186 2187 2188 void Assembler::fnstsw_ax() { 2189 EnsureSpace ensure_space(this); 2190 emit(0xDF); 2191 emit(0xE0); 2192 } 2193 2194 2195 void Assembler::fwait() { 2196 EnsureSpace ensure_space(this); 2197 emit(0x9B); 2198 } 2199 2200 2201 void Assembler::frndint() { 2202 EnsureSpace ensure_space(this); 2203 emit(0xD9); 2204 emit(0xFC); 2205 } 2206 2207 2208 void Assembler::fnclex() { 2209 EnsureSpace ensure_space(this); 2210 emit(0xDB); 2211 emit(0xE2); 2212 } 2213 2214 2215 void Assembler::sahf() { 2216 // TODO(X64): Test for presence. Not all 64-bit intel CPU's have sahf 2217 // in 64-bit mode. Test CpuID. 2218 DCHECK(IsEnabled(SAHF)); 2219 EnsureSpace ensure_space(this); 2220 emit(0x9E); 2221 } 2222 2223 2224 void Assembler::emit_farith(int b1, int b2, int i) { 2225 DCHECK(is_uint8(b1) && is_uint8(b2)); // wrong opcode 2226 DCHECK(is_uint3(i)); // illegal stack offset 2227 emit(b1); 2228 emit(b2 + i); 2229 } 2230 2231 2232 // SSE operations. 2233 2234 void Assembler::andps(XMMRegister dst, XMMRegister src) { 2235 EnsureSpace ensure_space(this); 2236 emit_optional_rex_32(dst, src); 2237 emit(0x0F); 2238 emit(0x54); 2239 emit_sse_operand(dst, src); 2240 } 2241 2242 2243 void Assembler::andps(XMMRegister dst, const Operand& src) { 2244 EnsureSpace ensure_space(this); 2245 emit_optional_rex_32(dst, src); 2246 emit(0x0F); 2247 emit(0x54); 2248 emit_sse_operand(dst, src); 2249 } 2250 2251 2252 void Assembler::orps(XMMRegister dst, XMMRegister src) { 2253 EnsureSpace ensure_space(this); 2254 emit_optional_rex_32(dst, src); 2255 emit(0x0F); 2256 emit(0x56); 2257 emit_sse_operand(dst, src); 2258 } 2259 2260 2261 void Assembler::orps(XMMRegister dst, const Operand& src) { 2262 EnsureSpace ensure_space(this); 2263 emit_optional_rex_32(dst, src); 2264 emit(0x0F); 2265 emit(0x56); 2266 emit_sse_operand(dst, src); 2267 } 2268 2269 2270 void Assembler::xorps(XMMRegister dst, XMMRegister src) { 2271 EnsureSpace ensure_space(this); 2272 emit_optional_rex_32(dst, src); 2273 emit(0x0F); 2274 emit(0x57); 2275 emit_sse_operand(dst, src); 2276 } 2277 2278 2279 void Assembler::xorps(XMMRegister dst, const Operand& src) { 2280 EnsureSpace ensure_space(this); 2281 emit_optional_rex_32(dst, src); 2282 emit(0x0F); 2283 emit(0x57); 2284 emit_sse_operand(dst, src); 2285 } 2286 2287 2288 void Assembler::addps(XMMRegister dst, XMMRegister src) { 2289 EnsureSpace ensure_space(this); 2290 emit_optional_rex_32(dst, src); 2291 emit(0x0F); 2292 emit(0x58); 2293 emit_sse_operand(dst, src); 2294 } 2295 2296 2297 void Assembler::addps(XMMRegister dst, const Operand& src) { 2298 EnsureSpace ensure_space(this); 2299 emit_optional_rex_32(dst, src); 2300 emit(0x0F); 2301 emit(0x58); 2302 emit_sse_operand(dst, src); 2303 } 2304 2305 2306 void Assembler::subps(XMMRegister dst, XMMRegister src) { 2307 EnsureSpace ensure_space(this); 2308 emit_optional_rex_32(dst, src); 2309 emit(0x0F); 2310 emit(0x5C); 2311 emit_sse_operand(dst, src); 2312 } 2313 2314 2315 void Assembler::subps(XMMRegister dst, const Operand& src) { 2316 EnsureSpace ensure_space(this); 2317 emit_optional_rex_32(dst, src); 2318 emit(0x0F); 2319 emit(0x5C); 2320 emit_sse_operand(dst, src); 2321 } 2322 2323 2324 void Assembler::mulps(XMMRegister dst, XMMRegister src) { 2325 EnsureSpace ensure_space(this); 2326 emit_optional_rex_32(dst, src); 2327 emit(0x0F); 2328 emit(0x59); 2329 emit_sse_operand(dst, src); 2330 } 2331 2332 2333 void Assembler::mulps(XMMRegister dst, const Operand& src) { 2334 EnsureSpace ensure_space(this); 2335 emit_optional_rex_32(dst, src); 2336 emit(0x0F); 2337 emit(0x59); 2338 emit_sse_operand(dst, src); 2339 } 2340 2341 2342 void Assembler::divps(XMMRegister dst, XMMRegister src) { 2343 EnsureSpace ensure_space(this); 2344 emit_optional_rex_32(dst, src); 2345 emit(0x0F); 2346 emit(0x5E); 2347 emit_sse_operand(dst, src); 2348 } 2349 2350 2351 void Assembler::divps(XMMRegister dst, const Operand& src) { 2352 EnsureSpace ensure_space(this); 2353 emit_optional_rex_32(dst, src); 2354 emit(0x0F); 2355 emit(0x5E); 2356 emit_sse_operand(dst, src); 2357 } 2358 2359 2360 // SSE 2 operations. 2361 2362 void Assembler::movd(XMMRegister dst, Register src) { 2363 EnsureSpace ensure_space(this); 2364 emit(0x66); 2365 emit_optional_rex_32(dst, src); 2366 emit(0x0F); 2367 emit(0x6E); 2368 emit_sse_operand(dst, src); 2369 } 2370 2371 2372 void Assembler::movd(Register dst, XMMRegister src) { 2373 EnsureSpace ensure_space(this); 2374 emit(0x66); 2375 emit_optional_rex_32(src, dst); 2376 emit(0x0F); 2377 emit(0x7E); 2378 emit_sse_operand(src, dst); 2379 } 2380 2381 2382 void Assembler::movq(XMMRegister dst, Register src) { 2383 EnsureSpace ensure_space(this); 2384 emit(0x66); 2385 emit_rex_64(dst, src); 2386 emit(0x0F); 2387 emit(0x6E); 2388 emit_sse_operand(dst, src); 2389 } 2390 2391 2392 void Assembler::movq(Register dst, XMMRegister src) { 2393 EnsureSpace ensure_space(this); 2394 emit(0x66); 2395 emit_rex_64(src, dst); 2396 emit(0x0F); 2397 emit(0x7E); 2398 emit_sse_operand(src, dst); 2399 } 2400 2401 2402 void Assembler::movq(XMMRegister dst, XMMRegister src) { 2403 EnsureSpace ensure_space(this); 2404 if (dst.low_bits() == 4) { 2405 // Avoid unnecessary SIB byte. 2406 emit(0xf3); 2407 emit_optional_rex_32(dst, src); 2408 emit(0x0F); 2409 emit(0x7e); 2410 emit_sse_operand(dst, src); 2411 } else { 2412 emit(0x66); 2413 emit_optional_rex_32(src, dst); 2414 emit(0x0F); 2415 emit(0xD6); 2416 emit_sse_operand(src, dst); 2417 } 2418 } 2419 2420 2421 void Assembler::movdqa(const Operand& dst, XMMRegister src) { 2422 EnsureSpace ensure_space(this); 2423 emit(0x66); 2424 emit_rex_64(src, dst); 2425 emit(0x0F); 2426 emit(0x7F); 2427 emit_sse_operand(src, dst); 2428 } 2429 2430 2431 void Assembler::movdqa(XMMRegister dst, const Operand& src) { 2432 EnsureSpace ensure_space(this); 2433 emit(0x66); 2434 emit_rex_64(dst, src); 2435 emit(0x0F); 2436 emit(0x6F); 2437 emit_sse_operand(dst, src); 2438 } 2439 2440 2441 void Assembler::movdqu(const Operand& dst, XMMRegister src) { 2442 EnsureSpace ensure_space(this); 2443 emit(0xF3); 2444 emit_rex_64(src, dst); 2445 emit(0x0F); 2446 emit(0x7F); 2447 emit_sse_operand(src, dst); 2448 } 2449 2450 2451 void Assembler::movdqu(XMMRegister dst, const Operand& src) { 2452 EnsureSpace ensure_space(this); 2453 emit(0xF3); 2454 emit_rex_64(dst, src); 2455 emit(0x0F); 2456 emit(0x6F); 2457 emit_sse_operand(dst, src); 2458 } 2459 2460 2461 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) { 2462 DCHECK(IsEnabled(SSE4_1)); 2463 DCHECK(is_uint8(imm8)); 2464 EnsureSpace ensure_space(this); 2465 emit(0x66); 2466 emit_optional_rex_32(src, dst); 2467 emit(0x0F); 2468 emit(0x3A); 2469 emit(0x17); 2470 emit_sse_operand(src, dst); 2471 emit(imm8); 2472 } 2473 2474 2475 void Assembler::movsd(const Operand& dst, XMMRegister src) { 2476 EnsureSpace ensure_space(this); 2477 emit(0xF2); // double 2478 emit_optional_rex_32(src, dst); 2479 emit(0x0F); 2480 emit(0x11); // store 2481 emit_sse_operand(src, dst); 2482 } 2483 2484 2485 void Assembler::movsd(XMMRegister dst, XMMRegister src) { 2486 EnsureSpace ensure_space(this); 2487 emit(0xF2); // double 2488 emit_optional_rex_32(dst, src); 2489 emit(0x0F); 2490 emit(0x10); // load 2491 emit_sse_operand(dst, src); 2492 } 2493 2494 2495 void Assembler::movsd(XMMRegister dst, const Operand& src) { 2496 EnsureSpace ensure_space(this); 2497 emit(0xF2); // double 2498 emit_optional_rex_32(dst, src); 2499 emit(0x0F); 2500 emit(0x10); // load 2501 emit_sse_operand(dst, src); 2502 } 2503 2504 2505 void Assembler::movaps(XMMRegister dst, XMMRegister src) { 2506 EnsureSpace ensure_space(this); 2507 if (src.low_bits() == 4) { 2508 // Try to avoid an unnecessary SIB byte. 2509 emit_optional_rex_32(src, dst); 2510 emit(0x0F); 2511 emit(0x29); 2512 emit_sse_operand(src, dst); 2513 } else { 2514 emit_optional_rex_32(dst, src); 2515 emit(0x0F); 2516 emit(0x28); 2517 emit_sse_operand(dst, src); 2518 } 2519 } 2520 2521 2522 void Assembler::shufps(XMMRegister dst, XMMRegister src, byte imm8) { 2523 DCHECK(is_uint8(imm8)); 2524 EnsureSpace ensure_space(this); 2525 emit_optional_rex_32(src, dst); 2526 emit(0x0F); 2527 emit(0xC6); 2528 emit_sse_operand(dst, src); 2529 emit(imm8); 2530 } 2531 2532 2533 void Assembler::movapd(XMMRegister dst, XMMRegister src) { 2534 EnsureSpace ensure_space(this); 2535 if (src.low_bits() == 4) { 2536 // Try to avoid an unnecessary SIB byte. 2537 emit(0x66); 2538 emit_optional_rex_32(src, dst); 2539 emit(0x0F); 2540 emit(0x29); 2541 emit_sse_operand(src, dst); 2542 } else { 2543 emit(0x66); 2544 emit_optional_rex_32(dst, src); 2545 emit(0x0F); 2546 emit(0x28); 2547 emit_sse_operand(dst, src); 2548 } 2549 } 2550 2551 2552 void Assembler::movss(XMMRegister dst, const Operand& src) { 2553 EnsureSpace ensure_space(this); 2554 emit(0xF3); // single 2555 emit_optional_rex_32(dst, src); 2556 emit(0x0F); 2557 emit(0x10); // load 2558 emit_sse_operand(dst, src); 2559 } 2560 2561 2562 void Assembler::movss(const Operand& src, XMMRegister dst) { 2563 EnsureSpace ensure_space(this); 2564 emit(0xF3); // single 2565 emit_optional_rex_32(dst, src); 2566 emit(0x0F); 2567 emit(0x11); // store 2568 emit_sse_operand(dst, src); 2569 } 2570 2571 2572 void Assembler::psllq(XMMRegister reg, byte imm8) { 2573 EnsureSpace ensure_space(this); 2574 emit(0x66); 2575 emit(0x0F); 2576 emit(0x73); 2577 emit_sse_operand(rsi, reg); // rsi == 6 2578 emit(imm8); 2579 } 2580 2581 2582 void Assembler::cvttss2si(Register dst, const Operand& src) { 2583 EnsureSpace ensure_space(this); 2584 emit(0xF3); 2585 emit_optional_rex_32(dst, src); 2586 emit(0x0F); 2587 emit(0x2C); 2588 emit_operand(dst, src); 2589 } 2590 2591 2592 void Assembler::cvttss2si(Register dst, XMMRegister src) { 2593 EnsureSpace ensure_space(this); 2594 emit(0xF3); 2595 emit_optional_rex_32(dst, src); 2596 emit(0x0F); 2597 emit(0x2C); 2598 emit_sse_operand(dst, src); 2599 } 2600 2601 2602 void Assembler::cvttsd2si(Register dst, const Operand& src) { 2603 EnsureSpace ensure_space(this); 2604 emit(0xF2); 2605 emit_optional_rex_32(dst, src); 2606 emit(0x0F); 2607 emit(0x2C); 2608 emit_operand(dst, src); 2609 } 2610 2611 2612 void Assembler::cvttsd2si(Register dst, XMMRegister src) { 2613 EnsureSpace ensure_space(this); 2614 emit(0xF2); 2615 emit_optional_rex_32(dst, src); 2616 emit(0x0F); 2617 emit(0x2C); 2618 emit_sse_operand(dst, src); 2619 } 2620 2621 2622 void Assembler::cvttsd2siq(Register dst, XMMRegister src) { 2623 EnsureSpace ensure_space(this); 2624 emit(0xF2); 2625 emit_rex_64(dst, src); 2626 emit(0x0F); 2627 emit(0x2C); 2628 emit_sse_operand(dst, src); 2629 } 2630 2631 2632 void Assembler::cvttsd2siq(Register dst, const Operand& src) { 2633 EnsureSpace ensure_space(this); 2634 emit(0xF2); 2635 emit_rex_64(dst, src); 2636 emit(0x0F); 2637 emit(0x2C); 2638 emit_sse_operand(dst, src); 2639 } 2640 2641 2642 void Assembler::cvtlsi2sd(XMMRegister dst, const Operand& src) { 2643 EnsureSpace ensure_space(this); 2644 emit(0xF2); 2645 emit_optional_rex_32(dst, src); 2646 emit(0x0F); 2647 emit(0x2A); 2648 emit_sse_operand(dst, src); 2649 } 2650 2651 2652 void Assembler::cvtlsi2sd(XMMRegister dst, Register src) { 2653 EnsureSpace ensure_space(this); 2654 emit(0xF2); 2655 emit_optional_rex_32(dst, src); 2656 emit(0x0F); 2657 emit(0x2A); 2658 emit_sse_operand(dst, src); 2659 } 2660 2661 2662 void Assembler::cvtlsi2ss(XMMRegister dst, Register src) { 2663 EnsureSpace ensure_space(this); 2664 emit(0xF3); 2665 emit_optional_rex_32(dst, src); 2666 emit(0x0F); 2667 emit(0x2A); 2668 emit_sse_operand(dst, src); 2669 } 2670 2671 2672 void Assembler::cvtqsi2sd(XMMRegister dst, Register src) { 2673 EnsureSpace ensure_space(this); 2674 emit(0xF2); 2675 emit_rex_64(dst, src); 2676 emit(0x0F); 2677 emit(0x2A); 2678 emit_sse_operand(dst, src); 2679 } 2680 2681 2682 void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) { 2683 EnsureSpace ensure_space(this); 2684 emit(0xF3); 2685 emit_optional_rex_32(dst, src); 2686 emit(0x0F); 2687 emit(0x5A); 2688 emit_sse_operand(dst, src); 2689 } 2690 2691 2692 void Assembler::cvtss2sd(XMMRegister dst, const Operand& src) { 2693 EnsureSpace ensure_space(this); 2694 emit(0xF3); 2695 emit_optional_rex_32(dst, src); 2696 emit(0x0F); 2697 emit(0x5A); 2698 emit_sse_operand(dst, src); 2699 } 2700 2701 2702 void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) { 2703 EnsureSpace ensure_space(this); 2704 emit(0xF2); 2705 emit_optional_rex_32(dst, src); 2706 emit(0x0F); 2707 emit(0x5A); 2708 emit_sse_operand(dst, src); 2709 } 2710 2711 2712 void Assembler::cvtsd2si(Register dst, XMMRegister src) { 2713 EnsureSpace ensure_space(this); 2714 emit(0xF2); 2715 emit_optional_rex_32(dst, src); 2716 emit(0x0F); 2717 emit(0x2D); 2718 emit_sse_operand(dst, src); 2719 } 2720 2721 2722 void Assembler::cvtsd2siq(Register dst, XMMRegister src) { 2723 EnsureSpace ensure_space(this); 2724 emit(0xF2); 2725 emit_rex_64(dst, src); 2726 emit(0x0F); 2727 emit(0x2D); 2728 emit_sse_operand(dst, src); 2729 } 2730 2731 2732 void Assembler::addsd(XMMRegister dst, XMMRegister src) { 2733 EnsureSpace ensure_space(this); 2734 emit(0xF2); 2735 emit_optional_rex_32(dst, src); 2736 emit(0x0F); 2737 emit(0x58); 2738 emit_sse_operand(dst, src); 2739 } 2740 2741 2742 void Assembler::addsd(XMMRegister dst, const Operand& src) { 2743 EnsureSpace ensure_space(this); 2744 emit(0xF2); 2745 emit_optional_rex_32(dst, src); 2746 emit(0x0F); 2747 emit(0x58); 2748 emit_sse_operand(dst, src); 2749 } 2750 2751 2752 void Assembler::mulsd(XMMRegister dst, XMMRegister src) { 2753 EnsureSpace ensure_space(this); 2754 emit(0xF2); 2755 emit_optional_rex_32(dst, src); 2756 emit(0x0F); 2757 emit(0x59); 2758 emit_sse_operand(dst, src); 2759 } 2760 2761 2762 void Assembler::mulsd(XMMRegister dst, const Operand& src) { 2763 EnsureSpace ensure_space(this); 2764 emit(0xF2); 2765 emit_optional_rex_32(dst, src); 2766 emit(0x0F); 2767 emit(0x59); 2768 emit_sse_operand(dst, src); 2769 } 2770 2771 2772 void Assembler::subsd(XMMRegister dst, XMMRegister src) { 2773 EnsureSpace ensure_space(this); 2774 emit(0xF2); 2775 emit_optional_rex_32(dst, src); 2776 emit(0x0F); 2777 emit(0x5C); 2778 emit_sse_operand(dst, src); 2779 } 2780 2781 2782 void Assembler::divsd(XMMRegister dst, XMMRegister src) { 2783 EnsureSpace ensure_space(this); 2784 emit(0xF2); 2785 emit_optional_rex_32(dst, src); 2786 emit(0x0F); 2787 emit(0x5E); 2788 emit_sse_operand(dst, src); 2789 } 2790 2791 2792 void Assembler::andpd(XMMRegister dst, XMMRegister src) { 2793 EnsureSpace ensure_space(this); 2794 emit(0x66); 2795 emit_optional_rex_32(dst, src); 2796 emit(0x0F); 2797 emit(0x54); 2798 emit_sse_operand(dst, src); 2799 } 2800 2801 2802 void Assembler::orpd(XMMRegister dst, XMMRegister src) { 2803 EnsureSpace ensure_space(this); 2804 emit(0x66); 2805 emit_optional_rex_32(dst, src); 2806 emit(0x0F); 2807 emit(0x56); 2808 emit_sse_operand(dst, src); 2809 } 2810 2811 2812 void Assembler::xorpd(XMMRegister dst, XMMRegister src) { 2813 EnsureSpace ensure_space(this); 2814 emit(0x66); 2815 emit_optional_rex_32(dst, src); 2816 emit(0x0F); 2817 emit(0x57); 2818 emit_sse_operand(dst, src); 2819 } 2820 2821 2822 void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) { 2823 EnsureSpace ensure_space(this); 2824 emit(0xF2); 2825 emit_optional_rex_32(dst, src); 2826 emit(0x0F); 2827 emit(0x51); 2828 emit_sse_operand(dst, src); 2829 } 2830 2831 2832 void Assembler::sqrtsd(XMMRegister dst, const Operand& src) { 2833 EnsureSpace ensure_space(this); 2834 emit(0xF2); 2835 emit_optional_rex_32(dst, src); 2836 emit(0x0F); 2837 emit(0x51); 2838 emit_sse_operand(dst, src); 2839 } 2840 2841 2842 void Assembler::ucomisd(XMMRegister dst, XMMRegister src) { 2843 EnsureSpace ensure_space(this); 2844 emit(0x66); 2845 emit_optional_rex_32(dst, src); 2846 emit(0x0f); 2847 emit(0x2e); 2848 emit_sse_operand(dst, src); 2849 } 2850 2851 2852 void Assembler::ucomisd(XMMRegister dst, const Operand& src) { 2853 EnsureSpace ensure_space(this); 2854 emit(0x66); 2855 emit_optional_rex_32(dst, src); 2856 emit(0x0f); 2857 emit(0x2e); 2858 emit_sse_operand(dst, src); 2859 } 2860 2861 2862 void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) { 2863 EnsureSpace ensure_space(this); 2864 emit(0xF2); 2865 emit_optional_rex_32(dst, src); 2866 emit(0x0F); 2867 emit(0xC2); 2868 emit_sse_operand(dst, src); 2869 emit(0x01); // LT == 1 2870 } 2871 2872 2873 void Assembler::roundsd(XMMRegister dst, XMMRegister src, 2874 Assembler::RoundingMode mode) { 2875 DCHECK(IsEnabled(SSE4_1)); 2876 EnsureSpace ensure_space(this); 2877 emit(0x66); 2878 emit_optional_rex_32(dst, src); 2879 emit(0x0f); 2880 emit(0x3a); 2881 emit(0x0b); 2882 emit_sse_operand(dst, src); 2883 // Mask precision exeption. 2884 emit(static_cast<byte>(mode) | 0x8); 2885 } 2886 2887 2888 void Assembler::movmskpd(Register dst, XMMRegister src) { 2889 EnsureSpace ensure_space(this); 2890 emit(0x66); 2891 emit_optional_rex_32(dst, src); 2892 emit(0x0f); 2893 emit(0x50); 2894 emit_sse_operand(dst, src); 2895 } 2896 2897 2898 void Assembler::movmskps(Register dst, XMMRegister src) { 2899 EnsureSpace ensure_space(this); 2900 emit_optional_rex_32(dst, src); 2901 emit(0x0f); 2902 emit(0x50); 2903 emit_sse_operand(dst, src); 2904 } 2905 2906 2907 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { 2908 Register ireg = { reg.code() }; 2909 emit_operand(ireg, adr); 2910 } 2911 2912 2913 void Assembler::emit_sse_operand(Register reg, const Operand& adr) { 2914 Register ireg = {reg.code()}; 2915 emit_operand(ireg, adr); 2916 } 2917 2918 2919 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) { 2920 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); 2921 } 2922 2923 2924 void Assembler::emit_sse_operand(XMMRegister dst, Register src) { 2925 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); 2926 } 2927 2928 2929 void Assembler::emit_sse_operand(Register dst, XMMRegister src) { 2930 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); 2931 } 2932 2933 2934 void Assembler::db(uint8_t data) { 2935 EnsureSpace ensure_space(this); 2936 emit(data); 2937 } 2938 2939 2940 void Assembler::dd(uint32_t data) { 2941 EnsureSpace ensure_space(this); 2942 emitl(data); 2943 } 2944 2945 2946 // Relocation information implementations. 2947 2948 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 2949 DCHECK(!RelocInfo::IsNone(rmode)); 2950 // Don't record external references unless the heap will be serialized. 2951 if (rmode == RelocInfo::EXTERNAL_REFERENCE && 2952 !serializer_enabled() && !emit_debug_code()) { 2953 return; 2954 } else if (rmode == RelocInfo::CODE_AGE_SEQUENCE) { 2955 // Don't record psuedo relocation info for code age sequence mode. 2956 return; 2957 } 2958 RelocInfo rinfo(pc_, rmode, data, NULL); 2959 reloc_info_writer.Write(&rinfo); 2960 } 2961 2962 2963 void Assembler::RecordJSReturn() { 2964 positions_recorder()->WriteRecordedPositions(); 2965 EnsureSpace ensure_space(this); 2966 RecordRelocInfo(RelocInfo::JS_RETURN); 2967 } 2968 2969 2970 void Assembler::RecordDebugBreakSlot() { 2971 positions_recorder()->WriteRecordedPositions(); 2972 EnsureSpace ensure_space(this); 2973 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT); 2974 } 2975 2976 2977 void Assembler::RecordComment(const char* msg, bool force) { 2978 if (FLAG_code_comments || force) { 2979 EnsureSpace ensure_space(this); 2980 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg)); 2981 } 2982 } 2983 2984 2985 Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) { 2986 // No out-of-line constant pool support. 2987 DCHECK(!FLAG_enable_ool_constant_pool); 2988 return isolate->factory()->empty_constant_pool_array(); 2989 } 2990 2991 2992 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { 2993 // No out-of-line constant pool support. 2994 DCHECK(!FLAG_enable_ool_constant_pool); 2995 return; 2996 } 2997 2998 2999 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask | 3000 1 << RelocInfo::RUNTIME_ENTRY | 3001 1 << RelocInfo::INTERNAL_REFERENCE | 3002 1 << RelocInfo::CODE_AGE_SEQUENCE; 3003 3004 3005 bool RelocInfo::IsCodedSpecially() { 3006 // The deserializer needs to know whether a pointer is specially coded. Being 3007 // specially coded on x64 means that it is a relative 32 bit address, as used 3008 // by branch instructions. 3009 return (1 << rmode_) & kApplyMask; 3010 } 3011 3012 3013 bool RelocInfo::IsInConstantPool() { 3014 return false; 3015 } 3016 3017 3018 } } // namespace v8::internal 3019 3020 #endif // V8_TARGET_ARCH_X64 3021