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