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