mirror of
https://github.com/netwide-assembler/nasm.git
synced 2024-11-21 03:14:19 +08:00
obsolete handing: handle a few more subcases in a useful way
Distinguish instructions which have once been valid (OBSOLETE) from those that never saw the light of day (NEVER). Futhermore, flag instructions which devolve to an architectural noop from those with undefined behavior and possibly recycled opcodes. Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
This commit is contained in:
parent
fb11889040
commit
5b39461178
@ -781,6 +781,11 @@ int64_t assemble(int32_t segment, int64_t start, int bits, insn *instruction)
|
||||
if (m == MOK_GOOD) {
|
||||
/* Matches! */
|
||||
if (unlikely(itemp_has(temp, IF_OBSOLETE))) {
|
||||
errflags warning;
|
||||
const char *whathappened;
|
||||
const char *validity;
|
||||
bool never = itemp_has(temp, IF_NEVER);
|
||||
|
||||
/*
|
||||
* If IF_OBSOLETE is set, warn the user. Different
|
||||
* warning classes for "obsolete but valid for this
|
||||
@ -794,20 +799,34 @@ int64_t assemble(int32_t segment, int64_t start, int bits, insn *instruction)
|
||||
*! which, \c{0Fh}, instead is an opcode prefix on
|
||||
*! CPUs newer than the first generation 8086.
|
||||
*
|
||||
*!obsolete-nop [on] instruction obsolete and is a noop on the target CPU
|
||||
*! warns for an instruction which has been removed
|
||||
*! from the architecture, but has been architecturally
|
||||
*! defined to be a noop for future CPUs.
|
||||
*
|
||||
*!obsolete-valid [on] instruction obsolete but valid on the target CPU
|
||||
*! warns for an instruction which has been removed
|
||||
*! from the architecture, but is still valid on the
|
||||
*! specific CPU given in the \c{CPU} directive. Code
|
||||
*! using these instructions is not forward compatible.
|
||||
*! using these instructions is most likely not
|
||||
*! forward compatible.
|
||||
*/
|
||||
|
||||
if (iflag_cmp_cpu_level(&insns_flags[temp->iflag_idx], &cpu)) {
|
||||
nasm_warn(WARN_OBSOLETE_REMOVED,
|
||||
"instruction obsolete and removed on the target CPU");
|
||||
whathappened = never ? "never implemented" : "obsolete";
|
||||
|
||||
if (!never && !iflag_cmp_cpu_level(&insns_flags[temp->iflag_idx], &cpu)) {
|
||||
warning = WARN_OBSOLETE_VALID;
|
||||
validity = "but valid on";
|
||||
} else if (itemp_has(temp, IF_NOP)) {
|
||||
warning = WARN_OBSOLETE_NOP;
|
||||
validity = "and is a noop on";
|
||||
} else {
|
||||
nasm_warn(WARN_OBSOLETE_VALID,
|
||||
"instruction obsolete but valid on the target CPU");
|
||||
warning = WARN_OBSOLETE_REMOVED;
|
||||
validity = "and removed from";
|
||||
}
|
||||
|
||||
nasm_warn(warning, "instruction %s %s the target CPU",
|
||||
whathappened, validity);
|
||||
}
|
||||
|
||||
data.itemp = temp;
|
||||
|
@ -7,3 +7,6 @@
|
||||
cpu 386
|
||||
pop cs
|
||||
mov cs,ax
|
||||
|
||||
cpu any
|
||||
pcommit
|
||||
|
@ -83,8 +83,10 @@ if_("AVX5124FMAPS", "AVX-512 4-iteration multiply-add");
|
||||
if_("AVX5124VNNIW", "AVX-512 4-iteration dot product");
|
||||
if_("SGX", "Intel Software Guard Extensions (SGX)");
|
||||
|
||||
# Put these last
|
||||
# Put these last [hpa: why?]
|
||||
if_("OBSOLETE", "Instruction removed from architecture");
|
||||
if_("NEVER", "Instruction never implemented");
|
||||
if_("NOP", "Instruction is always a (nonintentional) NOP");
|
||||
if_("VEX", "VEX or XOP encoded instruction");
|
||||
if_("EVEX", "EVEX encoded instruction");
|
||||
|
||||
|
@ -5262,7 +5262,7 @@ RDPID reg32 [m: f3 0f c7 /7] X64,UNDOC,FUTURE
|
||||
CLFLUSHOPT mem [m: 66 0f ae /7] FUTURE
|
||||
CLWB mem [m: 66 0f ae /6] FUTURE
|
||||
; This one was killed before it saw the light of day
|
||||
PCOMMIT void [ 66 0f ae f8] FUTURE,UNDOC,OBSOLETE
|
||||
PCOMMIT void [ 66 0f ae f8] FUTURE,NEVER,NOP
|
||||
|
||||
; AMD Zen v1
|
||||
CLZERO void [ 0f 01 fc] FUTURE,AMD
|
||||
|
21
x86/insns.pl
21
x86/insns.pl
@ -499,25 +499,32 @@ sub format_insn($$$$$) {
|
||||
}
|
||||
$decorators =~ tr/a-z/A-Z/;
|
||||
|
||||
# expand the flags
|
||||
my @flags;
|
||||
# expand and uniqify the flags
|
||||
my %flags;
|
||||
foreach my $flag (split(',', $flags)) {
|
||||
if ($flag eq 'ND') {
|
||||
$nd = 1;
|
||||
} elsif ($flag eq 'X64') {
|
||||
push(@flags, 'LONG', 'X86_64');
|
||||
# X64 is shorthand for "LONG,X86_64"
|
||||
$flags{'LONG'}++;
|
||||
$flags{'X86_64'}++;
|
||||
} elsif ($flag ne '') {
|
||||
push(@flags, $flag);
|
||||
$flags{$flag}++;
|
||||
}
|
||||
|
||||
if ($flag eq 'NEVER' || $flag eq 'NOP') {
|
||||
# These flags imply OBSOLETE
|
||||
$flags{'OBSOLETE'}++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($codes =~ /evex\./) {
|
||||
push(@flags, 'EVEX');
|
||||
$flags{'EVEX'}++;
|
||||
} elsif ($codes =~ /(vex|xop)\./) {
|
||||
push(@flags, 'VEX');
|
||||
$flags{'VEX'}++;
|
||||
}
|
||||
|
||||
$flagsindex = insns_flag_index(@flags);
|
||||
$flagsindex = insns_flag_index(keys %flags);
|
||||
die "$fname:$line: error in flags $flags" unless (defined($flagsindex));
|
||||
|
||||
@bytecode = (decodify($codes, $relax), 0);
|
||||
|
Loading…
Reference in New Issue
Block a user