Support EVEX encodings of maps 0-15

Treat bits [3:0] of EVEX byte 0 as opcode map bits.  Check the range
of opcode maps in insns.pl: 0-31 for VEX, 8-31 for XOP, 0-15 for EVEX.

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
This commit is contained in:
H. Peter Anvin 2016-05-13 14:42:55 -07:00
parent c0aaf9750f
commit 2c9b6ad3d9
3 changed files with 18 additions and 10 deletions

View file

@ -81,8 +81,8 @@
*
* EVEX prefixes are followed by the sequence:
* \cm\wlp\tup where cm is:
* cc 000 0mm
* c = 2 for EVEX and m is the legacy escape (0f, 0f38, 0f3a)
* cc 00m mmm
* c = 2 for EVEX and mmmm is the M field (EVEX.P0[3:0])
* and wlp is:
* 00 wwl lpp
* [l0] ll = 0 (.128, .lz)
@ -1662,7 +1662,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
/* EVEX.X can be set by either REX or EVEX for different reasons */
bytes[1] = ((((ins->rex & 7) << 5) |
(ins->evex_p[0] & (EVEX_P0X | EVEX_P0RP))) ^ 0xf0) |
(ins->vex_cm & 3);
(ins->vex_cm & EVEX_P0MM);
bytes[2] = ((ins->rex & REX_W) << (7 - 3)) |
((~ins->vexreg & 15) << 3) |
(1 << 2) | (ins->vex_wlp & 3);

View file

@ -1,7 +1,7 @@
#!/usr/bin/perl
## --------------------------------------------------------------------------
##
## Copyright 1996-2013 The NASM Authors - All Rights Reserved
## Copyright 1996-2016 The NASM Authors - All Rights Reserved
## See the file AUTHORS included with the NASM distribution for
## the specific copyright holders.
##
@ -864,7 +864,8 @@ sub byte_code_compile($$) {
push(@codes, 0200 + (($oppos{'m'} & 3) << 3) + $1);
$prefix_ok = 0;
} elsif ($op =~ /^(vex|xop)(|\..*)$/) {
my $c = $vexmap{$1};
my $vexname = $1;
my $c = $vexmap{$vexname};
my ($m,$w,$l,$p) = (undef,2,undef,0);
my $has_nds = 0;
my @subops = split(/\./, $op);
@ -902,19 +903,23 @@ sub byte_code_compile($$) {
$m = $1+0;
} elsif ($oq eq 'nds' || $oq eq 'ndd' || $oq eq 'dds') {
if (!defined($oppos{'v'})) {
die "$fname: $line: vex.$oq without 'v' operand\n";
die "$fname: $line: $vexname.$oq without 'v' operand\n";
}
$has_nds = 1;
} else {
die "$fname: $line: undefined VEX subcode: $oq\n";
die "$fname: $line: undefined \U$vexname\E subcode: $oq\n";
}
}
if (!defined($m) || !defined($w) || !defined($l) || !defined($p)) {
die "$fname: $line: missing fields in VEX specification\n";
die "$fname: $line: missing fields in \U$vexname\E specification\n";
}
if (defined($oppos{'v'}) && !$has_nds) {
die "$fname: $line: 'v' operand without vex.nds or vex.ndd\n";
die "$fname: $line: 'v' operand without ${vexname}.nds or ${vexname}.ndd\n";
}
my $minmap = ($c == 1) ? 8 : 0; # 0-31 for VEX, 8-31 for XOP
if ($m < $minmap || $m > 31) {
die "$fname: $line: Only maps ${minmap}-31 are valid for \U${vexname}\n";
}
push(@codes, defined($oppos{'v'}) ? 0260+($oppos{'v'} & 3) : 0270,
($c << 6)+$m, ($w << 4)+($l << 2)+$p);
$prefix_ok = 0;
@ -970,6 +975,9 @@ sub byte_code_compile($$) {
if (defined($oppos{'v'}) && !$has_nds) {
die "$fname: $line: 'v' operand without evex.nds or evex.ndd\n";
}
if ($m > 15) {
die "$fname: $line: Only maps 0-15 are valid for EVEX\n";
}
push(@codes, defined($oppos{'v'}) ? 0240+($oppos{'v'} & 3) : 0250,
($c << 6)+$m, ($w << 4)+($l << 2)+$p, $tup);
$prefix_ok = 0;

2
nasm.h
View file

@ -451,7 +451,7 @@ static inline uint8_t get_cond_opcode(enum ccode c)
/*
* EVEX bit field
*/
#define EVEX_P0MM 0x03 /* EVEX P[1:0] : Legacy escape */
#define EVEX_P0MM 0x0f /* EVEX P[3:0] : Opcode map */
#define EVEX_P0RP 0x10 /* EVEX P[4] : High-16 reg */
#define EVEX_P0X 0x40 /* EVEX P[6] : High-16 rm */
#define EVEX_P1PP 0x03 /* EVEX P[9:8] : Legacy prefix */