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