Revision 379f6698 tcg/x86_64/tcg-target.c
b/tcg/x86_64/tcg-target.c | ||
---|---|---|
508 | 508 |
int opc) |
509 | 509 |
{ |
510 | 510 |
int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, rexw; |
511 |
int32_t offset; |
|
511 | 512 |
#if defined(CONFIG_SOFTMMU) |
512 | 513 |
uint8_t *label1_ptr, *label2_ptr; |
513 | 514 |
#endif |
... | ... | |
604 | 605 |
/* add x(r1), r0 */ |
605 | 606 |
tcg_out_modrm_offset(s, 0x03 | P_REXW, r0, r1, offsetof(CPUTLBEntry, addend) - |
606 | 607 |
offsetof(CPUTLBEntry, addr_read)); |
608 |
offset = 0; |
|
607 | 609 |
#else |
608 |
r0 = addr_reg; |
|
610 |
if (GUEST_BASE == (int32_t)GUEST_BASE) { |
|
611 |
r0 = addr_reg; |
|
612 |
offset = GUEST_BASE; |
|
613 |
} else { |
|
614 |
offset = 0; |
|
615 |
/* movq $GUEST_BASE, r0 */ |
|
616 |
tcg_out_opc(s, (0xb8 + (r0 & 7)) | P_REXW, 0, r0, 0); |
|
617 |
tcg_out32(s, GUEST_BASE); |
|
618 |
tcg_out32(s, GUEST_BASE >> 32); |
|
619 |
/* addq addr_reg, r0 */ |
|
620 |
tcg_out_modrm(s, 0x01 | P_REXW, addr_reg, r0); |
|
621 |
} |
|
609 | 622 |
#endif |
610 | 623 |
|
611 | 624 |
#ifdef TARGET_WORDS_BIGENDIAN |
... | ... | |
616 | 629 |
switch(opc) { |
617 | 630 |
case 0: |
618 | 631 |
/* movzbl */ |
619 |
tcg_out_modrm_offset(s, 0xb6 | P_EXT, data_reg, r0, 0);
|
|
632 |
tcg_out_modrm_offset(s, 0xb6 | P_EXT, data_reg, r0, offset);
|
|
620 | 633 |
break; |
621 | 634 |
case 0 | 4: |
622 | 635 |
/* movsbX */ |
623 |
tcg_out_modrm_offset(s, 0xbe | P_EXT | rexw, data_reg, r0, 0);
|
|
636 |
tcg_out_modrm_offset(s, 0xbe | P_EXT | rexw, data_reg, r0, offset);
|
|
624 | 637 |
break; |
625 | 638 |
case 1: |
626 | 639 |
/* movzwl */ |
627 |
tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0);
|
|
640 |
tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, offset);
|
|
628 | 641 |
if (bswap) { |
629 | 642 |
/* rolw $8, data_reg */ |
630 | 643 |
tcg_out8(s, 0x66); |
... | ... | |
635 | 648 |
case 1 | 4: |
636 | 649 |
if (bswap) { |
637 | 650 |
/* movzwl */ |
638 |
tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0);
|
|
651 |
tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, offset);
|
|
639 | 652 |
/* rolw $8, data_reg */ |
640 | 653 |
tcg_out8(s, 0x66); |
641 | 654 |
tcg_out_modrm(s, 0xc1, 0, data_reg); |
... | ... | |
645 | 658 |
tcg_out_modrm(s, 0xbf | P_EXT | rexw, data_reg, data_reg); |
646 | 659 |
} else { |
647 | 660 |
/* movswX */ |
648 |
tcg_out_modrm_offset(s, 0xbf | P_EXT | rexw, data_reg, r0, 0);
|
|
661 |
tcg_out_modrm_offset(s, 0xbf | P_EXT | rexw, data_reg, r0, offset);
|
|
649 | 662 |
} |
650 | 663 |
break; |
651 | 664 |
case 2: |
652 | 665 |
/* movl (r0), data_reg */ |
653 |
tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
|
|
666 |
tcg_out_modrm_offset(s, 0x8b, data_reg, r0, offset);
|
|
654 | 667 |
if (bswap) { |
655 | 668 |
/* bswap */ |
656 | 669 |
tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT, 0, data_reg, 0); |
... | ... | |
659 | 672 |
case 2 | 4: |
660 | 673 |
if (bswap) { |
661 | 674 |
/* movl (r0), data_reg */ |
662 |
tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
|
|
675 |
tcg_out_modrm_offset(s, 0x8b, data_reg, r0, offset);
|
|
663 | 676 |
/* bswap */ |
664 | 677 |
tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT, 0, data_reg, 0); |
665 | 678 |
/* movslq */ |
666 | 679 |
tcg_out_modrm(s, 0x63 | P_REXW, data_reg, data_reg); |
667 | 680 |
} else { |
668 | 681 |
/* movslq */ |
669 |
tcg_out_modrm_offset(s, 0x63 | P_REXW, data_reg, r0, 0);
|
|
682 |
tcg_out_modrm_offset(s, 0x63 | P_REXW, data_reg, r0, offset);
|
|
670 | 683 |
} |
671 | 684 |
break; |
672 | 685 |
case 3: |
673 | 686 |
/* movq (r0), data_reg */ |
674 |
tcg_out_modrm_offset(s, 0x8b | P_REXW, data_reg, r0, 0);
|
|
687 |
tcg_out_modrm_offset(s, 0x8b | P_REXW, data_reg, r0, offset);
|
|
675 | 688 |
if (bswap) { |
676 | 689 |
/* bswap */ |
677 | 690 |
tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT | P_REXW, 0, data_reg, 0); |
... | ... | |
691 | 704 |
int opc) |
692 | 705 |
{ |
693 | 706 |
int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, rexw; |
707 |
int32_t offset; |
|
694 | 708 |
#if defined(CONFIG_SOFTMMU) |
695 | 709 |
uint8_t *label1_ptr, *label2_ptr; |
696 | 710 |
#endif |
... | ... | |
775 | 789 |
/* add x(r1), r0 */ |
776 | 790 |
tcg_out_modrm_offset(s, 0x03 | P_REXW, r0, r1, offsetof(CPUTLBEntry, addend) - |
777 | 791 |
offsetof(CPUTLBEntry, addr_write)); |
792 |
offset = 0; |
|
778 | 793 |
#else |
779 |
r0 = addr_reg; |
|
794 |
if (GUEST_BASE == (int32_t)GUEST_BASE) { |
|
795 |
r0 = addr_reg; |
|
796 |
offset = GUEST_BASE; |
|
797 |
} else { |
|
798 |
offset = 0; |
|
799 |
/* movq $GUEST_BASE, r0 */ |
|
800 |
tcg_out_opc(s, (0xb8 + (r0 & 7)) | P_REXW, 0, r0, 0); |
|
801 |
tcg_out32(s, GUEST_BASE); |
|
802 |
tcg_out32(s, GUEST_BASE >> 32); |
|
803 |
/* addq addr_reg, r0 */ |
|
804 |
tcg_out_modrm(s, 0x01 | P_REXW, addr_reg, r0); |
|
805 |
} |
|
780 | 806 |
#endif |
781 | 807 |
|
782 | 808 |
#ifdef TARGET_WORDS_BIGENDIAN |
... | ... | |
787 | 813 |
switch(opc) { |
788 | 814 |
case 0: |
789 | 815 |
/* movb */ |
790 |
tcg_out_modrm_offset(s, 0x88 | P_REXB, data_reg, r0, 0);
|
|
816 |
tcg_out_modrm_offset(s, 0x88 | P_REXB, data_reg, r0, offset);
|
|
791 | 817 |
break; |
792 | 818 |
case 1: |
793 | 819 |
if (bswap) { |
... | ... | |
799 | 825 |
} |
800 | 826 |
/* movw */ |
801 | 827 |
tcg_out8(s, 0x66); |
802 |
tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
|
|
828 |
tcg_out_modrm_offset(s, 0x89, data_reg, r0, offset);
|
|
803 | 829 |
break; |
804 | 830 |
case 2: |
805 | 831 |
if (bswap) { |
... | ... | |
809 | 835 |
data_reg = r1; |
810 | 836 |
} |
811 | 837 |
/* movl */ |
812 |
tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
|
|
838 |
tcg_out_modrm_offset(s, 0x89, data_reg, r0, offset);
|
|
813 | 839 |
break; |
814 | 840 |
case 3: |
815 | 841 |
if (bswap) { |
... | ... | |
819 | 845 |
data_reg = r1; |
820 | 846 |
} |
821 | 847 |
/* movq */ |
822 |
tcg_out_modrm_offset(s, 0x89 | P_REXW, data_reg, r0, 0);
|
|
848 |
tcg_out_modrm_offset(s, 0x89 | P_REXW, data_reg, r0, offset);
|
|
823 | 849 |
break; |
824 | 850 |
default: |
825 | 851 |
tcg_abort(); |
Also available in: Unified diff