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