1 // Copyright (c) 1994-2006 Sun Microsystems Inc. 2 // All Rights Reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions 6 // are met: 7 // 8 // - Redistributions of source code must retain the above copyright notice, 9 // this list of conditions and the following disclaimer. 10 // 11 // - Redistribution in binary form must reproduce the above copyright 12 // notice, this list of conditions and the following disclaimer in the 13 // documentation and/or other materials provided with the 14 // distribution. 15 // 16 // - Neither the name of Sun Microsystems or the names of contributors may 17 // be used to endorse or promote products derived from this software without 18 // specific prior written permission. 19 // 20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 31 // OF THE POSSIBILITY OF SUCH DAMAGE. 32 33 // The original source code covered by the above license above has been modified 34 // significantly by Google Inc. 35 // Copyright 2012 the V8 project authors. All rights reserved. 36 37 #include "src/ia32/assembler-ia32.h" 38 39 #include <cstring> 40 41 #if V8_TARGET_ARCH_IA32 42 43 #if V8_LIBC_MSVCRT 44 #include <intrin.h> // _xgetbv() 45 #endif 46 #if V8_OS_MACOSX 47 #include <sys/sysctl.h> 48 #endif 49 50 #include "src/base/bits.h" 51 #include "src/base/cpu.h" 52 #include "src/disassembler.h" 53 #include "src/macro-assembler.h" 54 #include "src/v8.h" 55 56 namespace v8 { 57 namespace internal { 58 59 // ----------------------------------------------------------------------------- 60 // Implementation of CpuFeatures 61 62 namespace { 63 64 #if !V8_LIBC_MSVCRT 65 66 V8_INLINE uint64_t _xgetbv(unsigned int xcr) { 67 unsigned eax, edx; 68 // Check xgetbv; this uses a .byte sequence instead of the instruction 69 // directly because older assemblers do not include support for xgetbv and 70 // there is no easy way to conditionally compile based on the assembler 71 // used. 72 __asm__ volatile(".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(xcr)); 73 return static_cast<uint64_t>(eax) | (static_cast<uint64_t>(edx) << 32); 74 } 75 76 #define _XCR_XFEATURE_ENABLED_MASK 0 77 78 #endif // !V8_LIBC_MSVCRT 79 80 81 bool OSHasAVXSupport() { 82 #if V8_OS_MACOSX 83 // Mac OS X up to 10.9 has a bug where AVX transitions were indeed being 84 // caused by ISRs, so we detect that here and disable AVX in that case. 85 char buffer[128]; 86 size_t buffer_size = arraysize(buffer); 87 int ctl_name[] = {CTL_KERN, KERN_OSRELEASE}; 88 if (sysctl(ctl_name, 2, buffer, &buffer_size, nullptr, 0) != 0) { 89 V8_Fatal(__FILE__, __LINE__, "V8 failed to get kernel version"); 90 } 91 // The buffer now contains a string of the form XX.YY.ZZ, where 92 // XX is the major kernel version component. 93 char* period_pos = strchr(buffer, '.'); 94 DCHECK_NOT_NULL(period_pos); 95 *period_pos = '\0'; 96 long kernel_version_major = strtol(buffer, nullptr, 10); // NOLINT 97 if (kernel_version_major <= 13) return false; 98 #endif // V8_OS_MACOSX 99 // Check whether OS claims to support AVX. 100 uint64_t feature_mask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK); 101 return (feature_mask & 0x6) == 0x6; 102 } 103 104 } // namespace 105 106 107 void CpuFeatures::ProbeImpl(bool cross_compile) { 108 base::CPU cpu; 109 CHECK(cpu.has_sse2()); // SSE2 support is mandatory. 110 CHECK(cpu.has_cmov()); // CMOV support is mandatory. 111 112 // Only use statically determined features for cross compile (snapshot). 113 if (cross_compile) return; 114 115 if (cpu.has_sse41() && FLAG_enable_sse4_1) supported_ |= 1u << SSE4_1; 116 if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3; 117 if (cpu.has_avx() && FLAG_enable_avx && cpu.has_osxsave() && 118 OSHasAVXSupport()) { 119 supported_ |= 1u << AVX; 120 } 121 if (cpu.has_fma3() && FLAG_enable_fma3 && cpu.has_osxsave() && 122 OSHasAVXSupport()) { 123 supported_ |= 1u << FMA3; 124 } 125 if (cpu.has_bmi1() && FLAG_enable_bmi1) supported_ |= 1u << BMI1; 126 if (cpu.has_bmi2() && FLAG_enable_bmi2) supported_ |= 1u << BMI2; 127 if (cpu.has_lzcnt() && FLAG_enable_lzcnt) supported_ |= 1u << LZCNT; 128 if (cpu.has_popcnt() && FLAG_enable_popcnt) supported_ |= 1u << POPCNT; 129 if (strcmp(FLAG_mcpu, "auto") == 0) { 130 if (cpu.is_atom()) supported_ |= 1u << ATOM; 131 } else if (strcmp(FLAG_mcpu, "atom") == 0) { 132 supported_ |= 1u << ATOM; 133 } 134 } 135 136 137 void CpuFeatures::PrintTarget() { } 138 void CpuFeatures::PrintFeatures() { 139 printf( 140 "SSE3=%d SSE4_1=%d AVX=%d FMA3=%d BMI1=%d BMI2=%d LZCNT=%d POPCNT=%d " 141 "ATOM=%d\n", 142 CpuFeatures::IsSupported(SSE3), CpuFeatures::IsSupported(SSE4_1), 143 CpuFeatures::IsSupported(AVX), CpuFeatures::IsSupported(FMA3), 144 CpuFeatures::IsSupported(BMI1), CpuFeatures::IsSupported(BMI2), 145 CpuFeatures::IsSupported(LZCNT), CpuFeatures::IsSupported(POPCNT), 146 CpuFeatures::IsSupported(ATOM)); 147 } 148 149 150 // ----------------------------------------------------------------------------- 151 // Implementation of Displacement 152 153 void Displacement::init(Label* L, Type type) { 154 DCHECK(!L->is_bound()); 155 int next = 0; 156 if (L->is_linked()) { 157 next = L->pos(); 158 DCHECK(next > 0); // Displacements must be at positions > 0 159 } 160 // Ensure that we _never_ overflow the next field. 161 DCHECK(NextField::is_valid(Assembler::kMaximalBufferSize)); 162 data_ = NextField::encode(next) | TypeField::encode(type); 163 } 164 165 166 // ----------------------------------------------------------------------------- 167 // Implementation of RelocInfo 168 169 170 const int RelocInfo::kApplyMask = 171 RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY | 172 1 << RelocInfo::INTERNAL_REFERENCE | 1 << RelocInfo::CODE_AGE_SEQUENCE | 173 RelocInfo::kDebugBreakSlotMask; 174 175 176 bool RelocInfo::IsCodedSpecially() { 177 // The deserializer needs to know whether a pointer is specially coded. Being 178 // specially coded on IA32 means that it is a relative address, as used by 179 // branch instructions. These are also the ones that need changing when a 180 // code object moves. 181 return (1 << rmode_) & kApplyMask; 182 } 183 184 185 bool RelocInfo::IsInConstantPool() { 186 return false; 187 } 188 189 Address RelocInfo::wasm_memory_reference() { 190 DCHECK(IsWasmMemoryReference(rmode_)); 191 return Memory::Address_at(pc_); 192 } 193 194 Address RelocInfo::wasm_global_reference() { 195 DCHECK(IsWasmGlobalReference(rmode_)); 196 return Memory::Address_at(pc_); 197 } 198 199 uint32_t RelocInfo::wasm_memory_size_reference() { 200 DCHECK(IsWasmMemorySizeReference(rmode_)); 201 return Memory::uint32_at(pc_); 202 } 203 204 uint32_t RelocInfo::wasm_function_table_size_reference() { 205 DCHECK(IsWasmFunctionTableSizeReference(rmode_)); 206 return Memory::uint32_at(pc_); 207 } 208 209 void RelocInfo::unchecked_update_wasm_memory_reference( 210 Address address, ICacheFlushMode flush_mode) { 211 Memory::Address_at(pc_) = address; 212 } 213 214 void RelocInfo::unchecked_update_wasm_size(uint32_t size, 215 ICacheFlushMode flush_mode) { 216 Memory::uint32_at(pc_) = size; 217 } 218 219 // ----------------------------------------------------------------------------- 220 // Implementation of Operand 221 222 Operand::Operand(Register base, int32_t disp, RelocInfo::Mode rmode) { 223 // [base + disp/r] 224 if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) { 225 // [base] 226 set_modrm(0, base); 227 if (base.is(esp)) set_sib(times_1, esp, base); 228 } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) { 229 // [base + disp8] 230 set_modrm(1, base); 231 if (base.is(esp)) set_sib(times_1, esp, base); 232 set_disp8(disp); 233 } else { 234 // [base + disp/r] 235 set_modrm(2, base); 236 if (base.is(esp)) set_sib(times_1, esp, base); 237 set_dispr(disp, rmode); 238 } 239 } 240 241 242 Operand::Operand(Register base, 243 Register index, 244 ScaleFactor scale, 245 int32_t disp, 246 RelocInfo::Mode rmode) { 247 DCHECK(!index.is(esp)); // illegal addressing mode 248 // [base + index*scale + disp/r] 249 if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) { 250 // [base + index*scale] 251 set_modrm(0, esp); 252 set_sib(scale, index, base); 253 } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) { 254 // [base + index*scale + disp8] 255 set_modrm(1, esp); 256 set_sib(scale, index, base); 257 set_disp8(disp); 258 } else { 259 // [base + index*scale + disp/r] 260 set_modrm(2, esp); 261 set_sib(scale, index, base); 262 set_dispr(disp, rmode); 263 } 264 } 265 266 267 Operand::Operand(Register index, 268 ScaleFactor scale, 269 int32_t disp, 270 RelocInfo::Mode rmode) { 271 DCHECK(!index.is(esp)); // illegal addressing mode 272 // [index*scale + disp/r] 273 set_modrm(0, esp); 274 set_sib(scale, index, ebp); 275 set_dispr(disp, rmode); 276 } 277 278 279 bool Operand::is_reg(Register reg) const { 280 return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only. 281 && ((buf_[0] & 0x07) == reg.code()); // register codes match. 282 } 283 284 285 bool Operand::is_reg_only() const { 286 return (buf_[0] & 0xF8) == 0xC0; // Addressing mode is register only. 287 } 288 289 290 Register Operand::reg() const { 291 DCHECK(is_reg_only()); 292 return Register::from_code(buf_[0] & 0x07); 293 } 294 295 296 // ----------------------------------------------------------------------------- 297 // Implementation of Assembler. 298 299 // Emit a single byte. Must always be inlined. 300 #define EMIT(x) \ 301 *pc_++ = (x) 302 303 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) 304 : AssemblerBase(isolate, buffer, buffer_size) { 305 // Clear the buffer in debug mode unless it was provided by the 306 // caller in which case we can't be sure it's okay to overwrite 307 // existing code in it; see CodePatcher::CodePatcher(...). 308 #ifdef DEBUG 309 if (own_buffer_) { 310 memset(buffer_, 0xCC, buffer_size_); // int3 311 } 312 #endif 313 314 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); 315 } 316 317 318 void Assembler::GetCode(CodeDesc* desc) { 319 // Finalize code (at this point overflow() may be true, but the gap ensures 320 // that we are still not overlapping instructions and relocation info). 321 DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap. 322 // Set up code descriptor. 323 desc->buffer = buffer_; 324 desc->buffer_size = buffer_size_; 325 desc->instr_size = pc_offset(); 326 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); 327 desc->origin = this; 328 desc->constant_pool_size = 0; 329 desc->unwinding_info_size = 0; 330 desc->unwinding_info = nullptr; 331 } 332 333 334 void Assembler::Align(int m) { 335 DCHECK(base::bits::IsPowerOfTwo32(m)); 336 int mask = m - 1; 337 int addr = pc_offset(); 338 Nop((m - (addr & mask)) & mask); 339 } 340 341 342 bool Assembler::IsNop(Address addr) { 343 Address a = addr; 344 while (*a == 0x66) a++; 345 if (*a == 0x90) return true; 346 if (a[0] == 0xf && a[1] == 0x1f) return true; 347 return false; 348 } 349 350 351 void Assembler::Nop(int bytes) { 352 EnsureSpace ensure_space(this); 353 354 // Multi byte nops from http://support.amd.com/us/Processor_TechDocs/40546.pdf 355 while (bytes > 0) { 356 switch (bytes) { 357 case 2: 358 EMIT(0x66); 359 case 1: 360 EMIT(0x90); 361 return; 362 case 3: 363 EMIT(0xf); 364 EMIT(0x1f); 365 EMIT(0); 366 return; 367 case 4: 368 EMIT(0xf); 369 EMIT(0x1f); 370 EMIT(0x40); 371 EMIT(0); 372 return; 373 case 6: 374 EMIT(0x66); 375 case 5: 376 EMIT(0xf); 377 EMIT(0x1f); 378 EMIT(0x44); 379 EMIT(0); 380 EMIT(0); 381 return; 382 case 7: 383 EMIT(0xf); 384 EMIT(0x1f); 385 EMIT(0x80); 386 EMIT(0); 387 EMIT(0); 388 EMIT(0); 389 EMIT(0); 390 return; 391 default: 392 case 11: 393 EMIT(0x66); 394 bytes--; 395 case 10: 396 EMIT(0x66); 397 bytes--; 398 case 9: 399 EMIT(0x66); 400 bytes--; 401 case 8: 402 EMIT(0xf); 403 EMIT(0x1f); 404 EMIT(0x84); 405 EMIT(0); 406 EMIT(0); 407 EMIT(0); 408 EMIT(0); 409 EMIT(0); 410 bytes -= 8; 411 } 412 } 413 } 414 415 416 void Assembler::CodeTargetAlign() { 417 Align(16); // Preferred alignment of jump targets on ia32. 418 } 419 420 421 void Assembler::cpuid() { 422 EnsureSpace ensure_space(this); 423 EMIT(0x0F); 424 EMIT(0xA2); 425 } 426 427 428 void Assembler::pushad() { 429 EnsureSpace ensure_space(this); 430 EMIT(0x60); 431 } 432 433 434 void Assembler::popad() { 435 EnsureSpace ensure_space(this); 436 EMIT(0x61); 437 } 438 439 440 void Assembler::pushfd() { 441 EnsureSpace ensure_space(this); 442 EMIT(0x9C); 443 } 444 445 446 void Assembler::popfd() { 447 EnsureSpace ensure_space(this); 448 EMIT(0x9D); 449 } 450 451 452 void Assembler::push(const Immediate& x) { 453 EnsureSpace ensure_space(this); 454 if (x.is_int8()) { 455 EMIT(0x6a); 456 EMIT(x.x_); 457 } else { 458 EMIT(0x68); 459 emit(x); 460 } 461 } 462 463 464 void Assembler::push_imm32(int32_t imm32) { 465 EnsureSpace ensure_space(this); 466 EMIT(0x68); 467 emit(imm32); 468 } 469 470 471 void Assembler::push(Register src) { 472 EnsureSpace ensure_space(this); 473 EMIT(0x50 | src.code()); 474 } 475 476 477 void Assembler::push(const Operand& src) { 478 EnsureSpace ensure_space(this); 479 EMIT(0xFF); 480 emit_operand(esi, src); 481 } 482 483 484 void Assembler::pop(Register dst) { 485 DCHECK(reloc_info_writer.last_pc() != NULL); 486 EnsureSpace ensure_space(this); 487 EMIT(0x58 | dst.code()); 488 } 489 490 491 void Assembler::pop(const Operand& dst) { 492 EnsureSpace ensure_space(this); 493 EMIT(0x8F); 494 emit_operand(eax, dst); 495 } 496 497 498 void Assembler::enter(const Immediate& size) { 499 EnsureSpace ensure_space(this); 500 EMIT(0xC8); 501 emit_w(size); 502 EMIT(0); 503 } 504 505 506 void Assembler::leave() { 507 EnsureSpace ensure_space(this); 508 EMIT(0xC9); 509 } 510 511 512 void Assembler::mov_b(Register dst, const Operand& src) { 513 CHECK(dst.is_byte_register()); 514 EnsureSpace ensure_space(this); 515 EMIT(0x8A); 516 emit_operand(dst, src); 517 } 518 519 520 void Assembler::mov_b(const Operand& dst, const Immediate& src) { 521 EnsureSpace ensure_space(this); 522 EMIT(0xC6); 523 emit_operand(eax, dst); 524 EMIT(static_cast<int8_t>(src.x_)); 525 } 526 527 528 void Assembler::mov_b(const Operand& dst, Register src) { 529 CHECK(src.is_byte_register()); 530 EnsureSpace ensure_space(this); 531 EMIT(0x88); 532 emit_operand(src, dst); 533 } 534 535 536 void Assembler::mov_w(Register dst, const Operand& src) { 537 EnsureSpace ensure_space(this); 538 EMIT(0x66); 539 EMIT(0x8B); 540 emit_operand(dst, src); 541 } 542 543 544 void Assembler::mov_w(const Operand& dst, Register src) { 545 EnsureSpace ensure_space(this); 546 EMIT(0x66); 547 EMIT(0x89); 548 emit_operand(src, dst); 549 } 550 551 552 void Assembler::mov_w(const Operand& dst, const Immediate& src) { 553 EnsureSpace ensure_space(this); 554 EMIT(0x66); 555 EMIT(0xC7); 556 emit_operand(eax, dst); 557 EMIT(static_cast<int8_t>(src.x_ & 0xff)); 558 EMIT(static_cast<int8_t>(src.x_ >> 8)); 559 } 560 561 562 void Assembler::mov(Register dst, int32_t imm32) { 563 EnsureSpace ensure_space(this); 564 EMIT(0xB8 | dst.code()); 565 emit(imm32); 566 } 567 568 569 void Assembler::mov(Register dst, const Immediate& x) { 570 EnsureSpace ensure_space(this); 571 EMIT(0xB8 | dst.code()); 572 emit(x); 573 } 574 575 576 void Assembler::mov(Register dst, Handle<Object> handle) { 577 EnsureSpace ensure_space(this); 578 EMIT(0xB8 | dst.code()); 579 emit(handle); 580 } 581 582 583 void Assembler::mov(Register dst, const Operand& src) { 584 EnsureSpace ensure_space(this); 585 EMIT(0x8B); 586 emit_operand(dst, src); 587 } 588 589 590 void Assembler::mov(Register dst, Register src) { 591 EnsureSpace ensure_space(this); 592 EMIT(0x89); 593 EMIT(0xC0 | src.code() << 3 | dst.code()); 594 } 595 596 597 void Assembler::mov(const Operand& dst, const Immediate& x) { 598 EnsureSpace ensure_space(this); 599 EMIT(0xC7); 600 emit_operand(eax, dst); 601 emit(x); 602 } 603 604 605 void Assembler::mov(const Operand& dst, Handle<Object> handle) { 606 EnsureSpace ensure_space(this); 607 EMIT(0xC7); 608 emit_operand(eax, dst); 609 emit(handle); 610 } 611 612 613 void Assembler::mov(const Operand& dst, Register src) { 614 EnsureSpace ensure_space(this); 615 EMIT(0x89); 616 emit_operand(src, dst); 617 } 618 619 620 void Assembler::movsx_b(Register dst, const Operand& src) { 621 EnsureSpace ensure_space(this); 622 EMIT(0x0F); 623 EMIT(0xBE); 624 emit_operand(dst, src); 625 } 626 627 628 void Assembler::movsx_w(Register dst, const Operand& src) { 629 EnsureSpace ensure_space(this); 630 EMIT(0x0F); 631 EMIT(0xBF); 632 emit_operand(dst, src); 633 } 634 635 636 void Assembler::movzx_b(Register dst, const Operand& src) { 637 EnsureSpace ensure_space(this); 638 EMIT(0x0F); 639 EMIT(0xB6); 640 emit_operand(dst, src); 641 } 642 643 644 void Assembler::movzx_w(Register dst, const Operand& src) { 645 EnsureSpace ensure_space(this); 646 EMIT(0x0F); 647 EMIT(0xB7); 648 emit_operand(dst, src); 649 } 650 651 652 void Assembler::cmov(Condition cc, Register dst, const Operand& src) { 653 EnsureSpace ensure_space(this); 654 // Opcode: 0f 40 + cc /r. 655 EMIT(0x0F); 656 EMIT(0x40 + cc); 657 emit_operand(dst, src); 658 } 659 660 661 void Assembler::cld() { 662 EnsureSpace ensure_space(this); 663 EMIT(0xFC); 664 } 665 666 667 void Assembler::rep_movs() { 668 EnsureSpace ensure_space(this); 669 EMIT(0xF3); 670 EMIT(0xA5); 671 } 672 673 674 void Assembler::rep_stos() { 675 EnsureSpace ensure_space(this); 676 EMIT(0xF3); 677 EMIT(0xAB); 678 } 679 680 681 void Assembler::stos() { 682 EnsureSpace ensure_space(this); 683 EMIT(0xAB); 684 } 685 686 687 void Assembler::xchg(Register dst, Register src) { 688 EnsureSpace ensure_space(this); 689 if (src.is(eax) || dst.is(eax)) { // Single-byte encoding. 690 EMIT(0x90 | (src.is(eax) ? dst.code() : src.code())); 691 } else { 692 EMIT(0x87); 693 EMIT(0xC0 | src.code() << 3 | dst.code()); 694 } 695 } 696 697 698 void Assembler::xchg(Register dst, const Operand& src) { 699 EnsureSpace ensure_space(this); 700 EMIT(0x87); 701 emit_operand(dst, src); 702 } 703 704 void Assembler::xchg_b(Register reg, const Operand& op) { 705 EnsureSpace ensure_space(this); 706 EMIT(0x86); 707 emit_operand(reg, op); 708 } 709 710 void Assembler::xchg_w(Register reg, const Operand& op) { 711 EnsureSpace ensure_space(this); 712 EMIT(0x66); 713 EMIT(0x87); 714 emit_operand(reg, op); 715 } 716 717 void Assembler::lock() { 718 EnsureSpace ensure_space(this); 719 EMIT(0xF0); 720 } 721 722 void Assembler::cmpxchg(const Operand& dst, Register src) { 723 EnsureSpace ensure_space(this); 724 EMIT(0x0F); 725 EMIT(0xB1); 726 emit_operand(src, dst); 727 } 728 729 void Assembler::cmpxchg_b(const Operand& dst, Register src) { 730 EnsureSpace ensure_space(this); 731 EMIT(0x0F); 732 EMIT(0xB0); 733 emit_operand(src, dst); 734 } 735 736 void Assembler::cmpxchg_w(const Operand& dst, Register src) { 737 EnsureSpace ensure_space(this); 738 EMIT(0x66); 739 EMIT(0x0F); 740 EMIT(0xB1); 741 emit_operand(src, dst); 742 } 743 744 void Assembler::adc(Register dst, int32_t imm32) { 745 EnsureSpace ensure_space(this); 746 emit_arith(2, Operand(dst), Immediate(imm32)); 747 } 748 749 750 void Assembler::adc(Register dst, const Operand& src) { 751 EnsureSpace ensure_space(this); 752 EMIT(0x13); 753 emit_operand(dst, src); 754 } 755 756 757 void Assembler::add(Register dst, const Operand& src) { 758 EnsureSpace ensure_space(this); 759 EMIT(0x03); 760 emit_operand(dst, src); 761 } 762 763 764 void Assembler::add(const Operand& dst, Register src) { 765 EnsureSpace ensure_space(this); 766 EMIT(0x01); 767 emit_operand(src, dst); 768 } 769 770 771 void Assembler::add(const Operand& dst, const Immediate& x) { 772 DCHECK(reloc_info_writer.last_pc() != NULL); 773 EnsureSpace ensure_space(this); 774 emit_arith(0, dst, x); 775 } 776 777 778 void Assembler::and_(Register dst, int32_t imm32) { 779 and_(dst, Immediate(imm32)); 780 } 781 782 783 void Assembler::and_(Register dst, const Immediate& x) { 784 EnsureSpace ensure_space(this); 785 emit_arith(4, Operand(dst), x); 786 } 787 788 789 void Assembler::and_(Register dst, const Operand& src) { 790 EnsureSpace ensure_space(this); 791 EMIT(0x23); 792 emit_operand(dst, src); 793 } 794 795 796 void Assembler::and_(const Operand& dst, const Immediate& x) { 797 EnsureSpace ensure_space(this); 798 emit_arith(4, dst, x); 799 } 800 801 802 void Assembler::and_(const Operand& dst, Register src) { 803 EnsureSpace ensure_space(this); 804 EMIT(0x21); 805 emit_operand(src, dst); 806 } 807 808 void Assembler::cmpb(const Operand& op, Immediate imm8) { 809 DCHECK(imm8.is_int8() || imm8.is_uint8()); 810 EnsureSpace ensure_space(this); 811 if (op.is_reg(eax)) { 812 EMIT(0x3C); 813 } else { 814 EMIT(0x80); 815 emit_operand(edi, op); // edi == 7 816 } 817 emit_b(imm8); 818 } 819 820 821 void Assembler::cmpb(const Operand& op, Register reg) { 822 CHECK(reg.is_byte_register()); 823 EnsureSpace ensure_space(this); 824 EMIT(0x38); 825 emit_operand(reg, op); 826 } 827 828 829 void Assembler::cmpb(Register reg, const Operand& op) { 830 CHECK(reg.is_byte_register()); 831 EnsureSpace ensure_space(this); 832 EMIT(0x3A); 833 emit_operand(reg, op); 834 } 835 836 837 void Assembler::cmpw(const Operand& op, Immediate imm16) { 838 DCHECK(imm16.is_int16() || imm16.is_uint16()); 839 EnsureSpace ensure_space(this); 840 EMIT(0x66); 841 EMIT(0x81); 842 emit_operand(edi, op); 843 emit_w(imm16); 844 } 845 846 void Assembler::cmpw(Register reg, const Operand& op) { 847 EnsureSpace ensure_space(this); 848 EMIT(0x66); 849 EMIT(0x3B); 850 emit_operand(reg, op); 851 } 852 853 void Assembler::cmpw(const Operand& op, Register reg) { 854 EnsureSpace ensure_space(this); 855 EMIT(0x66); 856 EMIT(0x39); 857 emit_operand(reg, op); 858 } 859 860 void Assembler::cmp(Register reg, int32_t imm32) { 861 EnsureSpace ensure_space(this); 862 emit_arith(7, Operand(reg), Immediate(imm32)); 863 } 864 865 866 void Assembler::cmp(Register reg, Handle<Object> handle) { 867 EnsureSpace ensure_space(this); 868 emit_arith(7, Operand(reg), Immediate(handle)); 869 } 870 871 872 void Assembler::cmp(Register reg, const Operand& op) { 873 EnsureSpace ensure_space(this); 874 EMIT(0x3B); 875 emit_operand(reg, op); 876 } 877 878 void Assembler::cmp(const Operand& op, Register reg) { 879 EnsureSpace ensure_space(this); 880 EMIT(0x39); 881 emit_operand(reg, op); 882 } 883 884 void Assembler::cmp(const Operand& op, const Immediate& imm) { 885 EnsureSpace ensure_space(this); 886 emit_arith(7, op, imm); 887 } 888 889 890 void Assembler::cmp(const Operand& op, Handle<Object> handle) { 891 EnsureSpace ensure_space(this); 892 emit_arith(7, op, Immediate(handle)); 893 } 894 895 896 void Assembler::cmpb_al(const Operand& op) { 897 EnsureSpace ensure_space(this); 898 EMIT(0x38); // CMP r/m8, r8 899 emit_operand(eax, op); // eax has same code as register al. 900 } 901 902 903 void Assembler::cmpw_ax(const Operand& op) { 904 EnsureSpace ensure_space(this); 905 EMIT(0x66); 906 EMIT(0x39); // CMP r/m16, r16 907 emit_operand(eax, op); // eax has same code as register ax. 908 } 909 910 911 void Assembler::dec_b(Register dst) { 912 CHECK(dst.is_byte_register()); 913 EnsureSpace ensure_space(this); 914 EMIT(0xFE); 915 EMIT(0xC8 | dst.code()); 916 } 917 918 919 void Assembler::dec_b(const Operand& dst) { 920 EnsureSpace ensure_space(this); 921 EMIT(0xFE); 922 emit_operand(ecx, dst); 923 } 924 925 926 void Assembler::dec(Register dst) { 927 EnsureSpace ensure_space(this); 928 EMIT(0x48 | dst.code()); 929 } 930 931 932 void Assembler::dec(const Operand& dst) { 933 EnsureSpace ensure_space(this); 934 EMIT(0xFF); 935 emit_operand(ecx, dst); 936 } 937 938 939 void Assembler::cdq() { 940 EnsureSpace ensure_space(this); 941 EMIT(0x99); 942 } 943 944 945 void Assembler::idiv(const Operand& src) { 946 EnsureSpace ensure_space(this); 947 EMIT(0xF7); 948 emit_operand(edi, src); 949 } 950 951 952 void Assembler::div(const Operand& src) { 953 EnsureSpace ensure_space(this); 954 EMIT(0xF7); 955 emit_operand(esi, src); 956 } 957 958 959 void Assembler::imul(Register reg) { 960 EnsureSpace ensure_space(this); 961 EMIT(0xF7); 962 EMIT(0xE8 | reg.code()); 963 } 964 965 966 void Assembler::imul(Register dst, const Operand& src) { 967 EnsureSpace ensure_space(this); 968 EMIT(0x0F); 969 EMIT(0xAF); 970 emit_operand(dst, src); 971 } 972 973 974 void Assembler::imul(Register dst, Register src, int32_t imm32) { 975 imul(dst, Operand(src), imm32); 976 } 977 978 979 void Assembler::imul(Register dst, const Operand& src, int32_t imm32) { 980 EnsureSpace ensure_space(this); 981 if (is_int8(imm32)) { 982 EMIT(0x6B); 983 emit_operand(dst, src); 984 EMIT(imm32); 985 } else { 986 EMIT(0x69); 987 emit_operand(dst, src); 988 emit(imm32); 989 } 990 } 991 992 993 void Assembler::inc(Register dst) { 994 EnsureSpace ensure_space(this); 995 EMIT(0x40 | dst.code()); 996 } 997 998 999 void Assembler::inc(const Operand& dst) { 1000 EnsureSpace ensure_space(this); 1001 EMIT(0xFF); 1002 emit_operand(eax, dst); 1003 } 1004 1005 1006 void Assembler::lea(Register dst, const Operand& src) { 1007 EnsureSpace ensure_space(this); 1008 EMIT(0x8D); 1009 emit_operand(dst, src); 1010 } 1011 1012 1013 void Assembler::mul(Register src) { 1014 EnsureSpace ensure_space(this); 1015 EMIT(0xF7); 1016 EMIT(0xE0 | src.code()); 1017 } 1018 1019 1020 void Assembler::neg(Register dst) { 1021 EnsureSpace ensure_space(this); 1022 EMIT(0xF7); 1023 EMIT(0xD8 | dst.code()); 1024 } 1025 1026 1027 void Assembler::neg(const Operand& dst) { 1028 EnsureSpace ensure_space(this); 1029 EMIT(0xF7); 1030 emit_operand(ebx, dst); 1031 } 1032 1033 1034 void Assembler::not_(Register dst) { 1035 EnsureSpace ensure_space(this); 1036 EMIT(0xF7); 1037 EMIT(0xD0 | dst.code()); 1038 } 1039 1040 1041 void Assembler::not_(const Operand& dst) { 1042 EnsureSpace ensure_space(this); 1043 EMIT(0xF7); 1044 emit_operand(edx, dst); 1045 } 1046 1047 1048 void Assembler::or_(Register dst, int32_t imm32) { 1049 EnsureSpace ensure_space(this); 1050 emit_arith(1, Operand(dst), Immediate(imm32)); 1051 } 1052 1053 1054 void Assembler::or_(Register dst, const Operand& src) { 1055 EnsureSpace ensure_space(this); 1056 EMIT(0x0B); 1057 emit_operand(dst, src); 1058 } 1059 1060 1061 void Assembler::or_(const Operand& dst, const Immediate& x) { 1062 EnsureSpace ensure_space(this); 1063 emit_arith(1, dst, x); 1064 } 1065 1066 1067 void Assembler::or_(const Operand& dst, Register src) { 1068 EnsureSpace ensure_space(this); 1069 EMIT(0x09); 1070 emit_operand(src, dst); 1071 } 1072 1073 1074 void Assembler::rcl(Register dst, uint8_t imm8) { 1075 EnsureSpace ensure_space(this); 1076 DCHECK(is_uint5(imm8)); // illegal shift count 1077 if (imm8 == 1) { 1078 EMIT(0xD1); 1079 EMIT(0xD0 | dst.code()); 1080 } else { 1081 EMIT(0xC1); 1082 EMIT(0xD0 | dst.code()); 1083 EMIT(imm8); 1084 } 1085 } 1086 1087 1088 void Assembler::rcr(Register dst, uint8_t imm8) { 1089 EnsureSpace ensure_space(this); 1090 DCHECK(is_uint5(imm8)); // illegal shift count 1091 if (imm8 == 1) { 1092 EMIT(0xD1); 1093 EMIT(0xD8 | dst.code()); 1094 } else { 1095 EMIT(0xC1); 1096 EMIT(0xD8 | dst.code()); 1097 EMIT(imm8); 1098 } 1099 } 1100 1101 1102 void Assembler::ror(const Operand& dst, uint8_t imm8) { 1103 EnsureSpace ensure_space(this); 1104 DCHECK(is_uint5(imm8)); // illegal shift count 1105 if (imm8 == 1) { 1106 EMIT(0xD1); 1107 emit_operand(ecx, dst); 1108 } else { 1109 EMIT(0xC1); 1110 emit_operand(ecx, dst); 1111 EMIT(imm8); 1112 } 1113 } 1114 1115 1116 void Assembler::ror_cl(const Operand& dst) { 1117 EnsureSpace ensure_space(this); 1118 EMIT(0xD3); 1119 emit_operand(ecx, dst); 1120 } 1121 1122 1123 void Assembler::sar(const Operand& dst, uint8_t imm8) { 1124 EnsureSpace ensure_space(this); 1125 DCHECK(is_uint5(imm8)); // illegal shift count 1126 if (imm8 == 1) { 1127 EMIT(0xD1); 1128 emit_operand(edi, dst); 1129 } else { 1130 EMIT(0xC1); 1131 emit_operand(edi, dst); 1132 EMIT(imm8); 1133 } 1134 } 1135 1136 1137 void Assembler::sar_cl(const Operand& dst) { 1138 EnsureSpace ensure_space(this); 1139 EMIT(0xD3); 1140 emit_operand(edi, dst); 1141 } 1142 1143 void Assembler::sbb(Register dst, const Operand& src) { 1144 EnsureSpace ensure_space(this); 1145 EMIT(0x1B); 1146 emit_operand(dst, src); 1147 } 1148 1149 void Assembler::shld(Register dst, Register src, uint8_t shift) { 1150 DCHECK(is_uint5(shift)); 1151 EnsureSpace ensure_space(this); 1152 EMIT(0x0F); 1153 EMIT(0xA4); 1154 emit_operand(src, Operand(dst)); 1155 EMIT(shift); 1156 } 1157 1158 void Assembler::shld_cl(Register dst, Register src) { 1159 EnsureSpace ensure_space(this); 1160 EMIT(0x0F); 1161 EMIT(0xA5); 1162 emit_operand(src, Operand(dst)); 1163 } 1164 1165 1166 void Assembler::shl(const Operand& dst, uint8_t imm8) { 1167 EnsureSpace ensure_space(this); 1168 DCHECK(is_uint5(imm8)); // illegal shift count 1169 if (imm8 == 1) { 1170 EMIT(0xD1); 1171 emit_operand(esp, dst); 1172 } else { 1173 EMIT(0xC1); 1174 emit_operand(esp, dst); 1175 EMIT(imm8); 1176 } 1177 } 1178 1179 1180 void Assembler::shl_cl(const Operand& dst) { 1181 EnsureSpace ensure_space(this); 1182 EMIT(0xD3); 1183 emit_operand(esp, dst); 1184 } 1185 1186 void Assembler::shr(const Operand& dst, uint8_t imm8) { 1187 EnsureSpace ensure_space(this); 1188 DCHECK(is_uint5(imm8)); // illegal shift count 1189 if (imm8 == 1) { 1190 EMIT(0xD1); 1191 emit_operand(ebp, dst); 1192 } else { 1193 EMIT(0xC1); 1194 emit_operand(ebp, dst); 1195 EMIT(imm8); 1196 } 1197 } 1198 1199 1200 void Assembler::shr_cl(const Operand& dst) { 1201 EnsureSpace ensure_space(this); 1202 EMIT(0xD3); 1203 emit_operand(ebp, dst); 1204 } 1205 1206 void Assembler::shrd(Register dst, Register src, uint8_t shift) { 1207 DCHECK(is_uint5(shift)); 1208 EnsureSpace ensure_space(this); 1209 EMIT(0x0F); 1210 EMIT(0xAC); 1211 emit_operand(dst, Operand(src)); 1212 EMIT(shift); 1213 } 1214 1215 void Assembler::shrd_cl(const Operand& dst, Register src) { 1216 EnsureSpace ensure_space(this); 1217 EMIT(0x0F); 1218 EMIT(0xAD); 1219 emit_operand(src, dst); 1220 } 1221 1222 void Assembler::sub(const Operand& dst, const Immediate& x) { 1223 EnsureSpace ensure_space(this); 1224 emit_arith(5, dst, x); 1225 } 1226 1227 1228 void Assembler::sub(Register dst, const Operand& src) { 1229 EnsureSpace ensure_space(this); 1230 EMIT(0x2B); 1231 emit_operand(dst, src); 1232 } 1233 1234 1235 void Assembler::sub(const Operand& dst, Register src) { 1236 EnsureSpace ensure_space(this); 1237 EMIT(0x29); 1238 emit_operand(src, dst); 1239 } 1240 1241 1242 void Assembler::test(Register reg, const Immediate& imm) { 1243 if (imm.is_uint8()) { 1244 test_b(reg, imm); 1245 return; 1246 } 1247 1248 EnsureSpace ensure_space(this); 1249 // This is not using emit_arith because test doesn't support 1250 // sign-extension of 8-bit operands. 1251 if (reg.is(eax)) { 1252 EMIT(0xA9); 1253 } else { 1254 EMIT(0xF7); 1255 EMIT(0xC0 | reg.code()); 1256 } 1257 emit(imm); 1258 } 1259 1260 1261 void Assembler::test(Register reg, const Operand& op) { 1262 EnsureSpace ensure_space(this); 1263 EMIT(0x85); 1264 emit_operand(reg, op); 1265 } 1266 1267 1268 void Assembler::test_b(Register reg, const Operand& op) { 1269 CHECK(reg.is_byte_register()); 1270 EnsureSpace ensure_space(this); 1271 EMIT(0x84); 1272 emit_operand(reg, op); 1273 } 1274 1275 1276 void Assembler::test(const Operand& op, const Immediate& imm) { 1277 if (op.is_reg_only()) { 1278 test(op.reg(), imm); 1279 return; 1280 } 1281 if (imm.is_uint8()) { 1282 return test_b(op, imm); 1283 } 1284 EnsureSpace ensure_space(this); 1285 EMIT(0xF7); 1286 emit_operand(eax, op); 1287 emit(imm); 1288 } 1289 1290 void Assembler::test_b(Register reg, Immediate imm8) { 1291 DCHECK(imm8.is_uint8()); 1292 EnsureSpace ensure_space(this); 1293 // Only use test against byte for registers that have a byte 1294 // variant: eax, ebx, ecx, and edx. 1295 if (reg.is(eax)) { 1296 EMIT(0xA8); 1297 emit_b(imm8); 1298 } else if (reg.is_byte_register()) { 1299 emit_arith_b(0xF6, 0xC0, reg, static_cast<uint8_t>(imm8.x_)); 1300 } else { 1301 EMIT(0x66); 1302 EMIT(0xF7); 1303 EMIT(0xC0 | reg.code()); 1304 emit_w(imm8); 1305 } 1306 } 1307 1308 void Assembler::test_b(const Operand& op, Immediate imm8) { 1309 if (op.is_reg_only()) { 1310 test_b(op.reg(), imm8); 1311 return; 1312 } 1313 EnsureSpace ensure_space(this); 1314 EMIT(0xF6); 1315 emit_operand(eax, op); 1316 emit_b(imm8); 1317 } 1318 1319 void Assembler::test_w(Register reg, Immediate imm16) { 1320 DCHECK(imm16.is_int16() || imm16.is_uint16()); 1321 EnsureSpace ensure_space(this); 1322 if (reg.is(eax)) { 1323 EMIT(0xA9); 1324 emit_w(imm16); 1325 } else { 1326 EMIT(0x66); 1327 EMIT(0xF7); 1328 EMIT(0xc0 | reg.code()); 1329 emit_w(imm16); 1330 } 1331 } 1332 1333 void Assembler::test_w(Register reg, const Operand& op) { 1334 EnsureSpace ensure_space(this); 1335 EMIT(0x66); 1336 EMIT(0x85); 1337 emit_operand(reg, op); 1338 } 1339 1340 void Assembler::test_w(const Operand& op, Immediate imm16) { 1341 DCHECK(imm16.is_int16() || imm16.is_uint16()); 1342 if (op.is_reg_only()) { 1343 test_w(op.reg(), imm16); 1344 return; 1345 } 1346 EnsureSpace ensure_space(this); 1347 EMIT(0x66); 1348 EMIT(0xF7); 1349 emit_operand(eax, op); 1350 emit_w(imm16); 1351 } 1352 1353 void Assembler::xor_(Register dst, int32_t imm32) { 1354 EnsureSpace ensure_space(this); 1355 emit_arith(6, Operand(dst), Immediate(imm32)); 1356 } 1357 1358 1359 void Assembler::xor_(Register dst, const Operand& src) { 1360 EnsureSpace ensure_space(this); 1361 EMIT(0x33); 1362 emit_operand(dst, src); 1363 } 1364 1365 1366 void Assembler::xor_(const Operand& dst, Register src) { 1367 EnsureSpace ensure_space(this); 1368 EMIT(0x31); 1369 emit_operand(src, dst); 1370 } 1371 1372 1373 void Assembler::xor_(const Operand& dst, const Immediate& x) { 1374 EnsureSpace ensure_space(this); 1375 emit_arith(6, dst, x); 1376 } 1377 1378 1379 void Assembler::bt(const Operand& dst, Register src) { 1380 EnsureSpace ensure_space(this); 1381 EMIT(0x0F); 1382 EMIT(0xA3); 1383 emit_operand(src, dst); 1384 } 1385 1386 1387 void Assembler::bts(const Operand& dst, Register src) { 1388 EnsureSpace ensure_space(this); 1389 EMIT(0x0F); 1390 EMIT(0xAB); 1391 emit_operand(src, dst); 1392 } 1393 1394 1395 void Assembler::bsr(Register dst, const Operand& src) { 1396 EnsureSpace ensure_space(this); 1397 EMIT(0x0F); 1398 EMIT(0xBD); 1399 emit_operand(dst, src); 1400 } 1401 1402 1403 void Assembler::bsf(Register dst, const Operand& src) { 1404 EnsureSpace ensure_space(this); 1405 EMIT(0x0F); 1406 EMIT(0xBC); 1407 emit_operand(dst, src); 1408 } 1409 1410 1411 void Assembler::hlt() { 1412 EnsureSpace ensure_space(this); 1413 EMIT(0xF4); 1414 } 1415 1416 1417 void Assembler::int3() { 1418 EnsureSpace ensure_space(this); 1419 EMIT(0xCC); 1420 } 1421 1422 1423 void Assembler::nop() { 1424 EnsureSpace ensure_space(this); 1425 EMIT(0x90); 1426 } 1427 1428 1429 void Assembler::ret(int imm16) { 1430 EnsureSpace ensure_space(this); 1431 DCHECK(is_uint16(imm16)); 1432 if (imm16 == 0) { 1433 EMIT(0xC3); 1434 } else { 1435 EMIT(0xC2); 1436 EMIT(imm16 & 0xFF); 1437 EMIT((imm16 >> 8) & 0xFF); 1438 } 1439 } 1440 1441 1442 void Assembler::ud2() { 1443 EnsureSpace ensure_space(this); 1444 EMIT(0x0F); 1445 EMIT(0x0B); 1446 } 1447 1448 1449 // Labels refer to positions in the (to be) generated code. 1450 // There are bound, linked, and unused labels. 1451 // 1452 // Bound labels refer to known positions in the already 1453 // generated code. pos() is the position the label refers to. 1454 // 1455 // Linked labels refer to unknown positions in the code 1456 // to be generated; pos() is the position of the 32bit 1457 // Displacement of the last instruction using the label. 1458 1459 1460 void Assembler::print(Label* L) { 1461 if (L->is_unused()) { 1462 PrintF("unused label\n"); 1463 } else if (L->is_bound()) { 1464 PrintF("bound label to %d\n", L->pos()); 1465 } else if (L->is_linked()) { 1466 Label l = *L; 1467 PrintF("unbound label"); 1468 while (l.is_linked()) { 1469 Displacement disp = disp_at(&l); 1470 PrintF("@ %d ", l.pos()); 1471 disp.print(); 1472 PrintF("\n"); 1473 disp.next(&l); 1474 } 1475 } else { 1476 PrintF("label in inconsistent state (pos = %d)\n", L->pos_); 1477 } 1478 } 1479 1480 1481 void Assembler::bind_to(Label* L, int pos) { 1482 EnsureSpace ensure_space(this); 1483 DCHECK(0 <= pos && pos <= pc_offset()); // must have a valid binding position 1484 while (L->is_linked()) { 1485 Displacement disp = disp_at(L); 1486 int fixup_pos = L->pos(); 1487 if (disp.type() == Displacement::CODE_ABSOLUTE) { 1488 long_at_put(fixup_pos, reinterpret_cast<int>(buffer_ + pos)); 1489 internal_reference_positions_.push_back(fixup_pos); 1490 } else if (disp.type() == Displacement::CODE_RELATIVE) { 1491 // Relative to Code* heap object pointer. 1492 long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag); 1493 } else { 1494 if (disp.type() == Displacement::UNCONDITIONAL_JUMP) { 1495 DCHECK(byte_at(fixup_pos - 1) == 0xE9); // jmp expected 1496 } 1497 // Relative address, relative to point after address. 1498 int imm32 = pos - (fixup_pos + sizeof(int32_t)); 1499 long_at_put(fixup_pos, imm32); 1500 } 1501 disp.next(L); 1502 } 1503 while (L->is_near_linked()) { 1504 int fixup_pos = L->near_link_pos(); 1505 int offset_to_next = 1506 static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos))); 1507 DCHECK(offset_to_next <= 0); 1508 // Relative address, relative to point after address. 1509 int disp = pos - fixup_pos - sizeof(int8_t); 1510 CHECK(0 <= disp && disp <= 127); 1511 set_byte_at(fixup_pos, disp); 1512 if (offset_to_next < 0) { 1513 L->link_to(fixup_pos + offset_to_next, Label::kNear); 1514 } else { 1515 L->UnuseNear(); 1516 } 1517 } 1518 L->bind_to(pos); 1519 } 1520 1521 1522 void Assembler::bind(Label* L) { 1523 EnsureSpace ensure_space(this); 1524 DCHECK(!L->is_bound()); // label can only be bound once 1525 bind_to(L, pc_offset()); 1526 } 1527 1528 1529 void Assembler::call(Label* L) { 1530 EnsureSpace ensure_space(this); 1531 if (L->is_bound()) { 1532 const int long_size = 5; 1533 int offs = L->pos() - pc_offset(); 1534 DCHECK(offs <= 0); 1535 // 1110 1000 #32-bit disp. 1536 EMIT(0xE8); 1537 emit(offs - long_size); 1538 } else { 1539 // 1110 1000 #32-bit disp. 1540 EMIT(0xE8); 1541 emit_disp(L, Displacement::OTHER); 1542 } 1543 } 1544 1545 1546 void Assembler::call(byte* entry, RelocInfo::Mode rmode) { 1547 EnsureSpace ensure_space(this); 1548 DCHECK(!RelocInfo::IsCodeTarget(rmode)); 1549 EMIT(0xE8); 1550 if (RelocInfo::IsRuntimeEntry(rmode)) { 1551 emit(reinterpret_cast<uint32_t>(entry), rmode); 1552 } else { 1553 emit(entry - (pc_ + sizeof(int32_t)), rmode); 1554 } 1555 } 1556 1557 1558 int Assembler::CallSize(const Operand& adr) { 1559 // Call size is 1 (opcode) + adr.len_ (operand). 1560 return 1 + adr.len_; 1561 } 1562 1563 1564 void Assembler::call(const Operand& adr) { 1565 EnsureSpace ensure_space(this); 1566 EMIT(0xFF); 1567 emit_operand(edx, adr); 1568 } 1569 1570 1571 int Assembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) { 1572 return 1 /* EMIT */ + sizeof(uint32_t) /* emit */; 1573 } 1574 1575 1576 void Assembler::call(Handle<Code> code, 1577 RelocInfo::Mode rmode, 1578 TypeFeedbackId ast_id) { 1579 EnsureSpace ensure_space(this); 1580 DCHECK(RelocInfo::IsCodeTarget(rmode) 1581 || rmode == RelocInfo::CODE_AGE_SEQUENCE); 1582 EMIT(0xE8); 1583 emit(code, rmode, ast_id); 1584 } 1585 1586 1587 void Assembler::jmp(Label* L, Label::Distance distance) { 1588 EnsureSpace ensure_space(this); 1589 if (L->is_bound()) { 1590 const int short_size = 2; 1591 const int long_size = 5; 1592 int offs = L->pos() - pc_offset(); 1593 DCHECK(offs <= 0); 1594 if (is_int8(offs - short_size)) { 1595 // 1110 1011 #8-bit disp. 1596 EMIT(0xEB); 1597 EMIT((offs - short_size) & 0xFF); 1598 } else { 1599 // 1110 1001 #32-bit disp. 1600 EMIT(0xE9); 1601 emit(offs - long_size); 1602 } 1603 } else if (distance == Label::kNear) { 1604 EMIT(0xEB); 1605 emit_near_disp(L); 1606 } else { 1607 // 1110 1001 #32-bit disp. 1608 EMIT(0xE9); 1609 emit_disp(L, Displacement::UNCONDITIONAL_JUMP); 1610 } 1611 } 1612 1613 1614 void Assembler::jmp(byte* entry, RelocInfo::Mode rmode) { 1615 EnsureSpace ensure_space(this); 1616 DCHECK(!RelocInfo::IsCodeTarget(rmode)); 1617 EMIT(0xE9); 1618 if (RelocInfo::IsRuntimeEntry(rmode)) { 1619 emit(reinterpret_cast<uint32_t>(entry), rmode); 1620 } else { 1621 emit(entry - (pc_ + sizeof(int32_t)), rmode); 1622 } 1623 } 1624 1625 1626 void Assembler::jmp(const Operand& adr) { 1627 EnsureSpace ensure_space(this); 1628 EMIT(0xFF); 1629 emit_operand(esp, adr); 1630 } 1631 1632 1633 void Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) { 1634 EnsureSpace ensure_space(this); 1635 DCHECK(RelocInfo::IsCodeTarget(rmode)); 1636 EMIT(0xE9); 1637 emit(code, rmode); 1638 } 1639 1640 1641 void Assembler::j(Condition cc, Label* L, Label::Distance distance) { 1642 EnsureSpace ensure_space(this); 1643 DCHECK(0 <= cc && static_cast<int>(cc) < 16); 1644 if (L->is_bound()) { 1645 const int short_size = 2; 1646 const int long_size = 6; 1647 int offs = L->pos() - pc_offset(); 1648 DCHECK(offs <= 0); 1649 if (is_int8(offs - short_size)) { 1650 // 0111 tttn #8-bit disp 1651 EMIT(0x70 | cc); 1652 EMIT((offs - short_size) & 0xFF); 1653 } else { 1654 // 0000 1111 1000 tttn #32-bit disp 1655 EMIT(0x0F); 1656 EMIT(0x80 | cc); 1657 emit(offs - long_size); 1658 } 1659 } else if (distance == Label::kNear) { 1660 EMIT(0x70 | cc); 1661 emit_near_disp(L); 1662 } else { 1663 // 0000 1111 1000 tttn #32-bit disp 1664 // Note: could eliminate cond. jumps to this jump if condition 1665 // is the same however, seems to be rather unlikely case. 1666 EMIT(0x0F); 1667 EMIT(0x80 | cc); 1668 emit_disp(L, Displacement::OTHER); 1669 } 1670 } 1671 1672 1673 void Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode) { 1674 EnsureSpace ensure_space(this); 1675 DCHECK((0 <= cc) && (static_cast<int>(cc) < 16)); 1676 // 0000 1111 1000 tttn #32-bit disp. 1677 EMIT(0x0F); 1678 EMIT(0x80 | cc); 1679 if (RelocInfo::IsRuntimeEntry(rmode)) { 1680 emit(reinterpret_cast<uint32_t>(entry), rmode); 1681 } else { 1682 emit(entry - (pc_ + sizeof(int32_t)), rmode); 1683 } 1684 } 1685 1686 1687 void Assembler::j(Condition cc, Handle<Code> code, RelocInfo::Mode rmode) { 1688 EnsureSpace ensure_space(this); 1689 // 0000 1111 1000 tttn #32-bit disp 1690 EMIT(0x0F); 1691 EMIT(0x80 | cc); 1692 emit(code, rmode); 1693 } 1694 1695 1696 // FPU instructions. 1697 1698 void Assembler::fld(int i) { 1699 EnsureSpace ensure_space(this); 1700 emit_farith(0xD9, 0xC0, i); 1701 } 1702 1703 1704 void Assembler::fstp(int i) { 1705 EnsureSpace ensure_space(this); 1706 emit_farith(0xDD, 0xD8, i); 1707 } 1708 1709 1710 void Assembler::fld1() { 1711 EnsureSpace ensure_space(this); 1712 EMIT(0xD9); 1713 EMIT(0xE8); 1714 } 1715 1716 1717 void Assembler::fldpi() { 1718 EnsureSpace ensure_space(this); 1719 EMIT(0xD9); 1720 EMIT(0xEB); 1721 } 1722 1723 1724 void Assembler::fldz() { 1725 EnsureSpace ensure_space(this); 1726 EMIT(0xD9); 1727 EMIT(0xEE); 1728 } 1729 1730 1731 void Assembler::fldln2() { 1732 EnsureSpace ensure_space(this); 1733 EMIT(0xD9); 1734 EMIT(0xED); 1735 } 1736 1737 1738 void Assembler::fld_s(const Operand& adr) { 1739 EnsureSpace ensure_space(this); 1740 EMIT(0xD9); 1741 emit_operand(eax, adr); 1742 } 1743 1744 1745 void Assembler::fld_d(const Operand& adr) { 1746 EnsureSpace ensure_space(this); 1747 EMIT(0xDD); 1748 emit_operand(eax, adr); 1749 } 1750 1751 1752 void Assembler::fstp_s(const Operand& adr) { 1753 EnsureSpace ensure_space(this); 1754 EMIT(0xD9); 1755 emit_operand(ebx, adr); 1756 } 1757 1758 1759 void Assembler::fst_s(const Operand& adr) { 1760 EnsureSpace ensure_space(this); 1761 EMIT(0xD9); 1762 emit_operand(edx, adr); 1763 } 1764 1765 1766 void Assembler::fstp_d(const Operand& adr) { 1767 EnsureSpace ensure_space(this); 1768 EMIT(0xDD); 1769 emit_operand(ebx, adr); 1770 } 1771 1772 1773 void Assembler::fst_d(const Operand& adr) { 1774 EnsureSpace ensure_space(this); 1775 EMIT(0xDD); 1776 emit_operand(edx, adr); 1777 } 1778 1779 1780 void Assembler::fild_s(const Operand& adr) { 1781 EnsureSpace ensure_space(this); 1782 EMIT(0xDB); 1783 emit_operand(eax, adr); 1784 } 1785 1786 1787 void Assembler::fild_d(const Operand& adr) { 1788 EnsureSpace ensure_space(this); 1789 EMIT(0xDF); 1790 emit_operand(ebp, adr); 1791 } 1792 1793 1794 void Assembler::fistp_s(const Operand& adr) { 1795 EnsureSpace ensure_space(this); 1796 EMIT(0xDB); 1797 emit_operand(ebx, adr); 1798 } 1799 1800 1801 void Assembler::fisttp_s(const Operand& adr) { 1802 DCHECK(IsEnabled(SSE3)); 1803 EnsureSpace ensure_space(this); 1804 EMIT(0xDB); 1805 emit_operand(ecx, adr); 1806 } 1807 1808 1809 void Assembler::fisttp_d(const Operand& adr) { 1810 DCHECK(IsEnabled(SSE3)); 1811 EnsureSpace ensure_space(this); 1812 EMIT(0xDD); 1813 emit_operand(ecx, adr); 1814 } 1815 1816 1817 void Assembler::fist_s(const Operand& adr) { 1818 EnsureSpace ensure_space(this); 1819 EMIT(0xDB); 1820 emit_operand(edx, adr); 1821 } 1822 1823 1824 void Assembler::fistp_d(const Operand& adr) { 1825 EnsureSpace ensure_space(this); 1826 EMIT(0xDF); 1827 emit_operand(edi, adr); 1828 } 1829 1830 1831 void Assembler::fabs() { 1832 EnsureSpace ensure_space(this); 1833 EMIT(0xD9); 1834 EMIT(0xE1); 1835 } 1836 1837 1838 void Assembler::fchs() { 1839 EnsureSpace ensure_space(this); 1840 EMIT(0xD9); 1841 EMIT(0xE0); 1842 } 1843 1844 1845 void Assembler::fcos() { 1846 EnsureSpace ensure_space(this); 1847 EMIT(0xD9); 1848 EMIT(0xFF); 1849 } 1850 1851 1852 void Assembler::fsin() { 1853 EnsureSpace ensure_space(this); 1854 EMIT(0xD9); 1855 EMIT(0xFE); 1856 } 1857 1858 1859 void Assembler::fptan() { 1860 EnsureSpace ensure_space(this); 1861 EMIT(0xD9); 1862 EMIT(0xF2); 1863 } 1864 1865 1866 void Assembler::fyl2x() { 1867 EnsureSpace ensure_space(this); 1868 EMIT(0xD9); 1869 EMIT(0xF1); 1870 } 1871 1872 1873 void Assembler::f2xm1() { 1874 EnsureSpace ensure_space(this); 1875 EMIT(0xD9); 1876 EMIT(0xF0); 1877 } 1878 1879 1880 void Assembler::fscale() { 1881 EnsureSpace ensure_space(this); 1882 EMIT(0xD9); 1883 EMIT(0xFD); 1884 } 1885 1886 1887 void Assembler::fninit() { 1888 EnsureSpace ensure_space(this); 1889 EMIT(0xDB); 1890 EMIT(0xE3); 1891 } 1892 1893 1894 void Assembler::fadd(int i) { 1895 EnsureSpace ensure_space(this); 1896 emit_farith(0xDC, 0xC0, i); 1897 } 1898 1899 1900 void Assembler::fadd_i(int i) { 1901 EnsureSpace ensure_space(this); 1902 emit_farith(0xD8, 0xC0, i); 1903 } 1904 1905 1906 void Assembler::fsub(int i) { 1907 EnsureSpace ensure_space(this); 1908 emit_farith(0xDC, 0xE8, i); 1909 } 1910 1911 1912 void Assembler::fsub_i(int i) { 1913 EnsureSpace ensure_space(this); 1914 emit_farith(0xD8, 0xE0, i); 1915 } 1916 1917 1918 void Assembler::fisub_s(const Operand& adr) { 1919 EnsureSpace ensure_space(this); 1920 EMIT(0xDA); 1921 emit_operand(esp, adr); 1922 } 1923 1924 1925 void Assembler::fmul_i(int i) { 1926 EnsureSpace ensure_space(this); 1927 emit_farith(0xD8, 0xC8, i); 1928 } 1929 1930 1931 void Assembler::fmul(int i) { 1932 EnsureSpace ensure_space(this); 1933 emit_farith(0xDC, 0xC8, i); 1934 } 1935 1936 1937 void Assembler::fdiv(int i) { 1938 EnsureSpace ensure_space(this); 1939 emit_farith(0xDC, 0xF8, i); 1940 } 1941 1942 1943 void Assembler::fdiv_i(int i) { 1944 EnsureSpace ensure_space(this); 1945 emit_farith(0xD8, 0xF0, i); 1946 } 1947 1948 1949 void Assembler::faddp(int i) { 1950 EnsureSpace ensure_space(this); 1951 emit_farith(0xDE, 0xC0, i); 1952 } 1953 1954 1955 void Assembler::fsubp(int i) { 1956 EnsureSpace ensure_space(this); 1957 emit_farith(0xDE, 0xE8, i); 1958 } 1959 1960 1961 void Assembler::fsubrp(int i) { 1962 EnsureSpace ensure_space(this); 1963 emit_farith(0xDE, 0xE0, i); 1964 } 1965 1966 1967 void Assembler::fmulp(int i) { 1968 EnsureSpace ensure_space(this); 1969 emit_farith(0xDE, 0xC8, i); 1970 } 1971 1972 1973 void Assembler::fdivp(int i) { 1974 EnsureSpace ensure_space(this); 1975 emit_farith(0xDE, 0xF8, i); 1976 } 1977 1978 1979 void Assembler::fprem() { 1980 EnsureSpace ensure_space(this); 1981 EMIT(0xD9); 1982 EMIT(0xF8); 1983 } 1984 1985 1986 void Assembler::fprem1() { 1987 EnsureSpace ensure_space(this); 1988 EMIT(0xD9); 1989 EMIT(0xF5); 1990 } 1991 1992 1993 void Assembler::fxch(int i) { 1994 EnsureSpace ensure_space(this); 1995 emit_farith(0xD9, 0xC8, i); 1996 } 1997 1998 1999 void Assembler::fincstp() { 2000 EnsureSpace ensure_space(this); 2001 EMIT(0xD9); 2002 EMIT(0xF7); 2003 } 2004 2005 2006 void Assembler::ffree(int i) { 2007 EnsureSpace ensure_space(this); 2008 emit_farith(0xDD, 0xC0, i); 2009 } 2010 2011 2012 void Assembler::ftst() { 2013 EnsureSpace ensure_space(this); 2014 EMIT(0xD9); 2015 EMIT(0xE4); 2016 } 2017 2018 2019 void Assembler::fucomp(int i) { 2020 EnsureSpace ensure_space(this); 2021 emit_farith(0xDD, 0xE8, i); 2022 } 2023 2024 2025 void Assembler::fucompp() { 2026 EnsureSpace ensure_space(this); 2027 EMIT(0xDA); 2028 EMIT(0xE9); 2029 } 2030 2031 2032 void Assembler::fucomi(int i) { 2033 EnsureSpace ensure_space(this); 2034 EMIT(0xDB); 2035 EMIT(0xE8 + i); 2036 } 2037 2038 2039 void Assembler::fucomip() { 2040 EnsureSpace ensure_space(this); 2041 EMIT(0xDF); 2042 EMIT(0xE9); 2043 } 2044 2045 2046 void Assembler::fcompp() { 2047 EnsureSpace ensure_space(this); 2048 EMIT(0xDE); 2049 EMIT(0xD9); 2050 } 2051 2052 2053 void Assembler::fnstsw_ax() { 2054 EnsureSpace ensure_space(this); 2055 EMIT(0xDF); 2056 EMIT(0xE0); 2057 } 2058 2059 2060 void Assembler::fwait() { 2061 EnsureSpace ensure_space(this); 2062 EMIT(0x9B); 2063 } 2064 2065 2066 void Assembler::frndint() { 2067 EnsureSpace ensure_space(this); 2068 EMIT(0xD9); 2069 EMIT(0xFC); 2070 } 2071 2072 2073 void Assembler::fnclex() { 2074 EnsureSpace ensure_space(this); 2075 EMIT(0xDB); 2076 EMIT(0xE2); 2077 } 2078 2079 2080 void Assembler::sahf() { 2081 EnsureSpace ensure_space(this); 2082 EMIT(0x9E); 2083 } 2084 2085 2086 void Assembler::setcc(Condition cc, Register reg) { 2087 DCHECK(reg.is_byte_register()); 2088 EnsureSpace ensure_space(this); 2089 EMIT(0x0F); 2090 EMIT(0x90 | cc); 2091 EMIT(0xC0 | reg.code()); 2092 } 2093 2094 2095 void Assembler::cvttss2si(Register dst, const Operand& src) { 2096 EnsureSpace ensure_space(this); 2097 EMIT(0xF3); 2098 EMIT(0x0F); 2099 EMIT(0x2C); 2100 emit_operand(dst, src); 2101 } 2102 2103 2104 void Assembler::cvttsd2si(Register dst, const Operand& src) { 2105 EnsureSpace ensure_space(this); 2106 EMIT(0xF2); 2107 EMIT(0x0F); 2108 EMIT(0x2C); 2109 emit_operand(dst, src); 2110 } 2111 2112 2113 void Assembler::cvtsd2si(Register dst, XMMRegister src) { 2114 EnsureSpace ensure_space(this); 2115 EMIT(0xF2); 2116 EMIT(0x0F); 2117 EMIT(0x2D); 2118 emit_sse_operand(dst, src); 2119 } 2120 2121 2122 void Assembler::cvtsi2ss(XMMRegister dst, const Operand& src) { 2123 EnsureSpace ensure_space(this); 2124 EMIT(0xF3); 2125 EMIT(0x0F); 2126 EMIT(0x2A); 2127 emit_sse_operand(dst, src); 2128 } 2129 2130 2131 void Assembler::cvtsi2sd(XMMRegister dst, const Operand& src) { 2132 EnsureSpace ensure_space(this); 2133 EMIT(0xF2); 2134 EMIT(0x0F); 2135 EMIT(0x2A); 2136 emit_sse_operand(dst, src); 2137 } 2138 2139 2140 void Assembler::cvtss2sd(XMMRegister dst, const Operand& src) { 2141 EnsureSpace ensure_space(this); 2142 EMIT(0xF3); 2143 EMIT(0x0F); 2144 EMIT(0x5A); 2145 emit_sse_operand(dst, src); 2146 } 2147 2148 2149 void Assembler::cvtsd2ss(XMMRegister dst, const Operand& src) { 2150 EnsureSpace ensure_space(this); 2151 EMIT(0xF2); 2152 EMIT(0x0F); 2153 EMIT(0x5A); 2154 emit_sse_operand(dst, src); 2155 } 2156 2157 2158 void Assembler::addsd(XMMRegister dst, const Operand& src) { 2159 EnsureSpace ensure_space(this); 2160 EMIT(0xF2); 2161 EMIT(0x0F); 2162 EMIT(0x58); 2163 emit_sse_operand(dst, src); 2164 } 2165 2166 2167 void Assembler::mulsd(XMMRegister dst, const Operand& src) { 2168 EnsureSpace ensure_space(this); 2169 EMIT(0xF2); 2170 EMIT(0x0F); 2171 EMIT(0x59); 2172 emit_sse_operand(dst, src); 2173 } 2174 2175 2176 void Assembler::subsd(XMMRegister dst, const Operand& src) { 2177 EnsureSpace ensure_space(this); 2178 EMIT(0xF2); 2179 EMIT(0x0F); 2180 EMIT(0x5C); 2181 emit_sse_operand(dst, src); 2182 } 2183 2184 2185 void Assembler::divsd(XMMRegister dst, const Operand& src) { 2186 EnsureSpace ensure_space(this); 2187 EMIT(0xF2); 2188 EMIT(0x0F); 2189 EMIT(0x5E); 2190 emit_sse_operand(dst, src); 2191 } 2192 2193 2194 void Assembler::xorpd(XMMRegister dst, XMMRegister src) { 2195 EnsureSpace ensure_space(this); 2196 EMIT(0x66); 2197 EMIT(0x0F); 2198 EMIT(0x57); 2199 emit_sse_operand(dst, src); 2200 } 2201 2202 2203 void Assembler::andps(XMMRegister dst, const Operand& src) { 2204 EnsureSpace ensure_space(this); 2205 EMIT(0x0F); 2206 EMIT(0x54); 2207 emit_sse_operand(dst, src); 2208 } 2209 2210 2211 void Assembler::orps(XMMRegister dst, const Operand& src) { 2212 EnsureSpace ensure_space(this); 2213 EMIT(0x0F); 2214 EMIT(0x56); 2215 emit_sse_operand(dst, src); 2216 } 2217 2218 2219 void Assembler::xorps(XMMRegister dst, const Operand& src) { 2220 EnsureSpace ensure_space(this); 2221 EMIT(0x0F); 2222 EMIT(0x57); 2223 emit_sse_operand(dst, src); 2224 } 2225 2226 2227 void Assembler::addps(XMMRegister dst, const Operand& src) { 2228 EnsureSpace ensure_space(this); 2229 EMIT(0x0F); 2230 EMIT(0x58); 2231 emit_sse_operand(dst, src); 2232 } 2233 2234 2235 void Assembler::subps(XMMRegister dst, const Operand& src) { 2236 EnsureSpace ensure_space(this); 2237 EMIT(0x0F); 2238 EMIT(0x5C); 2239 emit_sse_operand(dst, src); 2240 } 2241 2242 2243 void Assembler::mulps(XMMRegister dst, const Operand& src) { 2244 EnsureSpace ensure_space(this); 2245 EMIT(0x0F); 2246 EMIT(0x59); 2247 emit_sse_operand(dst, src); 2248 } 2249 2250 2251 void Assembler::divps(XMMRegister dst, const Operand& src) { 2252 EnsureSpace ensure_space(this); 2253 EMIT(0x0F); 2254 EMIT(0x5E); 2255 emit_sse_operand(dst, src); 2256 } 2257 2258 2259 void Assembler::sqrtsd(XMMRegister dst, const Operand& src) { 2260 EnsureSpace ensure_space(this); 2261 EMIT(0xF2); 2262 EMIT(0x0F); 2263 EMIT(0x51); 2264 emit_sse_operand(dst, src); 2265 } 2266 2267 2268 void Assembler::andpd(XMMRegister dst, XMMRegister src) { 2269 EnsureSpace ensure_space(this); 2270 EMIT(0x66); 2271 EMIT(0x0F); 2272 EMIT(0x54); 2273 emit_sse_operand(dst, src); 2274 } 2275 2276 2277 void Assembler::orpd(XMMRegister dst, XMMRegister src) { 2278 EnsureSpace ensure_space(this); 2279 EMIT(0x66); 2280 EMIT(0x0F); 2281 EMIT(0x56); 2282 emit_sse_operand(dst, src); 2283 } 2284 2285 2286 void Assembler::ucomisd(XMMRegister dst, const Operand& src) { 2287 EnsureSpace ensure_space(this); 2288 EMIT(0x66); 2289 EMIT(0x0F); 2290 EMIT(0x2E); 2291 emit_sse_operand(dst, src); 2292 } 2293 2294 2295 void Assembler::roundss(XMMRegister dst, XMMRegister src, RoundingMode mode) { 2296 DCHECK(IsEnabled(SSE4_1)); 2297 EnsureSpace ensure_space(this); 2298 EMIT(0x66); 2299 EMIT(0x0F); 2300 EMIT(0x3A); 2301 EMIT(0x0A); 2302 emit_sse_operand(dst, src); 2303 // Mask precision exeption. 2304 EMIT(static_cast<byte>(mode) | 0x8); 2305 } 2306 2307 2308 void Assembler::roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode) { 2309 DCHECK(IsEnabled(SSE4_1)); 2310 EnsureSpace ensure_space(this); 2311 EMIT(0x66); 2312 EMIT(0x0F); 2313 EMIT(0x3A); 2314 EMIT(0x0B); 2315 emit_sse_operand(dst, src); 2316 // Mask precision exeption. 2317 EMIT(static_cast<byte>(mode) | 0x8); 2318 } 2319 2320 2321 void Assembler::movmskpd(Register dst, XMMRegister src) { 2322 EnsureSpace ensure_space(this); 2323 EMIT(0x66); 2324 EMIT(0x0F); 2325 EMIT(0x50); 2326 emit_sse_operand(dst, src); 2327 } 2328 2329 2330 void Assembler::movmskps(Register dst, XMMRegister src) { 2331 EnsureSpace ensure_space(this); 2332 EMIT(0x0F); 2333 EMIT(0x50); 2334 emit_sse_operand(dst, src); 2335 } 2336 2337 2338 void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) { 2339 EnsureSpace ensure_space(this); 2340 EMIT(0x66); 2341 EMIT(0x0F); 2342 EMIT(0x76); 2343 emit_sse_operand(dst, src); 2344 } 2345 2346 2347 void Assembler::punpckldq(XMMRegister dst, XMMRegister src) { 2348 EnsureSpace ensure_space(this); 2349 EMIT(0x66); 2350 EMIT(0x0F); 2351 EMIT(0x62); 2352 emit_sse_operand(dst, src); 2353 } 2354 2355 2356 void Assembler::punpckhdq(XMMRegister dst, XMMRegister src) { 2357 EnsureSpace ensure_space(this); 2358 EMIT(0x66); 2359 EMIT(0x0F); 2360 EMIT(0x6A); 2361 emit_sse_operand(dst, src); 2362 } 2363 2364 2365 void Assembler::maxsd(XMMRegister dst, const Operand& src) { 2366 EnsureSpace ensure_space(this); 2367 EMIT(0xF2); 2368 EMIT(0x0F); 2369 EMIT(0x5F); 2370 emit_sse_operand(dst, src); 2371 } 2372 2373 2374 void Assembler::minsd(XMMRegister dst, const Operand& src) { 2375 EnsureSpace ensure_space(this); 2376 EMIT(0xF2); 2377 EMIT(0x0F); 2378 EMIT(0x5D); 2379 emit_sse_operand(dst, src); 2380 } 2381 2382 2383 void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) { 2384 EnsureSpace ensure_space(this); 2385 EMIT(0xF2); 2386 EMIT(0x0F); 2387 EMIT(0xC2); 2388 emit_sse_operand(dst, src); 2389 EMIT(1); // LT == 1 2390 } 2391 2392 2393 void Assembler::movaps(XMMRegister dst, XMMRegister src) { 2394 EnsureSpace ensure_space(this); 2395 EMIT(0x0F); 2396 EMIT(0x28); 2397 emit_sse_operand(dst, src); 2398 } 2399 2400 void Assembler::movups(XMMRegister dst, XMMRegister src) { 2401 EnsureSpace ensure_space(this); 2402 EMIT(0x0F); 2403 EMIT(0x11); 2404 emit_sse_operand(dst, src); 2405 } 2406 2407 void Assembler::movups(XMMRegister dst, const Operand& src) { 2408 EnsureSpace ensure_space(this); 2409 EMIT(0x0F); 2410 EMIT(0x10); 2411 emit_sse_operand(dst, src); 2412 } 2413 2414 void Assembler::movups(const Operand& dst, XMMRegister src) { 2415 EnsureSpace ensure_space(this); 2416 EMIT(0x0F); 2417 EMIT(0x11); 2418 emit_sse_operand(src, dst); 2419 } 2420 2421 void Assembler::shufps(XMMRegister dst, XMMRegister src, byte imm8) { 2422 DCHECK(is_uint8(imm8)); 2423 EnsureSpace ensure_space(this); 2424 EMIT(0x0F); 2425 EMIT(0xC6); 2426 emit_sse_operand(dst, src); 2427 EMIT(imm8); 2428 } 2429 2430 2431 void Assembler::movdqa(const Operand& dst, XMMRegister src) { 2432 EnsureSpace ensure_space(this); 2433 EMIT(0x66); 2434 EMIT(0x0F); 2435 EMIT(0x7F); 2436 emit_sse_operand(src, dst); 2437 } 2438 2439 2440 void Assembler::movdqa(XMMRegister dst, const Operand& src) { 2441 EnsureSpace ensure_space(this); 2442 EMIT(0x66); 2443 EMIT(0x0F); 2444 EMIT(0x6F); 2445 emit_sse_operand(dst, src); 2446 } 2447 2448 2449 void Assembler::movdqu(const Operand& dst, XMMRegister src ) { 2450 EnsureSpace ensure_space(this); 2451 EMIT(0xF3); 2452 EMIT(0x0F); 2453 EMIT(0x7F); 2454 emit_sse_operand(src, dst); 2455 } 2456 2457 2458 void Assembler::movdqu(XMMRegister dst, const Operand& src) { 2459 EnsureSpace ensure_space(this); 2460 EMIT(0xF3); 2461 EMIT(0x0F); 2462 EMIT(0x6F); 2463 emit_sse_operand(dst, src); 2464 } 2465 2466 2467 void Assembler::prefetch(const Operand& src, int level) { 2468 DCHECK(is_uint2(level)); 2469 EnsureSpace ensure_space(this); 2470 EMIT(0x0F); 2471 EMIT(0x18); 2472 // Emit hint number in Reg position of RegR/M. 2473 XMMRegister code = XMMRegister::from_code(level); 2474 emit_sse_operand(code, src); 2475 } 2476 2477 2478 void Assembler::movsd(const Operand& dst, XMMRegister src ) { 2479 EnsureSpace ensure_space(this); 2480 EMIT(0xF2); // double 2481 EMIT(0x0F); 2482 EMIT(0x11); // store 2483 emit_sse_operand(src, dst); 2484 } 2485 2486 2487 void Assembler::movsd(XMMRegister dst, const Operand& src) { 2488 EnsureSpace ensure_space(this); 2489 EMIT(0xF2); // double 2490 EMIT(0x0F); 2491 EMIT(0x10); // load 2492 emit_sse_operand(dst, src); 2493 } 2494 2495 2496 void Assembler::movss(const Operand& dst, XMMRegister src ) { 2497 EnsureSpace ensure_space(this); 2498 EMIT(0xF3); // float 2499 EMIT(0x0F); 2500 EMIT(0x11); // store 2501 emit_sse_operand(src, dst); 2502 } 2503 2504 2505 void Assembler::movss(XMMRegister dst, const Operand& src) { 2506 EnsureSpace ensure_space(this); 2507 EMIT(0xF3); // float 2508 EMIT(0x0F); 2509 EMIT(0x10); // load 2510 emit_sse_operand(dst, src); 2511 } 2512 2513 2514 void Assembler::movd(XMMRegister dst, const Operand& src) { 2515 EnsureSpace ensure_space(this); 2516 EMIT(0x66); 2517 EMIT(0x0F); 2518 EMIT(0x6E); 2519 emit_sse_operand(dst, src); 2520 } 2521 2522 2523 void Assembler::movd(const Operand& dst, XMMRegister src) { 2524 EnsureSpace ensure_space(this); 2525 EMIT(0x66); 2526 EMIT(0x0F); 2527 EMIT(0x7E); 2528 emit_sse_operand(src, dst); 2529 } 2530 2531 2532 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) { 2533 DCHECK(IsEnabled(SSE4_1)); 2534 DCHECK(is_uint8(imm8)); 2535 EnsureSpace ensure_space(this); 2536 EMIT(0x66); 2537 EMIT(0x0F); 2538 EMIT(0x3A); 2539 EMIT(0x17); 2540 emit_sse_operand(src, dst); 2541 EMIT(imm8); 2542 } 2543 2544 2545 void Assembler::pand(XMMRegister dst, XMMRegister src) { 2546 EnsureSpace ensure_space(this); 2547 EMIT(0x66); 2548 EMIT(0x0F); 2549 EMIT(0xDB); 2550 emit_sse_operand(dst, src); 2551 } 2552 2553 2554 void Assembler::pxor(XMMRegister dst, XMMRegister src) { 2555 EnsureSpace ensure_space(this); 2556 EMIT(0x66); 2557 EMIT(0x0F); 2558 EMIT(0xEF); 2559 emit_sse_operand(dst, src); 2560 } 2561 2562 2563 void Assembler::por(XMMRegister dst, XMMRegister src) { 2564 EnsureSpace ensure_space(this); 2565 EMIT(0x66); 2566 EMIT(0x0F); 2567 EMIT(0xEB); 2568 emit_sse_operand(dst, src); 2569 } 2570 2571 2572 void Assembler::ptest(XMMRegister dst, XMMRegister src) { 2573 DCHECK(IsEnabled(SSE4_1)); 2574 EnsureSpace ensure_space(this); 2575 EMIT(0x66); 2576 EMIT(0x0F); 2577 EMIT(0x38); 2578 EMIT(0x17); 2579 emit_sse_operand(dst, src); 2580 } 2581 2582 2583 void Assembler::pslld(XMMRegister reg, int8_t shift) { 2584 EnsureSpace ensure_space(this); 2585 EMIT(0x66); 2586 EMIT(0x0F); 2587 EMIT(0x72); 2588 emit_sse_operand(esi, reg); // esi == 6 2589 EMIT(shift); 2590 } 2591 2592 2593 void Assembler::psrld(XMMRegister reg, int8_t shift) { 2594 EnsureSpace ensure_space(this); 2595 EMIT(0x66); 2596 EMIT(0x0F); 2597 EMIT(0x72); 2598 emit_sse_operand(edx, reg); // edx == 2 2599 EMIT(shift); 2600 } 2601 2602 2603 void Assembler::psllq(XMMRegister reg, int8_t shift) { 2604 EnsureSpace ensure_space(this); 2605 EMIT(0x66); 2606 EMIT(0x0F); 2607 EMIT(0x73); 2608 emit_sse_operand(esi, reg); // esi == 6 2609 EMIT(shift); 2610 } 2611 2612 2613 void Assembler::psllq(XMMRegister dst, XMMRegister src) { 2614 EnsureSpace ensure_space(this); 2615 EMIT(0x66); 2616 EMIT(0x0F); 2617 EMIT(0xF3); 2618 emit_sse_operand(dst, src); 2619 } 2620 2621 2622 void Assembler::psrlq(XMMRegister reg, int8_t shift) { 2623 EnsureSpace ensure_space(this); 2624 EMIT(0x66); 2625 EMIT(0x0F); 2626 EMIT(0x73); 2627 emit_sse_operand(edx, reg); // edx == 2 2628 EMIT(shift); 2629 } 2630 2631 2632 void Assembler::psrlq(XMMRegister dst, XMMRegister src) { 2633 EnsureSpace ensure_space(this); 2634 EMIT(0x66); 2635 EMIT(0x0F); 2636 EMIT(0xD3); 2637 emit_sse_operand(dst, src); 2638 } 2639 2640 2641 void Assembler::pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) { 2642 EnsureSpace ensure_space(this); 2643 EMIT(0x66); 2644 EMIT(0x0F); 2645 EMIT(0x70); 2646 emit_sse_operand(dst, src); 2647 EMIT(shuffle); 2648 } 2649 2650 2651 void Assembler::pextrd(const Operand& dst, XMMRegister src, int8_t offset) { 2652 DCHECK(IsEnabled(SSE4_1)); 2653 EnsureSpace ensure_space(this); 2654 EMIT(0x66); 2655 EMIT(0x0F); 2656 EMIT(0x3A); 2657 EMIT(0x16); 2658 emit_sse_operand(src, dst); 2659 EMIT(offset); 2660 } 2661 2662 2663 void Assembler::pinsrd(XMMRegister dst, const Operand& src, int8_t offset) { 2664 DCHECK(IsEnabled(SSE4_1)); 2665 EnsureSpace ensure_space(this); 2666 EMIT(0x66); 2667 EMIT(0x0F); 2668 EMIT(0x3A); 2669 EMIT(0x22); 2670 emit_sse_operand(dst, src); 2671 EMIT(offset); 2672 } 2673 2674 2675 void Assembler::addss(XMMRegister dst, const Operand& src) { 2676 EnsureSpace ensure_space(this); 2677 EMIT(0xF3); 2678 EMIT(0x0F); 2679 EMIT(0x58); 2680 emit_sse_operand(dst, src); 2681 } 2682 2683 2684 void Assembler::subss(XMMRegister dst, const Operand& src) { 2685 EnsureSpace ensure_space(this); 2686 EMIT(0xF3); 2687 EMIT(0x0F); 2688 EMIT(0x5C); 2689 emit_sse_operand(dst, src); 2690 } 2691 2692 2693 void Assembler::mulss(XMMRegister dst, const Operand& src) { 2694 EnsureSpace ensure_space(this); 2695 EMIT(0xF3); 2696 EMIT(0x0F); 2697 EMIT(0x59); 2698 emit_sse_operand(dst, src); 2699 } 2700 2701 2702 void Assembler::divss(XMMRegister dst, const Operand& src) { 2703 EnsureSpace ensure_space(this); 2704 EMIT(0xF3); 2705 EMIT(0x0F); 2706 EMIT(0x5E); 2707 emit_sse_operand(dst, src); 2708 } 2709 2710 2711 void Assembler::sqrtss(XMMRegister dst, const Operand& src) { 2712 EnsureSpace ensure_space(this); 2713 EMIT(0xF3); 2714 EMIT(0x0F); 2715 EMIT(0x51); 2716 emit_sse_operand(dst, src); 2717 } 2718 2719 2720 void Assembler::ucomiss(XMMRegister dst, const Operand& src) { 2721 EnsureSpace ensure_space(this); 2722 EMIT(0x0f); 2723 EMIT(0x2e); 2724 emit_sse_operand(dst, src); 2725 } 2726 2727 2728 void Assembler::maxss(XMMRegister dst, const Operand& src) { 2729 EnsureSpace ensure_space(this); 2730 EMIT(0xF3); 2731 EMIT(0x0F); 2732 EMIT(0x5F); 2733 emit_sse_operand(dst, src); 2734 } 2735 2736 2737 void Assembler::minss(XMMRegister dst, const Operand& src) { 2738 EnsureSpace ensure_space(this); 2739 EMIT(0xF3); 2740 EMIT(0x0F); 2741 EMIT(0x5D); 2742 emit_sse_operand(dst, src); 2743 } 2744 2745 2746 // AVX instructions 2747 void Assembler::vfmasd(byte op, XMMRegister dst, XMMRegister src1, 2748 const Operand& src2) { 2749 DCHECK(IsEnabled(FMA3)); 2750 EnsureSpace ensure_space(this); 2751 emit_vex_prefix(src1, kLIG, k66, k0F38, kW1); 2752 EMIT(op); 2753 emit_sse_operand(dst, src2); 2754 } 2755 2756 2757 void Assembler::vfmass(byte op, XMMRegister dst, XMMRegister src1, 2758 const Operand& src2) { 2759 DCHECK(IsEnabled(FMA3)); 2760 EnsureSpace ensure_space(this); 2761 emit_vex_prefix(src1, kLIG, k66, k0F38, kW0); 2762 EMIT(op); 2763 emit_sse_operand(dst, src2); 2764 } 2765 2766 2767 void Assembler::vsd(byte op, XMMRegister dst, XMMRegister src1, 2768 const Operand& src2) { 2769 DCHECK(IsEnabled(AVX)); 2770 EnsureSpace ensure_space(this); 2771 emit_vex_prefix(src1, kLIG, kF2, k0F, kWIG); 2772 EMIT(op); 2773 emit_sse_operand(dst, src2); 2774 } 2775 2776 2777 void Assembler::vss(byte op, XMMRegister dst, XMMRegister src1, 2778 const Operand& src2) { 2779 DCHECK(IsEnabled(AVX)); 2780 EnsureSpace ensure_space(this); 2781 emit_vex_prefix(src1, kLIG, kF3, k0F, kWIG); 2782 EMIT(op); 2783 emit_sse_operand(dst, src2); 2784 } 2785 2786 2787 void Assembler::vps(byte op, XMMRegister dst, XMMRegister src1, 2788 const Operand& src2) { 2789 DCHECK(IsEnabled(AVX)); 2790 EnsureSpace ensure_space(this); 2791 emit_vex_prefix(src1, kL128, kNone, k0F, kWIG); 2792 EMIT(op); 2793 emit_sse_operand(dst, src2); 2794 } 2795 2796 2797 void Assembler::vpd(byte op, XMMRegister dst, XMMRegister src1, 2798 const Operand& src2) { 2799 DCHECK(IsEnabled(AVX)); 2800 EnsureSpace ensure_space(this); 2801 emit_vex_prefix(src1, kL128, k66, k0F, kWIG); 2802 EMIT(op); 2803 emit_sse_operand(dst, src2); 2804 } 2805 2806 2807 void Assembler::bmi1(byte op, Register reg, Register vreg, const Operand& rm) { 2808 DCHECK(IsEnabled(BMI1)); 2809 EnsureSpace ensure_space(this); 2810 emit_vex_prefix(vreg, kLZ, kNone, k0F38, kW0); 2811 EMIT(op); 2812 emit_operand(reg, rm); 2813 } 2814 2815 2816 void Assembler::tzcnt(Register dst, const Operand& src) { 2817 DCHECK(IsEnabled(BMI1)); 2818 EnsureSpace ensure_space(this); 2819 EMIT(0xF3); 2820 EMIT(0x0F); 2821 EMIT(0xBC); 2822 emit_operand(dst, src); 2823 } 2824 2825 2826 void Assembler::lzcnt(Register dst, const Operand& src) { 2827 DCHECK(IsEnabled(LZCNT)); 2828 EnsureSpace ensure_space(this); 2829 EMIT(0xF3); 2830 EMIT(0x0F); 2831 EMIT(0xBD); 2832 emit_operand(dst, src); 2833 } 2834 2835 2836 void Assembler::popcnt(Register dst, const Operand& src) { 2837 DCHECK(IsEnabled(POPCNT)); 2838 EnsureSpace ensure_space(this); 2839 EMIT(0xF3); 2840 EMIT(0x0F); 2841 EMIT(0xB8); 2842 emit_operand(dst, src); 2843 } 2844 2845 2846 void Assembler::bmi2(SIMDPrefix pp, byte op, Register reg, Register vreg, 2847 const Operand& rm) { 2848 DCHECK(IsEnabled(BMI2)); 2849 EnsureSpace ensure_space(this); 2850 emit_vex_prefix(vreg, kLZ, pp, k0F38, kW0); 2851 EMIT(op); 2852 emit_operand(reg, rm); 2853 } 2854 2855 2856 void Assembler::rorx(Register dst, const Operand& src, byte imm8) { 2857 DCHECK(IsEnabled(BMI2)); 2858 DCHECK(is_uint8(imm8)); 2859 Register vreg = {0}; // VEX.vvvv unused 2860 EnsureSpace ensure_space(this); 2861 emit_vex_prefix(vreg, kLZ, kF2, k0F3A, kW0); 2862 EMIT(0xF0); 2863 emit_operand(dst, src); 2864 EMIT(imm8); 2865 } 2866 2867 2868 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { 2869 Register ireg = { reg.code() }; 2870 emit_operand(ireg, adr); 2871 } 2872 2873 2874 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) { 2875 EMIT(0xC0 | dst.code() << 3 | src.code()); 2876 } 2877 2878 2879 void Assembler::emit_sse_operand(Register dst, XMMRegister src) { 2880 EMIT(0xC0 | dst.code() << 3 | src.code()); 2881 } 2882 2883 2884 void Assembler::emit_sse_operand(XMMRegister dst, Register src) { 2885 EMIT(0xC0 | (dst.code() << 3) | src.code()); 2886 } 2887 2888 2889 void Assembler::emit_vex_prefix(XMMRegister vreg, VectorLength l, SIMDPrefix pp, 2890 LeadingOpcode mm, VexW w) { 2891 if (mm != k0F || w != kW0) { 2892 EMIT(0xc4); 2893 // Change RXB from "110" to "111" to align with gdb disassembler. 2894 EMIT(0xe0 | mm); 2895 EMIT(w | ((~vreg.code() & 0xf) << 3) | l | pp); 2896 } else { 2897 EMIT(0xc5); 2898 EMIT(((~vreg.code()) << 3) | l | pp); 2899 } 2900 } 2901 2902 2903 void Assembler::emit_vex_prefix(Register vreg, VectorLength l, SIMDPrefix pp, 2904 LeadingOpcode mm, VexW w) { 2905 XMMRegister ivreg = {vreg.code()}; 2906 emit_vex_prefix(ivreg, l, pp, mm, w); 2907 } 2908 2909 2910 void Assembler::GrowBuffer() { 2911 DCHECK(buffer_overflow()); 2912 if (!own_buffer_) FATAL("external code buffer is too small"); 2913 2914 // Compute new buffer size. 2915 CodeDesc desc; // the new buffer 2916 desc.buffer_size = 2 * buffer_size_; 2917 2918 // Some internal data structures overflow for very large buffers, 2919 // they must ensure that kMaximalBufferSize is not too large. 2920 if (desc.buffer_size > kMaximalBufferSize || 2921 static_cast<size_t>(desc.buffer_size) > 2922 isolate()->heap()->MaxOldGenerationSize()) { 2923 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer"); 2924 } 2925 2926 // Set up new buffer. 2927 desc.buffer = NewArray<byte>(desc.buffer_size); 2928 desc.origin = this; 2929 desc.instr_size = pc_offset(); 2930 desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos()); 2931 2932 // Clear the buffer in debug mode. Use 'int3' instructions to make 2933 // sure to get into problems if we ever run uninitialized code. 2934 #ifdef DEBUG 2935 memset(desc.buffer, 0xCC, desc.buffer_size); 2936 #endif 2937 2938 // Copy the data. 2939 int pc_delta = desc.buffer - buffer_; 2940 int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_); 2941 MemMove(desc.buffer, buffer_, desc.instr_size); 2942 MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(), 2943 desc.reloc_size); 2944 2945 // Switch buffers. 2946 DeleteArray(buffer_); 2947 buffer_ = desc.buffer; 2948 buffer_size_ = desc.buffer_size; 2949 pc_ += pc_delta; 2950 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, 2951 reloc_info_writer.last_pc() + pc_delta); 2952 2953 // Relocate internal references. 2954 for (auto pos : internal_reference_positions_) { 2955 int32_t* p = reinterpret_cast<int32_t*>(buffer_ + pos); 2956 *p += pc_delta; 2957 } 2958 2959 DCHECK(!buffer_overflow()); 2960 } 2961 2962 2963 void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) { 2964 DCHECK(is_uint8(op1) && is_uint8(op2)); // wrong opcode 2965 DCHECK(is_uint8(imm8)); 2966 DCHECK((op1 & 0x01) == 0); // should be 8bit operation 2967 EMIT(op1); 2968 EMIT(op2 | dst.code()); 2969 EMIT(imm8); 2970 } 2971 2972 2973 void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) { 2974 DCHECK((0 <= sel) && (sel <= 7)); 2975 Register ireg = { sel }; 2976 if (x.is_int8()) { 2977 EMIT(0x83); // using a sign-extended 8-bit immediate. 2978 emit_operand(ireg, dst); 2979 EMIT(x.x_ & 0xFF); 2980 } else if (dst.is_reg(eax)) { 2981 EMIT((sel << 3) | 0x05); // short form if the destination is eax. 2982 emit(x); 2983 } else { 2984 EMIT(0x81); // using a literal 32-bit immediate. 2985 emit_operand(ireg, dst); 2986 emit(x); 2987 } 2988 } 2989 2990 2991 void Assembler::emit_operand(Register reg, const Operand& adr) { 2992 const unsigned length = adr.len_; 2993 DCHECK(length > 0); 2994 2995 // Emit updated ModRM byte containing the given register. 2996 pc_[0] = (adr.buf_[0] & ~0x38) | (reg.code() << 3); 2997 2998 // Emit the rest of the encoded operand. 2999 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; 3000 pc_ += length; 3001 3002 // Emit relocation information if necessary. 3003 if (length >= sizeof(int32_t) && !RelocInfo::IsNone(adr.rmode_)) { 3004 pc_ -= sizeof(int32_t); // pc_ must be *at* disp32 3005 RecordRelocInfo(adr.rmode_); 3006 if (adr.rmode_ == RelocInfo::INTERNAL_REFERENCE) { // Fixup for labels 3007 emit_label(*reinterpret_cast<Label**>(pc_)); 3008 } else { 3009 pc_ += sizeof(int32_t); 3010 } 3011 } 3012 } 3013 3014 3015 void Assembler::emit_label(Label* label) { 3016 if (label->is_bound()) { 3017 internal_reference_positions_.push_back(pc_offset()); 3018 emit(reinterpret_cast<uint32_t>(buffer_ + label->pos())); 3019 } else { 3020 emit_disp(label, Displacement::CODE_ABSOLUTE); 3021 } 3022 } 3023 3024 3025 void Assembler::emit_farith(int b1, int b2, int i) { 3026 DCHECK(is_uint8(b1) && is_uint8(b2)); // wrong opcode 3027 DCHECK(0 <= i && i < 8); // illegal stack offset 3028 EMIT(b1); 3029 EMIT(b2 + i); 3030 } 3031 3032 3033 void Assembler::db(uint8_t data) { 3034 EnsureSpace ensure_space(this); 3035 EMIT(data); 3036 } 3037 3038 3039 void Assembler::dd(uint32_t data) { 3040 EnsureSpace ensure_space(this); 3041 emit(data); 3042 } 3043 3044 3045 void Assembler::dq(uint64_t data) { 3046 EnsureSpace ensure_space(this); 3047 emit_q(data); 3048 } 3049 3050 3051 void Assembler::dd(Label* label) { 3052 EnsureSpace ensure_space(this); 3053 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE); 3054 emit_label(label); 3055 } 3056 3057 3058 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 3059 DCHECK(!RelocInfo::IsNone(rmode)); 3060 // Don't record external references unless the heap will be serialized. 3061 if (rmode == RelocInfo::EXTERNAL_REFERENCE && 3062 !serializer_enabled() && !emit_debug_code()) { 3063 return; 3064 } 3065 RelocInfo rinfo(isolate(), pc_, rmode, data, NULL); 3066 reloc_info_writer.Write(&rinfo); 3067 } 3068 3069 3070 } // namespace internal 3071 } // namespace v8 3072 3073 #endif // V8_TARGET_ARCH_IA32 3074