Clean up the 64-bitification of regs.dat for 64-bit ndisasm support

64-bit support required some major changes to regs.dat; clean some of
it up (re-introduce patterns, where appropriate) and allow a single
register to belong to multiple disassembly classes; also keep track
of the x86 register number again.
This commit is contained in:
H. Peter Anvin 2007-04-15 23:12:17 +00:00
parent 2b8f5d2b80
commit 99f309cc07
4 changed files with 157 additions and 186 deletions

1
nasm.h
View File

@ -433,7 +433,6 @@ enum {
#define REG_CREG 0x08101004L /* CRn */
#define REG_DREG 0x10101004L /* DRn */
#define REG_TREG 0x20101004L /* TRn */
#define REG_C8REG 0x40101004L /* CR8 */
/* special type of EA */
#define MEM_OFFS 0x00604000L /* simple [address] offset */

View File

@ -25,8 +25,8 @@ static const char *help =
"usage: ndisasm [-a] [-i] [-h] [-r] [-u] [-b bits] [-o origin] [-s sync...]\n"
" [-e bytes] [-k start,bytes] [-p vendor] file\n"
" -a or -i activates auto (intelligent) sync\n"
" -u sets USE32 (32-bit mode)\n"
" -b 16 or -b 32 sets number of bits too\n"
" -u same as -b 32\n"
" -b 16, -b 32 or -b 64 sets the processor mode\n"
" -h displays this text\n"
" -r or -v displays the version number\n"
" -e skips <bytes> bytes of header\n"
@ -38,7 +38,7 @@ static void skip(uint32_t dist, FILE * fp);
int main(int argc, char **argv)
{
uint8_t buffer[INSN_MAX * 2], *p, *q;
char buffer[INSN_MAX * 2], *p, *ep, *q;
char outbuf[256];
char *pname = *argv;
char *filename = NULL;
@ -46,7 +46,7 @@ int main(int argc, char **argv)
int lenread;
int32_t lendis;
int autosync = FALSE;
int bits = 16;
int bits = 16, b;
int eof = FALSE;
uint32_t prefer = 0;
int rn_error;
@ -76,8 +76,9 @@ int main(int argc, char **argv)
"NDISASM version %s compiled " __DATE__ "\n",
NASM_VER);
return 0;
case 'u': /* USE32 */
bits = 32;
case 'u': /* -u for -b 32, -uu for -b 64 */
if (bits < 64)
bits <<= 1;
p++;
break;
case 'b': /* bits */
@ -87,14 +88,13 @@ int main(int argc, char **argv)
pname);
return 1;
}
if (!strcmp(v, "16"))
bits = 16;
else if (!strcmp(v, "32"))
bits = 32;
else {
b = strtoul(v, &ep, 10);
if (*ep || !(bits == 16 || bits == 32 || bits == 64)) {
fprintf(stderr, "%s: argument to `-b' should"
" be `16' or `32'\n", pname);
}
" be 16, 32 or 64\n", pname);
} else {
bits = b;
}
p = ""; /* force to next argument */
break;
case 'o': /* origin */

256
regs.dat
View File

