diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2018-09-17 09:26:18 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2018-09-17 09:26:29 -0700 |
commit | 03751133023c5623cf60f8d3222cb79a376331f9 (patch) | |
tree | 0ae561fd6f959782ff846f94f20465ee0d47a3a1 /gas/config | |
parent | ec6f095abc396e60f46e1b4724d0eb2e4d18213d (diff) | |
download | binutils-03751133023c5623cf60f8d3222cb79a376331f9.zip binutils-03751133023c5623cf60f8d3222cb79a376331f9.tar.gz binutils-03751133023c5623cf60f8d3222cb79a376331f9.tar.bz2 |
x86: Add -mvexwig=[0|1] option to assembler
Add -mvexwig=[0|1] option to x86 assembler to control how the assembler
should encode the VEX.W bit in WIG VEX instructions.
* gas/NEWS: Mention -mvexwig=[0|1] option.
* config/tc-i386.c (vexwig): New.
(build_vex_prefix): Set the VEX.W bit for -mvexwig=1 for WIG
VEX instructions.
(OPTION_MVEXWIG): New.
(md_longopts): Add -mvexwig=.
(md_parse_option): Handle OPTION_MVEXWIG.
(md_show_usage): Show -mvexwig=[0|1].
* doc/c-i386.texi: Document -mvexwig=[0|1].
* testsuite/gas/i386/avx-wig.d: New file.
* testsuite/gas/i386/avx-wig.s: Likewise.
* testsuite/gas/i386/avx2-wig.d: Likewise.
* testsuite/gas/i386/avx2-wig.s: Likewise.
* testsuite/gas/i386/x86-64-avx-wig.d: Likewise.
* testsuite/gas/i386/x86-64-avx-wig.s: Likewise.
* testsuite/gas/i386/x86-64-avx2-wig.d: Likewise.
* testsuite/gas/i386/x86-64-avx2-wig.s: Likewise.
* testsuite/gas/i386/i386.exp: Run avx-wig, avx2-wig,
x86-64-avx-wig and x86-64-avx2-wig.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-i386.c | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index d2ee3b4..2204d00 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -684,6 +684,13 @@ static enum vex256 } avxscalar; +/* Encode VEX WIG instructions with specific vex.w. */ +static enum + { + vexw0 = 0, + vexw1 + } vexwig; + /* Encode scalar EVEX LIG instructions with specific vector length. */ static enum { @@ -3353,6 +3360,7 @@ build_vex_prefix (const insn_template *t) unsigned int register_specifier; unsigned int implied_prefix; unsigned int vector_length; + unsigned int w; /* Check register specifier. */ if (i.vex.register_specifier) @@ -3439,10 +3447,18 @@ build_vex_prefix (const insn_template *t) abort (); } + /* Check the REX.W bit and VEXW. */ + if (i.tm.opcode_modifier.vexw == VEXWIG) + w = (vexwig == vexw1 || (i.rex & REX_W)) ? 1 : 0; + else if (i.tm.opcode_modifier.vexw) + w = i.tm.opcode_modifier.vexw == VEXW1 ? 1 : 0; + else + w = (i.rex & REX_W) ? 1 : 0; + /* Use 2-byte VEX prefix if possible. */ - if (i.vec_encoding != vex_encoding_vex3 + if (w == 0 + && i.vec_encoding != vex_encoding_vex3 && i.tm.opcode_modifier.vexopcode == VEX0F - && i.tm.opcode_modifier.vexw != VEXW1 && (i.rex & (REX_W | REX_X | REX_B)) == 0) { /* 2-byte VEX prefix. */ @@ -3461,7 +3477,7 @@ build_vex_prefix (const insn_template *t) else { /* 3-byte VEX prefix. */ - unsigned int m, w; + unsigned int m; i.vex.length = 3; @@ -3499,14 +3515,6 @@ build_vex_prefix (const insn_template *t) of RXB bits from REX. */ i.vex.bytes[1] = (~i.rex & 0x7) << 5 | m; - /* Check the REX.W bit and VEXW. */ - if (i.tm.opcode_modifier.vexw == VEXWIG) - w = (i.rex & REX_W) ? 1 : 0; - else if (i.tm.opcode_modifier.vexw) - w = i.tm.opcode_modifier.vexw == VEXW1 ? 1 : 0; - else - w = (i.rex & REX_W) ? 1 : 0; - i.vex.bytes[2] = (w << 7 | register_specifier << 3 | vector_length << 2 @@ -10878,6 +10886,7 @@ const char *md_shortopts = "qnO::"; #define OPTION_MINTEL64 (OPTION_MD_BASE + 23) #define OPTION_MFENCE_AS_LOCK_ADD (OPTION_MD_BASE + 24) #define OPTION_X86_USED_NOTE (OPTION_MD_BASE + 25) +#define OPTION_MVEXWIG (OPTION_MD_BASE + 26) struct option md_longopts[] = { @@ -10902,6 +10911,7 @@ struct option md_longopts[] = {"msse-check", required_argument, NULL, OPTION_MSSE_CHECK}, {"moperand-check", required_argument, NULL, OPTION_MOPERAND_CHECK}, {"mavxscalar", required_argument, NULL, OPTION_MAVXSCALAR}, + {"mvexwig", required_argument, NULL, OPTION_MVEXWIG}, {"madd-bnd-prefix", no_argument, NULL, OPTION_MADD_BND_PREFIX}, {"mevexlig", required_argument, NULL, OPTION_MEVEXLIG}, {"mevexwig", required_argument, NULL, OPTION_MEVEXWIG}, @@ -11219,6 +11229,15 @@ md_parse_option (int c, const char *arg) as_fatal (_("invalid -mavxscalar= option: `%s'"), arg); break; + case OPTION_MVEXWIG: + if (strcmp (arg, "0") == 0) + vexwig = evexw0; + else if (strcmp (arg, "1") == 0) + vexwig = evexw1; + else + as_fatal (_("invalid -mvexwig= option: `%s'"), arg); + break; + case OPTION_MADD_BND_PREFIX: add_bnd_prefix = 1; break; @@ -11477,6 +11496,10 @@ md_show_usage (FILE *stream) encode scalar AVX instructions with specific vector\n\ length\n")); fprintf (stream, _("\ + -mvexwig=[0|1] (default: 0)\n\ + encode VEX instructions with specific VEX.W value\n\ + for VEX.W bit ignored instructions\n")); + fprintf (stream, _("\ -mevexlig=[128|256|512] (default: 128)\n\ encode scalar EVEX instructions with specific vector\n\ length\n")); |