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 56namespace v8 { 57namespace internal { 58 59// ----------------------------------------------------------------------------- 60// Implementation of CpuFeatures 61 62namespace { 63 64#if !V8_LIBC_MSVCRT 65 66V8_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 81bool 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 107void 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 137void CpuFeatures::PrintTarget() { } 138void 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 153void 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 170const 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 176bool 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 185bool RelocInfo::IsInConstantPool() { 186 return false; 187} 188 189Address RelocInfo::wasm_memory_reference() { 190 DCHECK(IsWasmMemoryReference(rmode_)); 191 return Memory::Address_at(pc_); 192} 193 194Address RelocInfo::wasm_global_reference() { 195 DCHECK(IsWasmGlobalReference(rmode_)); 196 return Memory::Address_at(pc_); 197} 198 199uint32_t RelocInfo::wasm_memory_size_reference() { 200 DCHECK(IsWasmMemorySizeReference(rmode_)); 201 return Memory::uint32_at(pc_); 202} 203 204uint32_t RelocInfo::wasm_function_table_size_reference() { 205 DCHECK(IsWasmFunctionTableSizeReference(rmode_)); 206 return Memory::uint32_at(pc_); 207} 208 209void RelocInfo::unchecked_update_wasm_memory_reference( 210 Address address, ICacheFlushMode flush_mode) { 211 Memory::Address_at(pc_) = address; 212} 213 214void 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 222Operand::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 242Operand::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 267Operand::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 279bool 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 285bool Operand::is_reg_only() const { 286 return (buf_[0] & 0xF8) == 0xC0; // Addressing mode is register only. 287} 288 289 290Register 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 303Assembler::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 318void 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 334void 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 342bool 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 351void 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 416void Assembler::CodeTargetAlign() { 417 Align(16); // Preferred alignment of jump targets on ia32. 418} 419 420 421void Assembler::cpuid() { 422 EnsureSpace ensure_space(this); 423 EMIT(0x0F); 424 EMIT(0xA2); 425} 426 427 428void Assembler::pushad() { 429 EnsureSpace ensure_space(this); 430 EMIT(0x60); 431} 432 433 434void Assembler::popad() { 435 EnsureSpace ensure_space(this); 436 EMIT(0x61); 437} 438 439 440void Assembler::pushfd() { 441 EnsureSpace ensure_space(this); 442 EMIT(0x9C); 443} 444 445 446void Assembler::popfd() { 447 EnsureSpace ensure_space(this); 448 EMIT(0x9D); 449} 450 451 452void 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 464void Assembler::push_imm32(int32_t imm32) { 465 EnsureSpace ensure_space(this); 466 EMIT(0x68); 467 emit(imm32); 468} 469 470 471void Assembler::push(Register src) { 472 EnsureSpace ensure_space(this); 473 EMIT(0x50 | src.code()); 474} 475 476 477void Assembler::push(const Operand& src) { 478 EnsureSpace ensure_space(this); 479 EMIT(0xFF); 480 emit_operand(esi, src); 481} 482 483 484void 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 491void Assembler::pop(const Operand& dst) { 492 EnsureSpace ensure_space(this); 493 EMIT(0x8F); 494 emit_operand(eax, dst); 495} 496 497 498void Assembler::enter(const Immediate& size) { 499 EnsureSpace ensure_space(this); 500 EMIT(0xC8); 501 emit_w(size); 502 EMIT(0); 503} 504 505 506void Assembler::leave() { 507 EnsureSpace ensure_space(this); 508 EMIT(0xC9); 509} 510 511 512void 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 520void 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 528void 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 536void 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 544void 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 552void 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 562void Assembler::mov(Register dst, int32_t imm32) { 563 EnsureSpace ensure_space(this); 564 EMIT(0xB8 | dst.code()); 565 emit(imm32); 566} 567 568 569void Assembler::mov(Register dst, const Immediate& x) { 570 EnsureSpace ensure_space(this); 571 EMIT(0xB8 | dst.code()); 572 emit(x); 573} 574 575 576void Assembler::mov(Register dst, Handle<Object> handle) { 577 EnsureSpace ensure_space(this); 578 EMIT(0xB8 | dst.code()); 579 emit(handle); 580} 581 582 583void Assembler::mov(Register dst, const Operand& src) { 584 EnsureSpace ensure_space(this); 585 EMIT(0x8B); 586 emit_operand(dst, src); 587} 588 589 590void 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 597void 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 605void 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 613void Assembler::mov(const Operand& dst, Register src) { 614 EnsureSpace ensure_space(this); 615 EMIT(0x89); 616 emit_operand(src, dst); 617} 618 619 620void 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 628void 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 636void 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 644void 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 652void 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 661void Assembler::cld() { 662 EnsureSpace ensure_space(this); 663 EMIT(0xFC); 664} 665 666 667void Assembler::rep_movs() { 668 EnsureSpace ensure_space(this); 669 EMIT(0xF3); 670 EMIT(0xA5); 671} 672 673 674void Assembler::rep_stos() { 675 EnsureSpace ensure_space(this); 676 EMIT(0xF3); 677 EMIT(0xAB); 678} 679 680 681void Assembler::stos() { 682 EnsureSpace ensure_space(this); 683 EMIT(0xAB); 684} 685 686 687void 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 698void Assembler::xchg(Register dst, const Operand& src) { 699 EnsureSpace ensure_space(this); 700 EMIT(0x87); 701 emit_operand(dst, src); 702} 703 704void Assembler::xchg_b(Register reg, const Operand& op) { 705 EnsureSpace ensure_space(this); 706 EMIT(0x86); 707 emit_operand(reg, op); 708} 709 710void 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 717void Assembler::lock() { 718 EnsureSpace ensure_space(this); 719 EMIT(0xF0); 720} 721 722void 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 729void 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 736void 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 744void Assembler::adc(Register dst, int32_t imm32) { 745 EnsureSpace ensure_space(this); 746 emit_arith(2, Operand(dst), Immediate(imm32)); 747} 748 749 750void Assembler::adc(Register dst, const Operand& src) { 751 EnsureSpace ensure_space(this); 752 EMIT(0x13); 753 emit_operand(dst, src); 754} 755 756 757void Assembler::add(Register dst, const Operand& src) { 758 EnsureSpace ensure_space(this); 759 EMIT(0x03); 760 emit_operand(dst, src); 761} 762 763 764void Assembler::add(const Operand& dst, Register src) { 765 EnsureSpace ensure_space(this); 766 EMIT(0x01); 767 emit_operand(src, dst); 768} 769 770 771void 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 778void Assembler::and_(Register dst, int32_t imm32) { 779 and_(dst, Immediate(imm32)); 780} 781 782 783void Assembler::and_(Register dst, const Immediate& x) { 784 EnsureSpace ensure_space(this); 785 emit_arith(4, Operand(dst), x); 786} 787 788 789void Assembler::and_(Register dst, const Operand& src) { 790 EnsureSpace ensure_space(this); 791 EMIT(0x23); 792 emit_operand(dst, src); 793} 794 795 796void Assembler::and_(const Operand& dst, const Immediate& x) { 797 EnsureSpace ensure_space(this); 798 emit_arith(4, dst, x); 799} 800 801 802void Assembler::and_(const Operand& dst, Register src) { 803 EnsureSpace ensure_space(this); 804 EMIT(0x21); 805 emit_operand(src, dst); 806} 807 808void 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 821void 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 829void 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 837void 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 846void 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 853void 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 860void Assembler::cmp(Register reg, int32_t imm32) { 861 EnsureSpace ensure_space(this); 862 emit_arith(7, Operand(reg), Immediate(imm32)); 863} 864 865 866void Assembler::cmp(Register reg, Handle<Object> handle) { 867 EnsureSpace ensure_space(this); 868 emit_arith(7, Operand(reg), Immediate(handle)); 869} 870 871 872void Assembler::cmp(Register reg, const Operand& op) { 873 EnsureSpace ensure_space(this); 874 EMIT(0x3B); 875 emit_operand(reg, op); 876} 877 878void Assembler::cmp(const Operand& op, Register reg) { 879 EnsureSpace ensure_space(this); 880 EMIT(0x39); 881 emit_operand(reg, op); 882} 883 884void Assembler::cmp(const Operand& op, const Immediate& imm) { 885 EnsureSpace ensure_space(this); 886 emit_arith(7, op, imm); 887} 888 889 890void Assembler::cmp(const Operand& op, Handle<Object> handle) { 891 EnsureSpace ensure_space(this); 892 emit_arith(7, op, Immediate(handle)); 893} 894 895 896void 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 903void 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 911void 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 919void Assembler::dec_b(const Operand& dst) { 920 EnsureSpace ensure_space(this); 921 EMIT(0xFE); 922 emit_operand(ecx, dst); 923} 924 925 926void Assembler::dec(Register dst) { 927 EnsureSpace ensure_space(this); 928 EMIT(0x48 | dst.code()); 929} 930 931 932void Assembler::dec(const Operand& dst) { 933 EnsureSpace ensure_space(this); 934 EMIT(0xFF); 935 emit_operand(ecx, dst); 936} 937 938 939void Assembler::cdq() { 940 EnsureSpace ensure_space(this); 941 EMIT(0x99); 942} 943 944 945void Assembler::idiv(const Operand& src) { 946 EnsureSpace ensure_space(this); 947 EMIT(0xF7); 948 emit_operand(edi, src); 949} 950 951 952void Assembler::div(const Operand& src) { 953 EnsureSpace ensure_space(this); 954 EMIT(0xF7); 955 emit_operand(esi, src); 956} 957 958 959void Assembler::imul(Register reg) { 960 EnsureSpace ensure_space(this); 961 EMIT(0xF7); 962 EMIT(0xE8 | reg.code()); 963} 964 965 966void 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 974void Assembler::imul(Register dst, Register src, int32_t imm32) { 975 imul(dst, Operand(src), imm32); 976} 977 978 979void 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 993void Assembler::inc(Register dst) { 994 EnsureSpace ensure_space(this); 995 EMIT(0x40 | dst.code()); 996} 997 998 999void Assembler::inc(const Operand& dst) { 1000 EnsureSpace ensure_space(this); 1001 EMIT(0xFF); 1002 emit_operand(eax, dst); 1003} 1004 1005 1006void Assembler::lea(Register dst, const Operand& src) { 1007 EnsureSpace ensure_space(this); 1008 EMIT(0x8D); 1009 emit_operand(dst, src); 1010} 1011 1012 1013void Assembler::mul(Register src) { 1014 EnsureSpace ensure_space(this); 1015 EMIT(0xF7); 1016 EMIT(0xE0 | src.code()); 1017} 1018 1019 1020void Assembler::neg(Register dst) { 1021 EnsureSpace ensure_space(this); 1022 EMIT(0xF7); 1023 EMIT(0xD8 | dst.code()); 1024} 1025 1026 1027void Assembler::neg(const Operand& dst) { 1028 EnsureSpace ensure_space(this); 1029 EMIT(0xF7); 1030 emit_operand(ebx, dst); 1031} 1032 1033 1034void Assembler::not_(Register dst) { 1035 EnsureSpace ensure_space(this); 1036 EMIT(0xF7); 1037 EMIT(0xD0 | dst.code()); 1038} 1039 1040 1041void Assembler::not_(const Operand& dst) { 1042 EnsureSpace ensure_space(this); 1043 EMIT(0xF7); 1044 emit_operand(edx, dst); 1045} 1046 1047 1048void Assembler::or_(Register dst, int32_t imm32) { 1049 EnsureSpace ensure_space(this); 1050 emit_arith(1, Operand(dst), Immediate(imm32)); 1051} 1052 1053 1054void Assembler::or_(Register dst, const Operand& src) { 1055 EnsureSpace ensure_space(this); 1056 EMIT(0x0B); 1057 emit_operand(dst, src); 1058} 1059 1060 1061void Assembler::or_(const Operand& dst, const Immediate& x) { 1062 EnsureSpace ensure_space(this); 1063 emit_arith(1, dst, x); 1064} 1065 1066 1067void Assembler::or_(const Operand& dst, Register src) { 1068 EnsureSpace ensure_space(this); 1069 EMIT(0x09); 1070 emit_operand(src, dst); 1071} 1072 1073 1074void 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 1088void 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 1102void 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 1116void Assembler::ror_cl(const Operand& dst) { 1117 EnsureSpace ensure_space(this); 1118 EMIT(0xD3); 1119 emit_operand(ecx, dst); 1120} 1121 1122 1123void 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 1137void Assembler::sar_cl(const Operand& dst) { 1138 EnsureSpace ensure_space(this); 1139 EMIT(0xD3); 1140 emit_operand(edi, dst); 1141} 1142 1143void Assembler::sbb(Register dst, const Operand& src) { 1144 EnsureSpace ensure_space(this); 1145 EMIT(0x1B); 1146 emit_operand(dst, src); 1147} 1148 1149void 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 1158void 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 1166void 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 1180void Assembler::shl_cl(const Operand& dst) { 1181 EnsureSpace ensure_space(this); 1182 EMIT(0xD3); 1183 emit_operand(esp, dst); 1184} 1185 1186void 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 1200void Assembler::shr_cl(const Operand& dst) { 1201 EnsureSpace ensure_space(this); 1202 EMIT(0xD3); 1203 emit_operand(ebp, dst); 1204} 1205 1206void 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 1215void 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 1222void Assembler::sub(const Operand& dst, const Immediate& x) { 1223 EnsureSpace ensure_space(this); 1224 emit_arith(5, dst, x); 1225} 1226 1227 1228void Assembler::sub(Register dst, const Operand& src) { 1229 EnsureSpace ensure_space(this); 1230 EMIT(0x2B); 1231 emit_operand(dst, src); 1232} 1233 1234 1235void Assembler::sub(const Operand& dst, Register src) { 1236 EnsureSpace ensure_space(this); 1237 EMIT(0x29); 1238 emit_operand(src, dst); 1239} 1240 1241 1242void 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 1261void Assembler::test(Register reg, const Operand& op) { 1262 EnsureSpace ensure_space(this); 1263 EMIT(0x85); 1264 emit_operand(reg, op); 1265} 1266 1267 1268void 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 1276void 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 1290void 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 1308void 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 1319void 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 1333void 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 1340void 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 1353void Assembler::xor_(Register dst, int32_t imm32) { 1354 EnsureSpace ensure_space(this); 1355 emit_arith(6, Operand(dst), Immediate(imm32)); 1356} 1357 1358 1359void Assembler::xor_(Register dst, const Operand& src) { 1360 EnsureSpace ensure_space(this); 1361 EMIT(0x33); 1362 emit_operand(dst, src); 1363} 1364 1365 1366void Assembler::xor_(const Operand& dst, Register src) { 1367 EnsureSpace ensure_space(this); 1368 EMIT(0x31); 1369 emit_operand(src, dst); 1370} 1371 1372 1373void Assembler::xor_(const Operand& dst, const Immediate& x) { 1374 EnsureSpace ensure_space(this); 1375 emit_arith(6, dst, x); 1376} 1377 1378 1379void 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 1387void 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 1395void 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 1403void 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 1411void Assembler::hlt() { 1412 EnsureSpace ensure_space(this); 1413 EMIT(0xF4); 1414} 1415 1416 1417void Assembler::int3() { 1418 EnsureSpace ensure_space(this); 1419 EMIT(0xCC); 1420} 1421 1422 1423void Assembler::nop() { 1424 EnsureSpace ensure_space(this); 1425 EMIT(0x90); 1426} 1427 1428 1429void 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 1442void 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 1460void 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 1481void 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 1522void 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 1529void 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 1546void 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 1558int Assembler::CallSize(const Operand& adr) { 1559 // Call size is 1 (opcode) + adr.len_ (operand). 1560 return 1 + adr.len_; 1561} 1562 1563 1564void Assembler::call(const Operand& adr) { 1565 EnsureSpace ensure_space(this); 1566 EMIT(0xFF); 1567 emit_operand(edx, adr); 1568} 1569 1570 1571int Assembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) { 1572 return 1 /* EMIT */ + sizeof(uint32_t) /* emit */; 1573} 1574 1575 1576void 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 1587void 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 1614void 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 1626void Assembler::jmp(const Operand& adr) { 1627 EnsureSpace ensure_space(this); 1628 EMIT(0xFF); 1629 emit_operand(esp, adr); 1630} 1631 1632 1633void 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 1641void 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 1673void 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 1687void 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 1698void Assembler::fld(int i) { 1699 EnsureSpace ensure_space(this); 1700 emit_farith(0xD9, 0xC0, i); 1701} 1702 1703 1704void Assembler::fstp(int i) { 1705 EnsureSpace ensure_space(this); 1706 emit_farith(0xDD, 0xD8, i); 1707} 1708 1709 1710void Assembler::fld1() { 1711 EnsureSpace ensure_space(this); 1712 EMIT(0xD9); 1713 EMIT(0xE8); 1714} 1715 1716 1717void Assembler::fldpi() { 1718 EnsureSpace ensure_space(this); 1719 EMIT(0xD9); 1720 EMIT(0xEB); 1721} 1722 1723 1724void Assembler::fldz() { 1725 EnsureSpace ensure_space(this); 1726 EMIT(0xD9); 1727 EMIT(0xEE); 1728} 1729 1730 1731void Assembler::fldln2() { 1732 EnsureSpace ensure_space(this); 1733 EMIT(0xD9); 1734 EMIT(0xED); 1735} 1736 1737 1738void Assembler::fld_s(const Operand& adr) { 1739 EnsureSpace ensure_space(this); 1740 EMIT(0xD9); 1741 emit_operand(eax, adr); 1742} 1743 1744 1745void Assembler::fld_d(const Operand& adr) { 1746 EnsureSpace ensure_space(this); 1747 EMIT(0xDD); 1748 emit_operand(eax, adr); 1749} 1750 1751 1752void Assembler::fstp_s(const Operand& adr) { 1753 EnsureSpace ensure_space(this); 1754 EMIT(0xD9); 1755 emit_operand(ebx, adr); 1756} 1757 1758 1759void Assembler::fst_s(const Operand& adr) { 1760 EnsureSpace ensure_space(this); 1761 EMIT(0xD9); 1762 emit_operand(edx, adr); 1763} 1764 1765 1766void Assembler::fstp_d(const Operand& adr) { 1767 EnsureSpace ensure_space(this); 1768 EMIT(0xDD); 1769 emit_operand(ebx, adr); 1770} 1771 1772 1773void Assembler::fst_d(const Operand& adr) { 1774 EnsureSpace ensure_space(this); 1775 EMIT(0xDD); 1776 emit_operand(edx, adr); 1777} 1778 1779 1780void Assembler::fild_s(const Operand& adr) { 1781 EnsureSpace ensure_space(this); 1782 EMIT(0xDB); 1783 emit_operand(eax, adr); 1784} 1785 1786 1787void Assembler::fild_d(const Operand& adr) { 1788 EnsureSpace ensure_space(this); 1789 EMIT(0xDF); 1790 emit_operand(ebp, adr); 1791} 1792 1793 1794void Assembler::fistp_s(const Operand& adr) { 1795 EnsureSpace ensure_space(this); 1796 EMIT(0xDB); 1797 emit_operand(ebx, adr); 1798} 1799 1800 1801void 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 1809void 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 1817void Assembler::fist_s(const Operand& adr) { 1818 EnsureSpace ensure_space(this); 1819 EMIT(0xDB); 1820 emit_operand(edx, adr); 1821} 1822 1823 1824void Assembler::fistp_d(const Operand& adr) { 1825 EnsureSpace ensure_space(this); 1826 EMIT(0xDF); 1827 emit_operand(edi, adr); 1828} 1829 1830 1831void Assembler::fabs() { 1832 EnsureSpace ensure_space(this); 1833 EMIT(0xD9); 1834 EMIT(0xE1); 1835} 1836 1837 1838void Assembler::fchs() { 1839 EnsureSpace ensure_space(this); 1840 EMIT(0xD9); 1841 EMIT(0xE0); 1842} 1843 1844 1845void Assembler::fcos() { 1846 EnsureSpace ensure_space(this); 1847 EMIT(0xD9); 1848 EMIT(0xFF); 1849} 1850 1851 1852void Assembler::fsin() { 1853 EnsureSpace ensure_space(this); 1854 EMIT(0xD9); 1855 EMIT(0xFE); 1856} 1857 1858 1859void Assembler::fptan() { 1860 EnsureSpace ensure_space(this); 1861 EMIT(0xD9); 1862 EMIT(0xF2); 1863} 1864 1865 1866void Assembler::fyl2x() { 1867 EnsureSpace ensure_space(this); 1868 EMIT(0xD9); 1869 EMIT(0xF1); 1870} 1871 1872 1873void Assembler::f2xm1() { 1874 EnsureSpace ensure_space(this); 1875 EMIT(0xD9); 1876 EMIT(0xF0); 1877} 1878 1879 1880void Assembler::fscale() { 1881 EnsureSpace ensure_space(this); 1882 EMIT(0xD9); 1883 EMIT(0xFD); 1884} 1885 1886 1887void Assembler::fninit() { 1888 EnsureSpace ensure_space(this); 1889 EMIT(0xDB); 1890 EMIT(0xE3); 1891} 1892 1893 1894void Assembler::fadd(int i) { 1895 EnsureSpace ensure_space(this); 1896 emit_farith(0xDC, 0xC0, i); 1897} 1898 1899 1900void Assembler::fadd_i(int i) { 1901 EnsureSpace ensure_space(this); 1902 emit_farith(0xD8, 0xC0, i); 1903} 1904 1905 1906void Assembler::fsub(int i) { 1907 EnsureSpace ensure_space(this); 1908 emit_farith(0xDC, 0xE8, i); 1909} 1910 1911 1912void Assembler::fsub_i(int i) { 1913 EnsureSpace ensure_space(this); 1914 emit_farith(0xD8, 0xE0, i); 1915} 1916 1917 1918void Assembler::fisub_s(const Operand& adr) { 1919 EnsureSpace ensure_space(this); 1920 EMIT(0xDA); 1921 emit_operand(esp, adr); 1922} 1923 1924 1925void Assembler::fmul_i(int i) { 1926 EnsureSpace ensure_space(this); 1927 emit_farith(0xD8, 0xC8, i); 1928} 1929 1930 1931void Assembler::fmul(int i) { 1932 EnsureSpace ensure_space(this); 1933 emit_farith(0xDC, 0xC8, i); 1934} 1935 1936 1937void Assembler::fdiv(int i) { 1938 EnsureSpace ensure_space(this); 1939 emit_farith(0xDC, 0xF8, i); 1940} 1941 1942 1943void Assembler::fdiv_i(int i) { 1944 EnsureSpace ensure_space(this); 1945 emit_farith(0xD8, 0xF0, i); 1946} 1947 1948 1949void Assembler::faddp(int i) { 1950 EnsureSpace ensure_space(this); 1951 emit_farith(0xDE, 0xC0, i); 1952} 1953 1954 1955void Assembler::fsubp(int i) { 1956 EnsureSpace ensure_space(this); 1957 emit_farith(0xDE, 0xE8, i); 1958} 1959 1960 1961void Assembler::fsubrp(int i) { 1962 EnsureSpace ensure_space(this); 1963 emit_farith(0xDE, 0xE0, i); 1964} 1965 1966 1967void Assembler::fmulp(int i) { 1968 EnsureSpace ensure_space(this); 1969 emit_farith(0xDE, 0xC8, i); 1970} 1971 1972 1973void Assembler::fdivp(int i) { 1974 EnsureSpace ensure_space(this); 1975 emit_farith(0xDE, 0xF8, i); 1976} 1977 1978 1979void Assembler::fprem() { 1980 EnsureSpace ensure_space(this); 1981 EMIT(0xD9); 1982 EMIT(0xF8); 1983} 1984 1985 1986void Assembler::fprem1() { 1987 EnsureSpace ensure_space(this); 1988 EMIT(0xD9); 1989 EMIT(0xF5); 1990} 1991 1992 1993void Assembler::fxch(int i) { 1994 EnsureSpace ensure_space(this); 1995 emit_farith(0xD9, 0xC8, i); 1996} 1997 1998 1999void Assembler::fincstp() { 2000 EnsureSpace ensure_space(this); 2001 EMIT(0xD9); 2002 EMIT(0xF7); 2003} 2004 2005 2006void Assembler::ffree(int i) { 2007 EnsureSpace ensure_space(this); 2008 emit_farith(0xDD, 0xC0, i); 2009} 2010 2011 2012void Assembler::ftst() { 2013 EnsureSpace ensure_space(this); 2014 EMIT(0xD9); 2015 EMIT(0xE4); 2016} 2017 2018 2019void Assembler::fucomp(int i) { 2020 EnsureSpace ensure_space(this); 2021 emit_farith(0xDD, 0xE8, i); 2022} 2023 2024 2025void Assembler::fucompp() { 2026 EnsureSpace ensure_space(this); 2027 EMIT(0xDA); 2028 EMIT(0xE9); 2029} 2030 2031 2032void Assembler::fucomi(int i) { 2033 EnsureSpace ensure_space(this); 2034 EMIT(0xDB); 2035 EMIT(0xE8 + i); 2036} 2037 2038 2039void Assembler::fucomip() { 2040 EnsureSpace ensure_space(this); 2041 EMIT(0xDF); 2042 EMIT(0xE9); 2043} 2044 2045 2046void Assembler::fcompp() { 2047 EnsureSpace ensure_space(this); 2048 EMIT(0xDE); 2049 EMIT(0xD9); 2050} 2051 2052 2053void Assembler::fnstsw_ax() { 2054 EnsureSpace ensure_space(this); 2055 EMIT(0xDF); 2056 EMIT(0xE0); 2057} 2058 2059 2060void Assembler::fwait() { 2061 EnsureSpace ensure_space(this); 2062 EMIT(0x9B); 2063} 2064 2065 2066void Assembler::frndint() { 2067 EnsureSpace ensure_space(this); 2068 EMIT(0xD9); 2069 EMIT(0xFC); 2070} 2071 2072 2073void Assembler::fnclex() { 2074 EnsureSpace ensure_space(this); 2075 EMIT(0xDB); 2076 EMIT(0xE2); 2077} 2078 2079 2080void Assembler::sahf() { 2081 EnsureSpace ensure_space(this); 2082 EMIT(0x9E); 2083} 2084 2085 2086void 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 2095void 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 2104void 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 2113void 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 2122void 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 2131void 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 2140void 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 2149void 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 2158void 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 2167void 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 2176void 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 2185void 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 2194void 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 2203void 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 2211void 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 2219void 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 2227void 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 2235void 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 2243void 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 2251void 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 2259void 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 2268void 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 2277void 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 2286void 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 2295void 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 2308void 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 2321void 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 2330void 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 2338void 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 2347void 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 2356void 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 2365void 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 2374void 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 2383void 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 2393void 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 2400void 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 2407void 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 2414void 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 2421void 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 2431void 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 2440void 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 2449void 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 2458void 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 2467void 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 2478void 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 2487void 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 2496void 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 2505void 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 2514void 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 2523void 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 2532void 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 2545void 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 2554void 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 2563void 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 2572void 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 2583void 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 2593void 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 2603void 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 2613void 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 2622void 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 2632void 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 2641void 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 2651void 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 2663void 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 2675void 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 2684void 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 2693void 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 2702void 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 2711void 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 2720void 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 2728void 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 2737void 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 2747void 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 2757void 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 2767void 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 2777void 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 2787void 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 2797void 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 2807void 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 2816void 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 2826void 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 2836void 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 2846void 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 2856void 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 2868void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { 2869 Register ireg = { reg.code() }; 2870 emit_operand(ireg, adr); 2871} 2872 2873 2874void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) { 2875 EMIT(0xC0 | dst.code() << 3 | src.code()); 2876} 2877 2878 2879void Assembler::emit_sse_operand(Register dst, XMMRegister src) { 2880 EMIT(0xC0 | dst.code() << 3 | src.code()); 2881} 2882 2883 2884void Assembler::emit_sse_operand(XMMRegister dst, Register src) { 2885 EMIT(0xC0 | (dst.code() << 3) | src.code()); 2886} 2887 2888 2889void 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 2903void 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 2910void 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 2963void 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 2973void 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 2991void 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 3015void 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 3025void 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 3033void Assembler::db(uint8_t data) { 3034 EnsureSpace ensure_space(this); 3035 EMIT(data); 3036} 3037 3038 3039void Assembler::dd(uint32_t data) { 3040 EnsureSpace ensure_space(this); 3041 emit(data); 3042} 3043 3044 3045void Assembler::dq(uint64_t data) { 3046 EnsureSpace ensure_space(this); 3047 emit_q(data); 3048} 3049 3050 3051void Assembler::dd(Label* label) { 3052 EnsureSpace ensure_space(this); 3053 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE); 3054 emit_label(label); 3055} 3056 3057 3058void 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