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 13namespace v8 { 14namespace internal { 15 16// ----------------------------------------------------------------------------- 17// Implementation of CpuFeatures 18 19void 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 34void CpuFeatures::PrintTarget() { } 35void 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. 43void 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 71void 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 85const 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 91const 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 99Operand::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 118Operand::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 139Operand::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 150Operand::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 197bool 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 228static void InitCoverageLog(); 229#endif 230 231Assembler::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 253void 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 268void 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 275void Assembler::CodeTargetAlign() { 276 Align(16); // Preferred alignment of jump targets on x64. 277} 278 279 280bool 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 289void 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 324void Assembler::bind(Label* L) { 325 bind_to(L, pc_offset()); 326} 327 328 329void 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 387void 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 404void 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 415void 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 434void 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 452void 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 463void 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 474void 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 496void 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 516void 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 534void 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 555void 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 573void 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 585void 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 600void 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 620void 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 628void 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 637void 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 646void 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 655void 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 676void 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 686void 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 697void 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 707void 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. 721void 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 733void Assembler::clc() { 734 EnsureSpace ensure_space(this); 735 emit(0xF8); 736} 737 738 739void Assembler::cld() { 740 EnsureSpace ensure_space(this); 741 emit(0xFC); 742} 743 744 745void Assembler::cdq() { 746 EnsureSpace ensure_space(this); 747 emit(0x99); 748} 749 750 751void 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 769void 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 785void 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 801void 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 817void 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 825void Assembler::cpuid() { 826 EnsureSpace ensure_space(this); 827 emit(0x0F); 828 emit(0xA2); 829} 830 831 832void Assembler::cqo() { 833 EnsureSpace ensure_space(this); 834 emit_rex_64(); 835 emit(0x99); 836} 837 838 839void 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 847void 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 855void 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 866void 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 874void 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 882void Assembler::hlt() { 883 EnsureSpace ensure_space(this); 884 emit(0xF4); 885} 886 887 888void 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 896void 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 904void 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 912void 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 921void 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 930void 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 945void 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 953void 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 961void Assembler::int3() { 962 EnsureSpace ensure_space(this); 963 emit(0xCC); 964} 965 966 967void 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 1028void 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 1038void 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 1050void 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 1092void 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 1100void 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 1109void 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 1118void 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 1127void 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 1135void 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 1153void Assembler::load_rax(ExternalReference ref) { 1154 load_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE); 1155} 1156 1157 1158void Assembler::leave() { 1159 EnsureSpace ensure_space(this); 1160 emit(0xC9); 1161} 1162 1163 1164void 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 1177void 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 1188void 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 1201void 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 1210void 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 1219void 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 1228void 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 1239void 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 1247void 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 1261void 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 1269void 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 1283void 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 1292void 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 1300void 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 1308void 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). 1315void 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 1336void 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 1345void 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 1354void 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 1363void 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 1372void 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 1380void 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 1388void 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 1399void 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 1415void 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 1426void 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 1437void Assembler::repmovsb() { 1438 EnsureSpace ensure_space(this); 1439 emit(0xF3); 1440 emit(0xA4); 1441} 1442 1443 1444void Assembler::repmovsw() { 1445 EnsureSpace ensure_space(this); 1446 emit(0x66); // Operand size override. 1447 emit(0xF3); 1448 emit(0xA4); 1449} 1450 1451 1452void Assembler::emit_repmovs(int size) { 1453 EnsureSpace ensure_space(this); 1454 emit(0xF3); 1455 emit_rex(size); 1456 emit(0xA5); 1457} 1458 1459 1460void 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 1468void 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 1476void 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 1484void Assembler::nop() { 1485 EnsureSpace ensure_space(this); 1486 emit(0x90); 1487} 1488 1489 1490void 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 1498void 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 1506void 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 1583void Assembler::popq(Register dst) { 1584 EnsureSpace ensure_space(this); 1585 emit_optional_rex_32(dst); 1586 emit(0x58 | dst.low_bits()); 1587} 1588 1589 1590void 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 1598void Assembler::popfq() { 1599 EnsureSpace ensure_space(this); 1600 emit(0x9D); 1601} 1602 1603 1604void Assembler::pushq(Register src) { 1605 EnsureSpace ensure_space(this); 1606 emit_optional_rex_32(src); 1607 emit(0x50 | src.low_bits()); 1608} 1609 1610 1611void 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 1619void 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 1631void Assembler::pushq_imm32(int32_t imm32) { 1632 EnsureSpace ensure_space(this); 1633 emit(0x68); 1634 emitl(imm32); 1635} 1636 1637 1638void Assembler::pushfq() { 1639 EnsureSpace ensure_space(this); 1640 emit(0x9C); 1641} 1642 1643 1644void 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 1657void 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 1674void 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 1683void 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 1692void 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 1710void 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 1718void 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 1736void Assembler::store_rax(ExternalReference ref) { 1737 store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE); 1738} 1739 1740 1741void 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 1758void 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 1776void 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 1786void 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 1799void 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 1813void 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 1833void 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 1847void 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 1858void Assembler::fld(int i) { 1859 EnsureSpace ensure_space(this); 1860 emit_farith(0xD9, 0xC0, i); 1861} 1862 1863 1864void Assembler::fld1() { 1865 EnsureSpace ensure_space(this); 1866 emit(0xD9); 1867 emit(0xE8); 1868} 1869 1870 1871void Assembler::fldz() { 1872 EnsureSpace ensure_space(this); 1873 emit(0xD9); 1874 emit(0xEE); 1875} 1876 1877 1878void Assembler::fldpi() { 1879 EnsureSpace ensure_space(this); 1880 emit(0xD9); 1881 emit(0xEB); 1882} 1883 1884 1885void Assembler::fldln2() { 1886 EnsureSpace ensure_space(this); 1887 emit(0xD9); 1888 emit(0xED); 1889} 1890 1891 1892void 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 1900void 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 1908void 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 1916void 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 1924void Assembler::fstp(int index) { 1925 DCHECK(is_uint3(index)); 1926 EnsureSpace ensure_space(this); 1927 emit_farith(0xDD, 0xD8, index); 1928} 1929 1930 1931void 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 1939void 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 1947void 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 1955void 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 1964void 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 1973void 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 1981void 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 1989void Assembler::fabs() { 1990 EnsureSpace ensure_space(this); 1991 emit(0xD9); 1992 emit(0xE1); 1993} 1994 1995 1996void Assembler::fchs() { 1997 EnsureSpace ensure_space(this); 1998 emit(0xD9); 1999 emit(0xE0); 2000} 2001 2002 2003void Assembler::fcos() { 2004 EnsureSpace ensure_space(this); 2005 emit(0xD9); 2006 emit(0xFF); 2007} 2008 2009 2010void Assembler::fsin() { 2011 EnsureSpace ensure_space(this); 2012 emit(0xD9); 2013 emit(0xFE); 2014} 2015 2016 2017void Assembler::fptan() { 2018 EnsureSpace ensure_space(this); 2019 emit(0xD9); 2020 emit(0xF2); 2021} 2022 2023 2024void Assembler::fyl2x() { 2025 EnsureSpace ensure_space(this); 2026 emit(0xD9); 2027 emit(0xF1); 2028} 2029 2030 2031void Assembler::f2xm1() { 2032 EnsureSpace ensure_space(this); 2033 emit(0xD9); 2034 emit(0xF0); 2035} 2036 2037 2038void Assembler::fscale() { 2039 EnsureSpace ensure_space(this); 2040 emit(0xD9); 2041 emit(0xFD); 2042} 2043 2044 2045void Assembler::fninit() { 2046 EnsureSpace ensure_space(this); 2047 emit(0xDB); 2048 emit(0xE3); 2049} 2050 2051 2052void Assembler::fadd(int i) { 2053 EnsureSpace ensure_space(this); 2054 emit_farith(0xDC, 0xC0, i); 2055} 2056 2057 2058void Assembler::fsub(int i) { 2059 EnsureSpace ensure_space(this); 2060 emit_farith(0xDC, 0xE8, i); 2061} 2062 2063 2064void 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 2072void Assembler::fmul(int i) { 2073 EnsureSpace ensure_space(this); 2074 emit_farith(0xDC, 0xC8, i); 2075} 2076 2077 2078void Assembler::fdiv(int i) { 2079 EnsureSpace ensure_space(this); 2080 emit_farith(0xDC, 0xF8, i); 2081} 2082 2083 2084void Assembler::faddp(int i) { 2085 EnsureSpace ensure_space(this); 2086 emit_farith(0xDE, 0xC0, i); 2087} 2088 2089 2090void Assembler::fsubp(int i) { 2091 EnsureSpace ensure_space(this); 2092 emit_farith(0xDE, 0xE8, i); 2093} 2094 2095 2096void Assembler::fsubrp(int i) { 2097 EnsureSpace ensure_space(this); 2098 emit_farith(0xDE, 0xE0, i); 2099} 2100 2101 2102void Assembler::fmulp(int i) { 2103 EnsureSpace ensure_space(this); 2104 emit_farith(0xDE, 0xC8, i); 2105} 2106 2107 2108void Assembler::fdivp(int i) { 2109 EnsureSpace ensure_space(this); 2110 emit_farith(0xDE, 0xF8, i); 2111} 2112 2113 2114void Assembler::fprem() { 2115 EnsureSpace ensure_space(this); 2116 emit(0xD9); 2117 emit(0xF8); 2118} 2119 2120 2121void Assembler::fprem1() { 2122 EnsureSpace ensure_space(this); 2123 emit(0xD9); 2124 emit(0xF5); 2125} 2126 2127 2128void Assembler::fxch(int i) { 2129 EnsureSpace ensure_space(this); 2130 emit_farith(0xD9, 0xC8, i); 2131} 2132 2133 2134void Assembler::fincstp() { 2135 EnsureSpace ensure_space(this); 2136 emit(0xD9); 2137 emit(0xF7); 2138} 2139 2140 2141void Assembler::ffree(int i) { 2142 EnsureSpace ensure_space(this); 2143 emit_farith(0xDD, 0xC0, i); 2144} 2145 2146 2147void Assembler::ftst() { 2148 EnsureSpace ensure_space(this); 2149 emit(0xD9); 2150 emit(0xE4); 2151} 2152 2153 2154void Assembler::fucomp(int i) { 2155 EnsureSpace ensure_space(this); 2156 emit_farith(0xDD, 0xE8, i); 2157} 2158 2159 2160void Assembler::fucompp() { 2161 EnsureSpace ensure_space(this); 2162 emit(0xDA); 2163 emit(0xE9); 2164} 2165 2166 2167void Assembler::fucomi(int i) { 2168 EnsureSpace ensure_space(this); 2169 emit(0xDB); 2170 emit(0xE8 + i); 2171} 2172 2173 2174void Assembler::fucomip() { 2175 EnsureSpace ensure_space(this); 2176 emit(0xDF); 2177 emit(0xE9); 2178} 2179 2180 2181void Assembler::fcompp() { 2182 EnsureSpace ensure_space(this); 2183 emit(0xDE); 2184 emit(0xD9); 2185} 2186 2187 2188void Assembler::fnstsw_ax() { 2189 EnsureSpace ensure_space(this); 2190 emit(0xDF); 2191 emit(0xE0); 2192} 2193 2194 2195void Assembler::fwait() { 2196 EnsureSpace ensure_space(this); 2197 emit(0x9B); 2198} 2199 2200 2201void Assembler::frndint() { 2202 EnsureSpace ensure_space(this); 2203 emit(0xD9); 2204 emit(0xFC); 2205} 2206 2207 2208void Assembler::fnclex() { 2209 EnsureSpace ensure_space(this); 2210 emit(0xDB); 2211 emit(0xE2); 2212} 2213 2214 2215void 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 2224void 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 2234void 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 2243void 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 2252void 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 2261void 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 2270void 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 2279void 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 2288void 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 2297void 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 2306void 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 2315void 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 2324void 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 2333void 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 2342void 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 2351void 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 2362void 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 2372void 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 2382void 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 2392void 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 2402void 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 2421void 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 2431void 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 2441void 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 2451void 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 2461void 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 2475void 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 2485void 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 2495void 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 2505void 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 2522void 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 2533void 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 2552void 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 2562void 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 2572void 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 2582void 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 2592void 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 2602void 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 2612void 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 2622void 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 2632void 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 2642void 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 2652void 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 2662void 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 2672void 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 2682void 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 2692void 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 2702void 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 2712void 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 2722void 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 2732void 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 2742void 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 2752void 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 2762void 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 2772void 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 2782void 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 2792void 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 2802void 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 2812void 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 2822void 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 2832void 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 2842void 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 2852void 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 2862void 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 2873void 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 2888void 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 2898void 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 2907void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { 2908 Register ireg = { reg.code() }; 2909 emit_operand(ireg, adr); 2910} 2911 2912 2913void Assembler::emit_sse_operand(Register reg, const Operand& adr) { 2914 Register ireg = {reg.code()}; 2915 emit_operand(ireg, adr); 2916} 2917 2918 2919void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) { 2920 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); 2921} 2922 2923 2924void Assembler::emit_sse_operand(XMMRegister dst, Register src) { 2925 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); 2926} 2927 2928 2929void Assembler::emit_sse_operand(Register dst, XMMRegister src) { 2930 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); 2931} 2932 2933 2934void Assembler::db(uint8_t data) { 2935 EnsureSpace ensure_space(this); 2936 emit(data); 2937} 2938 2939 2940void Assembler::dd(uint32_t data) { 2941 EnsureSpace ensure_space(this); 2942 emitl(data); 2943} 2944 2945 2946// Relocation information implementations. 2947 2948void 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 2963void Assembler::RecordJSReturn() { 2964 positions_recorder()->WriteRecordedPositions(); 2965 EnsureSpace ensure_space(this); 2966 RecordRelocInfo(RelocInfo::JS_RETURN); 2967} 2968 2969 2970void Assembler::RecordDebugBreakSlot() { 2971 positions_recorder()->WriteRecordedPositions(); 2972 EnsureSpace ensure_space(this); 2973 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT); 2974} 2975 2976 2977void 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 2985Handle<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 2992void 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 2999const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask | 3000 1 << RelocInfo::RUNTIME_ENTRY | 3001 1 << RelocInfo::INTERNAL_REFERENCE | 3002 1 << RelocInfo::CODE_AGE_SEQUENCE; 3003 3004 3005bool 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 3013bool RelocInfo::IsInConstantPool() { 3014 return false; 3015} 3016 3017 3018} } // namespace v8::internal 3019 3020#endif // V8_TARGET_ARCH_X64 3021