| OLD | NEW |
| 1 /* | 1 /* |
| 2 * x86 expression handling | 2 * x86 expression handling |
| 3 * | 3 * |
| 4 * Copyright (C) 2001-2007 Peter Johnson | 4 * Copyright (C) 2001-2007 Peter Johnson |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
| 8 * are met: | 8 * are met: |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| 11 * 2. Redistributions in binary form must reproduce the above copyright | 11 * 2. Redistributions in binary form must reproduce the above copyright |
| 12 * notice, this list of conditions and the following disclaimer in the | 12 * notice, this list of conditions and the following disclaimer in the |
| 13 * documentation and/or other materials provided with the distribution. | 13 * documentation and/or other materials provided with the distribution. |
| 14 * | 14 * |
| 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' | 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' |
| 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE | 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE |
| 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 25 * POSSIBILITY OF SUCH DAMAGE. | 25 * POSSIBILITY OF SUCH DAMAGE. |
| 26 */ | 26 */ |
| 27 #include <util.h> | 27 #include <util.h> |
| 28 /*@unused@*/ RCSID("$Id: x86expr.c 2199 2009-05-10 05:24:46Z peter $"); | |
| 29 | 28 |
| 30 #include <libyasm.h> | 29 #include <libyasm.h> |
| 31 | 30 |
| 32 #include "x86arch.h" | 31 #include "x86arch.h" |
| 33 | 32 |
| 34 | 33 |
| 35 typedef struct x86_checkea_reg3264_data { | 34 typedef struct x86_checkea_reg3264_data { |
| 36 int *regs; /* total multiplier for each reg */ | 35 int *regs; /* total multiplier for each reg */ |
| 36 unsigned char vsib_mode; |
| 37 unsigned char bits; | 37 unsigned char bits; |
| 38 unsigned char addrsize; | 38 unsigned char addrsize; |
| 39 } x86_checkea_reg3264_data; | 39 } x86_checkea_reg3264_data; |
| 40 | 40 |
| 41 /* Only works if ei->type == EXPR_REG (doesn't check). | 41 /* Only works if ei->type == EXPR_REG (doesn't check). |
| 42 * Overwrites ei with intnum of 0 (to eliminate regs from the final expr). | 42 * Overwrites ei with intnum of 0 (to eliminate regs from the final expr). |
| 43 */ | 43 */ |
| 44 static /*@null@*/ /*@dependent@*/ int * | 44 static /*@null@*/ /*@dependent@*/ int * |
| 45 x86_expr_checkea_get_reg3264(yasm_expr__item *ei, int *regnum, | 45 x86_expr_checkea_get_reg3264(yasm_expr__item *ei, int *regnum, |
| 46 /*returned*/ void *d) | 46 /*returned*/ void *d) |
| 47 { | 47 { |
| 48 x86_checkea_reg3264_data *data = d; | 48 x86_checkea_reg3264_data *data = d; |
| 49 | 49 |
| 50 switch ((x86_expritem_reg_size)(ei->data.reg & ~0xFUL)) { | 50 switch ((x86_expritem_reg_size)(ei->data.reg & ~0xFUL)) { |
| 51 case X86_REG32: | 51 case X86_REG32: |
| 52 if (data->addrsize != 32) | 52 if (data->addrsize != 32) |
| 53 return 0; | 53 return 0; |
| 54 *regnum = (unsigned int)(ei->data.reg & 0xF); | 54 *regnum = (unsigned int)(ei->data.reg & 0xF); |
| 55 break; | 55 break; |
| 56 case X86_REG64: | 56 case X86_REG64: |
| 57 if (data->addrsize != 64) | 57 if (data->addrsize != 64) |
| 58 return 0; | 58 return 0; |
| 59 *regnum = (unsigned int)(ei->data.reg & 0xF); | 59 *regnum = (unsigned int)(ei->data.reg & 0xF); |
| 60 break; | 60 break; |
| 61 case X86_XMMREG: |
| 62 if (data->vsib_mode != 1) |
| 63 return 0; |
| 64 if (data->bits != 64 && (ei->data.reg & 0x8) == 0x8) |
| 65 return 0; |
| 66 *regnum = 17+(unsigned int)(ei->data.reg & 0xF); |
| 67 break; |
| 68 case X86_YMMREG: |
| 69 if (data->vsib_mode != 2) |
| 70 return 0; |
| 71 if (data->bits != 64 && (ei->data.reg & 0x8) == 0x8) |
| 72 return 0; |
| 73 *regnum = 17+(unsigned int)(ei->data.reg & 0xF); |
| 74 break; |
| 61 case X86_RIP: | 75 case X86_RIP: |
| 62 if (data->bits != 64) | 76 if (data->bits != 64) |
| 63 return 0; | 77 return 0; |
| 64 *regnum = 16; | 78 *regnum = 16; |
| 65 break; | 79 break; |
| 66 default: | 80 default: |
| 67 return 0; | 81 return 0; |
| 68 } | 82 } |
| 69 | 83 |
| 70 /* overwrite with 0 to eliminate register from displacement expr */ | 84 /* overwrite with 0 to eliminate register from displacement expr */ |
| (...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 /* Must be 32-bit in 16-bit or 32-bit modes. In 64-bit mode, | 613 /* Must be 32-bit in 16-bit or 32-bit modes. In 64-bit mode, |
| 600 * we don't know unless we look at the registers, except in the | 614 * we don't know unless we look at the registers, except in the |
| 601 * MemOffs case (see the end of this function). | 615 * MemOffs case (see the end of this function). |
| 602 */ | 616 */ |
| 603 if (bits != 64 || (!x86_ea->need_modrm && !x86_ea->need_sib)) { | 617 if (bits != 64 || (!x86_ea->need_modrm && !x86_ea->need_sib)) { |
| 604 *addrsize = 32; | 618 *addrsize = 32; |
| 605 break; | 619 break; |
| 606 } | 620 } |
| 607 /*@fallthrough@*/ | 621 /*@fallthrough@*/ |
| 608 default: | 622 default: |
| 623 /* If SIB is required, but we're in 16-bit mode, set to 32. */ |
| 624 if (bits == 16 && x86_ea->need_sib == 1) { |
| 625 *addrsize = 32; |
| 626 break; |
| 627 } |
| 609 /* check for use of 16 or 32-bit registers; if none are used | 628 /* check for use of 16 or 32-bit registers; if none are used |
| 610 * default to bits setting. | 629 * default to bits setting. |
| 611 */ | 630 */ |
| 612 if (!x86_ea->ea.disp.abs || | 631 if (!x86_ea->ea.disp.abs || |
| 613 !yasm_expr__traverse_leaves_in(x86_ea->ea.disp.abs, | 632 !yasm_expr__traverse_leaves_in(x86_ea->ea.disp.abs, |
| 614 addrsize, x86_expr_checkea_getregsize_callback)) | 633 addrsize, x86_expr_checkea_getregsize_callback)) |
| 615 *addrsize = bits; | 634 *addrsize = bits; |
| 616 /* TODO: Add optional warning here if switched address size | 635 /* TODO: Add optional warning here if switched address size |
| 617 * from bits setting just by register use.. eg [ax] in | 636 * from bits setting just by register use.. eg [ax] in |
| 618 * 32-bit mode would generate a warning. | 637 * 32-bit mode would generate a warning. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 636 REG3264_ESI, | 655 REG3264_ESI, |
| 637 REG3264_EDI, | 656 REG3264_EDI, |
| 638 REG64_R8, | 657 REG64_R8, |
| 639 REG64_R9, | 658 REG64_R9, |
| 640 REG64_R10, | 659 REG64_R10, |
| 641 REG64_R11, | 660 REG64_R11, |
| 642 REG64_R12, | 661 REG64_R12, |
| 643 REG64_R13, | 662 REG64_R13, |
| 644 REG64_R14, | 663 REG64_R14, |
| 645 REG64_R15, | 664 REG64_R15, |
| 646 REG64_RIP | 665 REG64_RIP, |
| 666 SIMDREGS |
| 647 } reg3264type; | 667 } reg3264type; |
| 648 int reg3264mult[17] = {0, 0, 0, 0, 0, 0, 0, 0, | 668 int reg3264mult[33] = |
| 649 0, 0, 0, 0, 0, 0, 0, 0, 0}; | 669 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 670 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; |
| 650 x86_checkea_reg3264_data reg3264_data; | 671 x86_checkea_reg3264_data reg3264_data; |
| 651 int basereg = REG3264_NONE; /* "base" register (for SIB) */ | 672 int basereg = REG3264_NONE; /* "base" register (for SIB) */ |
| 652 int indexreg = REG3264_NONE; /* "index" register (for SIB) */ | 673 int indexreg = REG3264_NONE; /* "index" register (for SIB) */ |
| 674 int regcount = 17; /* normally don't check SIMD regs */ |
| 675 |
| 676 if (x86_ea->vsib_mode != 0) |
| 677 regcount = 33; |
| 653 | 678 |
| 654 /* We can only do 64-bit addresses in 64-bit mode. */ | 679 /* We can only do 64-bit addresses in 64-bit mode. */ |
| 655 if (*addrsize == 64 && bits != 64) { | 680 if (*addrsize == 64 && bits != 64) { |
| 656 yasm_error_set(YASM_ERROR_TYPE, | 681 yasm_error_set(YASM_ERROR_TYPE, |
| 657 N_("invalid effective address (64-bit in non-64-bit mode)")); | 682 N_("invalid effective address (64-bit in non-64-bit mode)")); |
| 658 return 1; | 683 return 1; |
| 659 } | 684 } |
| 660 | 685 |
| 661 if (x86_ea->ea.pc_rel && bits != 64) { | 686 if (x86_ea->ea.pc_rel && bits != 64) { |
| 662 yasm_warn_set(YASM_WARN_GENERAL, | 687 yasm_warn_set(YASM_WARN_GENERAL, |
| 663 N_("RIP-relative directive ignored in non-64-bit mode")); | 688 N_("RIP-relative directive ignored in non-64-bit mode")); |
| 664 x86_ea->ea.pc_rel = 0; | 689 x86_ea->ea.pc_rel = 0; |
| 665 } | 690 } |
| 666 | 691 |
| 667 reg3264_data.regs = reg3264mult; | 692 reg3264_data.regs = reg3264mult; |
| 693 reg3264_data.vsib_mode = x86_ea->vsib_mode; |
| 668 reg3264_data.bits = bits; | 694 reg3264_data.bits = bits; |
| 669 reg3264_data.addrsize = *addrsize; | 695 reg3264_data.addrsize = *addrsize; |
| 670 if (x86_ea->ea.disp.abs) { | 696 if (x86_ea->ea.disp.abs) { |
| 671 int pcrel = 0; | 697 int pcrel = 0; |
| 672 switch (x86_expr_checkea_getregusage | 698 switch (x86_expr_checkea_getregusage |
| 673 (&x86_ea->ea.disp.abs, &indexreg, &pcrel, bits, | 699 (&x86_ea->ea.disp.abs, &indexreg, &pcrel, bits, |
| 674 ®3264_data, x86_expr_checkea_get_reg3264)) { | 700 ®3264_data, x86_expr_checkea_get_reg3264)) { |
| 675 case 1: | 701 case 1: |
| 676 yasm_error_set(YASM_ERROR_VALUE, | 702 yasm_error_set(YASM_ERROR_VALUE, |
| 677 N_("invalid effective address")); | 703 N_("invalid effective address")); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 691 * This is possible because of the way indexreg is found in | 717 * This is possible because of the way indexreg is found in |
| 692 * expr_checkea_getregusage(). | 718 * expr_checkea_getregusage(). |
| 693 */ | 719 */ |
| 694 if (indexreg != REG3264_NONE && reg3264mult[indexreg] == 0) | 720 if (indexreg != REG3264_NONE && reg3264mult[indexreg] == 0) |
| 695 indexreg = REG3264_NONE; | 721 indexreg = REG3264_NONE; |
| 696 | 722 |
| 697 /* Find a basereg (*1, but not indexreg), if there is one. | 723 /* Find a basereg (*1, but not indexreg), if there is one. |
| 698 * Also, if an indexreg hasn't been assigned, try to find one. | 724 * Also, if an indexreg hasn't been assigned, try to find one. |
| 699 * Meanwhile, check to make sure there's no negative register mults. | 725 * Meanwhile, check to make sure there's no negative register mults. |
| 700 */ | 726 */ |
| 701 for (i=0; i<17; i++) { | 727 for (i=0; i<regcount; i++) { |
| 702 if (reg3264mult[i] < 0) { | 728 if (reg3264mult[i] < 0) { |
| 703 yasm_error_set(YASM_ERROR_VALUE, | 729 yasm_error_set(YASM_ERROR_VALUE, |
| 704 N_("invalid effective address")); | 730 N_("invalid effective address")); |
| 705 return 1; | 731 return 1; |
| 706 } | 732 } |
| 707 if (i != indexreg && reg3264mult[i] == 1 && | 733 if (i != indexreg && reg3264mult[i] == 1 && |
| 708 basereg == REG3264_NONE) | 734 basereg == REG3264_NONE) |
| 709 basereg = i; | 735 basereg = i; |
| 710 else if (indexreg == REG3264_NONE && reg3264mult[i] > 0) | 736 else if (indexreg == REG3264_NONE && reg3264mult[i] > 0) |
| 711 indexreg = i; | 737 indexreg = i; |
| 712 } | 738 } |
| 713 | 739 |
| 714 /* Handle certain special cases of indexreg mults when basereg is | 740 if (x86_ea->vsib_mode != 0) { |
| 715 * empty. | 741 /* For VSIB, the SIMD register needs to go into the indexreg. |
| 716 */ | 742 * Also check basereg (must be a GPR if present) and indexreg |
| 717 if (indexreg != REG3264_NONE && basereg == REG3264_NONE) | 743 * (must be a SIMD register). |
| 744 */ |
| 745 if (basereg >= SIMDREGS && |
| 746 (indexreg == REG3264_NONE || reg3264mult[indexreg] == 1)) { |
| 747 int temp = basereg; |
| 748 basereg = indexreg; |
| 749 indexreg = temp; |
| 750 } |
| 751 if (basereg >= REG64_RIP || indexreg < SIMDREGS) { |
| 752 yasm_error_set(YASM_ERROR_VALUE, |
| 753 N_("invalid effective address")); |
| 754 return 1; |
| 755 } |
| 756 } else if (indexreg != REG3264_NONE && basereg == REG3264_NONE) |
| 757 /* Handle certain special cases of indexreg mults when basereg is |
| 758 * empty. |
| 759 */ |
| 718 switch (reg3264mult[indexreg]) { | 760 switch (reg3264mult[indexreg]) { |
| 719 case 1: | 761 case 1: |
| 720 /* Only optimize this way if nosplit wasn't specified */ | 762 /* Only optimize this way if nosplit wasn't specified */ |
| 721 if (!x86_ea->ea.nosplit) { | 763 if (!x86_ea->ea.nosplit) { |
| 722 basereg = indexreg; | 764 basereg = indexreg; |
| 723 indexreg = -1; | 765 indexreg = -1; |
| 724 } | 766 } |
| 725 break; | 767 break; |
| 726 case 2: | 768 case 2: |
| 727 /* Only split if nosplit wasn't specified */ | 769 /* Only split if nosplit wasn't specified */ |
| 728 if (!x86_ea->ea.nosplit) { | 770 if (!x86_ea->ea.nosplit) { |
| 729 basereg = indexreg; | 771 basereg = indexreg; |
| 730 reg3264mult[indexreg] = 1; | 772 reg3264mult[indexreg] = 1; |
| 731 } | 773 } |
| 732 break; | 774 break; |
| 733 case 3: | 775 case 3: |
| 734 case 5: | 776 case 5: |
| 735 case 9: | 777 case 9: |
| 736 basereg = indexreg; | 778 basereg = indexreg; |
| 737 reg3264mult[indexreg]--; | 779 reg3264mult[indexreg]--; |
| 738 break; | 780 break; |
| 739 } | 781 } |
| 740 | 782 |
| 741 /* Make sure there's no other registers than the basereg and indexreg | 783 /* Make sure there's no other registers than the basereg and indexreg |
| 742 * we just found. | 784 * we just found. |
| 743 */ | 785 */ |
| 744 for (i=0; i<17; i++) | 786 for (i=0; i<regcount; i++) |
| 745 if (i != basereg && i != indexreg && reg3264mult[i] != 0) { | 787 if (i != basereg && i != indexreg && reg3264mult[i] != 0) { |
| 746 yasm_error_set(YASM_ERROR_VALUE, | 788 yasm_error_set(YASM_ERROR_VALUE, |
| 747 N_("invalid effective address")); | 789 N_("invalid effective address")); |
| 748 return 1; | 790 return 1; |
| 749 } | 791 } |
| 750 | 792 |
| 751 /* Check the index multiplier value for validity if present. */ | 793 /* Check the index multiplier value for validity if present. */ |
| 752 if (indexreg != REG3264_NONE && reg3264mult[indexreg] != 1 && | 794 if (indexreg != REG3264_NONE && reg3264mult[indexreg] != 1 && |
| 753 reg3264mult[indexreg] != 2 && reg3264mult[indexreg] != 4 && | 795 reg3264mult[indexreg] != 2 && reg3264mult[indexreg] != 4 && |
| 754 reg3264mult[indexreg] != 8) { | 796 reg3264mult[indexreg] != 8) { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 854 X86_REX_B)) | 896 X86_REX_B)) |
| 855 return 1; | 897 return 1; |
| 856 x86_ea->sib |= low3; | 898 x86_ea->sib |= low3; |
| 857 } | 899 } |
| 858 | 900 |
| 859 /* Put in indexreg, checking for none case */ | 901 /* Put in indexreg, checking for none case */ |
| 860 if (indexreg == REG3264_NONE) | 902 if (indexreg == REG3264_NONE) |
| 861 x86_ea->sib |= 040; | 903 x86_ea->sib |= 040; |
| 862 /* Any scale field is valid, just leave at 0. */ | 904 /* Any scale field is valid, just leave at 0. */ |
| 863 else { | 905 else { |
| 864 if (yasm_x86__set_rex_from_reg(rex, &low3, (unsigned int) | 906 if (indexreg >= SIMDREGS) { |
| 865 (X86_REG64 | indexreg), bits, | 907 if (yasm_x86__set_rex_from_reg(rex, &low3, |
| 866 X86_REX_X)) | 908 (unsigned int)(X86_XMMREG | (indexreg-SIMDREGS)), |
| 867 return 1; | 909 bits, X86_REX_X)) |
| 910 return 1; |
| 911 } else { |
| 912 if (yasm_x86__set_rex_from_reg(rex, &low3, |
| 913 (unsigned int)(X86_REG64 | indexreg), |
| 914 bits, X86_REX_X)) |
| 915 return 1; |
| 916 } |
| 868 x86_ea->sib |= low3 << 3; | 917 x86_ea->sib |= low3 << 3; |
| 869 /* Set scale field, 1 case -> 0, so don't bother. */ | 918 /* Set scale field, 1 case -> 0, so don't bother. */ |
| 870 switch (reg3264mult[indexreg]) { | 919 switch (reg3264mult[indexreg]) { |
| 871 case 2: | 920 case 2: |
| 872 x86_ea->sib |= 0100; | 921 x86_ea->sib |= 0100; |
| 873 break; | 922 break; |
| 874 case 4: | 923 case 4: |
| 875 x86_ea->sib |= 0200; | 924 x86_ea->sib |= 0200; |
| 876 break; | 925 break; |
| 877 case 8: | 926 case 8: |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1003 { | 1052 { |
| 1004 if (!yasm_floatnum_check_size(flt, valsize)) { | 1053 if (!yasm_floatnum_check_size(flt, valsize)) { |
| 1005 yasm_error_set(YASM_ERROR_FLOATING_POINT, | 1054 yasm_error_set(YASM_ERROR_FLOATING_POINT, |
| 1006 N_("invalid floating point constant size")); | 1055 N_("invalid floating point constant size")); |
| 1007 return 1; | 1056 return 1; |
| 1008 } | 1057 } |
| 1009 | 1058 |
| 1010 yasm_floatnum_get_sized(flt, buf, destsize, valsize, shift, 0, warn); | 1059 yasm_floatnum_get_sized(flt, buf, destsize, valsize, shift, 0, warn); |
| 1011 return 0; | 1060 return 0; |
| 1012 } | 1061 } |
| OLD | NEW |