summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-04-15 23:12:17 +0000
committerH. Peter Anvin <hpa@zytor.com>2007-04-15 23:12:17 +0000
commit99f309cc07b6cf7406711eed43f4b9d140a93bc2 (patch)
tree8848c1d7cc43b8b894107633433a25973bf7fe78
parent2b8f5d2b8044ea82a4413fc5609bb29090b30a32 (diff)
downloadnasm-99f309cc07b6cf7406711eed43f4b9d140a93bc2.tar.gz
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.
-rw-r--r--nasm.h1
-rw-r--r--ndisasm.c26
-rw-r--r--regs.dat256
-rwxr-xr-xregs.pl60
4 files changed, 157 insertions, 186 deletions
diff --git a/nasm.h b/nasm.h
index e4a725a5..e860eadc 100644
--- a/nasm.h
+++ b/nasm.h
@@ -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 */
diff --git a/ndisasm.c b/ndisasm.c
index d7bbc963..f9793838 100644
--- a/ndisasm.c
+++ b/ndisasm.c
@@ -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 */
diff --git a/regs.dat b/regs.dat
index 1842afa6..00a5afc9 100644
--- a/regs.dat
+++ b/regs.dat
@@ -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
diff --git a/regs.pl b/regs.pl
index b5c7e495..e96029a2 100755
--- a/regs.pl
+++ b/regs.pl
@@ -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;
-
- $regs{$reg} = $aclass;
- $regvals{$reg} = $regval;
+ $reg = $1;
+ $aclass = $2;
+ $dclasses = $3;
+ $regval = toint($4);
+ $x86regno = toint($5);
- 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";