From 65f3ed048fa0741e874c7aa372f9ddba153a2949 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 23 Nov 2017 11:04:18 +0100 Subject: [PATCH] x86: fix AVX-512 16-bit addressing Despite EVEX encodings not being available in real and VM86 modes, 16-bit addressing still needs to be handled properly for 16-bit protected mode as well as 16-bit addressing in 32-bit mode. Neither should displacements be dropped silently by the assembler, nor should the disassembler fail to correctly scale 8-bit displacements. --- gas/ChangeLog | 7 +++++++ gas/config/tc-i386.c | 6 +----- gas/testsuite/gas/i386/avx512f-intel.d | 6 ++++++ gas/testsuite/gas/i386/avx512f.d | 6 ++++++ gas/testsuite/gas/i386/avx512f.s | 8 ++++++++ opcodes/ChangeLog | 5 +++++ opcodes/i386-dis.c | 2 ++ 7 files changed, 35 insertions(+), 5 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index fbe7896af3a..923f75818ff 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2017-11-23 Jan Beulich + + * tc-i386.c (check_VecOperands): Don't clear .disp16. + * testsuite/gas/i386/avx512f.s: Add 16-bit addressing tests. + * testsuite/gas/i386/avx512f.d, + testsuite/gas/i386/avx512f-intel.d: Adjust expectations. + 2017-11-23 Jan Beulich PR gas/22441 diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 4b602d422dc..f623e820346 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -4798,12 +4798,8 @@ check_VecOperands (const insn_template *t) i.types[op].bitfield.vec_disp8 = 1; else { - /* Vector insn can only have Vec_Disp8/Disp32 in - 32/64bit modes, and Vec_Disp8/Disp16 in 16bit - mode. */ + /* Vector insn doesn't allow plain Disp8. */ i.types[op].bitfield.disp8 = 0; - if (flag_code != CODE_16BIT) - i.types[op].bitfield.disp16 = 0; } } else if (flag_code != CODE_16BIT) diff --git a/gas/testsuite/gas/i386/avx512f-intel.d b/gas/testsuite/gas/i386/avx512f-intel.d index 91c51e9c00f..27cea5eadc4 100644 --- a/gas/testsuite/gas/i386/avx512f-intel.d +++ b/gas/testsuite/gas/i386/avx512f-intel.d @@ -6649,6 +6649,9 @@ Disassembly of section .text: [ ]*[a-f0-9]+: 62 f2 d6 58 27 aa 00 04 00 00 vptestnmq k5,zmm5,QWORD PTR \[edx\+0x400\]\{1to8\} [ ]*[a-f0-9]+: 62 f2 d6 58 27 6a 80 vptestnmq k5,zmm5,QWORD PTR \[edx-0x400\]\{1to8\} [ ]*[a-f0-9]+: 62 f2 d6 58 27 aa f8 fb ff ff vptestnmq k5,zmm5,QWORD PTR \[edx-0x408\]\{1to8\} +[ ]*[a-f0-9]+: 67 62 f1 7c 48 58 07 vaddps zmm0,zmm0,ZMMWORD PTR \[bx\] +[ ]*[a-f0-9]+: 67 62 f1 7c 48 58 47 01 vaddps zmm0,zmm0,ZMMWORD PTR \[bx\+0x40\] +[ ]*[a-f0-9]+: 67 62 f1 7c 48 58 87 34 12 vaddps zmm0,zmm0,ZMMWORD PTR \[bx\+0x1234\] [ ]*[a-f0-9]+: 62 f1 d5 48 58 f4 vaddpd zmm6,zmm5,zmm4 [ ]*[a-f0-9]+: 62 f1 d5 4f 58 f4 vaddpd zmm6\{k7\},zmm5,zmm4 [ ]*[a-f0-9]+: 62 f1 d5 cf 58 f4 vaddpd zmm6\{k7\}\{z\},zmm5,zmm4 @@ -13289,4 +13292,7 @@ Disassembly of section .text: [ ]*[a-f0-9]+: 62 f2 d6 58 27 aa 00 04 00 00 vptestnmq k5,zmm5,QWORD PTR \[edx\+0x400\]\{1to8\} [ ]*[a-f0-9]+: 62 f2 d6 58 27 6a 80 vptestnmq k5,zmm5,QWORD PTR \[edx-0x400\]\{1to8\} [ ]*[a-f0-9]+: 62 f2 d6 58 27 aa f8 fb ff ff vptestnmq k5,zmm5,QWORD PTR \[edx-0x408\]\{1to8\} +[ ]*[a-f0-9]+: 67 62 f1 7c 48 58 07 vaddps zmm0,zmm0,ZMMWORD PTR \[bx\] +[ ]*[a-f0-9]+: 67 62 f1 7c 48 58 47 01 vaddps zmm0,zmm0,ZMMWORD PTR \[bx\+0x40\] +[ ]*[a-f0-9]+: 67 62 f1 7c 48 58 87 34 12 vaddps zmm0,zmm0,ZMMWORD PTR \[bx\+0x1234\] #pass diff --git a/gas/testsuite/gas/i386/avx512f.d b/gas/testsuite/gas/i386/avx512f.d index e5533f9c0dc..522b1e59cf4 100644 --- a/gas/testsuite/gas/i386/avx512f.d +++ b/gas/testsuite/gas/i386/avx512f.d @@ -6648,6 +6648,9 @@ Disassembly of section .text: [ ]*[a-f0-9]+: 62 f2 d6 58 27 aa 00 04 00 00 vptestnmq 0x400\(%edx\)\{1to8\},%zmm5,%k5 [ ]*[a-f0-9]+: 62 f2 d6 58 27 6a 80 vptestnmq -0x400\(%edx\)\{1to8\},%zmm5,%k5 [ ]*[a-f0-9]+: 62 f2 d6 58 27 aa f8 fb ff ff vptestnmq -0x408\(%edx\)\{1to8\},%zmm5,%k5 +[ ]*[a-f0-9]+: 67 62 f1 7c 48 58 07 vaddps \(%bx\),%zmm0,%zmm0 +[ ]*[a-f0-9]+: 67 62 f1 7c 48 58 47 01 vaddps 0x40\(%bx\),%zmm0,%zmm0 +[ ]*[a-f0-9]+: 67 62 f1 7c 48 58 87 34 12 vaddps 0x1234\(%bx\),%zmm0,%zmm0 [ ]*[a-f0-9]+: 62 f1 d5 48 58 f4 vaddpd %zmm4,%zmm5,%zmm6 [ ]*[a-f0-9]+: 62 f1 d5 4f 58 f4 vaddpd %zmm4,%zmm5,%zmm6\{%k7\} [ ]*[a-f0-9]+: 62 f1 d5 cf 58 f4 vaddpd %zmm4,%zmm5,%zmm6\{%k7\}\{z\} @@ -13288,4 +13291,7 @@ Disassembly of section .text: [ ]*[a-f0-9]+: 62 f2 d6 58 27 aa 00 04 00 00 vptestnmq 0x400\(%edx\)\{1to8\},%zmm5,%k5 [ ]*[a-f0-9]+: 62 f2 d6 58 27 6a 80 vptestnmq -0x400\(%edx\)\{1to8\},%zmm5,%k5 [ ]*[a-f0-9]+: 62 f2 d6 58 27 aa f8 fb ff ff vptestnmq -0x408\(%edx\)\{1to8\},%zmm5,%k5 +[ ]*[a-f0-9]+: 67 62 f1 7c 48 58 07 vaddps \(%bx\),%zmm0,%zmm0 +[ ]*[a-f0-9]+: 67 62 f1 7c 48 58 47 01 vaddps 0x40\(%bx\),%zmm0,%zmm0 +[ ]*[a-f0-9]+: 67 62 f1 7c 48 58 87 34 12 vaddps 0x1234\(%bx\),%zmm0,%zmm0 #pass diff --git a/gas/testsuite/gas/i386/avx512f.s b/gas/testsuite/gas/i386/avx512f.s index 1f172d53be3..199c786b240 100644 --- a/gas/testsuite/gas/i386/avx512f.s +++ b/gas/testsuite/gas/i386/avx512f.s @@ -7262,6 +7262,10 @@ _start: vptestnmq -1024(%edx){1to8}, %zmm5, %k5 # AVX512F Disp8 vptestnmq -1032(%edx){1to8}, %zmm5, %k5 # AVX512F + vaddps (%bx), %zmm0, %zmm0 + vaddps 0x40(%bx), %zmm0, %zmm0 + vaddps 0x1234(%bx), %zmm0, %zmm0 + .intel_syntax noprefix vaddpd zmm6, zmm5, zmm4 # AVX512F vaddpd zmm6{k7}, zmm5, zmm4 # AVX512F @@ -14520,3 +14524,7 @@ _start: vptestnmq k5, zmm5, [edx+1024]{1to8} # AVX512F vptestnmq k5, zmm5, [edx-1024]{1to8} # AVX512F Disp8 vptestnmq k5, zmm5, [edx-1032]{1to8} # AVX512F + + vaddps zmm0, zmm0, [bx] + vaddps zmm0, zmm0, [bx+0x40] + vaddps zmm0, zmm0, [bx+0x1234] diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 57624662036..c1a1e5ef672 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,8 @@ +2017-11-23 Jan Beulich + + * i386-dis.c (OP_E_memory): Also shift the 8-bit immediate in + the 16-bit addressing case. + 2017-11-23 Jan Beulich * i386-dis.c (dis386_twobyte): Correct ud1. Add ud0. diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 12b723a4056..6b8d1dc8025 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -15481,6 +15481,8 @@ OP_E_memory (int bytemode, int sizeflag) disp = *codep++; if ((disp & 0x80) != 0) disp -= 0x100; + if (vex.evex && shift > 0) + disp <<= shift; break; case 2: disp = get16 (); -- 2.30.2