mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-11-08 23:27:15 -05:00
Fix matching of branch instructions with prefixes and sizes
Matching of branch instructions with prefixes and sizes is, to say the least, tricky. Work through it, and add a new macro to help. Fixes: https://github.com/netwide-assembler/nasm/issues/144 Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
This commit is contained in:
3297
test/jmpxx.asm
Normal file
3297
test/jmpxx.asm
Normal file
File diff suppressed because it is too large
Load Diff
97
test/jmpxx.pl
Normal file
97
test/jmpxx.pl
Normal file
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
my $bw = 1;
|
||||
my @errs = ();
|
||||
foreach my $errf (@ARGV) {
|
||||
if (open(my $e, '<', $errf)) {
|
||||
while (defined(my $l = <$e>)) {
|
||||
if ($l =~ /^.*?\:([0-9]+)\:/) {
|
||||
$errs[$1] |= $bw;
|
||||
}
|
||||
}
|
||||
close($e);
|
||||
}
|
||||
$bw <<= 1;
|
||||
}
|
||||
|
||||
my $ln = 0;
|
||||
|
||||
$ln++; print "%pragma list options -befms\n";
|
||||
$ln++; print "%ifndef ERR\n";
|
||||
$ln++; print " %define ERR 0\n";
|
||||
$ln++; print "%endif\n";
|
||||
|
||||
my @nots = ('');
|
||||
|
||||
for (my $cc = 1; $cc < 7; $cc++) {
|
||||
my $ss = 'no';
|
||||
$ss .= 'w' if ($cc & 1);
|
||||
$ss .= 'd' if ($cc & 2);
|
||||
$ss .= 'q' if ($cc & 4);
|
||||
$ln++; print "%macro $ss 1+.nolist\n";
|
||||
$ln++; printf " %%if ERR || !(__BITS__ & 0x%02x)\n", $cc << 4;
|
||||
$ln++; print "\t%1\n";
|
||||
$ln++; print " %endif\n";
|
||||
$ln++; print "%endmacro\n";
|
||||
push(@nots, "$ss");
|
||||
}
|
||||
$ln++; print "%macro bogus 1+.nolist\n";
|
||||
$ln++; printf " %%if ERR\n";
|
||||
$ln++; print "\t%1\n";
|
||||
$ln++; print " %endif\n";
|
||||
$ln++; print "%endmacro\n";
|
||||
push(@nots, 'bogus');
|
||||
|
||||
$ln++; print "\n";
|
||||
|
||||
$ln++; print "\tsection text1\n";
|
||||
$ln++; print "top:\n";
|
||||
$ln++; print "\ttimes 128 nop\n";
|
||||
$ln++; print "\n";
|
||||
|
||||
foreach my $insn ('jmp', 'call', 'jz', 'jcxz', 'jecxz', 'jrcxz',
|
||||
'loop', 'loope', 'loopne') {
|
||||
$ln++; print "here_$insn:\n";
|
||||
|
||||
foreach my $tgt ('$', 'top', 'there') {
|
||||
foreach my $str ('', 'strict') {
|
||||
foreach my $sz ('', 'byte', 'word', 'dword', 'qword') {
|
||||
foreach my $o ('', 'o16', 'o32', 'o64') {
|
||||
foreach my $sn ('', 'short', 'near') {
|
||||
my $is_short =
|
||||
($sn eq 'short' || $insn =~ /^(j\w?cxz|loop\w*)$/);
|
||||
|
||||
$ln++;
|
||||
$errs[$ln] |= 3 if ($sz eq 'qword' || $o eq 'o64'
|
||||
|| $insn eq 'jrcxz');
|
||||
$errs[$ln] |= 4 if ($sz =~ /^d?word$'/ || $o =~ /^o(16|32)$/ ||
|
||||
$insn eq 'jcxz');
|
||||
if (($sz eq 'word' && $o =~ /^o(32|64)$/) ||
|
||||
($sz eq 'dword' && $o =~ /^o(16|64)$/) ||
|
||||
($sz eq 'qword' && $o =~ /^o(16|32)$/) ||
|
||||
($sz eq 'byte') ||
|
||||
($is_short &&
|
||||
($sn eq 'near' || $tgt ne '$' || $insn eq 'call'))) {
|
||||
$errs[$ln] |= 7;
|
||||
}
|
||||
|
||||
my $is_short =
|
||||
|
||||
printf " %-5s %s\n",
|
||||
$nots[$errs[$ln]],
|
||||
join(' ', grep { $_ ne '' }
|
||||
($o,$insn,$str,$sz,$sn,$tgt));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$ln++; print "\n";
|
||||
$ln++; print "\tsection text2\n";
|
||||
$ln++; print "there:\n";
|
||||
$ln++; print "\tret\n";
|
||||
Reference in New Issue
Block a user