@ -2,8 +2,17 @@
#
# List of registers and their classes; classes are defined in nasm.h
#
# The columns are: register name, assembler class, disassembler class, regval
# A * means the line should be repeated for each value from 0 to 7
# The columns are:
#
# register name, assembler class, disassembler class(es),
# NASM register number, x86 register number
#
# If the register name ends in *, then it is repeated 8 times
# with the following changes:
# - a numerical tail to register number is incremented
# - the NASM and x86 register numbers are incremented
#
# For 16-register register sets, two * lines are required.
#
# Legacy Registers
@ -35,169 +44,112 @@
# General-purpose registers
al REG_AL reg8 0000
ah REG8 reg8 0004
ax REG_AX reg16 0010
eax REG_EAX reg32 0020
rax REG_RAX reg64 0440
bl REG8 reg8 0003
bh REG8 reg8 0007
bx REG16 reg16 0013
ebx REG32 reg32 0023
rbx REG64 reg64 0443
cl REG_CL reg8 0001
ch REG8 reg8 0005
cx REG_CX reg16 0011
ecx REG_ECX reg32 0021
rcx REG_RCX reg64 0441
dl REG_DL reg8 0002
dh REG8 reg8 0006
dx REG_DX reg16 0012
edx REG_EDX reg32 0022
rdx REG_RDX reg64 0442
spl REG8 reg8 0404
sp REG16 reg16 0014
esp REG32 reg32 0024
rsp REG64 reg64 0444
bpl REG8 reg8 0405
bp REG16 reg16 0015
ebp REG32 reg32 0025
rbp REG64 reg64 0445
sil REG8 reg8 0406
si REG16 reg16 0016
esi REG32 reg32 0026
rsi REG64 reg64 0446
dil REG8 reg8 0407
di REG16 reg16 0017
edi REG32 reg32 0027
rdi REG64 reg64 0447
r8b REG8 reg8 0410
r8w REG16 reg16 0420
r8d REG32 reg32 0430
r8 REG64 reg64 0450
r9b REG8 reg8 0411
r9w REG16 reg16 0421
r9d REG32 reg32 0431
r9 REG64 reg64 0451
r10b REG8 reg8 0412
r10w REG16 reg16 0422
r10d REG32 reg32 0432
r10 REG64 reg64 0452
r11b REG8 reg8 0413
r11w REG16 reg16 0423
r11d REG32 reg32 0433
r11 REG64 reg64 0453
r12b REG8 reg8 0414
r12w REG16 reg16 0424
r12d REG32 reg32 0434
r12 REG64 reg64 0454
r13b REG8 reg8 0415
r13w REG16 reg16 0425
r13d REG32 reg32 0435
r13 REG64 reg64 0455
r14b REG8 reg8 0416
r14w REG16 reg16 0426
r14d REG32 reg32 0436
r14 REG64 reg64 0456
r15b REG8 reg8 0417
r15w REG16 reg16 0427
r15d REG32 reg32 0437
r15 REG64 reg64 0457
al REG_AL reg8,reg8_rex 0000 0
ah REG8 reg8 0004 4
ax REG_AX reg16 0010 0
eax REG_EAX reg32 0020 0
rax REG_RAX reg64 0440 0
bl REG8 reg8,reg8_rex 0003 3
bh REG8 reg8 0007 7
bx REG16 reg16 0013 3
ebx REG32 reg32 0023 3
rbx REG64 reg64 0443 3
cl REG_CL reg8,reg8_rex 0001 1
ch REG8 reg8 0005 5
cx REG_CX reg16 0011 1
ecx REG_ECX reg32 0021 1
rcx REG_RCX reg64 0441 1
dl REG_DL reg8,reg8_rex 0002 2
dh REG8 reg8 0006 6
dx REG_DX reg16 0012 2
edx REG_EDX reg32 0022 2
rdx REG_RDX reg64 0442 2
spl REG8 reg8_rex 0404 4
sp REG16 reg16 0014 4
esp REG32 reg32 0024 4
rsp REG64 reg64 0444 4
bpl REG8 reg8_rex 0405 5
bp REG16 reg16 0015 5
ebp REG32 reg32 0025 5
rbp REG64 reg64 0445 5
sil REG8 reg8_rex 0406 6
si REG16 reg16 0016 6
esi REG32 reg32 0026 6
rsi REG64 reg64 0446 6
dil REG8 reg8_rex 0407 7
di REG16 reg16 0017 7
edi REG32 reg32 0027 7
rdi REG64 reg64 0447 7
r8b REG8 reg8_rex 0410 8
r8w REG16 reg16 0420 8
r8d REG32 reg32 0430 8
r8 REG64 reg64 0450 8
r9b REG8 reg8_rex 0411 9
r9w REG16 reg16 0421 9
r9d REG32 reg32 0431 9
r9 REG64 reg64 0451 9
r10b REG8 reg8_rex 0412 10
r10w REG16 reg16 0422 10
r10d REG32 reg32 0432 10
r10 REG64 reg64 0452 10
r11b REG8 reg8_rex 0413 11
r11w REG16 reg16 0423 11
r11d REG32 reg32 0433 11
r11 REG64 reg64 0453 11
r12b REG8 reg8_rex 0414 12
r12w REG16 reg16 0424 12
r12d REG32 reg32 0434 12
r12 REG64 reg64 0454 12
r13b REG8 reg8_rex 0415 13
r13w REG16 reg16 0425 13
r13d REG32 reg32 0435 13
r13 REG64 reg64 0455 13
r14b REG8 reg8_rex 0416 14
r14w REG16 reg16 0426 14
r14d REG32 reg32 0436 14
r14 REG64 reg64 0456 14
r15b REG8 reg8_rex 0417 15
r15w REG16 reg16 0427 15
r15d REG32 reg32 0437 15
r15 REG64 reg64 0457 15
# Segment registers
cs REG_CS sreg 0101
ds REG_DESS sreg 0103
es REG_DESS sreg 0100
ss REG_DESS sreg 0102
fs REG_FSGS sreg 0104
gs REG_FSGS sreg 0105
segr6 REG_SEG67 sreg 0106
segr7 REG_SEG67 sreg 0107
cs REG_CS sreg 0101 1
ds REG_DESS sreg 0103 3
es REG_DESS sreg 0100 0
ss REG_DESS sreg 0102 2
fs REG_FSGS sreg 0104 4
gs REG_FSGS sreg 0105 5
segr6 REG_SEG67 sreg 0106 6
segr7 REG_SEG67 sreg 0107 7
# Control registers
cr0 REG_CREG creg 0110
cr1 REG_CREG creg 0111
cr2 REG_CREG creg 0112
cr3 REG_CREG creg 0113
cr4 REG_CREG creg 0114
cr5 REG_CREG creg 0115
cr6 REG_CREG creg 0116
cr7 REG_CREG creg 0117
cr8 REG_C8REG creg 0120
cr9 REG_CREG creg 0121
cr10 REG_CREG creg 0122
cr11 REG_CREG creg 0123
cr12 REG_CREG creg 0124
cr13 REG_CREG creg 0125
cr14 REG_CREG creg 0126
cr15 REG_CREG creg 0127
cr0* REG_CREG creg 0110 0
cr8* REG_CREG creg 0120 8
# Debug registers
dr0 REG_DREG dreg 0130
dr1 REG_DREG dreg 0131
dr2 REG_DREG dreg 0132
dr3 REG_DREG dreg 0133
dr4 REG_DREG dreg 0134
dr5 REG_DREG dreg 0135
dr6 REG_DREG dreg 0136
dr7 REG_DREG dreg 0137
dr8 REG_DREG dreg 0140
dr9 REG_DREG dreg 0141
dr10 REG_DREG dreg 0142
dr11 REG_DREG dreg 0143
dr12 REG_DREG dreg 0144
dr13 REG_DREG dreg 0145
dr14 REG_DREG dreg 0146
dr15 REG_DREG dreg 0147
dr0* REG_DREG dreg 0130 0
dr8* REG_DREG dreg 0140 8
# Test registers
tr0 REG_TREG treg 0150
tr1 REG_TREG treg 0151
tr2 REG_TREG treg 0152
tr3 REG_TREG treg 0153
tr4 REG_TREG treg 0154
tr5 REG_TREG treg 0155
tr6 REG_TREG treg 0156
tr7 REG_TREG treg 0157
tr0* REG_TREG treg 0150 0
# Floating-point registers
st0 FPU0 fpureg 0200
st1 FPUREG fpureg 0201
st2 FPUREG fpureg 0202
st3 FPUREG fpureg 0203
st4 FPUREG fpureg 0204
st5 FPUREG fpureg 0205
st6 FPUREG fpureg 0206
st7 FPUREG fpureg 0207
st0 FPU0 fpureg 0200 0
st1 FPUREG fpureg 0201 1
st2 FPUREG fpureg 0202 2
st3 FPUREG fpureg 0203 3
st4 FPUREG fpureg 0204 4
st5 FPUREG fpureg 0205 5
st6 FPUREG fpureg 0206 6
st7 FPUREG fpureg 0207 7
# MMX registers
mm0 MMXREG mmxreg 0220
mm1 MMXREG mmxreg 0221
mm2 MMXREG mmxreg 0222
mm3 MMXREG mmxreg 0223
mm4 MMXREG mmxreg 0224
mm5 MMXREG mmxreg 0225
mm6 MMXREG mmxreg 0226
mm7 MMXREG mmxreg 0227
mm0* MMXREG mmxreg 0220 0
# SSE registers
xmm0 XMMREG xmmreg 0240
xmm1 XMMREG xmmreg 0241
xmm2 XMMREG xmmreg 0242
xmm3 XMMREG xmmreg 0243
xmm4 XMMREG xmmreg 0244
xmm5 XMMREG xmmreg 0245
xmm6 XMMREG xmmreg 0246
xmm7 XMMREG xmmreg 0247
xmm8 XMMREG xmmreg 0460
xmm9 XMMREG xmmreg 0461
xmm10 XMMREG xmmreg 0462
xmm11 XMMREG xmmreg 0463
xmm12 XMMREG xmmreg 0464
xmm13 XMMREG xmmreg 0465
xmm14 XMMREG xmmreg 0466
xmm15 XMMREG xmmreg 0467
xmm0* XMMREG xmmreg 0240 0
xmm8* XMMREG xmmreg 0460 8
# Special registers
rip REG_RIP ripreg 0500
rip REG_RIP ripreg 0500

