| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 if (own_buffer_) { | 381 if (own_buffer_) { |
| 382 memset(buffer_, 0xCC, buffer_size); // int3 | 382 memset(buffer_, 0xCC, buffer_size); // int3 |
| 383 } | 383 } |
| 384 #endif | 384 #endif |
| 385 | 385 |
| 386 // Setup buffer pointers. | 386 // Setup buffer pointers. |
| 387 ASSERT(buffer_ != NULL); | 387 ASSERT(buffer_ != NULL); |
| 388 pc_ = buffer_; | 388 pc_ = buffer_; |
| 389 reloc_info_writer.Reposition(buffer_ + buffer_size, pc_); | 389 reloc_info_writer.Reposition(buffer_ + buffer_size, pc_); |
| 390 | 390 |
| 391 last_pc_ = NULL; | |
| 392 | 391 |
| 393 #ifdef GENERATED_CODE_COVERAGE | 392 #ifdef GENERATED_CODE_COVERAGE |
| 394 InitCoverageLog(); | 393 InitCoverageLog(); |
| 395 #endif | 394 #endif |
| 396 } | 395 } |
| 397 | 396 |
| 398 | 397 |
| 399 Assembler::~Assembler() { | 398 Assembler::~Assembler() { |
| 400 if (own_buffer_) { | 399 if (own_buffer_) { |
| 401 if (isolate()->assembler_spare_buffer() == NULL && | 400 if (isolate()->assembler_spare_buffer() == NULL && |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 } | 435 } |
| 437 | 436 |
| 438 | 437 |
| 439 void Assembler::CodeTargetAlign() { | 438 void Assembler::CodeTargetAlign() { |
| 440 Align(16); // Preferred alignment of jump targets on x64. | 439 Align(16); // Preferred alignment of jump targets on x64. |
| 441 } | 440 } |
| 442 | 441 |
| 443 | 442 |
| 444 void Assembler::bind_to(Label* L, int pos) { | 443 void Assembler::bind_to(Label* L, int pos) { |
| 445 ASSERT(!L->is_bound()); // Label may only be bound once. | 444 ASSERT(!L->is_bound()); // Label may only be bound once. |
| 446 last_pc_ = NULL; | |
| 447 ASSERT(0 <= pos && pos <= pc_offset()); // Position must be valid. | 445 ASSERT(0 <= pos && pos <= pc_offset()); // Position must be valid. |
| 448 if (L->is_linked()) { | 446 if (L->is_linked()) { |
| 449 int current = L->pos(); | 447 int current = L->pos(); |
| 450 int next = long_at(current); | 448 int next = long_at(current); |
| 451 while (next != current) { | 449 while (next != current) { |
| 452 // Relative address, relative to point after address. | 450 // Relative address, relative to point after address. |
| 453 int imm32 = pos - (current + sizeof(int32_t)); | 451 int imm32 = pos - (current + sizeof(int32_t)); |
| 454 long_at_put(current, imm32); | 452 long_at_put(current, imm32); |
| 455 current = next; | 453 current = next; |
| 456 next = long_at(next); | 454 next = long_at(next); |
| 457 } | 455 } |
| 458 // Fix up last fixup on linked list. | 456 // Fix up last fixup on linked list. |
| 459 int last_imm32 = pos - (current + sizeof(int32_t)); | 457 int last_imm32 = pos - (current + sizeof(int32_t)); |
| 460 long_at_put(current, last_imm32); | 458 long_at_put(current, last_imm32); |
| 461 } | 459 } |
| 462 L->bind_to(pos); | 460 L->bind_to(pos); |
| 463 } | 461 } |
| 464 | 462 |
| 465 | 463 |
| 466 void Assembler::bind(Label* L) { | 464 void Assembler::bind(Label* L) { |
| 467 bind_to(L, pc_offset()); | 465 bind_to(L, pc_offset()); |
| 468 } | 466 } |
| 469 | 467 |
| 470 | 468 |
| 471 void Assembler::bind(NearLabel* L) { | 469 void Assembler::bind(NearLabel* L) { |
| 472 ASSERT(!L->is_bound()); | 470 ASSERT(!L->is_bound()); |
| 473 last_pc_ = NULL; | |
| 474 while (L->unresolved_branches_ > 0) { | 471 while (L->unresolved_branches_ > 0) { |
| 475 int branch_pos = L->unresolved_positions_[L->unresolved_branches_ - 1]; | 472 int branch_pos = L->unresolved_positions_[L->unresolved_branches_ - 1]; |
| 476 int disp = pc_offset() - branch_pos; | 473 int disp = pc_offset() - branch_pos; |
| 477 ASSERT(is_int8(disp)); | 474 ASSERT(is_int8(disp)); |
| 478 set_byte_at(branch_pos - sizeof(int8_t), disp); | 475 set_byte_at(branch_pos - sizeof(int8_t), disp); |
| 479 L->unresolved_branches_--; | 476 L->unresolved_branches_--; |
| 480 } | 477 } |
| 481 L->bind_to(pc_offset()); | 478 L->bind_to(pc_offset()); |
| 482 } | 479 } |
| 483 | 480 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 // Switch buffers. | 520 // Switch buffers. |
| 524 if (isolate()->assembler_spare_buffer() == NULL && | 521 if (isolate()->assembler_spare_buffer() == NULL && |
| 525 buffer_size_ == kMinimalBufferSize) { | 522 buffer_size_ == kMinimalBufferSize) { |
| 526 isolate()->set_assembler_spare_buffer(buffer_); | 523 isolate()->set_assembler_spare_buffer(buffer_); |
| 527 } else { | 524 } else { |
| 528 DeleteArray(buffer_); | 525 DeleteArray(buffer_); |
| 529 } | 526 } |
| 530 buffer_ = desc.buffer; | 527 buffer_ = desc.buffer; |
| 531 buffer_size_ = desc.buffer_size; | 528 buffer_size_ = desc.buffer_size; |
| 532 pc_ += pc_delta; | 529 pc_ += pc_delta; |
| 533 if (last_pc_ != NULL) { | |
| 534 last_pc_ += pc_delta; | |
| 535 } | |
| 536 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, | 530 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, |
| 537 reloc_info_writer.last_pc() + pc_delta); | 531 reloc_info_writer.last_pc() + pc_delta); |
| 538 | 532 |
| 539 // Relocate runtime entries. | 533 // Relocate runtime entries. |
| 540 for (RelocIterator it(desc); !it.done(); it.next()) { | 534 for (RelocIterator it(desc); !it.done(); it.next()) { |
| 541 RelocInfo::Mode rmode = it.rinfo()->rmode(); | 535 RelocInfo::Mode rmode = it.rinfo()->rmode(); |
| 542 if (rmode == RelocInfo::INTERNAL_REFERENCE) { | 536 if (rmode == RelocInfo::INTERNAL_REFERENCE) { |
| 543 intptr_t* p = reinterpret_cast<intptr_t*>(it.rinfo()->pc()); | 537 intptr_t* p = reinterpret_cast<intptr_t*>(it.rinfo()->pc()); |
| 544 if (*p != 0) { // 0 means uninitialized. | 538 if (*p != 0) { // 0 means uninitialized. |
| 545 *p += pc_delta; | 539 *p += pc_delta; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 563 // Emit the rest of the encoded operand. | 557 // Emit the rest of the encoded operand. |
| 564 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; | 558 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; |
| 565 pc_ += length; | 559 pc_ += length; |
| 566 } | 560 } |
| 567 | 561 |
| 568 | 562 |
| 569 // Assembler Instruction implementations. | 563 // Assembler Instruction implementations. |
| 570 | 564 |
| 571 void Assembler::arithmetic_op(byte opcode, Register reg, const Operand& op) { | 565 void Assembler::arithmetic_op(byte opcode, Register reg, const Operand& op) { |
| 572 EnsureSpace ensure_space(this); | 566 EnsureSpace ensure_space(this); |
| 573 last_pc_ = pc_; | |
| 574 emit_rex_64(reg, op); | 567 emit_rex_64(reg, op); |
| 575 emit(opcode); | 568 emit(opcode); |
| 576 emit_operand(reg, op); | 569 emit_operand(reg, op); |
| 577 } | 570 } |
| 578 | 571 |
| 579 | 572 |
| 580 void Assembler::arithmetic_op(byte opcode, Register reg, Register rm_reg) { | 573 void Assembler::arithmetic_op(byte opcode, Register reg, Register rm_reg) { |
| 581 EnsureSpace ensure_space(this); | 574 EnsureSpace ensure_space(this); |
| 582 last_pc_ = pc_; | |
| 583 ASSERT((opcode & 0xC6) == 2); | 575 ASSERT((opcode & 0xC6) == 2); |
| 584 if (rm_reg.low_bits() == 4) { // Forces SIB byte. | 576 if (rm_reg.low_bits() == 4) { // Forces SIB byte. |
| 585 // Swap reg and rm_reg and change opcode operand order. | 577 // Swap reg and rm_reg and change opcode operand order. |
| 586 emit_rex_64(rm_reg, reg); | 578 emit_rex_64(rm_reg, reg); |
| 587 emit(opcode ^ 0x02); | 579 emit(opcode ^ 0x02); |
| 588 emit_modrm(rm_reg, reg); | 580 emit_modrm(rm_reg, reg); |
| 589 } else { | 581 } else { |
| 590 emit_rex_64(reg, rm_reg); | 582 emit_rex_64(reg, rm_reg); |
| 591 emit(opcode); | 583 emit(opcode); |
| 592 emit_modrm(reg, rm_reg); | 584 emit_modrm(reg, rm_reg); |
| 593 } | 585 } |
| 594 } | 586 } |
| 595 | 587 |
| 596 | 588 |
| 597 void Assembler::arithmetic_op_16(byte opcode, Register reg, Register rm_reg) { | 589 void Assembler::arithmetic_op_16(byte opcode, Register reg, Register rm_reg) { |
| 598 EnsureSpace ensure_space(this); | 590 EnsureSpace ensure_space(this); |
| 599 last_pc_ = pc_; | |
| 600 ASSERT((opcode & 0xC6) == 2); | 591 ASSERT((opcode & 0xC6) == 2); |
| 601 if (rm_reg.low_bits() == 4) { // Forces SIB byte. | 592 if (rm_reg.low_bits() == 4) { // Forces SIB byte. |
| 602 // Swap reg and rm_reg and change opcode operand order. | 593 // Swap reg and rm_reg and change opcode operand order. |
| 603 emit(0x66); | 594 emit(0x66); |
| 604 emit_optional_rex_32(rm_reg, reg); | 595 emit_optional_rex_32(rm_reg, reg); |
| 605 emit(opcode ^ 0x02); | 596 emit(opcode ^ 0x02); |
| 606 emit_modrm(rm_reg, reg); | 597 emit_modrm(rm_reg, reg); |
| 607 } else { | 598 } else { |
| 608 emit(0x66); | 599 emit(0x66); |
| 609 emit_optional_rex_32(reg, rm_reg); | 600 emit_optional_rex_32(reg, rm_reg); |
| 610 emit(opcode); | 601 emit(opcode); |
| 611 emit_modrm(reg, rm_reg); | 602 emit_modrm(reg, rm_reg); |
| 612 } | 603 } |
| 613 } | 604 } |
| 614 | 605 |
| 615 | 606 |
| 616 void Assembler::arithmetic_op_16(byte opcode, | 607 void Assembler::arithmetic_op_16(byte opcode, |
| 617 Register reg, | 608 Register reg, |
| 618 const Operand& rm_reg) { | 609 const Operand& rm_reg) { |
| 619 EnsureSpace ensure_space(this); | 610 EnsureSpace ensure_space(this); |
| 620 last_pc_ = pc_; | |
| 621 emit(0x66); | 611 emit(0x66); |
| 622 emit_optional_rex_32(reg, rm_reg); | 612 emit_optional_rex_32(reg, rm_reg); |
| 623 emit(opcode); | 613 emit(opcode); |
| 624 emit_operand(reg, rm_reg); | 614 emit_operand(reg, rm_reg); |
| 625 } | 615 } |
| 626 | 616 |
| 627 | 617 |
| 628 void Assembler::arithmetic_op_32(byte opcode, Register reg, Register rm_reg) { | 618 void Assembler::arithmetic_op_32(byte opcode, Register reg, Register rm_reg) { |
| 629 EnsureSpace ensure_space(this); | 619 EnsureSpace ensure_space(this); |
| 630 last_pc_ = pc_; | |
| 631 ASSERT((opcode & 0xC6) == 2); | 620 ASSERT((opcode & 0xC6) == 2); |
| 632 if (rm_reg.low_bits() == 4) { // Forces SIB byte. | 621 if (rm_reg.low_bits() == 4) { // Forces SIB byte. |
| 633 // Swap reg and rm_reg and change opcode operand order. | 622 // Swap reg and rm_reg and change opcode operand order. |
| 634 emit_optional_rex_32(rm_reg, reg); | 623 emit_optional_rex_32(rm_reg, reg); |
| 635 emit(opcode ^ 0x02); // E.g. 0x03 -> 0x01 for ADD. | 624 emit(opcode ^ 0x02); // E.g. 0x03 -> 0x01 for ADD. |
| 636 emit_modrm(rm_reg, reg); | 625 emit_modrm(rm_reg, reg); |
| 637 } else { | 626 } else { |
| 638 emit_optional_rex_32(reg, rm_reg); | 627 emit_optional_rex_32(reg, rm_reg); |
| 639 emit(opcode); | 628 emit(opcode); |
| 640 emit_modrm(reg, rm_reg); | 629 emit_modrm(reg, rm_reg); |
| 641 } | 630 } |
| 642 } | 631 } |
| 643 | 632 |
| 644 | 633 |
| 645 void Assembler::arithmetic_op_32(byte opcode, | 634 void Assembler::arithmetic_op_32(byte opcode, |
| 646 Register reg, | 635 Register reg, |
| 647 const Operand& rm_reg) { | 636 const Operand& rm_reg) { |
| 648 EnsureSpace ensure_space(this); | 637 EnsureSpace ensure_space(this); |
| 649 last_pc_ = pc_; | |
| 650 emit_optional_rex_32(reg, rm_reg); | 638 emit_optional_rex_32(reg, rm_reg); |
| 651 emit(opcode); | 639 emit(opcode); |
| 652 emit_operand(reg, rm_reg); | 640 emit_operand(reg, rm_reg); |
| 653 } | 641 } |
| 654 | 642 |
| 655 | 643 |
| 656 void Assembler::immediate_arithmetic_op(byte subcode, | 644 void Assembler::immediate_arithmetic_op(byte subcode, |
| 657 Register dst, | 645 Register dst, |
| 658 Immediate src) { | 646 Immediate src) { |
| 659 EnsureSpace ensure_space(this); | 647 EnsureSpace ensure_space(this); |
| 660 last_pc_ = pc_; | |
| 661 emit_rex_64(dst); | 648 emit_rex_64(dst); |
| 662 if (is_int8(src.value_)) { | 649 if (is_int8(src.value_)) { |
| 663 emit(0x83); | 650 emit(0x83); |
| 664 emit_modrm(subcode, dst); | 651 emit_modrm(subcode, dst); |
| 665 emit(src.value_); | 652 emit(src.value_); |
| 666 } else if (dst.is(rax)) { | 653 } else if (dst.is(rax)) { |
| 667 emit(0x05 | (subcode << 3)); | 654 emit(0x05 | (subcode << 3)); |
| 668 emitl(src.value_); | 655 emitl(src.value_); |
| 669 } else { | 656 } else { |
| 670 emit(0x81); | 657 emit(0x81); |
| 671 emit_modrm(subcode, dst); | 658 emit_modrm(subcode, dst); |
| 672 emitl(src.value_); | 659 emitl(src.value_); |
| 673 } | 660 } |
| 674 } | 661 } |
| 675 | 662 |
| 676 void Assembler::immediate_arithmetic_op(byte subcode, | 663 void Assembler::immediate_arithmetic_op(byte subcode, |
| 677 const Operand& dst, | 664 const Operand& dst, |
| 678 Immediate src) { | 665 Immediate src) { |
| 679 EnsureSpace ensure_space(this); | 666 EnsureSpace ensure_space(this); |
| 680 last_pc_ = pc_; | |
| 681 emit_rex_64(dst); | 667 emit_rex_64(dst); |
| 682 if (is_int8(src.value_)) { | 668 if (is_int8(src.value_)) { |
| 683 emit(0x83); | 669 emit(0x83); |
| 684 emit_operand(subcode, dst); | 670 emit_operand(subcode, dst); |
| 685 emit(src.value_); | 671 emit(src.value_); |
| 686 } else { | 672 } else { |
| 687 emit(0x81); | 673 emit(0x81); |
| 688 emit_operand(subcode, dst); | 674 emit_operand(subcode, dst); |
| 689 emitl(src.value_); | 675 emitl(src.value_); |
| 690 } | 676 } |
| 691 } | 677 } |
| 692 | 678 |
| 693 | 679 |
| 694 void Assembler::immediate_arithmetic_op_16(byte subcode, | 680 void Assembler::immediate_arithmetic_op_16(byte subcode, |
| 695 Register dst, | 681 Register dst, |
| 696 Immediate src) { | 682 Immediate src) { |
| 697 EnsureSpace ensure_space(this); | 683 EnsureSpace ensure_space(this); |
| 698 last_pc_ = pc_; | |
| 699 emit(0x66); // Operand size override prefix. | 684 emit(0x66); // Operand size override prefix. |
| 700 emit_optional_rex_32(dst); | 685 emit_optional_rex_32(dst); |
| 701 if (is_int8(src.value_)) { | 686 if (is_int8(src.value_)) { |
| 702 emit(0x83); | 687 emit(0x83); |
| 703 emit_modrm(subcode, dst); | 688 emit_modrm(subcode, dst); |
| 704 emit(src.value_); | 689 emit(src.value_); |
| 705 } else if (dst.is(rax)) { | 690 } else if (dst.is(rax)) { |
| 706 emit(0x05 | (subcode << 3)); | 691 emit(0x05 | (subcode << 3)); |
| 707 emitw(src.value_); | 692 emitw(src.value_); |
| 708 } else { | 693 } else { |
| 709 emit(0x81); | 694 emit(0x81); |
| 710 emit_modrm(subcode, dst); | 695 emit_modrm(subcode, dst); |
| 711 emitw(src.value_); | 696 emitw(src.value_); |
| 712 } | 697 } |
| 713 } | 698 } |
| 714 | 699 |
| 715 | 700 |
| 716 void Assembler::immediate_arithmetic_op_16(byte subcode, | 701 void Assembler::immediate_arithmetic_op_16(byte subcode, |
| 717 const Operand& dst, | 702 const Operand& dst, |
| 718 Immediate src) { | 703 Immediate src) { |
| 719 EnsureSpace ensure_space(this); | 704 EnsureSpace ensure_space(this); |
| 720 last_pc_ = pc_; | |
| 721 emit(0x66); // Operand size override prefix. | 705 emit(0x66); // Operand size override prefix. |
| 722 emit_optional_rex_32(dst); | 706 emit_optional_rex_32(dst); |
| 723 if (is_int8(src.value_)) { | 707 if (is_int8(src.value_)) { |
| 724 emit(0x83); | 708 emit(0x83); |
| 725 emit_operand(subcode, dst); | 709 emit_operand(subcode, dst); |
| 726 emit(src.value_); | 710 emit(src.value_); |
| 727 } else { | 711 } else { |
| 728 emit(0x81); | 712 emit(0x81); |
| 729 emit_operand(subcode, dst); | 713 emit_operand(subcode, dst); |
| 730 emitw(src.value_); | 714 emitw(src.value_); |
| 731 } | 715 } |
| 732 } | 716 } |
| 733 | 717 |
| 734 | 718 |
| 735 void Assembler::immediate_arithmetic_op_32(byte subcode, | 719 void Assembler::immediate_arithmetic_op_32(byte subcode, |
| 736 Register dst, | 720 Register dst, |
| 737 Immediate src) { | 721 Immediate src) { |
| 738 EnsureSpace ensure_space(this); | 722 EnsureSpace ensure_space(this); |
| 739 last_pc_ = pc_; | |
| 740 emit_optional_rex_32(dst); | 723 emit_optional_rex_32(dst); |
| 741 if (is_int8(src.value_)) { | 724 if (is_int8(src.value_)) { |
| 742 emit(0x83); | 725 emit(0x83); |
| 743 emit_modrm(subcode, dst); | 726 emit_modrm(subcode, dst); |
| 744 emit(src.value_); | 727 emit(src.value_); |
| 745 } else if (dst.is(rax)) { | 728 } else if (dst.is(rax)) { |
| 746 emit(0x05 | (subcode << 3)); | 729 emit(0x05 | (subcode << 3)); |
| 747 emitl(src.value_); | 730 emitl(src.value_); |
| 748 } else { | 731 } else { |
| 749 emit(0x81); | 732 emit(0x81); |
| 750 emit_modrm(subcode, dst); | 733 emit_modrm(subcode, dst); |
| 751 emitl(src.value_); | 734 emitl(src.value_); |
| 752 } | 735 } |
| 753 } | 736 } |
| 754 | 737 |
| 755 | 738 |
| 756 void Assembler::immediate_arithmetic_op_32(byte subcode, | 739 void Assembler::immediate_arithmetic_op_32(byte subcode, |
| 757 const Operand& dst, | 740 const Operand& dst, |
| 758 Immediate src) { | 741 Immediate src) { |
| 759 EnsureSpace ensure_space(this); | 742 EnsureSpace ensure_space(this); |
| 760 last_pc_ = pc_; | |
| 761 emit_optional_rex_32(dst); | 743 emit_optional_rex_32(dst); |
| 762 if (is_int8(src.value_)) { | 744 if (is_int8(src.value_)) { |
| 763 emit(0x83); | 745 emit(0x83); |
| 764 emit_operand(subcode, dst); | 746 emit_operand(subcode, dst); |
| 765 emit(src.value_); | 747 emit(src.value_); |
| 766 } else { | 748 } else { |
| 767 emit(0x81); | 749 emit(0x81); |
| 768 emit_operand(subcode, dst); | 750 emit_operand(subcode, dst); |
| 769 emitl(src.value_); | 751 emitl(src.value_); |
| 770 } | 752 } |
| 771 } | 753 } |
| 772 | 754 |
| 773 | 755 |
| 774 void Assembler::immediate_arithmetic_op_8(byte subcode, | 756 void Assembler::immediate_arithmetic_op_8(byte subcode, |
| 775 const Operand& dst, | 757 const Operand& dst, |
| 776 Immediate src) { | 758 Immediate src) { |
| 777 EnsureSpace ensure_space(this); | 759 EnsureSpace ensure_space(this); |
| 778 last_pc_ = pc_; | |
| 779 emit_optional_rex_32(dst); | 760 emit_optional_rex_32(dst); |
| 780 ASSERT(is_int8(src.value_) || is_uint8(src.value_)); | 761 ASSERT(is_int8(src.value_) || is_uint8(src.value_)); |
| 781 emit(0x80); | 762 emit(0x80); |
| 782 emit_operand(subcode, dst); | 763 emit_operand(subcode, dst); |
| 783 emit(src.value_); | 764 emit(src.value_); |
| 784 } | 765 } |
| 785 | 766 |
| 786 | 767 |
| 787 void Assembler::immediate_arithmetic_op_8(byte subcode, | 768 void Assembler::immediate_arithmetic_op_8(byte subcode, |
| 788 Register dst, | 769 Register dst, |
| 789 Immediate src) { | 770 Immediate src) { |
| 790 EnsureSpace ensure_space(this); | 771 EnsureSpace ensure_space(this); |
| 791 last_pc_ = pc_; | |
| 792 if (dst.code() > 3) { | 772 if (dst.code() > 3) { |
| 793 // Use 64-bit mode byte registers. | 773 // Use 64-bit mode byte registers. |
| 794 emit_rex_64(dst); | 774 emit_rex_64(dst); |
| 795 } | 775 } |
| 796 ASSERT(is_int8(src.value_) || is_uint8(src.value_)); | 776 ASSERT(is_int8(src.value_) || is_uint8(src.value_)); |
| 797 emit(0x80); | 777 emit(0x80); |
| 798 emit_modrm(subcode, dst); | 778 emit_modrm(subcode, dst); |
| 799 emit(src.value_); | 779 emit(src.value_); |
| 800 } | 780 } |
| 801 | 781 |
| 802 | 782 |
| 803 void Assembler::shift(Register dst, Immediate shift_amount, int subcode) { | 783 void Assembler::shift(Register dst, Immediate shift_amount, int subcode) { |
| 804 EnsureSpace ensure_space(this); | 784 EnsureSpace ensure_space(this); |
| 805 last_pc_ = pc_; | |
| 806 ASSERT(is_uint6(shift_amount.value_)); // illegal shift count | 785 ASSERT(is_uint6(shift_amount.value_)); // illegal shift count |
| 807 if (shift_amount.value_ == 1) { | 786 if (shift_amount.value_ == 1) { |
| 808 emit_rex_64(dst); | 787 emit_rex_64(dst); |
| 809 emit(0xD1); | 788 emit(0xD1); |
| 810 emit_modrm(subcode, dst); | 789 emit_modrm(subcode, dst); |
| 811 } else { | 790 } else { |
| 812 emit_rex_64(dst); | 791 emit_rex_64(dst); |
| 813 emit(0xC1); | 792 emit(0xC1); |
| 814 emit_modrm(subcode, dst); | 793 emit_modrm(subcode, dst); |
| 815 emit(shift_amount.value_); | 794 emit(shift_amount.value_); |
| 816 } | 795 } |
| 817 } | 796 } |
| 818 | 797 |
| 819 | 798 |
| 820 void Assembler::shift(Register dst, int subcode) { | 799 void Assembler::shift(Register dst, int subcode) { |
| 821 EnsureSpace ensure_space(this); | 800 EnsureSpace ensure_space(this); |
| 822 last_pc_ = pc_; | |
| 823 emit_rex_64(dst); | 801 emit_rex_64(dst); |
| 824 emit(0xD3); | 802 emit(0xD3); |
| 825 emit_modrm(subcode, dst); | 803 emit_modrm(subcode, dst); |
| 826 } | 804 } |
| 827 | 805 |
| 828 | 806 |
| 829 void Assembler::shift_32(Register dst, int subcode) { | 807 void Assembler::shift_32(Register dst, int subcode) { |
| 830 EnsureSpace ensure_space(this); | 808 EnsureSpace ensure_space(this); |
| 831 last_pc_ = pc_; | |
| 832 emit_optional_rex_32(dst); | 809 emit_optional_rex_32(dst); |
| 833 emit(0xD3); | 810 emit(0xD3); |
| 834 emit_modrm(subcode, dst); | 811 emit_modrm(subcode, dst); |
| 835 } | 812 } |
| 836 | 813 |
| 837 | 814 |
| 838 void Assembler::shift_32(Register dst, Immediate shift_amount, int subcode) { | 815 void Assembler::shift_32(Register dst, Immediate shift_amount, int subcode) { |
| 839 EnsureSpace ensure_space(this); | 816 EnsureSpace ensure_space(this); |
| 840 last_pc_ = pc_; | |
| 841 ASSERT(is_uint5(shift_amount.value_)); // illegal shift count | 817 ASSERT(is_uint5(shift_amount.value_)); // illegal shift count |
| 842 if (shift_amount.value_ == 1) { | 818 if (shift_amount.value_ == 1) { |
| 843 emit_optional_rex_32(dst); | 819 emit_optional_rex_32(dst); |
| 844 emit(0xD1); | 820 emit(0xD1); |
| 845 emit_modrm(subcode, dst); | 821 emit_modrm(subcode, dst); |
| 846 } else { | 822 } else { |
| 847 emit_optional_rex_32(dst); | 823 emit_optional_rex_32(dst); |
| 848 emit(0xC1); | 824 emit(0xC1); |
| 849 emit_modrm(subcode, dst); | 825 emit_modrm(subcode, dst); |
| 850 emit(shift_amount.value_); | 826 emit(shift_amount.value_); |
| 851 } | 827 } |
| 852 } | 828 } |
| 853 | 829 |
| 854 | 830 |
| 855 void Assembler::bt(const Operand& dst, Register src) { | 831 void Assembler::bt(const Operand& dst, Register src) { |
| 856 EnsureSpace ensure_space(this); | 832 EnsureSpace ensure_space(this); |
| 857 last_pc_ = pc_; | |
| 858 emit_rex_64(src, dst); | 833 emit_rex_64(src, dst); |
| 859 emit(0x0F); | 834 emit(0x0F); |
| 860 emit(0xA3); | 835 emit(0xA3); |
| 861 emit_operand(src, dst); | 836 emit_operand(src, dst); |
| 862 } | 837 } |
| 863 | 838 |
| 864 | 839 |
| 865 void Assembler::bts(const Operand& dst, Register src) { | 840 void Assembler::bts(const Operand& dst, Register src) { |
| 866 EnsureSpace ensure_space(this); | 841 EnsureSpace ensure_space(this); |
| 867 last_pc_ = pc_; | |
| 868 emit_rex_64(src, dst); | 842 emit_rex_64(src, dst); |
| 869 emit(0x0F); | 843 emit(0x0F); |
| 870 emit(0xAB); | 844 emit(0xAB); |
| 871 emit_operand(src, dst); | 845 emit_operand(src, dst); |
| 872 } | 846 } |
| 873 | 847 |
| 874 | 848 |
| 875 void Assembler::call(Label* L) { | 849 void Assembler::call(Label* L) { |
| 876 positions_recorder()->WriteRecordedPositions(); | 850 positions_recorder()->WriteRecordedPositions(); |
| 877 EnsureSpace ensure_space(this); | 851 EnsureSpace ensure_space(this); |
| 878 last_pc_ = pc_; | |
| 879 // 1110 1000 #32-bit disp. | 852 // 1110 1000 #32-bit disp. |
| 880 emit(0xE8); | 853 emit(0xE8); |
| 881 if (L->is_bound()) { | 854 if (L->is_bound()) { |
| 882 int offset = L->pos() - pc_offset() - sizeof(int32_t); | 855 int offset = L->pos() - pc_offset() - sizeof(int32_t); |
| 883 ASSERT(offset <= 0); | 856 ASSERT(offset <= 0); |
| 884 emitl(offset); | 857 emitl(offset); |
| 885 } else if (L->is_linked()) { | 858 } else if (L->is_linked()) { |
| 886 emitl(L->pos()); | 859 emitl(L->pos()); |
| 887 L->link_to(pc_offset() - sizeof(int32_t)); | 860 L->link_to(pc_offset() - sizeof(int32_t)); |
| 888 } else { | 861 } else { |
| 889 ASSERT(L->is_unused()); | 862 ASSERT(L->is_unused()); |
| 890 int32_t current = pc_offset(); | 863 int32_t current = pc_offset(); |
| 891 emitl(current); | 864 emitl(current); |
| 892 L->link_to(current); | 865 L->link_to(current); |
| 893 } | 866 } |
| 894 } | 867 } |
| 895 | 868 |
| 896 | 869 |
| 897 void Assembler::call(Handle<Code> target, RelocInfo::Mode rmode) { | 870 void Assembler::call(Handle<Code> target, RelocInfo::Mode rmode) { |
| 898 positions_recorder()->WriteRecordedPositions(); | 871 positions_recorder()->WriteRecordedPositions(); |
| 899 EnsureSpace ensure_space(this); | 872 EnsureSpace ensure_space(this); |
| 900 last_pc_ = pc_; | |
| 901 // 1110 1000 #32-bit disp. | 873 // 1110 1000 #32-bit disp. |
| 902 emit(0xE8); | 874 emit(0xE8); |
| 903 emit_code_target(target, rmode); | 875 emit_code_target(target, rmode); |
| 904 } | 876 } |
| 905 | 877 |
| 906 | 878 |
| 907 void Assembler::call(Register adr) { | 879 void Assembler::call(Register adr) { |
| 908 positions_recorder()->WriteRecordedPositions(); | 880 positions_recorder()->WriteRecordedPositions(); |
| 909 EnsureSpace ensure_space(this); | 881 EnsureSpace ensure_space(this); |
| 910 last_pc_ = pc_; | |
| 911 // Opcode: FF /2 r64. | 882 // Opcode: FF /2 r64. |
| 912 emit_optional_rex_32(adr); | 883 emit_optional_rex_32(adr); |
| 913 emit(0xFF); | 884 emit(0xFF); |
| 914 emit_modrm(0x2, adr); | 885 emit_modrm(0x2, adr); |
| 915 } | 886 } |
| 916 | 887 |
| 917 | 888 |
| 918 void Assembler::call(const Operand& op) { | 889 void Assembler::call(const Operand& op) { |
| 919 positions_recorder()->WriteRecordedPositions(); | 890 positions_recorder()->WriteRecordedPositions(); |
| 920 EnsureSpace ensure_space(this); | 891 EnsureSpace ensure_space(this); |
| 921 last_pc_ = pc_; | |
| 922 // Opcode: FF /2 m64. | 892 // Opcode: FF /2 m64. |
| 923 emit_optional_rex_32(op); | 893 emit_optional_rex_32(op); |
| 924 emit(0xFF); | 894 emit(0xFF); |
| 925 emit_operand(0x2, op); | 895 emit_operand(0x2, op); |
| 926 } | 896 } |
| 927 | 897 |
| 928 | 898 |
| 929 // Calls directly to the given address using a relative offset. | 899 // Calls directly to the given address using a relative offset. |
| 930 // Should only ever be used in Code objects for calls within the | 900 // Should only ever be used in Code objects for calls within the |
| 931 // same Code object. Should not be used when generating new code (use labels), | 901 // same Code object. Should not be used when generating new code (use labels), |
| 932 // but only when patching existing code. | 902 // but only when patching existing code. |
| 933 void Assembler::call(Address target) { | 903 void Assembler::call(Address target) { |
| 934 positions_recorder()->WriteRecordedPositions(); | 904 positions_recorder()->WriteRecordedPositions(); |
| 935 EnsureSpace ensure_space(this); | 905 EnsureSpace ensure_space(this); |
| 936 last_pc_ = pc_; | |
| 937 // 1110 1000 #32-bit disp. | 906 // 1110 1000 #32-bit disp. |
| 938 emit(0xE8); | 907 emit(0xE8); |
| 939 Address source = pc_ + 4; | 908 Address source = pc_ + 4; |
| 940 intptr_t displacement = target - source; | 909 intptr_t displacement = target - source; |
| 941 ASSERT(is_int32(displacement)); | 910 ASSERT(is_int32(displacement)); |
| 942 emitl(static_cast<int32_t>(displacement)); | 911 emitl(static_cast<int32_t>(displacement)); |
| 943 } | 912 } |
| 944 | 913 |
| 945 | 914 |
| 946 void Assembler::clc() { | 915 void Assembler::clc() { |
| 947 EnsureSpace ensure_space(this); | 916 EnsureSpace ensure_space(this); |
| 948 last_pc_ = pc_; | |
| 949 emit(0xF8); | 917 emit(0xF8); |
| 950 } | 918 } |
| 951 | 919 |
| 952 void Assembler::cld() { | 920 void Assembler::cld() { |
| 953 EnsureSpace ensure_space(this); | 921 EnsureSpace ensure_space(this); |
| 954 last_pc_ = pc_; | |
| 955 emit(0xFC); | 922 emit(0xFC); |
| 956 } | 923 } |
| 957 | 924 |
| 958 void Assembler::cdq() { | 925 void Assembler::cdq() { |
| 959 EnsureSpace ensure_space(this); | 926 EnsureSpace ensure_space(this); |
| 960 last_pc_ = pc_; | |
| 961 emit(0x99); | 927 emit(0x99); |
| 962 } | 928 } |
| 963 | 929 |
| 964 | 930 |
| 965 void Assembler::cmovq(Condition cc, Register dst, Register src) { | 931 void Assembler::cmovq(Condition cc, Register dst, Register src) { |
| 966 if (cc == always) { | 932 if (cc == always) { |
| 967 movq(dst, src); | 933 movq(dst, src); |
| 968 } else if (cc == never) { | 934 } else if (cc == never) { |
| 969 return; | 935 return; |
| 970 } | 936 } |
| 971 // No need to check CpuInfo for CMOV support, it's a required part of the | 937 // No need to check CpuInfo for CMOV support, it's a required part of the |
| 972 // 64-bit architecture. | 938 // 64-bit architecture. |
| 973 ASSERT(cc >= 0); // Use mov for unconditional moves. | 939 ASSERT(cc >= 0); // Use mov for unconditional moves. |
| 974 EnsureSpace ensure_space(this); | 940 EnsureSpace ensure_space(this); |
| 975 last_pc_ = pc_; | |
| 976 // Opcode: REX.W 0f 40 + cc /r. | 941 // Opcode: REX.W 0f 40 + cc /r. |
| 977 emit_rex_64(dst, src); | 942 emit_rex_64(dst, src); |
| 978 emit(0x0f); | 943 emit(0x0f); |
| 979 emit(0x40 + cc); | 944 emit(0x40 + cc); |
| 980 emit_modrm(dst, src); | 945 emit_modrm(dst, src); |
| 981 } | 946 } |
| 982 | 947 |
| 983 | 948 |
| 984 void Assembler::cmovq(Condition cc, Register dst, const Operand& src) { | 949 void Assembler::cmovq(Condition cc, Register dst, const Operand& src) { |
| 985 if (cc == always) { | 950 if (cc == always) { |
| 986 movq(dst, src); | 951 movq(dst, src); |
| 987 } else if (cc == never) { | 952 } else if (cc == never) { |
| 988 return; | 953 return; |
| 989 } | 954 } |
| 990 ASSERT(cc >= 0); | 955 ASSERT(cc >= 0); |
| 991 EnsureSpace ensure_space(this); | 956 EnsureSpace ensure_space(this); |
| 992 last_pc_ = pc_; | |
| 993 // Opcode: REX.W 0f 40 + cc /r. | 957 // Opcode: REX.W 0f 40 + cc /r. |
| 994 emit_rex_64(dst, src); | 958 emit_rex_64(dst, src); |
| 995 emit(0x0f); | 959 emit(0x0f); |
| 996 emit(0x40 + cc); | 960 emit(0x40 + cc); |
| 997 emit_operand(dst, src); | 961 emit_operand(dst, src); |
| 998 } | 962 } |
| 999 | 963 |
| 1000 | 964 |
| 1001 void Assembler::cmovl(Condition cc, Register dst, Register src) { | 965 void Assembler::cmovl(Condition cc, Register dst, Register src) { |
| 1002 if (cc == always) { | 966 if (cc == always) { |
| 1003 movl(dst, src); | 967 movl(dst, src); |
| 1004 } else if (cc == never) { | 968 } else if (cc == never) { |
| 1005 return; | 969 return; |
| 1006 } | 970 } |
| 1007 ASSERT(cc >= 0); | 971 ASSERT(cc >= 0); |
| 1008 EnsureSpace ensure_space(this); | 972 EnsureSpace ensure_space(this); |
| 1009 last_pc_ = pc_; | |
| 1010 // Opcode: 0f 40 + cc /r. | 973 // Opcode: 0f 40 + cc /r. |
| 1011 emit_optional_rex_32(dst, src); | 974 emit_optional_rex_32(dst, src); |
| 1012 emit(0x0f); | 975 emit(0x0f); |
| 1013 emit(0x40 + cc); | 976 emit(0x40 + cc); |
| 1014 emit_modrm(dst, src); | 977 emit_modrm(dst, src); |
| 1015 } | 978 } |
| 1016 | 979 |
| 1017 | 980 |
| 1018 void Assembler::cmovl(Condition cc, Register dst, const Operand& src) { | 981 void Assembler::cmovl(Condition cc, Register dst, const Operand& src) { |
| 1019 if (cc == always) { | 982 if (cc == always) { |
| 1020 movl(dst, src); | 983 movl(dst, src); |
| 1021 } else if (cc == never) { | 984 } else if (cc == never) { |
| 1022 return; | 985 return; |
| 1023 } | 986 } |
| 1024 ASSERT(cc >= 0); | 987 ASSERT(cc >= 0); |
| 1025 EnsureSpace ensure_space(this); | 988 EnsureSpace ensure_space(this); |
| 1026 last_pc_ = pc_; | |
| 1027 // Opcode: 0f 40 + cc /r. | 989 // Opcode: 0f 40 + cc /r. |
| 1028 emit_optional_rex_32(dst, src); | 990 emit_optional_rex_32(dst, src); |
| 1029 emit(0x0f); | 991 emit(0x0f); |
| 1030 emit(0x40 + cc); | 992 emit(0x40 + cc); |
| 1031 emit_operand(dst, src); | 993 emit_operand(dst, src); |
| 1032 } | 994 } |
| 1033 | 995 |
| 1034 | 996 |
| 1035 void Assembler::cmpb_al(Immediate imm8) { | 997 void Assembler::cmpb_al(Immediate imm8) { |
| 1036 ASSERT(is_int8(imm8.value_) || is_uint8(imm8.value_)); | 998 ASSERT(is_int8(imm8.value_) || is_uint8(imm8.value_)); |
| 1037 EnsureSpace ensure_space(this); | 999 EnsureSpace ensure_space(this); |
| 1038 last_pc_ = pc_; | |
| 1039 emit(0x3c); | 1000 emit(0x3c); |
| 1040 emit(imm8.value_); | 1001 emit(imm8.value_); |
| 1041 } | 1002 } |
| 1042 | 1003 |
| 1043 | 1004 |
| 1044 void Assembler::cpuid() { | 1005 void Assembler::cpuid() { |
| 1045 ASSERT(CpuFeatures::IsEnabled(CPUID)); | 1006 ASSERT(CpuFeatures::IsEnabled(CPUID)); |
| 1046 EnsureSpace ensure_space(this); | 1007 EnsureSpace ensure_space(this); |
| 1047 last_pc_ = pc_; | |
| 1048 emit(0x0F); | 1008 emit(0x0F); |
| 1049 emit(0xA2); | 1009 emit(0xA2); |
| 1050 } | 1010 } |
| 1051 | 1011 |
| 1052 | 1012 |
| 1053 void Assembler::cqo() { | 1013 void Assembler::cqo() { |
| 1054 EnsureSpace ensure_space(this); | 1014 EnsureSpace ensure_space(this); |
| 1055 last_pc_ = pc_; | |
| 1056 emit_rex_64(); | 1015 emit_rex_64(); |
| 1057 emit(0x99); | 1016 emit(0x99); |
| 1058 } | 1017 } |
| 1059 | 1018 |
| 1060 | 1019 |
| 1061 void Assembler::decq(Register dst) { | 1020 void Assembler::decq(Register dst) { |
| 1062 EnsureSpace ensure_space(this); | 1021 EnsureSpace ensure_space(this); |
| 1063 last_pc_ = pc_; | |
| 1064 emit_rex_64(dst); | 1022 emit_rex_64(dst); |
| 1065 emit(0xFF); | 1023 emit(0xFF); |
| 1066 emit_modrm(0x1, dst); | 1024 emit_modrm(0x1, dst); |
| 1067 } | 1025 } |
| 1068 | 1026 |
| 1069 | 1027 |
| 1070 void Assembler::decq(const Operand& dst) { | 1028 void Assembler::decq(const Operand& dst) { |
| 1071 EnsureSpace ensure_space(this); | 1029 EnsureSpace ensure_space(this); |
| 1072 last_pc_ = pc_; | |
| 1073 emit_rex_64(dst); | 1030 emit_rex_64(dst); |
| 1074 emit(0xFF); | 1031 emit(0xFF); |
| 1075 emit_operand(1, dst); | 1032 emit_operand(1, dst); |
| 1076 } | 1033 } |
| 1077 | 1034 |
| 1078 | 1035 |
| 1079 void Assembler::decl(Register dst) { | 1036 void Assembler::decl(Register dst) { |
| 1080 EnsureSpace ensure_space(this); | 1037 EnsureSpace ensure_space(this); |
| 1081 last_pc_ = pc_; | |
| 1082 emit_optional_rex_32(dst); | 1038 emit_optional_rex_32(dst); |
| 1083 emit(0xFF); | 1039 emit(0xFF); |
| 1084 emit_modrm(0x1, dst); | 1040 emit_modrm(0x1, dst); |
| 1085 } | 1041 } |
| 1086 | 1042 |
| 1087 | 1043 |
| 1088 void Assembler::decl(const Operand& dst) { | 1044 void Assembler::decl(const Operand& dst) { |
| 1089 EnsureSpace ensure_space(this); | 1045 EnsureSpace ensure_space(this); |
| 1090 last_pc_ = pc_; | |
| 1091 emit_optional_rex_32(dst); | 1046 emit_optional_rex_32(dst); |
| 1092 emit(0xFF); | 1047 emit(0xFF); |
| 1093 emit_operand(1, dst); | 1048 emit_operand(1, dst); |
| 1094 } | 1049 } |
| 1095 | 1050 |
| 1096 | 1051 |
| 1097 void Assembler::decb(Register dst) { | 1052 void Assembler::decb(Register dst) { |
| 1098 EnsureSpace ensure_space(this); | 1053 EnsureSpace ensure_space(this); |
| 1099 last_pc_ = pc_; | |
| 1100 if (dst.code() > 3) { | 1054 if (dst.code() > 3) { |
| 1101 // Register is not one of al, bl, cl, dl. Its encoding needs REX. | 1055 // Register is not one of al, bl, cl, dl. Its encoding needs REX. |
| 1102 emit_rex_32(dst); | 1056 emit_rex_32(dst); |
| 1103 } | 1057 } |
| 1104 emit(0xFE); | 1058 emit(0xFE); |
| 1105 emit_modrm(0x1, dst); | 1059 emit_modrm(0x1, dst); |
| 1106 } | 1060 } |
| 1107 | 1061 |
| 1108 | 1062 |
| 1109 void Assembler::decb(const Operand& dst) { | 1063 void Assembler::decb(const Operand& dst) { |
| 1110 EnsureSpace ensure_space(this); | 1064 EnsureSpace ensure_space(this); |
| 1111 last_pc_ = pc_; | |
| 1112 emit_optional_rex_32(dst); | 1065 emit_optional_rex_32(dst); |
| 1113 emit(0xFE); | 1066 emit(0xFE); |
| 1114 emit_operand(1, dst); | 1067 emit_operand(1, dst); |
| 1115 } | 1068 } |
| 1116 | 1069 |
| 1117 | 1070 |
| 1118 void Assembler::enter(Immediate size) { | 1071 void Assembler::enter(Immediate size) { |
| 1119 EnsureSpace ensure_space(this); | 1072 EnsureSpace ensure_space(this); |
| 1120 last_pc_ = pc_; | |
| 1121 emit(0xC8); | 1073 emit(0xC8); |
| 1122 emitw(size.value_); // 16 bit operand, always. | 1074 emitw(size.value_); // 16 bit operand, always. |
| 1123 emit(0); | 1075 emit(0); |
| 1124 } | 1076 } |
| 1125 | 1077 |
| 1126 | 1078 |
| 1127 void Assembler::hlt() { | 1079 void Assembler::hlt() { |
| 1128 EnsureSpace ensure_space(this); | 1080 EnsureSpace ensure_space(this); |
| 1129 last_pc_ = pc_; | |
| 1130 emit(0xF4); | 1081 emit(0xF4); |
| 1131 } | 1082 } |
| 1132 | 1083 |
| 1133 | 1084 |
| 1134 void Assembler::idivq(Register src) { | 1085 void Assembler::idivq(Register src) { |
| 1135 EnsureSpace ensure_space(this); | 1086 EnsureSpace ensure_space(this); |
| 1136 last_pc_ = pc_; | |
| 1137 emit_rex_64(src); | 1087 emit_rex_64(src); |
| 1138 emit(0xF7); | 1088 emit(0xF7); |
| 1139 emit_modrm(0x7, src); | 1089 emit_modrm(0x7, src); |
| 1140 } | 1090 } |
| 1141 | 1091 |
| 1142 | 1092 |
| 1143 void Assembler::idivl(Register src) { | 1093 void Assembler::idivl(Register src) { |
| 1144 EnsureSpace ensure_space(this); | 1094 EnsureSpace ensure_space(this); |
| 1145 last_pc_ = pc_; | |
| 1146 emit_optional_rex_32(src); | 1095 emit_optional_rex_32(src); |
| 1147 emit(0xF7); | 1096 emit(0xF7); |
| 1148 emit_modrm(0x7, src); | 1097 emit_modrm(0x7, src); |
| 1149 } | 1098 } |
| 1150 | 1099 |
| 1151 | 1100 |
| 1152 void Assembler::imul(Register src) { | 1101 void Assembler::imul(Register src) { |
| 1153 EnsureSpace ensure_space(this); | 1102 EnsureSpace ensure_space(this); |
| 1154 last_pc_ = pc_; | |
| 1155 emit_rex_64(src); | 1103 emit_rex_64(src); |
| 1156 emit(0xF7); | 1104 emit(0xF7); |
| 1157 emit_modrm(0x5, src); | 1105 emit_modrm(0x5, src); |
| 1158 } | 1106 } |
| 1159 | 1107 |
| 1160 | 1108 |
| 1161 void Assembler::imul(Register dst, Register src) { | 1109 void Assembler::imul(Register dst, Register src) { |
| 1162 EnsureSpace ensure_space(this); | 1110 EnsureSpace ensure_space(this); |
| 1163 last_pc_ = pc_; | |
| 1164 emit_rex_64(dst, src); | 1111 emit_rex_64(dst, src); |
| 1165 emit(0x0F); | 1112 emit(0x0F); |
| 1166 emit(0xAF); | 1113 emit(0xAF); |
| 1167 emit_modrm(dst, src); | 1114 emit_modrm(dst, src); |
| 1168 } | 1115 } |
| 1169 | 1116 |
| 1170 | 1117 |
| 1171 void Assembler::imul(Register dst, const Operand& src) { | 1118 void Assembler::imul(Register dst, const Operand& src) { |
| 1172 EnsureSpace ensure_space(this); | 1119 EnsureSpace ensure_space(this); |
| 1173 last_pc_ = pc_; | |
| 1174 emit_rex_64(dst, src); | 1120 emit_rex_64(dst, src); |
| 1175 emit(0x0F); | 1121 emit(0x0F); |
| 1176 emit(0xAF); | 1122 emit(0xAF); |
| 1177 emit_operand(dst, src); | 1123 emit_operand(dst, src); |
| 1178 } | 1124 } |
| 1179 | 1125 |
| 1180 | 1126 |
| 1181 void Assembler::imul(Register dst, Register src, Immediate imm) { | 1127 void Assembler::imul(Register dst, Register src, Immediate imm) { |
| 1182 EnsureSpace ensure_space(this); | 1128 EnsureSpace ensure_space(this); |
| 1183 last_pc_ = pc_; | |
| 1184 emit_rex_64(dst, src); | 1129 emit_rex_64(dst, src); |
| 1185 if (is_int8(imm.value_)) { | 1130 if (is_int8(imm.value_)) { |
| 1186 emit(0x6B); | 1131 emit(0x6B); |
| 1187 emit_modrm(dst, src); | 1132 emit_modrm(dst, src); |
| 1188 emit(imm.value_); | 1133 emit(imm.value_); |
| 1189 } else { | 1134 } else { |
| 1190 emit(0x69); | 1135 emit(0x69); |
| 1191 emit_modrm(dst, src); | 1136 emit_modrm(dst, src); |
| 1192 emitl(imm.value_); | 1137 emitl(imm.value_); |
| 1193 } | 1138 } |
| 1194 } | 1139 } |
| 1195 | 1140 |
| 1196 | 1141 |
| 1197 void Assembler::imull(Register dst, Register src) { | 1142 void Assembler::imull(Register dst, Register src) { |
| 1198 EnsureSpace ensure_space(this); | 1143 EnsureSpace ensure_space(this); |
| 1199 last_pc_ = pc_; | |
| 1200 emit_optional_rex_32(dst, src); | 1144 emit_optional_rex_32(dst, src); |
| 1201 emit(0x0F); | 1145 emit(0x0F); |
| 1202 emit(0xAF); | 1146 emit(0xAF); |
| 1203 emit_modrm(dst, src); | 1147 emit_modrm(dst, src); |
| 1204 } | 1148 } |
| 1205 | 1149 |
| 1206 | 1150 |
| 1207 void Assembler::imull(Register dst, const Operand& src) { | 1151 void Assembler::imull(Register dst, const Operand& src) { |
| 1208 EnsureSpace ensure_space(this); | 1152 EnsureSpace ensure_space(this); |
| 1209 last_pc_ = pc_; | |
| 1210 emit_optional_rex_32(dst, src); | 1153 emit_optional_rex_32(dst, src); |
| 1211 emit(0x0F); | 1154 emit(0x0F); |
| 1212 emit(0xAF); | 1155 emit(0xAF); |
| 1213 emit_operand(dst, src); | 1156 emit_operand(dst, src); |
| 1214 } | 1157 } |
| 1215 | 1158 |
| 1216 | 1159 |
| 1217 void Assembler::imull(Register dst, Register src, Immediate imm) { | 1160 void Assembler::imull(Register dst, Register src, Immediate imm) { |
| 1218 EnsureSpace ensure_space(this); | 1161 EnsureSpace ensure_space(this); |
| 1219 last_pc_ = pc_; | |
| 1220 emit_optional_rex_32(dst, src); | 1162 emit_optional_rex_32(dst, src); |
| 1221 if (is_int8(imm.value_)) { | 1163 if (is_int8(imm.value_)) { |
| 1222 emit(0x6B); | 1164 emit(0x6B); |
| 1223 emit_modrm(dst, src); | 1165 emit_modrm(dst, src); |
| 1224 emit(imm.value_); | 1166 emit(imm.value_); |
| 1225 } else { | 1167 } else { |
| 1226 emit(0x69); | 1168 emit(0x69); |
| 1227 emit_modrm(dst, src); | 1169 emit_modrm(dst, src); |
| 1228 emitl(imm.value_); | 1170 emitl(imm.value_); |
| 1229 } | 1171 } |
| 1230 } | 1172 } |
| 1231 | 1173 |
| 1232 | 1174 |
| 1233 void Assembler::incq(Register dst) { | 1175 void Assembler::incq(Register dst) { |
| 1234 EnsureSpace ensure_space(this); | 1176 EnsureSpace ensure_space(this); |
| 1235 last_pc_ = pc_; | |
| 1236 emit_rex_64(dst); | 1177 emit_rex_64(dst); |
| 1237 emit(0xFF); | 1178 emit(0xFF); |
| 1238 emit_modrm(0x0, dst); | 1179 emit_modrm(0x0, dst); |
| 1239 } | 1180 } |
| 1240 | 1181 |
| 1241 | 1182 |
| 1242 void Assembler::incq(const Operand& dst) { | 1183 void Assembler::incq(const Operand& dst) { |
| 1243 EnsureSpace ensure_space(this); | 1184 EnsureSpace ensure_space(this); |
| 1244 last_pc_ = pc_; | |
| 1245 emit_rex_64(dst); | 1185 emit_rex_64(dst); |
| 1246 emit(0xFF); | 1186 emit(0xFF); |
| 1247 emit_operand(0, dst); | 1187 emit_operand(0, dst); |
| 1248 } | 1188 } |
| 1249 | 1189 |
| 1250 | 1190 |
| 1251 void Assembler::incl(const Operand& dst) { | 1191 void Assembler::incl(const Operand& dst) { |
| 1252 EnsureSpace ensure_space(this); | 1192 EnsureSpace ensure_space(this); |
| 1253 last_pc_ = pc_; | |
| 1254 emit_optional_rex_32(dst); | 1193 emit_optional_rex_32(dst); |
| 1255 emit(0xFF); | 1194 emit(0xFF); |
| 1256 emit_operand(0, dst); | 1195 emit_operand(0, dst); |
| 1257 } | 1196 } |
| 1258 | 1197 |
| 1259 | 1198 |
| 1260 void Assembler::incl(Register dst) { | 1199 void Assembler::incl(Register dst) { |
| 1261 EnsureSpace ensure_space(this); | 1200 EnsureSpace ensure_space(this); |
| 1262 last_pc_ = pc_; | |
| 1263 emit_optional_rex_32(dst); | 1201 emit_optional_rex_32(dst); |
| 1264 emit(0xFF); | 1202 emit(0xFF); |
| 1265 emit_modrm(0, dst); | 1203 emit_modrm(0, dst); |
| 1266 } | 1204 } |
| 1267 | 1205 |
| 1268 | 1206 |
| 1269 void Assembler::int3() { | 1207 void Assembler::int3() { |
| 1270 EnsureSpace ensure_space(this); | 1208 EnsureSpace ensure_space(this); |
| 1271 last_pc_ = pc_; | |
| 1272 emit(0xCC); | 1209 emit(0xCC); |
| 1273 } | 1210 } |
| 1274 | 1211 |
| 1275 | 1212 |
| 1276 void Assembler::j(Condition cc, Label* L) { | 1213 void Assembler::j(Condition cc, Label* L) { |
| 1277 if (cc == always) { | 1214 if (cc == always) { |
| 1278 jmp(L); | 1215 jmp(L); |
| 1279 return; | 1216 return; |
| 1280 } else if (cc == never) { | 1217 } else if (cc == never) { |
| 1281 return; | 1218 return; |
| 1282 } | 1219 } |
| 1283 EnsureSpace ensure_space(this); | 1220 EnsureSpace ensure_space(this); |
| 1284 last_pc_ = pc_; | |
| 1285 ASSERT(is_uint4(cc)); | 1221 ASSERT(is_uint4(cc)); |
| 1286 if (L->is_bound()) { | 1222 if (L->is_bound()) { |
| 1287 const int short_size = 2; | 1223 const int short_size = 2; |
| 1288 const int long_size = 6; | 1224 const int long_size = 6; |
| 1289 int offs = L->pos() - pc_offset(); | 1225 int offs = L->pos() - pc_offset(); |
| 1290 ASSERT(offs <= 0); | 1226 ASSERT(offs <= 0); |
| 1291 if (is_int8(offs - short_size)) { | 1227 if (is_int8(offs - short_size)) { |
| 1292 // 0111 tttn #8-bit disp. | 1228 // 0111 tttn #8-bit disp. |
| 1293 emit(0x70 | cc); | 1229 emit(0x70 | cc); |
| 1294 emit((offs - short_size) & 0xFF); | 1230 emit((offs - short_size) & 0xFF); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1312 emitl(current); | 1248 emitl(current); |
| 1313 L->link_to(current); | 1249 L->link_to(current); |
| 1314 } | 1250 } |
| 1315 } | 1251 } |
| 1316 | 1252 |
| 1317 | 1253 |
| 1318 void Assembler::j(Condition cc, | 1254 void Assembler::j(Condition cc, |
| 1319 Handle<Code> target, | 1255 Handle<Code> target, |
| 1320 RelocInfo::Mode rmode) { | 1256 RelocInfo::Mode rmode) { |
| 1321 EnsureSpace ensure_space(this); | 1257 EnsureSpace ensure_space(this); |
| 1322 last_pc_ = pc_; | |
| 1323 ASSERT(is_uint4(cc)); | 1258 ASSERT(is_uint4(cc)); |
| 1324 // 0000 1111 1000 tttn #32-bit disp. | 1259 // 0000 1111 1000 tttn #32-bit disp. |
| 1325 emit(0x0F); | 1260 emit(0x0F); |
| 1326 emit(0x80 | cc); | 1261 emit(0x80 | cc); |
| 1327 emit_code_target(target, rmode); | 1262 emit_code_target(target, rmode); |
| 1328 } | 1263 } |
| 1329 | 1264 |
| 1330 | 1265 |
| 1331 void Assembler::j(Condition cc, NearLabel* L, Hint hint) { | 1266 void Assembler::j(Condition cc, NearLabel* L, Hint hint) { |
| 1332 EnsureSpace ensure_space(this); | 1267 EnsureSpace ensure_space(this); |
| 1333 last_pc_ = pc_; | |
| 1334 ASSERT(0 <= cc && cc < 16); | 1268 ASSERT(0 <= cc && cc < 16); |
| 1335 if (FLAG_emit_branch_hints && hint != no_hint) emit(hint); | 1269 if (FLAG_emit_branch_hints && hint != no_hint) emit(hint); |
| 1336 if (L->is_bound()) { | 1270 if (L->is_bound()) { |
| 1337 const int short_size = 2; | 1271 const int short_size = 2; |
| 1338 int offs = L->pos() - pc_offset(); | 1272 int offs = L->pos() - pc_offset(); |
| 1339 ASSERT(offs <= 0); | 1273 ASSERT(offs <= 0); |
| 1340 ASSERT(is_int8(offs - short_size)); | 1274 ASSERT(is_int8(offs - short_size)); |
| 1341 // 0111 tttn #8-bit disp | 1275 // 0111 tttn #8-bit disp |
| 1342 emit(0x70 | cc); | 1276 emit(0x70 | cc); |
| 1343 emit((offs - short_size) & 0xFF); | 1277 emit((offs - short_size) & 0xFF); |
| 1344 } else { | 1278 } else { |
| 1345 emit(0x70 | cc); | 1279 emit(0x70 | cc); |
| 1346 emit(0x00); // The displacement will be resolved later. | 1280 emit(0x00); // The displacement will be resolved later. |
| 1347 L->link_to(pc_offset()); | 1281 L->link_to(pc_offset()); |
| 1348 } | 1282 } |
| 1349 } | 1283 } |
| 1350 | 1284 |
| 1351 | 1285 |
| 1352 void Assembler::jmp(Label* L) { | 1286 void Assembler::jmp(Label* L) { |
| 1353 EnsureSpace ensure_space(this); | 1287 EnsureSpace ensure_space(this); |
| 1354 last_pc_ = pc_; | |
| 1355 const int short_size = sizeof(int8_t); | 1288 const int short_size = sizeof(int8_t); |
| 1356 const int long_size = sizeof(int32_t); | 1289 const int long_size = sizeof(int32_t); |
| 1357 if (L->is_bound()) { | 1290 if (L->is_bound()) { |
| 1358 int offs = L->pos() - pc_offset() - 1; | 1291 int offs = L->pos() - pc_offset() - 1; |
| 1359 ASSERT(offs <= 0); | 1292 ASSERT(offs <= 0); |
| 1360 if (is_int8(offs - short_size)) { | 1293 if (is_int8(offs - short_size)) { |
| 1361 // 1110 1011 #8-bit disp. | 1294 // 1110 1011 #8-bit disp. |
| 1362 emit(0xEB); | 1295 emit(0xEB); |
| 1363 emit((offs - short_size) & 0xFF); | 1296 emit((offs - short_size) & 0xFF); |
| 1364 } else { | 1297 } else { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1377 emit(0xE9); | 1310 emit(0xE9); |
| 1378 int32_t current = pc_offset(); | 1311 int32_t current = pc_offset(); |
| 1379 emitl(current); | 1312 emitl(current); |
| 1380 L->link_to(current); | 1313 L->link_to(current); |
| 1381 } | 1314 } |
| 1382 } | 1315 } |
| 1383 | 1316 |
| 1384 | 1317 |
| 1385 void Assembler::jmp(Handle<Code> target, RelocInfo::Mode rmode) { | 1318 void Assembler::jmp(Handle<Code> target, RelocInfo::Mode rmode) { |
| 1386 EnsureSpace ensure_space(this); | 1319 EnsureSpace ensure_space(this); |
| 1387 last_pc_ = pc_; | |
| 1388 // 1110 1001 #32-bit disp. | 1320 // 1110 1001 #32-bit disp. |
| 1389 emit(0xE9); | 1321 emit(0xE9); |
| 1390 emit_code_target(target, rmode); | 1322 emit_code_target(target, rmode); |
| 1391 } | 1323 } |
| 1392 | 1324 |
| 1393 | 1325 |
| 1394 void Assembler::jmp(NearLabel* L) { | 1326 void Assembler::jmp(NearLabel* L) { |
| 1395 EnsureSpace ensure_space(this); | 1327 EnsureSpace ensure_space(this); |
| 1396 last_pc_ = pc_; | |
| 1397 if (L->is_bound()) { | 1328 if (L->is_bound()) { |
| 1398 const int short_size = sizeof(int8_t); | 1329 const int short_size = sizeof(int8_t); |
| 1399 int offs = L->pos() - pc_offset(); | 1330 int offs = L->pos() - pc_offset(); |
| 1400 ASSERT(offs <= 0); | 1331 ASSERT(offs <= 0); |
| 1401 ASSERT(is_int8(offs - short_size)); | 1332 ASSERT(is_int8(offs - short_size)); |
| 1402 // 1110 1011 #8-bit disp. | 1333 // 1110 1011 #8-bit disp. |
| 1403 emit(0xEB); | 1334 emit(0xEB); |
| 1404 emit((offs - short_size) & 0xFF); | 1335 emit((offs - short_size) & 0xFF); |
| 1405 } else { | 1336 } else { |
| 1406 emit(0xEB); | 1337 emit(0xEB); |
| 1407 emit(0x00); // The displacement will be resolved later. | 1338 emit(0x00); // The displacement will be resolved later. |
| 1408 L->link_to(pc_offset()); | 1339 L->link_to(pc_offset()); |
| 1409 } | 1340 } |
| 1410 } | 1341 } |
| 1411 | 1342 |
| 1412 | 1343 |
| 1413 void Assembler::jmp(Register target) { | 1344 void Assembler::jmp(Register target) { |
| 1414 EnsureSpace ensure_space(this); | 1345 EnsureSpace ensure_space(this); |
| 1415 last_pc_ = pc_; | |
| 1416 // Opcode FF/4 r64. | 1346 // Opcode FF/4 r64. |
| 1417 emit_optional_rex_32(target); | 1347 emit_optional_rex_32(target); |
| 1418 emit(0xFF); | 1348 emit(0xFF); |
| 1419 emit_modrm(0x4, target); | 1349 emit_modrm(0x4, target); |
| 1420 } | 1350 } |
| 1421 | 1351 |
| 1422 | 1352 |
| 1423 void Assembler::jmp(const Operand& src) { | 1353 void Assembler::jmp(const Operand& src) { |
| 1424 EnsureSpace ensure_space(this); | 1354 EnsureSpace ensure_space(this); |
| 1425 last_pc_ = pc_; | |
| 1426 // Opcode FF/4 m64. | 1355 // Opcode FF/4 m64. |
| 1427 emit_optional_rex_32(src); | 1356 emit_optional_rex_32(src); |
| 1428 emit(0xFF); | 1357 emit(0xFF); |
| 1429 emit_operand(0x4, src); | 1358 emit_operand(0x4, src); |
| 1430 } | 1359 } |
| 1431 | 1360 |
| 1432 | 1361 |
| 1433 void Assembler::lea(Register dst, const Operand& src) { | 1362 void Assembler::lea(Register dst, const Operand& src) { |
| 1434 EnsureSpace ensure_space(this); | 1363 EnsureSpace ensure_space(this); |
| 1435 last_pc_ = pc_; | |
| 1436 emit_rex_64(dst, src); | 1364 emit_rex_64(dst, src); |
| 1437 emit(0x8D); | 1365 emit(0x8D); |
| 1438 emit_operand(dst, src); | 1366 emit_operand(dst, src); |
| 1439 } | 1367 } |
| 1440 | 1368 |
| 1441 | 1369 |
| 1442 void Assembler::leal(Register dst, const Operand& src) { | 1370 void Assembler::leal(Register dst, const Operand& src) { |
| 1443 EnsureSpace ensure_space(this); | 1371 EnsureSpace ensure_space(this); |
| 1444 last_pc_ = pc_; | |
| 1445 emit_optional_rex_32(dst, src); | 1372 emit_optional_rex_32(dst, src); |
| 1446 emit(0x8D); | 1373 emit(0x8D); |
| 1447 emit_operand(dst, src); | 1374 emit_operand(dst, src); |
| 1448 } | 1375 } |
| 1449 | 1376 |
| 1450 | 1377 |
| 1451 void Assembler::load_rax(void* value, RelocInfo::Mode mode) { | 1378 void Assembler::load_rax(void* value, RelocInfo::Mode mode) { |
| 1452 EnsureSpace ensure_space(this); | 1379 EnsureSpace ensure_space(this); |
| 1453 last_pc_ = pc_; | |
| 1454 emit(0x48); // REX.W | 1380 emit(0x48); // REX.W |
| 1455 emit(0xA1); | 1381 emit(0xA1); |
| 1456 emitq(reinterpret_cast<uintptr_t>(value), mode); | 1382 emitq(reinterpret_cast<uintptr_t>(value), mode); |
| 1457 } | 1383 } |
| 1458 | 1384 |
| 1459 | 1385 |
| 1460 void Assembler::load_rax(ExternalReference ref) { | 1386 void Assembler::load_rax(ExternalReference ref) { |
| 1461 load_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE); | 1387 load_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE); |
| 1462 } | 1388 } |
| 1463 | 1389 |
| 1464 | 1390 |
| 1465 void Assembler::leave() { | 1391 void Assembler::leave() { |
| 1466 EnsureSpace ensure_space(this); | 1392 EnsureSpace ensure_space(this); |
| 1467 last_pc_ = pc_; | |
| 1468 emit(0xC9); | 1393 emit(0xC9); |
| 1469 } | 1394 } |
| 1470 | 1395 |
| 1471 | 1396 |
| 1472 void Assembler::movb(Register dst, const Operand& src) { | 1397 void Assembler::movb(Register dst, const Operand& src) { |
| 1473 EnsureSpace ensure_space(this); | 1398 EnsureSpace ensure_space(this); |
| 1474 last_pc_ = pc_; | |
| 1475 emit_rex_32(dst, src); | 1399 emit_rex_32(dst, src); |
| 1476 emit(0x8A); | 1400 emit(0x8A); |
| 1477 emit_operand(dst, src); | 1401 emit_operand(dst, src); |
| 1478 } | 1402 } |
| 1479 | 1403 |
| 1480 | 1404 |
| 1481 void Assembler::movb(Register dst, Immediate imm) { | 1405 void Assembler::movb(Register dst, Immediate imm) { |
| 1482 EnsureSpace ensure_space(this); | 1406 EnsureSpace ensure_space(this); |
| 1483 last_pc_ = pc_; | |
| 1484 emit_rex_32(dst); | 1407 emit_rex_32(dst); |
| 1485 emit(0xC6); | 1408 emit(0xC6); |
| 1486 emit_modrm(0x0, dst); | 1409 emit_modrm(0x0, dst); |
| 1487 emit(imm.value_); | 1410 emit(imm.value_); |
| 1488 } | 1411 } |
| 1489 | 1412 |
| 1490 | 1413 |
| 1491 void Assembler::movb(const Operand& dst, Register src) { | 1414 void Assembler::movb(const Operand& dst, Register src) { |
| 1492 EnsureSpace ensure_space(this); | 1415 EnsureSpace ensure_space(this); |
| 1493 last_pc_ = pc_; | |
| 1494 emit_rex_32(src, dst); | 1416 emit_rex_32(src, dst); |
| 1495 emit(0x88); | 1417 emit(0x88); |
| 1496 emit_operand(src, dst); | 1418 emit_operand(src, dst); |
| 1497 } | 1419 } |
| 1498 | 1420 |
| 1499 | 1421 |
| 1500 void Assembler::movw(const Operand& dst, Register src) { | 1422 void Assembler::movw(const Operand& dst, Register src) { |
| 1501 EnsureSpace ensure_space(this); | 1423 EnsureSpace ensure_space(this); |
| 1502 last_pc_ = pc_; | |
| 1503 emit(0x66); | 1424 emit(0x66); |
| 1504 emit_optional_rex_32(src, dst); | 1425 emit_optional_rex_32(src, dst); |
| 1505 emit(0x89); | 1426 emit(0x89); |
| 1506 emit_operand(src, dst); | 1427 emit_operand(src, dst); |
| 1507 } | 1428 } |
| 1508 | 1429 |
| 1509 | 1430 |
| 1510 void Assembler::movl(Register dst, const Operand& src) { | 1431 void Assembler::movl(Register dst, const Operand& src) { |
| 1511 EnsureSpace ensure_space(this); | 1432 EnsureSpace ensure_space(this); |
| 1512 last_pc_ = pc_; | |
| 1513 emit_optional_rex_32(dst, src); | 1433 emit_optional_rex_32(dst, src); |
| 1514 emit(0x8B); | 1434 emit(0x8B); |
| 1515 emit_operand(dst, src); | 1435 emit_operand(dst, src); |
| 1516 } | 1436 } |
| 1517 | 1437 |
| 1518 | 1438 |
| 1519 void Assembler::movl(Register dst, Register src) { | 1439 void Assembler::movl(Register dst, Register src) { |
| 1520 EnsureSpace ensure_space(this); | 1440 EnsureSpace ensure_space(this); |
| 1521 last_pc_ = pc_; | |
| 1522 if (src.low_bits() == 4) { | 1441 if (src.low_bits() == 4) { |
| 1523 emit_optional_rex_32(src, dst); | 1442 emit_optional_rex_32(src, dst); |
| 1524 emit(0x89); | 1443 emit(0x89); |
| 1525 emit_modrm(src, dst); | 1444 emit_modrm(src, dst); |
| 1526 } else { | 1445 } else { |
| 1527 emit_optional_rex_32(dst, src); | 1446 emit_optional_rex_32(dst, src); |
| 1528 emit(0x8B); | 1447 emit(0x8B); |
| 1529 emit_modrm(dst, src); | 1448 emit_modrm(dst, src); |
| 1530 } | 1449 } |
| 1531 } | 1450 } |
| 1532 | 1451 |
| 1533 | 1452 |
| 1534 void Assembler::movl(const Operand& dst, Register src) { | 1453 void Assembler::movl(const Operand& dst, Register src) { |
| 1535 EnsureSpace ensure_space(this); | 1454 EnsureSpace ensure_space(this); |
| 1536 last_pc_ = pc_; | |
| 1537 emit_optional_rex_32(src, dst); | 1455 emit_optional_rex_32(src, dst); |
| 1538 emit(0x89); | 1456 emit(0x89); |
| 1539 emit_operand(src, dst); | 1457 emit_operand(src, dst); |
| 1540 } | 1458 } |
| 1541 | 1459 |
| 1542 | 1460 |
| 1543 void Assembler::movl(const Operand& dst, Immediate value) { | 1461 void Assembler::movl(const Operand& dst, Immediate value) { |
| 1544 EnsureSpace ensure_space(this); | 1462 EnsureSpace ensure_space(this); |
| 1545 last_pc_ = pc_; | |
| 1546 emit_optional_rex_32(dst); | 1463 emit_optional_rex_32(dst); |
| 1547 emit(0xC7); | 1464 emit(0xC7); |
| 1548 emit_operand(0x0, dst); | 1465 emit_operand(0x0, dst); |
| 1549 emit(value); // Only 32-bit immediates are possible, not 8-bit immediates. | 1466 emit(value); // Only 32-bit immediates are possible, not 8-bit immediates. |
| 1550 } | 1467 } |
| 1551 | 1468 |
| 1552 | 1469 |
| 1553 void Assembler::movl(Register dst, Immediate value) { | 1470 void Assembler::movl(Register dst, Immediate value) { |
| 1554 EnsureSpace ensure_space(this); | 1471 EnsureSpace ensure_space(this); |
| 1555 last_pc_ = pc_; | |
| 1556 emit_optional_rex_32(dst); | 1472 emit_optional_rex_32(dst); |
| 1557 emit(0xC7); | 1473 emit(0xC7); |
| 1558 emit_modrm(0x0, dst); | 1474 emit_modrm(0x0, dst); |
| 1559 emit(value); // Only 32-bit immediates are possible, not 8-bit immediates. | 1475 emit(value); // Only 32-bit immediates are possible, not 8-bit immediates. |
| 1560 } | 1476 } |
| 1561 | 1477 |
| 1562 | 1478 |
| 1563 void Assembler::movq(Register dst, const Operand& src) { | 1479 void Assembler::movq(Register dst, const Operand& src) { |
| 1564 EnsureSpace ensure_space(this); | 1480 EnsureSpace ensure_space(this); |
| 1565 last_pc_ = pc_; | |
| 1566 emit_rex_64(dst, src); | 1481 emit_rex_64(dst, src); |
| 1567 emit(0x8B); | 1482 emit(0x8B); |
| 1568 emit_operand(dst, src); | 1483 emit_operand(dst, src); |
| 1569 } | 1484 } |
| 1570 | 1485 |
| 1571 | 1486 |
| 1572 void Assembler::movq(Register dst, Register src) { | 1487 void Assembler::movq(Register dst, Register src) { |
| 1573 EnsureSpace ensure_space(this); | 1488 EnsureSpace ensure_space(this); |
| 1574 last_pc_ = pc_; | |
| 1575 if (src.low_bits() == 4) { | 1489 if (src.low_bits() == 4) { |
| 1576 emit_rex_64(src, dst); | 1490 emit_rex_64(src, dst); |
| 1577 emit(0x89); | 1491 emit(0x89); |
| 1578 emit_modrm(src, dst); | 1492 emit_modrm(src, dst); |
| 1579 } else { | 1493 } else { |
| 1580 emit_rex_64(dst, src); | 1494 emit_rex_64(dst, src); |
| 1581 emit(0x8B); | 1495 emit(0x8B); |
| 1582 emit_modrm(dst, src); | 1496 emit_modrm(dst, src); |
| 1583 } | 1497 } |
| 1584 } | 1498 } |
| 1585 | 1499 |
| 1586 | 1500 |
| 1587 void Assembler::movq(Register dst, Immediate value) { | 1501 void Assembler::movq(Register dst, Immediate value) { |
| 1588 EnsureSpace ensure_space(this); | 1502 EnsureSpace ensure_space(this); |
| 1589 last_pc_ = pc_; | |
| 1590 emit_rex_64(dst); | 1503 emit_rex_64(dst); |
| 1591 emit(0xC7); | 1504 emit(0xC7); |
| 1592 emit_modrm(0x0, dst); | 1505 emit_modrm(0x0, dst); |
| 1593 emit(value); // Only 32-bit immediates are possible, not 8-bit immediates. | 1506 emit(value); // Only 32-bit immediates are possible, not 8-bit immediates. |
| 1594 } | 1507 } |
| 1595 | 1508 |
| 1596 | 1509 |
| 1597 void Assembler::movq(const Operand& dst, Register src) { | 1510 void Assembler::movq(const Operand& dst, Register src) { |
| 1598 EnsureSpace ensure_space(this); | 1511 EnsureSpace ensure_space(this); |
| 1599 last_pc_ = pc_; | |
| 1600 emit_rex_64(src, dst); | 1512 emit_rex_64(src, dst); |
| 1601 emit(0x89); | 1513 emit(0x89); |
| 1602 emit_operand(src, dst); | 1514 emit_operand(src, dst); |
| 1603 } | 1515 } |
| 1604 | 1516 |
| 1605 | 1517 |
| 1606 void Assembler::movq(Register dst, void* value, RelocInfo::Mode rmode) { | 1518 void Assembler::movq(Register dst, void* value, RelocInfo::Mode rmode) { |
| 1607 // This method must not be used with heap object references. The stored | 1519 // This method must not be used with heap object references. The stored |
| 1608 // address is not GC safe. Use the handle version instead. | 1520 // address is not GC safe. Use the handle version instead. |
| 1609 ASSERT(rmode > RelocInfo::LAST_GCED_ENUM); | 1521 ASSERT(rmode > RelocInfo::LAST_GCED_ENUM); |
| 1610 EnsureSpace ensure_space(this); | 1522 EnsureSpace ensure_space(this); |
| 1611 last_pc_ = pc_; | |
| 1612 emit_rex_64(dst); | 1523 emit_rex_64(dst); |
| 1613 emit(0xB8 | dst.low_bits()); | 1524 emit(0xB8 | dst.low_bits()); |
| 1614 emitq(reinterpret_cast<uintptr_t>(value), rmode); | 1525 emitq(reinterpret_cast<uintptr_t>(value), rmode); |
| 1615 } | 1526 } |
| 1616 | 1527 |
| 1617 | 1528 |
| 1618 void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) { | 1529 void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) { |
| 1619 // Non-relocatable values might not need a 64-bit representation. | 1530 // Non-relocatable values might not need a 64-bit representation. |
| 1620 if (rmode == RelocInfo::NONE) { | 1531 if (rmode == RelocInfo::NONE) { |
| 1621 // Sadly, there is no zero or sign extending move for 8-bit immediates. | 1532 // Sadly, there is no zero or sign extending move for 8-bit immediates. |
| 1622 if (is_int32(value)) { | 1533 if (is_int32(value)) { |
| 1623 movq(dst, Immediate(static_cast<int32_t>(value))); | 1534 movq(dst, Immediate(static_cast<int32_t>(value))); |
| 1624 return; | 1535 return; |
| 1625 } else if (is_uint32(value)) { | 1536 } else if (is_uint32(value)) { |
| 1626 movl(dst, Immediate(static_cast<int32_t>(value))); | 1537 movl(dst, Immediate(static_cast<int32_t>(value))); |
| 1627 return; | 1538 return; |
| 1628 } | 1539 } |
| 1629 // Value cannot be represented by 32 bits, so do a full 64 bit immediate | 1540 // Value cannot be represented by 32 bits, so do a full 64 bit immediate |
| 1630 // value. | 1541 // value. |
| 1631 } | 1542 } |
| 1632 EnsureSpace ensure_space(this); | 1543 EnsureSpace ensure_space(this); |
| 1633 last_pc_ = pc_; | |
| 1634 emit_rex_64(dst); | 1544 emit_rex_64(dst); |
| 1635 emit(0xB8 | dst.low_bits()); | 1545 emit(0xB8 | dst.low_bits()); |
| 1636 emitq(value, rmode); | 1546 emitq(value, rmode); |
| 1637 } | 1547 } |
| 1638 | 1548 |
| 1639 | 1549 |
| 1640 void Assembler::movq(Register dst, ExternalReference ref) { | 1550 void Assembler::movq(Register dst, ExternalReference ref) { |
| 1641 int64_t value = reinterpret_cast<int64_t>(ref.address()); | 1551 int64_t value = reinterpret_cast<int64_t>(ref.address()); |
| 1642 movq(dst, value, RelocInfo::EXTERNAL_REFERENCE); | 1552 movq(dst, value, RelocInfo::EXTERNAL_REFERENCE); |
| 1643 } | 1553 } |
| 1644 | 1554 |
| 1645 | 1555 |
| 1646 void Assembler::movq(const Operand& dst, Immediate value) { | 1556 void Assembler::movq(const Operand& dst, Immediate value) { |
| 1647 EnsureSpace ensure_space(this); | 1557 EnsureSpace ensure_space(this); |
| 1648 last_pc_ = pc_; | |
| 1649 emit_rex_64(dst); | 1558 emit_rex_64(dst); |
| 1650 emit(0xC7); | 1559 emit(0xC7); |
| 1651 emit_operand(0, dst); | 1560 emit_operand(0, dst); |
| 1652 emit(value); | 1561 emit(value); |
| 1653 } | 1562 } |
| 1654 | 1563 |
| 1655 | 1564 |
| 1656 // Loads the ip-relative location of the src label into the target location | 1565 // Loads the ip-relative location of the src label into the target location |
| 1657 // (as a 32-bit offset sign extended to 64-bit). | 1566 // (as a 32-bit offset sign extended to 64-bit). |
| 1658 void Assembler::movl(const Operand& dst, Label* src) { | 1567 void Assembler::movl(const Operand& dst, Label* src) { |
| 1659 EnsureSpace ensure_space(this); | 1568 EnsureSpace ensure_space(this); |
| 1660 last_pc_ = pc_; | |
| 1661 emit_optional_rex_32(dst); | 1569 emit_optional_rex_32(dst); |
| 1662 emit(0xC7); | 1570 emit(0xC7); |
| 1663 emit_operand(0, dst); | 1571 emit_operand(0, dst); |
| 1664 if (src->is_bound()) { | 1572 if (src->is_bound()) { |
| 1665 int offset = src->pos() - pc_offset() - sizeof(int32_t); | 1573 int offset = src->pos() - pc_offset() - sizeof(int32_t); |
| 1666 ASSERT(offset <= 0); | 1574 ASSERT(offset <= 0); |
| 1667 emitl(offset); | 1575 emitl(offset); |
| 1668 } else if (src->is_linked()) { | 1576 } else if (src->is_linked()) { |
| 1669 emitl(src->pos()); | 1577 emitl(src->pos()); |
| 1670 src->link_to(pc_offset() - sizeof(int32_t)); | 1578 src->link_to(pc_offset() - sizeof(int32_t)); |
| 1671 } else { | 1579 } else { |
| 1672 ASSERT(src->is_unused()); | 1580 ASSERT(src->is_unused()); |
| 1673 int32_t current = pc_offset(); | 1581 int32_t current = pc_offset(); |
| 1674 emitl(current); | 1582 emitl(current); |
| 1675 src->link_to(current); | 1583 src->link_to(current); |
| 1676 } | 1584 } |
| 1677 } | 1585 } |
| 1678 | 1586 |
| 1679 | 1587 |
| 1680 void Assembler::movq(Register dst, Handle<Object> value, RelocInfo::Mode mode) { | 1588 void Assembler::movq(Register dst, Handle<Object> value, RelocInfo::Mode mode) { |
| 1681 // If there is no relocation info, emit the value of the handle efficiently | 1589 // If there is no relocation info, emit the value of the handle efficiently |
| 1682 // (possibly using less that 8 bytes for the value). | 1590 // (possibly using less that 8 bytes for the value). |
| 1683 if (mode == RelocInfo::NONE) { | 1591 if (mode == RelocInfo::NONE) { |
| 1684 // There is no possible reason to store a heap pointer without relocation | 1592 // There is no possible reason to store a heap pointer without relocation |
| 1685 // info, so it must be a smi. | 1593 // info, so it must be a smi. |
| 1686 ASSERT(value->IsSmi()); | 1594 ASSERT(value->IsSmi()); |
| 1687 movq(dst, reinterpret_cast<int64_t>(*value), RelocInfo::NONE); | 1595 movq(dst, reinterpret_cast<int64_t>(*value), RelocInfo::NONE); |
| 1688 } else { | 1596 } else { |
| 1689 EnsureSpace ensure_space(this); | 1597 EnsureSpace ensure_space(this); |
| 1690 last_pc_ = pc_; | |
| 1691 ASSERT(value->IsHeapObject()); | 1598 ASSERT(value->IsHeapObject()); |
| 1692 ASSERT(!HEAP->InNewSpace(*value)); | 1599 ASSERT(!HEAP->InNewSpace(*value)); |
| 1693 emit_rex_64(dst); | 1600 emit_rex_64(dst); |
| 1694 emit(0xB8 | dst.low_bits()); | 1601 emit(0xB8 | dst.low_bits()); |
| 1695 emitq(reinterpret_cast<uintptr_t>(value.location()), mode); | 1602 emitq(reinterpret_cast<uintptr_t>(value.location()), mode); |
| 1696 } | 1603 } |
| 1697 } | 1604 } |
| 1698 | 1605 |
| 1699 | 1606 |
| 1700 void Assembler::movsxbq(Register dst, const Operand& src) { | 1607 void Assembler::movsxbq(Register dst, const Operand& src) { |
| 1701 EnsureSpace ensure_space(this); | 1608 EnsureSpace ensure_space(this); |
| 1702 last_pc_ = pc_; | |
| 1703 emit_rex_64(dst, src); | 1609 emit_rex_64(dst, src); |
| 1704 emit(0x0F); | 1610 emit(0x0F); |
| 1705 emit(0xBE); | 1611 emit(0xBE); |
| 1706 emit_operand(dst, src); | 1612 emit_operand(dst, src); |
| 1707 } | 1613 } |
| 1708 | 1614 |
| 1709 | 1615 |
| 1710 void Assembler::movsxwq(Register dst, const Operand& src) { | 1616 void Assembler::movsxwq(Register dst, const Operand& src) { |
| 1711 EnsureSpace ensure_space(this); | 1617 EnsureSpace ensure_space(this); |
| 1712 last_pc_ = pc_; | |
| 1713 emit_rex_64(dst, src); | 1618 emit_rex_64(dst, src); |
| 1714 emit(0x0F); | 1619 emit(0x0F); |
| 1715 emit(0xBF); | 1620 emit(0xBF); |
| 1716 emit_operand(dst, src); | 1621 emit_operand(dst, src); |
| 1717 } | 1622 } |
| 1718 | 1623 |
| 1719 | 1624 |
| 1720 void Assembler::movsxlq(Register dst, Register src) { | 1625 void Assembler::movsxlq(Register dst, Register src) { |
| 1721 EnsureSpace ensure_space(this); | 1626 EnsureSpace ensure_space(this); |
| 1722 last_pc_ = pc_; | |
| 1723 emit_rex_64(dst, src); | 1627 emit_rex_64(dst, src); |
| 1724 emit(0x63); | 1628 emit(0x63); |
| 1725 emit_modrm(dst, src); | 1629 emit_modrm(dst, src); |
| 1726 } | 1630 } |
| 1727 | 1631 |
| 1728 | 1632 |
| 1729 void Assembler::movsxlq(Register dst, const Operand& src) { | 1633 void Assembler::movsxlq(Register dst, const Operand& src) { |
| 1730 EnsureSpace ensure_space(this); | 1634 EnsureSpace ensure_space(this); |
| 1731 last_pc_ = pc_; | |
| 1732 emit_rex_64(dst, src); | 1635 emit_rex_64(dst, src); |
| 1733 emit(0x63); | 1636 emit(0x63); |
| 1734 emit_operand(dst, src); | 1637 emit_operand(dst, src); |
| 1735 } | 1638 } |
| 1736 | 1639 |
| 1737 | 1640 |
| 1738 void Assembler::movzxbq(Register dst, const Operand& src) { | 1641 void Assembler::movzxbq(Register dst, const Operand& src) { |
| 1739 EnsureSpace ensure_space(this); | 1642 EnsureSpace ensure_space(this); |
| 1740 last_pc_ = pc_; | |
| 1741 emit_optional_rex_32(dst, src); | 1643 emit_optional_rex_32(dst, src); |
| 1742 emit(0x0F); | 1644 emit(0x0F); |
| 1743 emit(0xB6); | 1645 emit(0xB6); |
| 1744 emit_operand(dst, src); | 1646 emit_operand(dst, src); |
| 1745 } | 1647 } |
| 1746 | 1648 |
| 1747 | 1649 |
| 1748 void Assembler::movzxbl(Register dst, const Operand& src) { | 1650 void Assembler::movzxbl(Register dst, const Operand& src) { |
| 1749 EnsureSpace ensure_space(this); | 1651 EnsureSpace ensure_space(this); |
| 1750 last_pc_ = pc_; | |
| 1751 emit_optional_rex_32(dst, src); | 1652 emit_optional_rex_32(dst, src); |
| 1752 emit(0x0F); | 1653 emit(0x0F); |
| 1753 emit(0xB6); | 1654 emit(0xB6); |
| 1754 emit_operand(dst, src); | 1655 emit_operand(dst, src); |
| 1755 } | 1656 } |
| 1756 | 1657 |
| 1757 | 1658 |
| 1758 void Assembler::movzxwq(Register dst, const Operand& src) { | 1659 void Assembler::movzxwq(Register dst, const Operand& src) { |
| 1759 EnsureSpace ensure_space(this); | 1660 EnsureSpace ensure_space(this); |
| 1760 last_pc_ = pc_; | |
| 1761 emit_optional_rex_32(dst, src); | 1661 emit_optional_rex_32(dst, src); |
| 1762 emit(0x0F); | 1662 emit(0x0F); |
| 1763 emit(0xB7); | 1663 emit(0xB7); |
| 1764 emit_operand(dst, src); | 1664 emit_operand(dst, src); |
| 1765 } | 1665 } |
| 1766 | 1666 |
| 1767 | 1667 |
| 1768 void Assembler::movzxwl(Register dst, const Operand& src) { | 1668 void Assembler::movzxwl(Register dst, const Operand& src) { |
| 1769 EnsureSpace ensure_space(this); | 1669 EnsureSpace ensure_space(this); |
| 1770 last_pc_ = pc_; | |
| 1771 emit_optional_rex_32(dst, src); | 1670 emit_optional_rex_32(dst, src); |
| 1772 emit(0x0F); | 1671 emit(0x0F); |
| 1773 emit(0xB7); | 1672 emit(0xB7); |
| 1774 emit_operand(dst, src); | 1673 emit_operand(dst, src); |
| 1775 } | 1674 } |
| 1776 | 1675 |
| 1777 | 1676 |
| 1778 void Assembler::repmovsb() { | 1677 void Assembler::repmovsb() { |
| 1779 EnsureSpace ensure_space(this); | 1678 EnsureSpace ensure_space(this); |
| 1780 last_pc_ = pc_; | |
| 1781 emit(0xF3); | 1679 emit(0xF3); |
| 1782 emit(0xA4); | 1680 emit(0xA4); |
| 1783 } | 1681 } |
| 1784 | 1682 |
| 1785 | 1683 |
| 1786 void Assembler::repmovsw() { | 1684 void Assembler::repmovsw() { |
| 1787 EnsureSpace ensure_space(this); | 1685 EnsureSpace ensure_space(this); |
| 1788 last_pc_ = pc_; | |
| 1789 emit(0x66); // Operand size override. | 1686 emit(0x66); // Operand size override. |
| 1790 emit(0xF3); | 1687 emit(0xF3); |
| 1791 emit(0xA4); | 1688 emit(0xA4); |
| 1792 } | 1689 } |
| 1793 | 1690 |
| 1794 | 1691 |
| 1795 void Assembler::repmovsl() { | 1692 void Assembler::repmovsl() { |
| 1796 EnsureSpace ensure_space(this); | 1693 EnsureSpace ensure_space(this); |
| 1797 last_pc_ = pc_; | |
| 1798 emit(0xF3); | 1694 emit(0xF3); |
| 1799 emit(0xA5); | 1695 emit(0xA5); |
| 1800 } | 1696 } |
| 1801 | 1697 |
| 1802 | 1698 |
| 1803 void Assembler::repmovsq() { | 1699 void Assembler::repmovsq() { |
| 1804 EnsureSpace ensure_space(this); | 1700 EnsureSpace ensure_space(this); |
| 1805 last_pc_ = pc_; | |
| 1806 emit(0xF3); | 1701 emit(0xF3); |
| 1807 emit_rex_64(); | 1702 emit_rex_64(); |
| 1808 emit(0xA5); | 1703 emit(0xA5); |
| 1809 } | 1704 } |
| 1810 | 1705 |
| 1811 | 1706 |
| 1812 void Assembler::mul(Register src) { | 1707 void Assembler::mul(Register src) { |
| 1813 EnsureSpace ensure_space(this); | 1708 EnsureSpace ensure_space(this); |
| 1814 last_pc_ = pc_; | |
| 1815 emit_rex_64(src); | 1709 emit_rex_64(src); |
| 1816 emit(0xF7); | 1710 emit(0xF7); |
| 1817 emit_modrm(0x4, src); | 1711 emit_modrm(0x4, src); |
| 1818 } | 1712 } |
| 1819 | 1713 |
| 1820 | 1714 |
| 1821 void Assembler::neg(Register dst) { | 1715 void Assembler::neg(Register dst) { |
| 1822 EnsureSpace ensure_space(this); | 1716 EnsureSpace ensure_space(this); |
| 1823 last_pc_ = pc_; | |
| 1824 emit_rex_64(dst); | 1717 emit_rex_64(dst); |
| 1825 emit(0xF7); | 1718 emit(0xF7); |
| 1826 emit_modrm(0x3, dst); | 1719 emit_modrm(0x3, dst); |
| 1827 } | 1720 } |
| 1828 | 1721 |
| 1829 | 1722 |
| 1830 void Assembler::negl(Register dst) { | 1723 void Assembler::negl(Register dst) { |
| 1831 EnsureSpace ensure_space(this); | 1724 EnsureSpace ensure_space(this); |
| 1832 last_pc_ = pc_; | |
| 1833 emit_optional_rex_32(dst); | 1725 emit_optional_rex_32(dst); |
| 1834 emit(0xF7); | 1726 emit(0xF7); |
| 1835 emit_modrm(0x3, dst); | 1727 emit_modrm(0x3, dst); |
| 1836 } | 1728 } |
| 1837 | 1729 |
| 1838 | 1730 |
| 1839 void Assembler::neg(const Operand& dst) { | 1731 void Assembler::neg(const Operand& dst) { |
| 1840 EnsureSpace ensure_space(this); | 1732 EnsureSpace ensure_space(this); |
| 1841 last_pc_ = pc_; | |
| 1842 emit_rex_64(dst); | 1733 emit_rex_64(dst); |
| 1843 emit(0xF7); | 1734 emit(0xF7); |
| 1844 emit_operand(3, dst); | 1735 emit_operand(3, dst); |
| 1845 } | 1736 } |
| 1846 | 1737 |
| 1847 | 1738 |
| 1848 void Assembler::nop() { | 1739 void Assembler::nop() { |
| 1849 EnsureSpace ensure_space(this); | 1740 EnsureSpace ensure_space(this); |
| 1850 last_pc_ = pc_; | |
| 1851 emit(0x90); | 1741 emit(0x90); |
| 1852 } | 1742 } |
| 1853 | 1743 |
| 1854 | 1744 |
| 1855 void Assembler::not_(Register dst) { | 1745 void Assembler::not_(Register dst) { |
| 1856 EnsureSpace ensure_space(this); | 1746 EnsureSpace ensure_space(this); |
| 1857 last_pc_ = pc_; | |
| 1858 emit_rex_64(dst); | 1747 emit_rex_64(dst); |
| 1859 emit(0xF7); | 1748 emit(0xF7); |
| 1860 emit_modrm(0x2, dst); | 1749 emit_modrm(0x2, dst); |
| 1861 } | 1750 } |
| 1862 | 1751 |
| 1863 | 1752 |
| 1864 void Assembler::not_(const Operand& dst) { | 1753 void Assembler::not_(const Operand& dst) { |
| 1865 EnsureSpace ensure_space(this); | 1754 EnsureSpace ensure_space(this); |
| 1866 last_pc_ = pc_; | |
| 1867 emit_rex_64(dst); | 1755 emit_rex_64(dst); |
| 1868 emit(0xF7); | 1756 emit(0xF7); |
| 1869 emit_operand(2, dst); | 1757 emit_operand(2, dst); |
| 1870 } | 1758 } |
| 1871 | 1759 |
| 1872 | 1760 |
| 1873 void Assembler::notl(Register dst) { | 1761 void Assembler::notl(Register dst) { |
| 1874 EnsureSpace ensure_space(this); | 1762 EnsureSpace ensure_space(this); |
| 1875 last_pc_ = pc_; | |
| 1876 emit_optional_rex_32(dst); | 1763 emit_optional_rex_32(dst); |
| 1877 emit(0xF7); | 1764 emit(0xF7); |
| 1878 emit_modrm(0x2, dst); | 1765 emit_modrm(0x2, dst); |
| 1879 } | 1766 } |
| 1880 | 1767 |
| 1881 | 1768 |
| 1882 void Assembler::nop(int n) { | 1769 void Assembler::nop(int n) { |
| 1883 // The recommended muti-byte sequences of NOP instructions from the Intel 64 | 1770 // The recommended muti-byte sequences of NOP instructions from the Intel 64 |
| 1884 // and IA-32 Architectures Software Developer's Manual. | 1771 // and IA-32 Architectures Software Developer's Manual. |
| 1885 // | 1772 // |
| 1886 // Length Assembly Byte Sequence | 1773 // Length Assembly Byte Sequence |
| 1887 // 2 bytes 66 NOP 66 90H | 1774 // 2 bytes 66 NOP 66 90H |
| 1888 // 3 bytes NOP DWORD ptr [EAX] 0F 1F 00H | 1775 // 3 bytes NOP DWORD ptr [EAX] 0F 1F 00H |
| 1889 // 4 bytes NOP DWORD ptr [EAX + 00H] 0F 1F 40 00H | 1776 // 4 bytes NOP DWORD ptr [EAX + 00H] 0F 1F 40 00H |
| 1890 // 5 bytes NOP DWORD ptr [EAX + EAX*1 + 00H] 0F 1F 44 00 00H | 1777 // 5 bytes NOP DWORD ptr [EAX + EAX*1 + 00H] 0F 1F 44 00 00H |
| 1891 // 6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H | 1778 // 6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H |
| 1892 // 7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H | 1779 // 7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H |
| 1893 // 8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H | 1780 // 8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H |
| 1894 // 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 66 0F 1F 84 00 00 00 00 | 1781 // 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 66 0F 1F 84 00 00 00 00 |
| 1895 // 00000000H] 00H | 1782 // 00000000H] 00H |
| 1896 | 1783 |
| 1897 ASSERT(1 <= n); | 1784 ASSERT(1 <= n); |
| 1898 ASSERT(n <= 9); | 1785 ASSERT(n <= 9); |
| 1899 EnsureSpace ensure_space(this); | 1786 EnsureSpace ensure_space(this); |
| 1900 last_pc_ = pc_; | |
| 1901 switch (n) { | 1787 switch (n) { |
| 1902 case 1: | 1788 case 1: |
| 1903 emit(0x90); | 1789 emit(0x90); |
| 1904 return; | 1790 return; |
| 1905 case 2: | 1791 case 2: |
| 1906 emit(0x66); | 1792 emit(0x66); |
| 1907 emit(0x90); | 1793 emit(0x90); |
| 1908 return; | 1794 return; |
| 1909 case 3: | 1795 case 3: |
| 1910 emit(0x0f); | 1796 emit(0x0f); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1961 emit(0x00); | 1847 emit(0x00); |
| 1962 emit(0x00); | 1848 emit(0x00); |
| 1963 emit(0x00); | 1849 emit(0x00); |
| 1964 return; | 1850 return; |
| 1965 } | 1851 } |
| 1966 } | 1852 } |
| 1967 | 1853 |
| 1968 | 1854 |
| 1969 void Assembler::pop(Register dst) { | 1855 void Assembler::pop(Register dst) { |
| 1970 EnsureSpace ensure_space(this); | 1856 EnsureSpace ensure_space(this); |
| 1971 last_pc_ = pc_; | |
| 1972 emit_optional_rex_32(dst); | 1857 emit_optional_rex_32(dst); |
| 1973 emit(0x58 | dst.low_bits()); | 1858 emit(0x58 | dst.low_bits()); |
| 1974 } | 1859 } |
| 1975 | 1860 |
| 1976 | 1861 |
| 1977 void Assembler::pop(const Operand& dst) { | 1862 void Assembler::pop(const Operand& dst) { |
| 1978 EnsureSpace ensure_space(this); | 1863 EnsureSpace ensure_space(this); |
| 1979 last_pc_ = pc_; | |
| 1980 emit_optional_rex_32(dst); | 1864 emit_optional_rex_32(dst); |
| 1981 emit(0x8F); | 1865 emit(0x8F); |
| 1982 emit_operand(0, dst); | 1866 emit_operand(0, dst); |
| 1983 } | 1867 } |
| 1984 | 1868 |
| 1985 | 1869 |
| 1986 void Assembler::popfq() { | 1870 void Assembler::popfq() { |
| 1987 EnsureSpace ensure_space(this); | 1871 EnsureSpace ensure_space(this); |
| 1988 last_pc_ = pc_; | |
| 1989 emit(0x9D); | 1872 emit(0x9D); |
| 1990 } | 1873 } |
| 1991 | 1874 |
| 1992 | 1875 |
| 1993 void Assembler::push(Register src) { | 1876 void Assembler::push(Register src) { |
| 1994 EnsureSpace ensure_space(this); | 1877 EnsureSpace ensure_space(this); |
| 1995 last_pc_ = pc_; | |
| 1996 emit_optional_rex_32(src); | 1878 emit_optional_rex_32(src); |
| 1997 emit(0x50 | src.low_bits()); | 1879 emit(0x50 | src.low_bits()); |
| 1998 } | 1880 } |
| 1999 | 1881 |
| 2000 | 1882 |
| 2001 void Assembler::push(const Operand& src) { | 1883 void Assembler::push(const Operand& src) { |
| 2002 EnsureSpace ensure_space(this); | 1884 EnsureSpace ensure_space(this); |
| 2003 last_pc_ = pc_; | |
| 2004 emit_optional_rex_32(src); | 1885 emit_optional_rex_32(src); |
| 2005 emit(0xFF); | 1886 emit(0xFF); |
| 2006 emit_operand(6, src); | 1887 emit_operand(6, src); |
| 2007 } | 1888 } |
| 2008 | 1889 |
| 2009 | 1890 |
| 2010 void Assembler::push(Immediate value) { | 1891 void Assembler::push(Immediate value) { |
| 2011 EnsureSpace ensure_space(this); | 1892 EnsureSpace ensure_space(this); |
| 2012 last_pc_ = pc_; | |
| 2013 if (is_int8(value.value_)) { | 1893 if (is_int8(value.value_)) { |
| 2014 emit(0x6A); | 1894 emit(0x6A); |
| 2015 emit(value.value_); // Emit low byte of value. | 1895 emit(value.value_); // Emit low byte of value. |
| 2016 } else { | 1896 } else { |
| 2017 emit(0x68); | 1897 emit(0x68); |
| 2018 emitl(value.value_); | 1898 emitl(value.value_); |
| 2019 } | 1899 } |
| 2020 } | 1900 } |
| 2021 | 1901 |
| 2022 | 1902 |
| 2023 void Assembler::push_imm32(int32_t imm32) { | 1903 void Assembler::push_imm32(int32_t imm32) { |
| 2024 EnsureSpace ensure_space(this); | 1904 EnsureSpace ensure_space(this); |
| 2025 last_pc_ = pc_; | |
| 2026 emit(0x68); | 1905 emit(0x68); |
| 2027 emitl(imm32); | 1906 emitl(imm32); |
| 2028 } | 1907 } |
| 2029 | 1908 |
| 2030 | 1909 |
| 2031 void Assembler::pushfq() { | 1910 void Assembler::pushfq() { |
| 2032 EnsureSpace ensure_space(this); | 1911 EnsureSpace ensure_space(this); |
| 2033 last_pc_ = pc_; | |
| 2034 emit(0x9C); | 1912 emit(0x9C); |
| 2035 } | 1913 } |
| 2036 | 1914 |
| 2037 | 1915 |
| 2038 void Assembler::rdtsc() { | 1916 void Assembler::rdtsc() { |
| 2039 EnsureSpace ensure_space(this); | 1917 EnsureSpace ensure_space(this); |
| 2040 last_pc_ = pc_; | |
| 2041 emit(0x0F); | 1918 emit(0x0F); |
| 2042 emit(0x31); | 1919 emit(0x31); |
| 2043 } | 1920 } |
| 2044 | 1921 |
| 2045 | 1922 |
| 2046 void Assembler::ret(int imm16) { | 1923 void Assembler::ret(int imm16) { |
| 2047 EnsureSpace ensure_space(this); | 1924 EnsureSpace ensure_space(this); |
| 2048 last_pc_ = pc_; | |
| 2049 ASSERT(is_uint16(imm16)); | 1925 ASSERT(is_uint16(imm16)); |
| 2050 if (imm16 == 0) { | 1926 if (imm16 == 0) { |
| 2051 emit(0xC3); | 1927 emit(0xC3); |
| 2052 } else { | 1928 } else { |
| 2053 emit(0xC2); | 1929 emit(0xC2); |
| 2054 emit(imm16 & 0xFF); | 1930 emit(imm16 & 0xFF); |
| 2055 emit((imm16 >> 8) & 0xFF); | 1931 emit((imm16 >> 8) & 0xFF); |
| 2056 } | 1932 } |
| 2057 } | 1933 } |
| 2058 | 1934 |
| 2059 | 1935 |
| 2060 void Assembler::setcc(Condition cc, Register reg) { | 1936 void Assembler::setcc(Condition cc, Register reg) { |
| 2061 if (cc > last_condition) { | 1937 if (cc > last_condition) { |
| 2062 movb(reg, Immediate(cc == always ? 1 : 0)); | 1938 movb(reg, Immediate(cc == always ? 1 : 0)); |
| 2063 return; | 1939 return; |
| 2064 } | 1940 } |
| 2065 EnsureSpace ensure_space(this); | 1941 EnsureSpace ensure_space(this); |
| 2066 last_pc_ = pc_; | |
| 2067 ASSERT(is_uint4(cc)); | 1942 ASSERT(is_uint4(cc)); |
| 2068 if (reg.code() > 3) { // Use x64 byte registers, where different. | 1943 if (reg.code() > 3) { // Use x64 byte registers, where different. |
| 2069 emit_rex_32(reg); | 1944 emit_rex_32(reg); |
| 2070 } | 1945 } |
| 2071 emit(0x0F); | 1946 emit(0x0F); |
| 2072 emit(0x90 | cc); | 1947 emit(0x90 | cc); |
| 2073 emit_modrm(0x0, reg); | 1948 emit_modrm(0x0, reg); |
| 2074 } | 1949 } |
| 2075 | 1950 |
| 2076 | 1951 |
| 2077 void Assembler::shld(Register dst, Register src) { | 1952 void Assembler::shld(Register dst, Register src) { |
| 2078 EnsureSpace ensure_space(this); | 1953 EnsureSpace ensure_space(this); |
| 2079 last_pc_ = pc_; | |
| 2080 emit_rex_64(src, dst); | 1954 emit_rex_64(src, dst); |
| 2081 emit(0x0F); | 1955 emit(0x0F); |
| 2082 emit(0xA5); | 1956 emit(0xA5); |
| 2083 emit_modrm(src, dst); | 1957 emit_modrm(src, dst); |
| 2084 } | 1958 } |
| 2085 | 1959 |
| 2086 | 1960 |
| 2087 void Assembler::shrd(Register dst, Register src) { | 1961 void Assembler::shrd(Register dst, Register src) { |
| 2088 EnsureSpace ensure_space(this); | 1962 EnsureSpace ensure_space(this); |
| 2089 last_pc_ = pc_; | |
| 2090 emit_rex_64(src, dst); | 1963 emit_rex_64(src, dst); |
| 2091 emit(0x0F); | 1964 emit(0x0F); |
| 2092 emit(0xAD); | 1965 emit(0xAD); |
| 2093 emit_modrm(src, dst); | 1966 emit_modrm(src, dst); |
| 2094 } | 1967 } |
| 2095 | 1968 |
| 2096 | 1969 |
| 2097 void Assembler::xchg(Register dst, Register src) { | 1970 void Assembler::xchg(Register dst, Register src) { |
| 2098 EnsureSpace ensure_space(this); | 1971 EnsureSpace ensure_space(this); |
| 2099 last_pc_ = pc_; | |
| 2100 if (src.is(rax) || dst.is(rax)) { // Single-byte encoding | 1972 if (src.is(rax) || dst.is(rax)) { // Single-byte encoding |
| 2101 Register other = src.is(rax) ? dst : src; | 1973 Register other = src.is(rax) ? dst : src; |
| 2102 emit_rex_64(other); | 1974 emit_rex_64(other); |
| 2103 emit(0x90 | other.low_bits()); | 1975 emit(0x90 | other.low_bits()); |
| 2104 } else if (dst.low_bits() == 4) { | 1976 } else if (dst.low_bits() == 4) { |
| 2105 emit_rex_64(dst, src); | 1977 emit_rex_64(dst, src); |
| 2106 emit(0x87); | 1978 emit(0x87); |
| 2107 emit_modrm(dst, src); | 1979 emit_modrm(dst, src); |
| 2108 } else { | 1980 } else { |
| 2109 emit_rex_64(src, dst); | 1981 emit_rex_64(src, dst); |
| 2110 emit(0x87); | 1982 emit(0x87); |
| 2111 emit_modrm(src, dst); | 1983 emit_modrm(src, dst); |
| 2112 } | 1984 } |
| 2113 } | 1985 } |
| 2114 | 1986 |
| 2115 | 1987 |
| 2116 void Assembler::store_rax(void* dst, RelocInfo::Mode mode) { | 1988 void Assembler::store_rax(void* dst, RelocInfo::Mode mode) { |
| 2117 EnsureSpace ensure_space(this); | 1989 EnsureSpace ensure_space(this); |
| 2118 last_pc_ = pc_; | |
| 2119 emit(0x48); // REX.W | 1990 emit(0x48); // REX.W |
| 2120 emit(0xA3); | 1991 emit(0xA3); |
| 2121 emitq(reinterpret_cast<uintptr_t>(dst), mode); | 1992 emitq(reinterpret_cast<uintptr_t>(dst), mode); |
| 2122 } | 1993 } |
| 2123 | 1994 |
| 2124 | 1995 |
| 2125 void Assembler::store_rax(ExternalReference ref) { | 1996 void Assembler::store_rax(ExternalReference ref) { |
| 2126 store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE); | 1997 store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE); |
| 2127 } | 1998 } |
| 2128 | 1999 |
| 2129 | 2000 |
| 2130 void Assembler::testb(Register dst, Register src) { | 2001 void Assembler::testb(Register dst, Register src) { |
| 2131 EnsureSpace ensure_space(this); | 2002 EnsureSpace ensure_space(this); |
| 2132 last_pc_ = pc_; | |
| 2133 if (src.low_bits() == 4) { | 2003 if (src.low_bits() == 4) { |
| 2134 emit_rex_32(src, dst); | 2004 emit_rex_32(src, dst); |
| 2135 emit(0x84); | 2005 emit(0x84); |
| 2136 emit_modrm(src, dst); | 2006 emit_modrm(src, dst); |
| 2137 } else { | 2007 } else { |
| 2138 if (dst.code() > 3 || src.code() > 3) { | 2008 if (dst.code() > 3 || src.code() > 3) { |
| 2139 // Register is not one of al, bl, cl, dl. Its encoding needs REX. | 2009 // Register is not one of al, bl, cl, dl. Its encoding needs REX. |
| 2140 emit_rex_32(dst, src); | 2010 emit_rex_32(dst, src); |
| 2141 } | 2011 } |
| 2142 emit(0x84); | 2012 emit(0x84); |
| 2143 emit_modrm(dst, src); | 2013 emit_modrm(dst, src); |
| 2144 } | 2014 } |
| 2145 } | 2015 } |
| 2146 | 2016 |
| 2147 | 2017 |
| 2148 void Assembler::testb(Register reg, Immediate mask) { | 2018 void Assembler::testb(Register reg, Immediate mask) { |
| 2149 ASSERT(is_int8(mask.value_) || is_uint8(mask.value_)); | 2019 ASSERT(is_int8(mask.value_) || is_uint8(mask.value_)); |
| 2150 EnsureSpace ensure_space(this); | 2020 EnsureSpace ensure_space(this); |
| 2151 last_pc_ = pc_; | |
| 2152 if (reg.is(rax)) { | 2021 if (reg.is(rax)) { |
| 2153 emit(0xA8); | 2022 emit(0xA8); |
| 2154 emit(mask.value_); // Low byte emitted. | 2023 emit(mask.value_); // Low byte emitted. |
| 2155 } else { | 2024 } else { |
| 2156 if (reg.code() > 3) { | 2025 if (reg.code() > 3) { |
| 2157 // Register is not one of al, bl, cl, dl. Its encoding needs REX. | 2026 // Register is not one of al, bl, cl, dl. Its encoding needs REX. |
| 2158 emit_rex_32(reg); | 2027 emit_rex_32(reg); |
| 2159 } | 2028 } |
| 2160 emit(0xF6); | 2029 emit(0xF6); |
| 2161 emit_modrm(0x0, reg); | 2030 emit_modrm(0x0, reg); |
| 2162 emit(mask.value_); // Low byte emitted. | 2031 emit(mask.value_); // Low byte emitted. |
| 2163 } | 2032 } |
| 2164 } | 2033 } |
| 2165 | 2034 |
| 2166 | 2035 |
| 2167 void Assembler::testb(const Operand& op, Immediate mask) { | 2036 void Assembler::testb(const Operand& op, Immediate mask) { |
| 2168 ASSERT(is_int8(mask.value_) || is_uint8(mask.value_)); | 2037 ASSERT(is_int8(mask.value_) || is_uint8(mask.value_)); |
| 2169 EnsureSpace ensure_space(this); | 2038 EnsureSpace ensure_space(this); |
| 2170 last_pc_ = pc_; | |
| 2171 emit_optional_rex_32(rax, op); | 2039 emit_optional_rex_32(rax, op); |
| 2172 emit(0xF6); | 2040 emit(0xF6); |
| 2173 emit_operand(rax, op); // Operation code 0 | 2041 emit_operand(rax, op); // Operation code 0 |
| 2174 emit(mask.value_); // Low byte emitted. | 2042 emit(mask.value_); // Low byte emitted. |
| 2175 } | 2043 } |
| 2176 | 2044 |
| 2177 | 2045 |
| 2178 void Assembler::testb(const Operand& op, Register reg) { | 2046 void Assembler::testb(const Operand& op, Register reg) { |
| 2179 EnsureSpace ensure_space(this); | 2047 EnsureSpace ensure_space(this); |
| 2180 last_pc_ = pc_; | |
| 2181 if (reg.code() > 3) { | 2048 if (reg.code() > 3) { |
| 2182 // Register is not one of al, bl, cl, dl. Its encoding needs REX. | 2049 // Register is not one of al, bl, cl, dl. Its encoding needs REX. |
| 2183 emit_rex_32(reg, op); | 2050 emit_rex_32(reg, op); |
| 2184 } else { | 2051 } else { |
| 2185 emit_optional_rex_32(reg, op); | 2052 emit_optional_rex_32(reg, op); |
| 2186 } | 2053 } |
| 2187 emit(0x84); | 2054 emit(0x84); |
| 2188 emit_operand(reg, op); | 2055 emit_operand(reg, op); |
| 2189 } | 2056 } |
| 2190 | 2057 |
| 2191 | 2058 |
| 2192 void Assembler::testl(Register dst, Register src) { | 2059 void Assembler::testl(Register dst, Register src) { |
| 2193 EnsureSpace ensure_space(this); | 2060 EnsureSpace ensure_space(this); |
| 2194 last_pc_ = pc_; | |
| 2195 if (src.low_bits() == 4) { | 2061 if (src.low_bits() == 4) { |
| 2196 emit_optional_rex_32(src, dst); | 2062 emit_optional_rex_32(src, dst); |
| 2197 emit(0x85); | 2063 emit(0x85); |
| 2198 emit_modrm(src, dst); | 2064 emit_modrm(src, dst); |
| 2199 } else { | 2065 } else { |
| 2200 emit_optional_rex_32(dst, src); | 2066 emit_optional_rex_32(dst, src); |
| 2201 emit(0x85); | 2067 emit(0x85); |
| 2202 emit_modrm(dst, src); | 2068 emit_modrm(dst, src); |
| 2203 } | 2069 } |
| 2204 } | 2070 } |
| 2205 | 2071 |
| 2206 | 2072 |
| 2207 void Assembler::testl(Register reg, Immediate mask) { | 2073 void Assembler::testl(Register reg, Immediate mask) { |
| 2208 // testl with a mask that fits in the low byte is exactly testb. | 2074 // testl with a mask that fits in the low byte is exactly testb. |
| 2209 if (is_uint8(mask.value_)) { | 2075 if (is_uint8(mask.value_)) { |
| 2210 testb(reg, mask); | 2076 testb(reg, mask); |
| 2211 return; | 2077 return; |
| 2212 } | 2078 } |
| 2213 EnsureSpace ensure_space(this); | 2079 EnsureSpace ensure_space(this); |
| 2214 last_pc_ = pc_; | |
| 2215 if (reg.is(rax)) { | 2080 if (reg.is(rax)) { |
| 2216 emit(0xA9); | 2081 emit(0xA9); |
| 2217 emit(mask); | 2082 emit(mask); |
| 2218 } else { | 2083 } else { |
| 2219 emit_optional_rex_32(rax, reg); | 2084 emit_optional_rex_32(rax, reg); |
| 2220 emit(0xF7); | 2085 emit(0xF7); |
| 2221 emit_modrm(0x0, reg); | 2086 emit_modrm(0x0, reg); |
| 2222 emit(mask); | 2087 emit(mask); |
| 2223 } | 2088 } |
| 2224 } | 2089 } |
| 2225 | 2090 |
| 2226 | 2091 |
| 2227 void Assembler::testl(const Operand& op, Immediate mask) { | 2092 void Assembler::testl(const Operand& op, Immediate mask) { |
| 2228 // testl with a mask that fits in the low byte is exactly testb. | 2093 // testl with a mask that fits in the low byte is exactly testb. |
| 2229 if (is_uint8(mask.value_)) { | 2094 if (is_uint8(mask.value_)) { |
| 2230 testb(op, mask); | 2095 testb(op, mask); |
| 2231 return; | 2096 return; |
| 2232 } | 2097 } |
| 2233 EnsureSpace ensure_space(this); | 2098 EnsureSpace ensure_space(this); |
| 2234 last_pc_ = pc_; | |
| 2235 emit_optional_rex_32(rax, op); | 2099 emit_optional_rex_32(rax, op); |
| 2236 emit(0xF7); | 2100 emit(0xF7); |
| 2237 emit_operand(rax, op); // Operation code 0 | 2101 emit_operand(rax, op); // Operation code 0 |
| 2238 emit(mask); | 2102 emit(mask); |
| 2239 } | 2103 } |
| 2240 | 2104 |
| 2241 | 2105 |
| 2242 void Assembler::testq(const Operand& op, Register reg) { | 2106 void Assembler::testq(const Operand& op, Register reg) { |
| 2243 EnsureSpace ensure_space(this); | 2107 EnsureSpace ensure_space(this); |
| 2244 last_pc_ = pc_; | |
| 2245 emit_rex_64(reg, op); | 2108 emit_rex_64(reg, op); |
| 2246 emit(0x85); | 2109 emit(0x85); |
| 2247 emit_operand(reg, op); | 2110 emit_operand(reg, op); |
| 2248 } | 2111 } |
| 2249 | 2112 |
| 2250 | 2113 |
| 2251 void Assembler::testq(Register dst, Register src) { | 2114 void Assembler::testq(Register dst, Register src) { |
| 2252 EnsureSpace ensure_space(this); | 2115 EnsureSpace ensure_space(this); |
| 2253 last_pc_ = pc_; | |
| 2254 if (src.low_bits() == 4) { | 2116 if (src.low_bits() == 4) { |
| 2255 emit_rex_64(src, dst); | 2117 emit_rex_64(src, dst); |
| 2256 emit(0x85); | 2118 emit(0x85); |
| 2257 emit_modrm(src, dst); | 2119 emit_modrm(src, dst); |
| 2258 } else { | 2120 } else { |
| 2259 emit_rex_64(dst, src); | 2121 emit_rex_64(dst, src); |
| 2260 emit(0x85); | 2122 emit(0x85); |
| 2261 emit_modrm(dst, src); | 2123 emit_modrm(dst, src); |
| 2262 } | 2124 } |
| 2263 } | 2125 } |
| 2264 | 2126 |
| 2265 | 2127 |
| 2266 void Assembler::testq(Register dst, Immediate mask) { | 2128 void Assembler::testq(Register dst, Immediate mask) { |
| 2267 EnsureSpace ensure_space(this); | 2129 EnsureSpace ensure_space(this); |
| 2268 last_pc_ = pc_; | |
| 2269 if (dst.is(rax)) { | 2130 if (dst.is(rax)) { |
| 2270 emit_rex_64(); | 2131 emit_rex_64(); |
| 2271 emit(0xA9); | 2132 emit(0xA9); |
| 2272 emit(mask); | 2133 emit(mask); |
| 2273 } else { | 2134 } else { |
| 2274 emit_rex_64(dst); | 2135 emit_rex_64(dst); |
| 2275 emit(0xF7); | 2136 emit(0xF7); |
| 2276 emit_modrm(0, dst); | 2137 emit_modrm(0, dst); |
| 2277 emit(mask); | 2138 emit(mask); |
| 2278 } | 2139 } |
| 2279 } | 2140 } |
| 2280 | 2141 |
| 2281 | 2142 |
| 2282 // FPU instructions. | 2143 // FPU instructions. |
| 2283 | 2144 |
| 2284 | 2145 |
| 2285 void Assembler::fld(int i) { | 2146 void Assembler::fld(int i) { |
| 2286 EnsureSpace ensure_space(this); | 2147 EnsureSpace ensure_space(this); |
| 2287 last_pc_ = pc_; | |
| 2288 emit_farith(0xD9, 0xC0, i); | 2148 emit_farith(0xD9, 0xC0, i); |
| 2289 } | 2149 } |
| 2290 | 2150 |
| 2291 | 2151 |
| 2292 void Assembler::fld1() { | 2152 void Assembler::fld1() { |
| 2293 EnsureSpace ensure_space(this); | 2153 EnsureSpace ensure_space(this); |
| 2294 last_pc_ = pc_; | |
| 2295 emit(0xD9); | 2154 emit(0xD9); |
| 2296 emit(0xE8); | 2155 emit(0xE8); |
| 2297 } | 2156 } |
| 2298 | 2157 |
| 2299 | 2158 |
| 2300 void Assembler::fldz() { | 2159 void Assembler::fldz() { |
| 2301 EnsureSpace ensure_space(this); | 2160 EnsureSpace ensure_space(this); |
| 2302 last_pc_ = pc_; | |
| 2303 emit(0xD9); | 2161 emit(0xD9); |
| 2304 emit(0xEE); | 2162 emit(0xEE); |
| 2305 } | 2163 } |
| 2306 | 2164 |
| 2307 | 2165 |
| 2308 void Assembler::fldpi() { | 2166 void Assembler::fldpi() { |
| 2309 EnsureSpace ensure_space(this); | 2167 EnsureSpace ensure_space(this); |
| 2310 last_pc_ = pc_; | |
| 2311 emit(0xD9); | 2168 emit(0xD9); |
| 2312 emit(0xEB); | 2169 emit(0xEB); |
| 2313 } | 2170 } |
| 2314 | 2171 |
| 2315 | 2172 |
| 2316 void Assembler::fldln2() { | 2173 void Assembler::fldln2() { |
| 2317 EnsureSpace ensure_space(this); | 2174 EnsureSpace ensure_space(this); |
| 2318 last_pc_ = pc_; | |
| 2319 emit(0xD9); | 2175 emit(0xD9); |
| 2320 emit(0xED); | 2176 emit(0xED); |
| 2321 } | 2177 } |
| 2322 | 2178 |
| 2323 | 2179 |
| 2324 void Assembler::fld_s(const Operand& adr) { | 2180 void Assembler::fld_s(const Operand& adr) { |
| 2325 EnsureSpace ensure_space(this); | 2181 EnsureSpace ensure_space(this); |
| 2326 last_pc_ = pc_; | |
| 2327 emit_optional_rex_32(adr); | 2182 emit_optional_rex_32(adr); |
| 2328 emit(0xD9); | 2183 emit(0xD9); |
| 2329 emit_operand(0, adr); | 2184 emit_operand(0, adr); |
| 2330 } | 2185 } |
| 2331 | 2186 |
| 2332 | 2187 |
| 2333 void Assembler::fld_d(const Operand& adr) { | 2188 void Assembler::fld_d(const Operand& adr) { |
| 2334 EnsureSpace ensure_space(this); | 2189 EnsureSpace ensure_space(this); |
| 2335 last_pc_ = pc_; | |
| 2336 emit_optional_rex_32(adr); | 2190 emit_optional_rex_32(adr); |
| 2337 emit(0xDD); | 2191 emit(0xDD); |
| 2338 emit_operand(0, adr); | 2192 emit_operand(0, adr); |
| 2339 } | 2193 } |
| 2340 | 2194 |
| 2341 | 2195 |
| 2342 void Assembler::fstp_s(const Operand& adr) { | 2196 void Assembler::fstp_s(const Operand& adr) { |
| 2343 EnsureSpace ensure_space(this); | 2197 EnsureSpace ensure_space(this); |
| 2344 last_pc_ = pc_; | |
| 2345 emit_optional_rex_32(adr); | 2198 emit_optional_rex_32(adr); |
| 2346 emit(0xD9); | 2199 emit(0xD9); |
| 2347 emit_operand(3, adr); | 2200 emit_operand(3, adr); |
| 2348 } | 2201 } |
| 2349 | 2202 |
| 2350 | 2203 |
| 2351 void Assembler::fstp_d(const Operand& adr) { | 2204 void Assembler::fstp_d(const Operand& adr) { |
| 2352 EnsureSpace ensure_space(this); | 2205 EnsureSpace ensure_space(this); |
| 2353 last_pc_ = pc_; | |
| 2354 emit_optional_rex_32(adr); | 2206 emit_optional_rex_32(adr); |
| 2355 emit(0xDD); | 2207 emit(0xDD); |
| 2356 emit_operand(3, adr); | 2208 emit_operand(3, adr); |
| 2357 } | 2209 } |
| 2358 | 2210 |
| 2359 | 2211 |
| 2360 void Assembler::fstp(int index) { | 2212 void Assembler::fstp(int index) { |
| 2361 ASSERT(is_uint3(index)); | 2213 ASSERT(is_uint3(index)); |
| 2362 EnsureSpace ensure_space(this); | 2214 EnsureSpace ensure_space(this); |
| 2363 last_pc_ = pc_; | |
| 2364 emit_farith(0xDD, 0xD8, index); | 2215 emit_farith(0xDD, 0xD8, index); |
| 2365 } | 2216 } |
| 2366 | 2217 |
| 2367 | 2218 |
| 2368 void Assembler::fild_s(const Operand& adr) { | 2219 void Assembler::fild_s(const Operand& adr) { |
| 2369 EnsureSpace ensure_space(this); | 2220 EnsureSpace ensure_space(this); |
| 2370 last_pc_ = pc_; | |
| 2371 emit_optional_rex_32(adr); | 2221 emit_optional_rex_32(adr); |
| 2372 emit(0xDB); | 2222 emit(0xDB); |
| 2373 emit_operand(0, adr); | 2223 emit_operand(0, adr); |
| 2374 } | 2224 } |
| 2375 | 2225 |
| 2376 | 2226 |
| 2377 void Assembler::fild_d(const Operand& adr) { | 2227 void Assembler::fild_d(const Operand& adr) { |
| 2378 EnsureSpace ensure_space(this); | 2228 EnsureSpace ensure_space(this); |
| 2379 last_pc_ = pc_; | |
| 2380 emit_optional_rex_32(adr); | 2229 emit_optional_rex_32(adr); |
| 2381 emit(0xDF); | 2230 emit(0xDF); |
| 2382 emit_operand(5, adr); | 2231 emit_operand(5, adr); |
| 2383 } | 2232 } |
| 2384 | 2233 |
| 2385 | 2234 |
| 2386 void Assembler::fistp_s(const Operand& adr) { | 2235 void Assembler::fistp_s(const Operand& adr) { |
| 2387 EnsureSpace ensure_space(this); | 2236 EnsureSpace ensure_space(this); |
| 2388 last_pc_ = pc_; | |
| 2389 emit_optional_rex_32(adr); | 2237 emit_optional_rex_32(adr); |
| 2390 emit(0xDB); | 2238 emit(0xDB); |
| 2391 emit_operand(3, adr); | 2239 emit_operand(3, adr); |
| 2392 } | 2240 } |
| 2393 | 2241 |
| 2394 | 2242 |
| 2395 void Assembler::fisttp_s(const Operand& adr) { | 2243 void Assembler::fisttp_s(const Operand& adr) { |
| 2396 ASSERT(CpuFeatures::IsEnabled(SSE3)); | 2244 ASSERT(CpuFeatures::IsEnabled(SSE3)); |
| 2397 EnsureSpace ensure_space(this); | 2245 EnsureSpace ensure_space(this); |
| 2398 last_pc_ = pc_; | |
| 2399 emit_optional_rex_32(adr); | 2246 emit_optional_rex_32(adr); |
| 2400 emit(0xDB); | 2247 emit(0xDB); |
| 2401 emit_operand(1, adr); | 2248 emit_operand(1, adr); |
| 2402 } | 2249 } |
| 2403 | 2250 |
| 2404 | 2251 |
| 2405 void Assembler::fisttp_d(const Operand& adr) { | 2252 void Assembler::fisttp_d(const Operand& adr) { |
| 2406 ASSERT(CpuFeatures::IsEnabled(SSE3)); | 2253 ASSERT(CpuFeatures::IsEnabled(SSE3)); |
| 2407 EnsureSpace ensure_space(this); | 2254 EnsureSpace ensure_space(this); |
| 2408 last_pc_ = pc_; | |
| 2409 emit_optional_rex_32(adr); | 2255 emit_optional_rex_32(adr); |
| 2410 emit(0xDD); | 2256 emit(0xDD); |
| 2411 emit_operand(1, adr); | 2257 emit_operand(1, adr); |
| 2412 } | 2258 } |
| 2413 | 2259 |
| 2414 | 2260 |
| 2415 void Assembler::fist_s(const Operand& adr) { | 2261 void Assembler::fist_s(const Operand& adr) { |
| 2416 EnsureSpace ensure_space(this); | 2262 EnsureSpace ensure_space(this); |
| 2417 last_pc_ = pc_; | |
| 2418 emit_optional_rex_32(adr); | 2263 emit_optional_rex_32(adr); |
| 2419 emit(0xDB); | 2264 emit(0xDB); |
| 2420 emit_operand(2, adr); | 2265 emit_operand(2, adr); |
| 2421 } | 2266 } |
| 2422 | 2267 |
| 2423 | 2268 |
| 2424 void Assembler::fistp_d(const Operand& adr) { | 2269 void Assembler::fistp_d(const Operand& adr) { |
| 2425 EnsureSpace ensure_space(this); | 2270 EnsureSpace ensure_space(this); |
| 2426 last_pc_ = pc_; | |
| 2427 emit_optional_rex_32(adr); | 2271 emit_optional_rex_32(adr); |
| 2428 emit(0xDF); | 2272 emit(0xDF); |
| 2429 emit_operand(7, adr); | 2273 emit_operand(7, adr); |
| 2430 } | 2274 } |
| 2431 | 2275 |
| 2432 | 2276 |
| 2433 void Assembler::fabs() { | 2277 void Assembler::fabs() { |
| 2434 EnsureSpace ensure_space(this); | 2278 EnsureSpace ensure_space(this); |
| 2435 last_pc_ = pc_; | |
| 2436 emit(0xD9); | 2279 emit(0xD9); |
| 2437 emit(0xE1); | 2280 emit(0xE1); |
| 2438 } | 2281 } |
| 2439 | 2282 |
| 2440 | 2283 |
| 2441 void Assembler::fchs() { | 2284 void Assembler::fchs() { |
| 2442 EnsureSpace ensure_space(this); | 2285 EnsureSpace ensure_space(this); |
| 2443 last_pc_ = pc_; | |
| 2444 emit(0xD9); | 2286 emit(0xD9); |
| 2445 emit(0xE0); | 2287 emit(0xE0); |
| 2446 } | 2288 } |
| 2447 | 2289 |
| 2448 | 2290 |
| 2449 void Assembler::fcos() { | 2291 void Assembler::fcos() { |
| 2450 EnsureSpace ensure_space(this); | 2292 EnsureSpace ensure_space(this); |
| 2451 last_pc_ = pc_; | |
| 2452 emit(0xD9); | 2293 emit(0xD9); |
| 2453 emit(0xFF); | 2294 emit(0xFF); |
| 2454 } | 2295 } |
| 2455 | 2296 |
| 2456 | 2297 |
| 2457 void Assembler::fsin() { | 2298 void Assembler::fsin() { |
| 2458 EnsureSpace ensure_space(this); | 2299 EnsureSpace ensure_space(this); |
| 2459 last_pc_ = pc_; | |
| 2460 emit(0xD9); | 2300 emit(0xD9); |
| 2461 emit(0xFE); | 2301 emit(0xFE); |
| 2462 } | 2302 } |
| 2463 | 2303 |
| 2464 | 2304 |
| 2465 void Assembler::fyl2x() { | 2305 void Assembler::fyl2x() { |
| 2466 EnsureSpace ensure_space(this); | 2306 EnsureSpace ensure_space(this); |
| 2467 last_pc_ = pc_; | |
| 2468 emit(0xD9); | 2307 emit(0xD9); |
| 2469 emit(0xF1); | 2308 emit(0xF1); |
| 2470 } | 2309 } |
| 2471 | 2310 |
| 2472 | 2311 |
| 2473 void Assembler::fadd(int i) { | 2312 void Assembler::fadd(int i) { |
| 2474 EnsureSpace ensure_space(this); | 2313 EnsureSpace ensure_space(this); |
| 2475 last_pc_ = pc_; | |
| 2476 emit_farith(0xDC, 0xC0, i); | 2314 emit_farith(0xDC, 0xC0, i); |
| 2477 } | 2315 } |
| 2478 | 2316 |
| 2479 | 2317 |
| 2480 void Assembler::fsub(int i) { | 2318 void Assembler::fsub(int i) { |
| 2481 EnsureSpace ensure_space(this); | 2319 EnsureSpace ensure_space(this); |
| 2482 last_pc_ = pc_; | |
| 2483 emit_farith(0xDC, 0xE8, i); | 2320 emit_farith(0xDC, 0xE8, i); |
| 2484 } | 2321 } |
| 2485 | 2322 |
| 2486 | 2323 |
| 2487 void Assembler::fisub_s(const Operand& adr) { | 2324 void Assembler::fisub_s(const Operand& adr) { |
| 2488 EnsureSpace ensure_space(this); | 2325 EnsureSpace ensure_space(this); |
| 2489 last_pc_ = pc_; | |
| 2490 emit_optional_rex_32(adr); | 2326 emit_optional_rex_32(adr); |
| 2491 emit(0xDA); | 2327 emit(0xDA); |
| 2492 emit_operand(4, adr); | 2328 emit_operand(4, adr); |
| 2493 } | 2329 } |
| 2494 | 2330 |
| 2495 | 2331 |
| 2496 void Assembler::fmul(int i) { | 2332 void Assembler::fmul(int i) { |
| 2497 EnsureSpace ensure_space(this); | 2333 EnsureSpace ensure_space(this); |
| 2498 last_pc_ = pc_; | |
| 2499 emit_farith(0xDC, 0xC8, i); | 2334 emit_farith(0xDC, 0xC8, i); |
| 2500 } | 2335 } |
| 2501 | 2336 |
| 2502 | 2337 |
| 2503 void Assembler::fdiv(int i) { | 2338 void Assembler::fdiv(int i) { |
| 2504 EnsureSpace ensure_space(this); | 2339 EnsureSpace ensure_space(this); |
| 2505 last_pc_ = pc_; | |
| 2506 emit_farith(0xDC, 0xF8, i); | 2340 emit_farith(0xDC, 0xF8, i); |
| 2507 } | 2341 } |
| 2508 | 2342 |
| 2509 | 2343 |
| 2510 void Assembler::faddp(int i) { | 2344 void Assembler::faddp(int i) { |
| 2511 EnsureSpace ensure_space(this); | 2345 EnsureSpace ensure_space(this); |
| 2512 last_pc_ = pc_; | |
| 2513 emit_farith(0xDE, 0xC0, i); | 2346 emit_farith(0xDE, 0xC0, i); |
| 2514 } | 2347 } |
| 2515 | 2348 |
| 2516 | 2349 |
| 2517 void Assembler::fsubp(int i) { | 2350 void Assembler::fsubp(int i) { |
| 2518 EnsureSpace ensure_space(this); | 2351 EnsureSpace ensure_space(this); |
| 2519 last_pc_ = pc_; | |
| 2520 emit_farith(0xDE, 0xE8, i); | 2352 emit_farith(0xDE, 0xE8, i); |
| 2521 } | 2353 } |
| 2522 | 2354 |
| 2523 | 2355 |
| 2524 void Assembler::fsubrp(int i) { | 2356 void Assembler::fsubrp(int i) { |
| 2525 EnsureSpace ensure_space(this); | 2357 EnsureSpace ensure_space(this); |
| 2526 last_pc_ = pc_; | |
| 2527 emit_farith(0xDE, 0xE0, i); | 2358 emit_farith(0xDE, 0xE0, i); |
| 2528 } | 2359 } |
| 2529 | 2360 |
| 2530 | 2361 |
| 2531 void Assembler::fmulp(int i) { | 2362 void Assembler::fmulp(int i) { |
| 2532 EnsureSpace ensure_space(this); | 2363 EnsureSpace ensure_space(this); |
| 2533 last_pc_ = pc_; | |
| 2534 emit_farith(0xDE, 0xC8, i); | 2364 emit_farith(0xDE, 0xC8, i); |
| 2535 } | 2365 } |
| 2536 | 2366 |
| 2537 | 2367 |
| 2538 void Assembler::fdivp(int i) { | 2368 void Assembler::fdivp(int i) { |
| 2539 EnsureSpace ensure_space(this); | 2369 EnsureSpace ensure_space(this); |
| 2540 last_pc_ = pc_; | |
| 2541 emit_farith(0xDE, 0xF8, i); | 2370 emit_farith(0xDE, 0xF8, i); |
| 2542 } | 2371 } |
| 2543 | 2372 |
| 2544 | 2373 |
| 2545 void Assembler::fprem() { | 2374 void Assembler::fprem() { |
| 2546 EnsureSpace ensure_space(this); | 2375 EnsureSpace ensure_space(this); |
| 2547 last_pc_ = pc_; | |
| 2548 emit(0xD9); | 2376 emit(0xD9); |
| 2549 emit(0xF8); | 2377 emit(0xF8); |
| 2550 } | 2378 } |
| 2551 | 2379 |
| 2552 | 2380 |
| 2553 void Assembler::fprem1() { | 2381 void Assembler::fprem1() { |
| 2554 EnsureSpace ensure_space(this); | 2382 EnsureSpace ensure_space(this); |
| 2555 last_pc_ = pc_; | |
| 2556 emit(0xD9); | 2383 emit(0xD9); |
| 2557 emit(0xF5); | 2384 emit(0xF5); |
| 2558 } | 2385 } |
| 2559 | 2386 |
| 2560 | 2387 |
| 2561 void Assembler::fxch(int i) { | 2388 void Assembler::fxch(int i) { |
| 2562 EnsureSpace ensure_space(this); | 2389 EnsureSpace ensure_space(this); |
| 2563 last_pc_ = pc_; | |
| 2564 emit_farith(0xD9, 0xC8, i); | 2390 emit_farith(0xD9, 0xC8, i); |
| 2565 } | 2391 } |
| 2566 | 2392 |
| 2567 | 2393 |
| 2568 void Assembler::fincstp() { | 2394 void Assembler::fincstp() { |
| 2569 EnsureSpace ensure_space(this); | 2395 EnsureSpace ensure_space(this); |
| 2570 last_pc_ = pc_; | |
| 2571 emit(0xD9); | 2396 emit(0xD9); |
| 2572 emit(0xF7); | 2397 emit(0xF7); |
| 2573 } | 2398 } |
| 2574 | 2399 |
| 2575 | 2400 |
| 2576 void Assembler::ffree(int i) { | 2401 void Assembler::ffree(int i) { |
| 2577 EnsureSpace ensure_space(this); | 2402 EnsureSpace ensure_space(this); |
| 2578 last_pc_ = pc_; | |
| 2579 emit_farith(0xDD, 0xC0, i); | 2403 emit_farith(0xDD, 0xC0, i); |
| 2580 } | 2404 } |
| 2581 | 2405 |
| 2582 | 2406 |
| 2583 void Assembler::ftst() { | 2407 void Assembler::ftst() { |
| 2584 EnsureSpace ensure_space(this); | 2408 EnsureSpace ensure_space(this); |
| 2585 last_pc_ = pc_; | |
| 2586 emit(0xD9); | 2409 emit(0xD9); |
| 2587 emit(0xE4); | 2410 emit(0xE4); |
| 2588 } | 2411 } |
| 2589 | 2412 |
| 2590 | 2413 |
| 2591 void Assembler::fucomp(int i) { | 2414 void Assembler::fucomp(int i) { |
| 2592 EnsureSpace ensure_space(this); | 2415 EnsureSpace ensure_space(this); |
| 2593 last_pc_ = pc_; | |
| 2594 emit_farith(0xDD, 0xE8, i); | 2416 emit_farith(0xDD, 0xE8, i); |
| 2595 } | 2417 } |
| 2596 | 2418 |
| 2597 | 2419 |
| 2598 void Assembler::fucompp() { | 2420 void Assembler::fucompp() { |
| 2599 EnsureSpace ensure_space(this); | 2421 EnsureSpace ensure_space(this); |
| 2600 last_pc_ = pc_; | |
| 2601 emit(0xDA); | 2422 emit(0xDA); |
| 2602 emit(0xE9); | 2423 emit(0xE9); |
| 2603 } | 2424 } |
| 2604 | 2425 |
| 2605 | 2426 |
| 2606 void Assembler::fucomi(int i) { | 2427 void Assembler::fucomi(int i) { |
| 2607 EnsureSpace ensure_space(this); | 2428 EnsureSpace ensure_space(this); |
| 2608 last_pc_ = pc_; | |
| 2609 emit(0xDB); | 2429 emit(0xDB); |
| 2610 emit(0xE8 + i); | 2430 emit(0xE8 + i); |
| 2611 } | 2431 } |
| 2612 | 2432 |
| 2613 | 2433 |
| 2614 void Assembler::fucomip() { | 2434 void Assembler::fucomip() { |
| 2615 EnsureSpace ensure_space(this); | 2435 EnsureSpace ensure_space(this); |
| 2616 last_pc_ = pc_; | |
| 2617 emit(0xDF); | 2436 emit(0xDF); |
| 2618 emit(0xE9); | 2437 emit(0xE9); |
| 2619 } | 2438 } |
| 2620 | 2439 |
| 2621 | 2440 |
| 2622 void Assembler::fcompp() { | 2441 void Assembler::fcompp() { |
| 2623 EnsureSpace ensure_space(this); | 2442 EnsureSpace ensure_space(this); |
| 2624 last_pc_ = pc_; | |
| 2625 emit(0xDE); | 2443 emit(0xDE); |
| 2626 emit(0xD9); | 2444 emit(0xD9); |
| 2627 } | 2445 } |
| 2628 | 2446 |
| 2629 | 2447 |
| 2630 void Assembler::fnstsw_ax() { | 2448 void Assembler::fnstsw_ax() { |
| 2631 EnsureSpace ensure_space(this); | 2449 EnsureSpace ensure_space(this); |
| 2632 last_pc_ = pc_; | |
| 2633 emit(0xDF); | 2450 emit(0xDF); |
| 2634 emit(0xE0); | 2451 emit(0xE0); |
| 2635 } | 2452 } |
| 2636 | 2453 |
| 2637 | 2454 |
| 2638 void Assembler::fwait() { | 2455 void Assembler::fwait() { |
| 2639 EnsureSpace ensure_space(this); | 2456 EnsureSpace ensure_space(this); |
| 2640 last_pc_ = pc_; | |
| 2641 emit(0x9B); | 2457 emit(0x9B); |
| 2642 } | 2458 } |
| 2643 | 2459 |
| 2644 | 2460 |
| 2645 void Assembler::frndint() { | 2461 void Assembler::frndint() { |
| 2646 EnsureSpace ensure_space(this); | 2462 EnsureSpace ensure_space(this); |
| 2647 last_pc_ = pc_; | |
| 2648 emit(0xD9); | 2463 emit(0xD9); |
| 2649 emit(0xFC); | 2464 emit(0xFC); |
| 2650 } | 2465 } |
| 2651 | 2466 |
| 2652 | 2467 |
| 2653 void Assembler::fnclex() { | 2468 void Assembler::fnclex() { |
| 2654 EnsureSpace ensure_space(this); | 2469 EnsureSpace ensure_space(this); |
| 2655 last_pc_ = pc_; | |
| 2656 emit(0xDB); | 2470 emit(0xDB); |
| 2657 emit(0xE2); | 2471 emit(0xE2); |
| 2658 } | 2472 } |
| 2659 | 2473 |
| 2660 | 2474 |
| 2661 void Assembler::sahf() { | 2475 void Assembler::sahf() { |
| 2662 // TODO(X64): Test for presence. Not all 64-bit intel CPU's have sahf | 2476 // TODO(X64): Test for presence. Not all 64-bit intel CPU's have sahf |
| 2663 // in 64-bit mode. Test CpuID. | 2477 // in 64-bit mode. Test CpuID. |
| 2664 EnsureSpace ensure_space(this); | 2478 EnsureSpace ensure_space(this); |
| 2665 last_pc_ = pc_; | |
| 2666 emit(0x9E); | 2479 emit(0x9E); |
| 2667 } | 2480 } |
| 2668 | 2481 |
| 2669 | 2482 |
| 2670 void Assembler::emit_farith(int b1, int b2, int i) { | 2483 void Assembler::emit_farith(int b1, int b2, int i) { |
| 2671 ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode | 2484 ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode |
| 2672 ASSERT(is_uint3(i)); // illegal stack offset | 2485 ASSERT(is_uint3(i)); // illegal stack offset |
| 2673 emit(b1); | 2486 emit(b1); |
| 2674 emit(b2 + i); | 2487 emit(b2 + i); |
| 2675 } | 2488 } |
| 2676 | 2489 |
| 2677 // SSE 2 operations. | 2490 // SSE 2 operations. |
| 2678 | 2491 |
| 2679 void Assembler::movd(XMMRegister dst, Register src) { | 2492 void Assembler::movd(XMMRegister dst, Register src) { |
| 2680 EnsureSpace ensure_space(this); | 2493 EnsureSpace ensure_space(this); |
| 2681 last_pc_ = pc_; | |
| 2682 emit(0x66); | 2494 emit(0x66); |
| 2683 emit_optional_rex_32(dst, src); | 2495 emit_optional_rex_32(dst, src); |
| 2684 emit(0x0F); | 2496 emit(0x0F); |
| 2685 emit(0x6E); | 2497 emit(0x6E); |
| 2686 emit_sse_operand(dst, src); | 2498 emit_sse_operand(dst, src); |
| 2687 } | 2499 } |
| 2688 | 2500 |
| 2689 | 2501 |
| 2690 void Assembler::movd(Register dst, XMMRegister src) { | 2502 void Assembler::movd(Register dst, XMMRegister src) { |
| 2691 EnsureSpace ensure_space(this); | 2503 EnsureSpace ensure_space(this); |
| 2692 last_pc_ = pc_; | |
| 2693 emit(0x66); | 2504 emit(0x66); |
| 2694 emit_optional_rex_32(src, dst); | 2505 emit_optional_rex_32(src, dst); |
| 2695 emit(0x0F); | 2506 emit(0x0F); |
| 2696 emit(0x7E); | 2507 emit(0x7E); |
| 2697 emit_sse_operand(src, dst); | 2508 emit_sse_operand(src, dst); |
| 2698 } | 2509 } |
| 2699 | 2510 |
| 2700 | 2511 |
| 2701 void Assembler::movq(XMMRegister dst, Register src) { | 2512 void Assembler::movq(XMMRegister dst, Register src) { |
| 2702 EnsureSpace ensure_space(this); | 2513 EnsureSpace ensure_space(this); |
| 2703 last_pc_ = pc_; | |
| 2704 emit(0x66); | 2514 emit(0x66); |
| 2705 emit_rex_64(dst, src); | 2515 emit_rex_64(dst, src); |
| 2706 emit(0x0F); | 2516 emit(0x0F); |
| 2707 emit(0x6E); | 2517 emit(0x6E); |
| 2708 emit_sse_operand(dst, src); | 2518 emit_sse_operand(dst, src); |
| 2709 } | 2519 } |
| 2710 | 2520 |
| 2711 | 2521 |
| 2712 void Assembler::movq(Register dst, XMMRegister src) { | 2522 void Assembler::movq(Register dst, XMMRegister src) { |
| 2713 EnsureSpace ensure_space(this); | 2523 EnsureSpace ensure_space(this); |
| 2714 last_pc_ = pc_; | |
| 2715 emit(0x66); | 2524 emit(0x66); |
| 2716 emit_rex_64(src, dst); | 2525 emit_rex_64(src, dst); |
| 2717 emit(0x0F); | 2526 emit(0x0F); |
| 2718 emit(0x7E); | 2527 emit(0x7E); |
| 2719 emit_sse_operand(src, dst); | 2528 emit_sse_operand(src, dst); |
| 2720 } | 2529 } |
| 2721 | 2530 |
| 2722 | 2531 |
| 2723 void Assembler::movdqa(const Operand& dst, XMMRegister src) { | 2532 void Assembler::movdqa(const Operand& dst, XMMRegister src) { |
| 2724 ASSERT(CpuFeatures::IsEnabled(SSE2)); | |
| 2725 EnsureSpace ensure_space(this); | 2533 EnsureSpace ensure_space(this); |
| 2726 last_pc_ = pc_; | |
| 2727 emit(0x66); | 2534 emit(0x66); |
| 2728 emit_rex_64(src, dst); | 2535 emit_rex_64(src, dst); |
| 2729 emit(0x0F); | 2536 emit(0x0F); |
| 2730 emit(0x7F); | 2537 emit(0x7F); |
| 2731 emit_sse_operand(src, dst); | 2538 emit_sse_operand(src, dst); |
| 2732 } | 2539 } |
| 2733 | 2540 |
| 2734 | 2541 |
| 2735 void Assembler::movdqa(XMMRegister dst, const Operand& src) { | 2542 void Assembler::movdqa(XMMRegister dst, const Operand& src) { |
| 2736 ASSERT(CpuFeatures::IsEnabled(SSE2)); | |
| 2737 EnsureSpace ensure_space(this); | 2543 EnsureSpace ensure_space(this); |
| 2738 last_pc_ = pc_; | |
| 2739 emit(0x66); | 2544 emit(0x66); |
| 2740 emit_rex_64(dst, src); | 2545 emit_rex_64(dst, src); |
| 2741 emit(0x0F); | 2546 emit(0x0F); |
| 2742 emit(0x6F); | 2547 emit(0x6F); |
| 2743 emit_sse_operand(dst, src); | 2548 emit_sse_operand(dst, src); |
| 2744 } | 2549 } |
| 2745 | 2550 |
| 2746 | 2551 |
| 2747 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) { | 2552 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) { |
| 2748 ASSERT(is_uint2(imm8)); | 2553 ASSERT(is_uint2(imm8)); |
| 2749 EnsureSpace ensure_space(this); | 2554 EnsureSpace ensure_space(this); |
| 2750 last_pc_ = pc_; | |
| 2751 emit(0x66); | 2555 emit(0x66); |
| 2752 emit_optional_rex_32(dst, src); | 2556 emit_optional_rex_32(dst, src); |
| 2753 emit(0x0F); | 2557 emit(0x0F); |
| 2754 emit(0x3A); | 2558 emit(0x3A); |
| 2755 emit(0x17); | 2559 emit(0x17); |
| 2756 emit_sse_operand(dst, src); | 2560 emit_sse_operand(dst, src); |
| 2757 emit(imm8); | 2561 emit(imm8); |
| 2758 } | 2562 } |
| 2759 | 2563 |
| 2760 | 2564 |
| 2761 void Assembler::movsd(const Operand& dst, XMMRegister src) { | 2565 void Assembler::movsd(const Operand& dst, XMMRegister src) { |
| 2762 EnsureSpace ensure_space(this); | 2566 EnsureSpace ensure_space(this); |
| 2763 last_pc_ = pc_; | |
| 2764 emit(0xF2); // double | 2567 emit(0xF2); // double |
| 2765 emit_optional_rex_32(src, dst); | 2568 emit_optional_rex_32(src, dst); |
| 2766 emit(0x0F); | 2569 emit(0x0F); |
| 2767 emit(0x11); // store | 2570 emit(0x11); // store |
| 2768 emit_sse_operand(src, dst); | 2571 emit_sse_operand(src, dst); |
| 2769 } | 2572 } |
| 2770 | 2573 |
| 2771 | 2574 |
| 2772 void Assembler::movsd(XMMRegister dst, XMMRegister src) { | 2575 void Assembler::movsd(XMMRegister dst, XMMRegister src) { |
| 2773 EnsureSpace ensure_space(this); | 2576 EnsureSpace ensure_space(this); |
| 2774 last_pc_ = pc_; | |
| 2775 emit(0xF2); // double | 2577 emit(0xF2); // double |
| 2776 emit_optional_rex_32(dst, src); | 2578 emit_optional_rex_32(dst, src); |
| 2777 emit(0x0F); | 2579 emit(0x0F); |
| 2778 emit(0x10); // load | 2580 emit(0x10); // load |
| 2779 emit_sse_operand(dst, src); | 2581 emit_sse_operand(dst, src); |
| 2780 } | 2582 } |
| 2781 | 2583 |
| 2782 | 2584 |
| 2783 void Assembler::movsd(XMMRegister dst, const Operand& src) { | 2585 void Assembler::movsd(XMMRegister dst, const Operand& src) { |
| 2784 EnsureSpace ensure_space(this); | 2586 EnsureSpace ensure_space(this); |
| 2785 last_pc_ = pc_; | |
| 2786 emit(0xF2); // double | 2587 emit(0xF2); // double |
| 2787 emit_optional_rex_32(dst, src); | 2588 emit_optional_rex_32(dst, src); |
| 2788 emit(0x0F); | 2589 emit(0x0F); |
| 2789 emit(0x10); // load | 2590 emit(0x10); // load |
| 2790 emit_sse_operand(dst, src); | 2591 emit_sse_operand(dst, src); |
| 2791 } | 2592 } |
| 2792 | 2593 |
| 2793 | 2594 |
| 2794 void Assembler::movss(XMMRegister dst, const Operand& src) { | 2595 void Assembler::movss(XMMRegister dst, const Operand& src) { |
| 2795 EnsureSpace ensure_space(this); | 2596 EnsureSpace ensure_space(this); |
| 2796 last_pc_ = pc_; | |
| 2797 emit(0xF3); // single | 2597 emit(0xF3); // single |
| 2798 emit_optional_rex_32(dst, src); | 2598 emit_optional_rex_32(dst, src); |
| 2799 emit(0x0F); | 2599 emit(0x0F); |
| 2800 emit(0x10); // load | 2600 emit(0x10); // load |
| 2801 emit_sse_operand(dst, src); | 2601 emit_sse_operand(dst, src); |
| 2802 } | 2602 } |
| 2803 | 2603 |
| 2804 | 2604 |
| 2805 void Assembler::movss(const Operand& src, XMMRegister dst) { | 2605 void Assembler::movss(const Operand& src, XMMRegister dst) { |
| 2806 EnsureSpace ensure_space(this); | 2606 EnsureSpace ensure_space(this); |
| 2807 last_pc_ = pc_; | |
| 2808 emit(0xF3); // single | 2607 emit(0xF3); // single |
| 2809 emit_optional_rex_32(dst, src); | 2608 emit_optional_rex_32(dst, src); |
| 2810 emit(0x0F); | 2609 emit(0x0F); |
| 2811 emit(0x11); // store | 2610 emit(0x11); // store |
| 2812 emit_sse_operand(dst, src); | 2611 emit_sse_operand(dst, src); |
| 2813 } | 2612 } |
| 2814 | 2613 |
| 2815 | 2614 |
| 2816 void Assembler::cvttss2si(Register dst, const Operand& src) { | 2615 void Assembler::cvttss2si(Register dst, const Operand& src) { |
| 2817 EnsureSpace ensure_space(this); | 2616 EnsureSpace ensure_space(this); |
| 2818 last_pc_ = pc_; | |
| 2819 emit(0xF3); | 2617 emit(0xF3); |
| 2820 emit_optional_rex_32(dst, src); | 2618 emit_optional_rex_32(dst, src); |
| 2821 emit(0x0F); | 2619 emit(0x0F); |
| 2822 emit(0x2C); | 2620 emit(0x2C); |
| 2823 emit_operand(dst, src); | 2621 emit_operand(dst, src); |
| 2824 } | 2622 } |
| 2825 | 2623 |
| 2826 | 2624 |
| 2827 void Assembler::cvttss2si(Register dst, XMMRegister src) { | 2625 void Assembler::cvttss2si(Register dst, XMMRegister src) { |
| 2828 EnsureSpace ensure_space(this); | 2626 EnsureSpace ensure_space(this); |
| 2829 last_pc_ = pc_; | |
| 2830 emit(0xF3); | 2627 emit(0xF3); |
| 2831 emit_optional_rex_32(dst, src); | 2628 emit_optional_rex_32(dst, src); |
| 2832 emit(0x0F); | 2629 emit(0x0F); |
| 2833 emit(0x2C); | 2630 emit(0x2C); |
| 2834 emit_sse_operand(dst, src); | 2631 emit_sse_operand(dst, src); |
| 2835 } | 2632 } |
| 2836 | 2633 |
| 2837 | 2634 |
| 2838 void Assembler::cvttsd2si(Register dst, const Operand& src) { | 2635 void Assembler::cvttsd2si(Register dst, const Operand& src) { |
| 2839 EnsureSpace ensure_space(this); | 2636 EnsureSpace ensure_space(this); |
| 2840 last_pc_ = pc_; | |
| 2841 emit(0xF2); | 2637 emit(0xF2); |
| 2842 emit_optional_rex_32(dst, src); | 2638 emit_optional_rex_32(dst, src); |
| 2843 emit(0x0F); | 2639 emit(0x0F); |
| 2844 emit(0x2C); | 2640 emit(0x2C); |
| 2845 emit_operand(dst, src); | 2641 emit_operand(dst, src); |
| 2846 } | 2642 } |
| 2847 | 2643 |
| 2848 | 2644 |
| 2849 void Assembler::cvttsd2si(Register dst, XMMRegister src) { | 2645 void Assembler::cvttsd2si(Register dst, XMMRegister src) { |
| 2850 EnsureSpace ensure_space(this); | 2646 EnsureSpace ensure_space(this); |
| 2851 last_pc_ = pc_; | |
| 2852 emit(0xF2); | 2647 emit(0xF2); |
| 2853 emit_optional_rex_32(dst, src); | 2648 emit_optional_rex_32(dst, src); |
| 2854 emit(0x0F); | 2649 emit(0x0F); |
| 2855 emit(0x2C); | 2650 emit(0x2C); |
| 2856 emit_sse_operand(dst, src); | 2651 emit_sse_operand(dst, src); |
| 2857 } | 2652 } |
| 2858 | 2653 |
| 2859 | 2654 |
| 2860 void Assembler::cvttsd2siq(Register dst, XMMRegister src) { | 2655 void Assembler::cvttsd2siq(Register dst, XMMRegister src) { |
| 2861 EnsureSpace ensure_space(this); | 2656 EnsureSpace ensure_space(this); |
| 2862 last_pc_ = pc_; | |
| 2863 emit(0xF2); | 2657 emit(0xF2); |
| 2864 emit_rex_64(dst, src); | 2658 emit_rex_64(dst, src); |
| 2865 emit(0x0F); | 2659 emit(0x0F); |
| 2866 emit(0x2C); | 2660 emit(0x2C); |
| 2867 emit_sse_operand(dst, src); | 2661 emit_sse_operand(dst, src); |
| 2868 } | 2662 } |
| 2869 | 2663 |
| 2870 | 2664 |
| 2871 void Assembler::cvtlsi2sd(XMMRegister dst, const Operand& src) { | 2665 void Assembler::cvtlsi2sd(XMMRegister dst, const Operand& src) { |
| 2872 EnsureSpace ensure_space(this); | 2666 EnsureSpace ensure_space(this); |
| 2873 last_pc_ = pc_; | |
| 2874 emit(0xF2); | 2667 emit(0xF2); |
| 2875 emit_optional_rex_32(dst, src); | 2668 emit_optional_rex_32(dst, src); |
| 2876 emit(0x0F); | 2669 emit(0x0F); |
| 2877 emit(0x2A); | 2670 emit(0x2A); |
| 2878 emit_sse_operand(dst, src); | 2671 emit_sse_operand(dst, src); |
| 2879 } | 2672 } |
| 2880 | 2673 |
| 2881 | 2674 |
| 2882 void Assembler::cvtlsi2sd(XMMRegister dst, Register src) { | 2675 void Assembler::cvtlsi2sd(XMMRegister dst, Register src) { |
| 2883 EnsureSpace ensure_space(this); | 2676 EnsureSpace ensure_space(this); |
| 2884 last_pc_ = pc_; | |
| 2885 emit(0xF2); | 2677 emit(0xF2); |
| 2886 emit_optional_rex_32(dst, src); | 2678 emit_optional_rex_32(dst, src); |
| 2887 emit(0x0F); | 2679 emit(0x0F); |
| 2888 emit(0x2A); | 2680 emit(0x2A); |
| 2889 emit_sse_operand(dst, src); | 2681 emit_sse_operand(dst, src); |
| 2890 } | 2682 } |
| 2891 | 2683 |
| 2892 | 2684 |
| 2893 void Assembler::cvtlsi2ss(XMMRegister dst, Register src) { | 2685 void Assembler::cvtlsi2ss(XMMRegister dst, Register src) { |
| 2894 EnsureSpace ensure_space(this); | 2686 EnsureSpace ensure_space(this); |
| 2895 last_pc_ = pc_; | |
| 2896 emit(0xF3); | 2687 emit(0xF3); |
| 2897 emit_optional_rex_32(dst, src); | 2688 emit_optional_rex_32(dst, src); |
| 2898 emit(0x0F); | 2689 emit(0x0F); |
| 2899 emit(0x2A); | 2690 emit(0x2A); |
| 2900 emit_sse_operand(dst, src); | 2691 emit_sse_operand(dst, src); |
| 2901 } | 2692 } |
| 2902 | 2693 |
| 2903 | 2694 |
| 2904 void Assembler::cvtqsi2sd(XMMRegister dst, Register src) { | 2695 void Assembler::cvtqsi2sd(XMMRegister dst, Register src) { |
| 2905 EnsureSpace ensure_space(this); | 2696 EnsureSpace ensure_space(this); |
| 2906 last_pc_ = pc_; | |
| 2907 emit(0xF2); | 2697 emit(0xF2); |
| 2908 emit_rex_64(dst, src); | 2698 emit_rex_64(dst, src); |
| 2909 emit(0x0F); | 2699 emit(0x0F); |
| 2910 emit(0x2A); | 2700 emit(0x2A); |
| 2911 emit_sse_operand(dst, src); | 2701 emit_sse_operand(dst, src); |
| 2912 } | 2702 } |
| 2913 | 2703 |
| 2914 | 2704 |
| 2915 void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) { | 2705 void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) { |
| 2916 EnsureSpace ensure_space(this); | 2706 EnsureSpace ensure_space(this); |
| 2917 last_pc_ = pc_; | |
| 2918 emit(0xF3); | 2707 emit(0xF3); |
| 2919 emit_optional_rex_32(dst, src); | 2708 emit_optional_rex_32(dst, src); |
| 2920 emit(0x0F); | 2709 emit(0x0F); |
| 2921 emit(0x5A); | 2710 emit(0x5A); |
| 2922 emit_sse_operand(dst, src); | 2711 emit_sse_operand(dst, src); |
| 2923 } | 2712 } |
| 2924 | 2713 |
| 2925 | 2714 |
| 2926 void Assembler::cvtss2sd(XMMRegister dst, const Operand& src) { | 2715 void Assembler::cvtss2sd(XMMRegister dst, const Operand& src) { |
| 2927 EnsureSpace ensure_space(this); | 2716 EnsureSpace ensure_space(this); |
| 2928 last_pc_ = pc_; | |
| 2929 emit(0xF3); | 2717 emit(0xF3); |
| 2930 emit_optional_rex_32(dst, src); | 2718 emit_optional_rex_32(dst, src); |
| 2931 emit(0x0F); | 2719 emit(0x0F); |
| 2932 emit(0x5A); | 2720 emit(0x5A); |
| 2933 emit_sse_operand(dst, src); | 2721 emit_sse_operand(dst, src); |
| 2934 } | 2722 } |
| 2935 | 2723 |
| 2936 | 2724 |
| 2937 void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) { | 2725 void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) { |
| 2938 EnsureSpace ensure_space(this); | 2726 EnsureSpace ensure_space(this); |
| 2939 last_pc_ = pc_; | |
| 2940 emit(0xF2); | 2727 emit(0xF2); |
| 2941 emit_optional_rex_32(dst, src); | 2728 emit_optional_rex_32(dst, src); |
| 2942 emit(0x0F); | 2729 emit(0x0F); |
| 2943 emit(0x5A); | 2730 emit(0x5A); |
| 2944 emit_sse_operand(dst, src); | 2731 emit_sse_operand(dst, src); |
| 2945 } | 2732 } |
| 2946 | 2733 |
| 2947 | 2734 |
| 2948 void Assembler::cvtsd2si(Register dst, XMMRegister src) { | 2735 void Assembler::cvtsd2si(Register dst, XMMRegister src) { |
| 2949 EnsureSpace ensure_space(this); | 2736 EnsureSpace ensure_space(this); |
| 2950 last_pc_ = pc_; | |
| 2951 emit(0xF2); | 2737 emit(0xF2); |
| 2952 emit_optional_rex_32(dst, src); | 2738 emit_optional_rex_32(dst, src); |
| 2953 emit(0x0F); | 2739 emit(0x0F); |
| 2954 emit(0x2D); | 2740 emit(0x2D); |
| 2955 emit_sse_operand(dst, src); | 2741 emit_sse_operand(dst, src); |
| 2956 } | 2742 } |
| 2957 | 2743 |
| 2958 | 2744 |
| 2959 void Assembler::cvtsd2siq(Register dst, XMMRegister src) { | 2745 void Assembler::cvtsd2siq(Register dst, XMMRegister src) { |
| 2960 EnsureSpace ensure_space(this); | 2746 EnsureSpace ensure_space(this); |
| 2961 last_pc_ = pc_; | |
| 2962 emit(0xF2); | 2747 emit(0xF2); |
| 2963 emit_rex_64(dst, src); | 2748 emit_rex_64(dst, src); |
| 2964 emit(0x0F); | 2749 emit(0x0F); |
| 2965 emit(0x2D); | 2750 emit(0x2D); |
| 2966 emit_sse_operand(dst, src); | 2751 emit_sse_operand(dst, src); |
| 2967 } | 2752 } |
| 2968 | 2753 |
| 2969 | 2754 |
| 2970 void Assembler::addsd(XMMRegister dst, XMMRegister src) { | 2755 void Assembler::addsd(XMMRegister dst, XMMRegister src) { |
| 2971 EnsureSpace ensure_space(this); | 2756 EnsureSpace ensure_space(this); |
| 2972 last_pc_ = pc_; | |
| 2973 emit(0xF2); | 2757 emit(0xF2); |
| 2974 emit_optional_rex_32(dst, src); | 2758 emit_optional_rex_32(dst, src); |
| 2975 emit(0x0F); | 2759 emit(0x0F); |
| 2976 emit(0x58); | 2760 emit(0x58); |
| 2977 emit_sse_operand(dst, src); | 2761 emit_sse_operand(dst, src); |
| 2978 } | 2762 } |
| 2979 | 2763 |
| 2980 | 2764 |
| 2981 void Assembler::mulsd(XMMRegister dst, XMMRegister src) { | 2765 void Assembler::mulsd(XMMRegister dst, XMMRegister src) { |
| 2982 EnsureSpace ensure_space(this); | 2766 EnsureSpace ensure_space(this); |
| 2983 last_pc_ = pc_; | |
| 2984 emit(0xF2); | 2767 emit(0xF2); |
| 2985 emit_optional_rex_32(dst, src); | 2768 emit_optional_rex_32(dst, src); |
| 2986 emit(0x0F); | 2769 emit(0x0F); |
| 2987 emit(0x59); | 2770 emit(0x59); |
| 2988 emit_sse_operand(dst, src); | 2771 emit_sse_operand(dst, src); |
| 2989 } | 2772 } |
| 2990 | 2773 |
| 2991 | 2774 |
| 2992 void Assembler::subsd(XMMRegister dst, XMMRegister src) { | 2775 void Assembler::subsd(XMMRegister dst, XMMRegister src) { |
| 2993 EnsureSpace ensure_space(this); | 2776 EnsureSpace ensure_space(this); |
| 2994 last_pc_ = pc_; | |
| 2995 emit(0xF2); | 2777 emit(0xF2); |
| 2996 emit_optional_rex_32(dst, src); | 2778 emit_optional_rex_32(dst, src); |
| 2997 emit(0x0F); | 2779 emit(0x0F); |
| 2998 emit(0x5C); | 2780 emit(0x5C); |
| 2999 emit_sse_operand(dst, src); | 2781 emit_sse_operand(dst, src); |
| 3000 } | 2782 } |
| 3001 | 2783 |
| 3002 | 2784 |
| 3003 void Assembler::divsd(XMMRegister dst, XMMRegister src) { | 2785 void Assembler::divsd(XMMRegister dst, XMMRegister src) { |
| 3004 EnsureSpace ensure_space(this); | 2786 EnsureSpace ensure_space(this); |
| 3005 last_pc_ = pc_; | |
| 3006 emit(0xF2); | 2787 emit(0xF2); |
| 3007 emit_optional_rex_32(dst, src); | 2788 emit_optional_rex_32(dst, src); |
| 3008 emit(0x0F); | 2789 emit(0x0F); |
| 3009 emit(0x5E); | 2790 emit(0x5E); |
| 3010 emit_sse_operand(dst, src); | 2791 emit_sse_operand(dst, src); |
| 3011 } | 2792 } |
| 3012 | 2793 |
| 3013 | 2794 |
| 3014 void Assembler::andpd(XMMRegister dst, XMMRegister src) { | 2795 void Assembler::andpd(XMMRegister dst, XMMRegister src) { |
| 3015 EnsureSpace ensure_space(this); | 2796 EnsureSpace ensure_space(this); |
| 3016 last_pc_ = pc_; | |
| 3017 emit(0x66); | 2797 emit(0x66); |
| 3018 emit_optional_rex_32(dst, src); | 2798 emit_optional_rex_32(dst, src); |
| 3019 emit(0x0F); | 2799 emit(0x0F); |
| 3020 emit(0x54); | 2800 emit(0x54); |
| 3021 emit_sse_operand(dst, src); | 2801 emit_sse_operand(dst, src); |
| 3022 } | 2802 } |
| 3023 | 2803 |
| 3024 | 2804 |
| 3025 void Assembler::orpd(XMMRegister dst, XMMRegister src) { | 2805 void Assembler::orpd(XMMRegister dst, XMMRegister src) { |
| 3026 EnsureSpace ensure_space(this); | 2806 EnsureSpace ensure_space(this); |
| 3027 last_pc_ = pc_; | |
| 3028 emit(0x66); | 2807 emit(0x66); |
| 3029 emit_optional_rex_32(dst, src); | 2808 emit_optional_rex_32(dst, src); |
| 3030 emit(0x0F); | 2809 emit(0x0F); |
| 3031 emit(0x56); | 2810 emit(0x56); |
| 3032 emit_sse_operand(dst, src); | 2811 emit_sse_operand(dst, src); |
| 3033 } | 2812 } |
| 3034 | 2813 |
| 3035 | 2814 |
| 3036 void Assembler::xorpd(XMMRegister dst, XMMRegister src) { | 2815 void Assembler::xorpd(XMMRegister dst, XMMRegister src) { |
| 3037 EnsureSpace ensure_space(this); | 2816 EnsureSpace ensure_space(this); |
| 3038 last_pc_ = pc_; | |
| 3039 emit(0x66); | 2817 emit(0x66); |
| 3040 emit_optional_rex_32(dst, src); | 2818 emit_optional_rex_32(dst, src); |
| 3041 emit(0x0F); | 2819 emit(0x0F); |
| 3042 emit(0x57); | 2820 emit(0x57); |
| 3043 emit_sse_operand(dst, src); | 2821 emit_sse_operand(dst, src); |
| 3044 } | 2822 } |
| 3045 | 2823 |
| 3046 | 2824 |
| 3047 void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) { | 2825 void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) { |
| 3048 EnsureSpace ensure_space(this); | 2826 EnsureSpace ensure_space(this); |
| 3049 last_pc_ = pc_; | |
| 3050 emit(0xF2); | 2827 emit(0xF2); |
| 3051 emit_optional_rex_32(dst, src); | 2828 emit_optional_rex_32(dst, src); |
| 3052 emit(0x0F); | 2829 emit(0x0F); |
| 3053 emit(0x51); | 2830 emit(0x51); |
| 3054 emit_sse_operand(dst, src); | 2831 emit_sse_operand(dst, src); |
| 3055 } | 2832 } |
| 3056 | 2833 |
| 3057 | 2834 |
| 3058 void Assembler::ucomisd(XMMRegister dst, XMMRegister src) { | 2835 void Assembler::ucomisd(XMMRegister dst, XMMRegister src) { |
| 3059 EnsureSpace ensure_space(this); | 2836 EnsureSpace ensure_space(this); |
| 3060 last_pc_ = pc_; | |
| 3061 emit(0x66); | 2837 emit(0x66); |
| 3062 emit_optional_rex_32(dst, src); | 2838 emit_optional_rex_32(dst, src); |
| 3063 emit(0x0f); | 2839 emit(0x0f); |
| 3064 emit(0x2e); | 2840 emit(0x2e); |
| 3065 emit_sse_operand(dst, src); | 2841 emit_sse_operand(dst, src); |
| 3066 } | 2842 } |
| 3067 | 2843 |
| 3068 | 2844 |
| 3069 void Assembler::ucomisd(XMMRegister dst, const Operand& src) { | 2845 void Assembler::ucomisd(XMMRegister dst, const Operand& src) { |
| 3070 EnsureSpace ensure_space(this); | 2846 EnsureSpace ensure_space(this); |
| 3071 last_pc_ = pc_; | |
| 3072 emit(0x66); | 2847 emit(0x66); |
| 3073 emit_optional_rex_32(dst, src); | 2848 emit_optional_rex_32(dst, src); |
| 3074 emit(0x0f); | 2849 emit(0x0f); |
| 3075 emit(0x2e); | 2850 emit(0x2e); |
| 3076 emit_sse_operand(dst, src); | 2851 emit_sse_operand(dst, src); |
| 3077 } | 2852 } |
| 3078 | 2853 |
| 3079 | 2854 |
| 3080 void Assembler::movmskpd(Register dst, XMMRegister src) { | 2855 void Assembler::movmskpd(Register dst, XMMRegister src) { |
| 3081 EnsureSpace ensure_space(this); | 2856 EnsureSpace ensure_space(this); |
| 3082 last_pc_ = pc_; | |
| 3083 emit(0x66); | 2857 emit(0x66); |
| 3084 emit_optional_rex_32(dst, src); | 2858 emit_optional_rex_32(dst, src); |
| 3085 emit(0x0f); | 2859 emit(0x0f); |
| 3086 emit(0x50); | 2860 emit(0x50); |
| 3087 emit_sse_operand(dst, src); | 2861 emit_sse_operand(dst, src); |
| 3088 } | 2862 } |
| 3089 | 2863 |
| 3090 | 2864 |
| 3091 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { | 2865 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { |
| 3092 Register ireg = { reg.code() }; | 2866 Register ireg = { reg.code() }; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3169 // specially coded on x64 means that it is a relative 32 bit address, as used | 2943 // specially coded on x64 means that it is a relative 32 bit address, as used |
| 3170 // by branch instructions. | 2944 // by branch instructions. |
| 3171 return (1 << rmode_) & kApplyMask; | 2945 return (1 << rmode_) & kApplyMask; |
| 3172 } | 2946 } |
| 3173 | 2947 |
| 3174 | 2948 |
| 3175 | 2949 |
| 3176 } } // namespace v8::internal | 2950 } } // namespace v8::internal |
| 3177 | 2951 |
| 3178 #endif // V8_TARGET_ARCH_X64 | 2952 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |