mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-03-19 18:00:23 +08:00
assemble: handle vex.lig
AVX version 7 introduces the concept of .lig, meaning VEX.L is ignored. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
This commit is contained in:
parent
978c2170fc
commit
421059c689
12
assemble.c
12
assemble.c
@ -92,7 +92,11 @@
|
||||
*
|
||||
* VEX/XOP prefixes are followed by the sequence:
|
||||
* \tmm\wlp where mm is the M field; and wlp is:
|
||||
* 00 0ww lpp
|
||||
* 00 wwl lpp
|
||||
* [l0] ll = 0 for L = 0 (.128, .lz)
|
||||
* [l1] ll = 1 for L = 1 (.256)
|
||||
* [lig] ll = 2 for L don't care (always assembled as 0)
|
||||
*
|
||||
* [w0] ww = 0 for W = 0
|
||||
* [w1 ] ww = 1 for W = 1
|
||||
* [wig] ww = 2 for W don't care (always assembled as 0)
|
||||
@ -1130,16 +1134,16 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
|
||||
errfunc(ERR_NONFATAL, "cannot use high register in vex instruction");
|
||||
return -1;
|
||||
}
|
||||
switch (ins->vex_wlp & 030) {
|
||||
switch (ins->vex_wlp & 060) {
|
||||
case 000:
|
||||
case 020:
|
||||
ins->rex &= ~REX_W;
|
||||
break;
|
||||
case 010:
|
||||
case 040:
|
||||
ins->rex |= REX_W;
|
||||
bad32 &= ~REX_W;
|
||||
break;
|
||||
case 030:
|
||||
case 060:
|
||||
/* Follow REX_W */
|
||||
break;
|
||||
}
|
||||
|
12
disasm.c
12
disasm.c
@ -678,6 +678,7 @@ static int matches(const struct itemplate *t, uint8_t *data,
|
||||
{
|
||||
int vexm = *r++;
|
||||
int vexwlp = *r++;
|
||||
|
||||
ins->rex |= REX_V;
|
||||
if ((prefix->rex & (REX_V|REX_D|REX_P)) != REX_V)
|
||||
return false;
|
||||
@ -685,24 +686,25 @@ static int matches(const struct itemplate *t, uint8_t *data,
|
||||
if ((vexm & 0x1f) != prefix->vex_m)
|
||||
return false;
|
||||
|
||||
switch (vexwlp & 030) {
|
||||
switch (vexwlp & 060) {
|
||||
case 000:
|
||||
if (prefix->rex & REX_W)
|
||||
return false;
|
||||
break;
|
||||
case 010:
|
||||
case 020:
|
||||
if (!(prefix->rex & REX_W))
|
||||
return false;
|
||||
ins->rex &= ~REX_W;
|
||||
break;
|
||||
case 020: /* VEX.W is a don't care */
|
||||
case 040: /* VEX.W is a don't care */
|
||||
ins->rex &= ~REX_W;
|
||||
break;
|
||||
case 030:
|
||||
case 060:
|
||||
break;
|
||||
}
|
||||
|
||||
if ((vexwlp & 007) != prefix->vex_lp)
|
||||
/* The 010 bit of vexwlp is set if VEX.L is ignored */
|
||||
if ((vexwlp ^ prefix->vex_lp) & ((vexwlp & 010) ? 03 : 07))
|
||||
return false;
|
||||
|
||||
opx->segment |= SEG_RMREG;
|
||||
|
6
insns.pl
6
insns.pl
@ -761,10 +761,12 @@ sub byte_code_compile($$) {
|
||||
my @subops = split(/\./, $op);
|
||||
shift @subops; # Drop prefix
|
||||
foreach $oq (@subops) {
|
||||
if ($oq eq '128' || $oq eq 'l0') {
|
||||
if ($oq eq '128' || $oq eq 'l0' || $oq eq 'lz') {
|
||||
$l = 0;
|
||||
} elsif ($oq eq '256' || $oq eq 'l1') {
|
||||
$l = 1;
|
||||
} elsif ($oq eq 'lig') {
|
||||
$l = 2;
|
||||
} elsif ($oq eq 'w0') {
|
||||
$w = 0;
|
||||
} elsif ($oq eq 'w1') {
|
||||
@ -805,7 +807,7 @@ sub byte_code_compile($$) {
|
||||
die "$fname: $line: 'v' operand without vex.nds or vex.ndd\n";
|
||||
}
|
||||
push(@codes, defined($oppos{'v'}) ? 0260+($oppos{'v'} & 3) : 0270,
|
||||
($c << 6)+$m, ($w << 3)+($l << 2)+$p);
|
||||
($c << 6)+$m, ($w << 4)+($l << 2)+$p);
|
||||
$prefix_ok = 0;
|
||||
} elsif ($op =~ /^\/drex([01])$/) {
|
||||
my $oc0 = $1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user