60
regs.pl
View File

@ -6,26 +6,51 @@
$nline = 0;
sub toint($) {
my($v) = @_;
return ($v =~ /^0/) ? oct $v : $v+0;
}
sub process_line($) {
my($line) = @_;
my @v;
if ( $line !~ /^\s*(\S+)\s*(\S+)\s*(\S+)\s*([0-9]+)\s*$/ ) {
if ( $line !~ /^\s*(\S+)\s*(\S+)\s*(\S+)\s*([1-9][0-9]+|0[0-7]+|0x[0-9a-f]+)\s*([0-9]+)$/i ) {
die "regs.dat:$nline: invalid input\n";
}
$reg = $1;
$aclass = $2;
$dclass = $3;
$regval = $4;
$reg = $1;
$aclass = $2;
$dclasses = $3;
$regval = toint($4);
$x86regno = toint($5);
$regs{$reg} = $aclass;
$regvals{$reg} = $regval;
if ( !defined($disclass{$dclass}) ) {
$disclass{$dclass} = [(undef) x 8];
if ($reg =~ /\*$/) {
$nregs = 8;
$reg =~ s/\*$//;
} else {
$nregs = 1;
}
$disclass{$dclass}->[$regval] = $reg;
while ($nregs--) {
$regs{$reg} = $aclass;
$regvals{$reg} = $regval;
foreach $dclass (split(/,/, $dclasses)) {
if ( !defined($disclass{$dclass}) ) {
$disclass{$dclass} = [];
}
$disclass{$dclass}->[$x86regno] = $reg;
}
# Compute the next register, if any
$regval++;
$x86regno++;
if ($reg =~ /^(|.*[^0-9])([0-9]+)$/) {
$reg = sprintf("%s%u", $1, $2+1);
}
}
}
($fmt, $file) = @ARGV;
@ -42,14 +67,7 @@ while ( defined($line = <REGS>) ) {
next if ( $line eq '' );
if ( $line =~ /\*/ ) {
for ( $i = 0 ; $i < 8 ; $i++ ) {
($xline = $line) =~ s/\*/$i/g;
process_line($xline);
}
} else {
process_line($line);
}
process_line($line);
}
close(REGS);
@ -93,7 +111,7 @@ if ( $fmt eq 'h' ) {
print "static const int regvals[] = {\n";
print " -1"; # Dummy entry for 0
foreach $reg ( sort(keys(%regs)) ) {
print ",\n ", $regvals{$reg}; # Print the regval of the register
printf ",\n 0%03o", $regvals{$reg}; # Print the regval of the register
}
print "\n};\n";
} elsif ( $fmt eq 'dc' ) {
@ -106,6 +124,8 @@ if ( $fmt eq 'h' ) {
for ( $i = 0 ; $i < scalar(@foo) ; $i++ ) {
if (defined($foo[$i])) {
push(@bar, "R_\U$foo[$i]\E");
} else {
die "$0: No register name for class $class, value $i\n";
}
}
print join(',', @bar), "};\n";