From 99f309cc07b6cf7406711eed43f4b9d140a93bc2 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sun, 15 Apr 2007 23:12:17 +0000 Subject: [PATCH] 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. --- nasm.h | 1 - ndisasm.c | 26 +++--- regs.dat | 256 ++++++++++++++++++++++-------------------------------- regs.pl | 60 ++++++++----- 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 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; + $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 = ) ) { 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";