mirror of
https://github.com/netwide-assembler/nasm.git
synced 2024-11-21 03:14:19 +08:00
Don't sort opcodes; move all pseudo-ops to the beginning
We don't need to sort opcodes anymore, since we are using an O(1) hash and not binary search. Instead, sort them in the order they first appear in insns.dat; this lets us move all the pseudo-ops to a contiguous range at the start of the file, for more efficient handling. Change the functions that process pseudo-ops accordingly. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
parent
d23066906c
commit
af9fe8f597
@ -555,7 +555,7 @@ int64_t assemble(int32_t segment, int64_t start, int bits, insn *instruction)
|
||||
data.sign = OUT_WRAP;
|
||||
data.bits = bits;
|
||||
|
||||
wsize = idata_bytes(instruction->opcode);
|
||||
wsize = db_bytes(instruction->opcode);
|
||||
if (wsize == -1)
|
||||
return 0;
|
||||
|
||||
@ -790,7 +790,7 @@ int64_t insn_size(int32_t segment, int64_t offset, int bits, insn *instruction)
|
||||
int32_t isize, osize, wsize;
|
||||
|
||||
isize = 0;
|
||||
wsize = idata_bytes(instruction->opcode);
|
||||
wsize = db_bytes(instruction->opcode);
|
||||
nasm_assert(wsize > 0);
|
||||
|
||||
list_for_each(e, instruction->eops) {
|
||||
|
@ -666,7 +666,7 @@ is_float:
|
||||
eop->type = EOT_DB_STRING;
|
||||
result->eops_float = true;
|
||||
|
||||
eop->stringlen = idata_bytes(result->opcode);
|
||||
eop->stringlen = db_bytes(result->opcode);
|
||||
if (eop->stringlen > 16) {
|
||||
nasm_error(ERR_NONFATAL, "floating-point constant"
|
||||
" encountered in DY or DZ instruction");
|
||||
@ -1129,7 +1129,7 @@ is_expression:
|
||||
* Transform RESW, RESD, RESQ, REST, RESO, RESY, RESZ into RESB.
|
||||
*/
|
||||
if (opcode_is_resb(result->opcode)) {
|
||||
result->oprs[0].offset *= resv_bytes(result->opcode);
|
||||
result->oprs[0].offset *= resb_bytes(result->opcode);
|
||||
result->oprs[0].offset *= result->times;
|
||||
result->times = 1;
|
||||
result->opcode = I_RESB;
|
||||
|
@ -62,61 +62,3 @@ const char *prefix_name(int token)
|
||||
|
||||
return prefix_names[prefix];
|
||||
}
|
||||
|
||||
/*
|
||||
* initialized data bytes length from opcode
|
||||
*/
|
||||
int idata_bytes(int opcode)
|
||||
{
|
||||
switch (opcode) {
|
||||
case I_DB:
|
||||
return 1;
|
||||
case I_DW:
|
||||
return 2;
|
||||
case I_DD:
|
||||
return 4;
|
||||
case I_DQ:
|
||||
return 8;
|
||||
case I_DT:
|
||||
return 10;
|
||||
case I_DO:
|
||||
return 16;
|
||||
case I_DY:
|
||||
return 32;
|
||||
case I_DZ:
|
||||
return 64;
|
||||
case I_none:
|
||||
return -1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Uninitialized data bytes length from opcode
|
||||
*/
|
||||
int resv_bytes(int opcode)
|
||||
{
|
||||
switch (opcode) {
|
||||
case I_RESB:
|
||||
return 1;
|
||||
case I_RESW:
|
||||
return 2;
|
||||
case I_RESD:
|
||||
return 4;
|
||||
case I_RESQ:
|
||||
return 8;
|
||||
case I_REST:
|
||||
return 10;
|
||||
case I_RESO:
|
||||
return 16;
|
||||
case I_RESY:
|
||||
return 32;
|
||||
case I_RESZ:
|
||||
return 64;
|
||||
case I_none:
|
||||
return -1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -48,23 +48,79 @@ extern const uint8_t nasm_bytecodes[];
|
||||
*/
|
||||
#define ITEMPLATE_END {-1,-1,{-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1},NULL,0}
|
||||
|
||||
/* Width of Dx and RESx instructions */
|
||||
int const_func idata_bytes(enum opcode opcode);
|
||||
int const_func resv_bytes(enum opcode opcode);
|
||||
|
||||
/*
|
||||
* Pseudo-op tests
|
||||
*/
|
||||
/* DB-type instruction (DB, DW, ...) */
|
||||
static inline bool opcode_is_db(enum opcode opcode)
|
||||
static inline bool const_func opcode_is_db(enum opcode opcode)
|
||||
{
|
||||
return idata_bytes(opcode) > 0;
|
||||
return opcode >= I_DB && opcode < I_RESB;
|
||||
}
|
||||
|
||||
/* RESB-type instruction (RESB, RESW, ...) */
|
||||
static inline bool opcode_is_resb(enum opcode opcode)
|
||||
static inline bool const_func opcode_is_resb(enum opcode opcode)
|
||||
{
|
||||
return resv_bytes(opcode) > 0;
|
||||
return opcode >= I_RESB && opcode < I_INCBIN;
|
||||
}
|
||||
|
||||
/* Width of Dx and RESx instructions */
|
||||
|
||||
/*
|
||||
* initialized data bytes length from opcode
|
||||
*/
|
||||
static inline int const_func db_bytes(int opcode)
|
||||
{
|
||||
switch (opcode) {
|
||||
case I_DB:
|
||||
return 1;
|
||||
case I_DW:
|
||||
return 2;
|
||||
case I_DD:
|
||||
return 4;
|
||||
case I_DQ:
|
||||
return 8;
|
||||
case I_DT:
|
||||
return 10;
|
||||
case I_DO:
|
||||
return 16;
|
||||
case I_DY:
|
||||
return 32;
|
||||
case I_DZ:
|
||||
return 64;
|
||||
case I_none:
|
||||
return -1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Uninitialized data bytes length from opcode
|
||||
*/
|
||||
static inline int resb_bytes(enum opcode opcode)
|
||||
{
|
||||
switch (opcode) {
|
||||
case I_RESB:
|
||||
return 1;
|
||||
case I_RESW:
|
||||
return 2;
|
||||
case I_RESD:
|
||||
return 4;
|
||||
case I_RESQ:
|
||||
return 8;
|
||||
case I_REST:
|
||||
return 10;
|
||||
case I_RESO:
|
||||
return 16;
|
||||
case I_RESY:
|
||||
return 32;
|
||||
case I_RESZ:
|
||||
return 64;
|
||||
case I_none:
|
||||
return -1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NASM_INSNS_H */
|
||||
|
@ -48,6 +48,8 @@
|
||||
;
|
||||
|
||||
;# Special instructions...
|
||||
; These MUST be first in this file and must maintain the pattern of
|
||||
; Dx by size, RESx by size, and INCBIN in that order.
|
||||
DB ignore ignore ignore
|
||||
DW ignore ignore ignore
|
||||
DD ignore ignore ignore
|
||||
@ -64,6 +66,7 @@ REST ignore ignore ignore
|
||||
RESO ignore ignore ignore
|
||||
RESY ignore ignore ignore
|
||||
RESZ ignore ignore ignore
|
||||
INCBIN ignore ignore ignore
|
||||
|
||||
;# Conventional instructions
|
||||
AAA void [ 37] 8086,NOLONG
|
||||
@ -652,7 +655,6 @@ INC rm8 [m: hle fe /0] 8086,LOCK
|
||||
INC rm16 [m: hle o16 ff /0] 8086,LOCK
|
||||
INC rm32 [m: hle o32 ff /0] 386,LOCK
|
||||
INC rm64 [m: hle o64 ff /0] X64,LOCK
|
||||
INCBIN ignore ignore ignore
|
||||
INSB void [ 6c] 186
|
||||
INSD void [ o32 6d] 386
|
||||
INSW void [ o16 6d] 186
|
||||
|
15
x86/insns.pl
15
x86/insns.pl
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/perl
|
||||
## --------------------------------------------------------------------------
|
||||
##
|
||||
## Copyright 1996-2016 The NASM Authors - All Rights Reserved
|
||||
## Copyright 1996-2017 The NASM Authors - All Rights Reserved
|
||||
## See the file AUTHORS included with the NASM distribution for
|
||||
## the specific copyright holders.
|
||||
##
|
||||
@ -89,6 +89,7 @@ open(F, '<', $fname) || die "unable to open $fname";
|
||||
|
||||
$line = 0;
|
||||
$insns = 0;
|
||||
$n_opcodes = $n_opcodes_cc = 0;
|
||||
while (<F>) {
|
||||
$line++;
|
||||
chomp;
|
||||
@ -146,10 +147,14 @@ while (<F>) {
|
||||
}
|
||||
if ( $fields[0] =~ /cc$/ ) {
|
||||
# Conditional instruction
|
||||
$k_opcodes_cc{$fields[0]}++;
|
||||
if (!defined($k_opcodes_cc{$fields[0]})) {
|
||||
$k_opcodes_cc{$fields[0]} = $n_opcodes_cc++;
|
||||
}
|
||||
} else {
|
||||
# Unconditional instruction
|
||||
$k_opcodes{$fields[0]}++;
|
||||
if (!defined($k_opcodes{$fields[0]})) {
|
||||
$k_opcodes{$fields[0]} = $n_opcodes++;
|
||||
}
|
||||
}
|
||||
if ($formatted && !$nd) {
|
||||
push @big, $formatted;
|
||||
@ -189,8 +194,8 @@ foreach $bl (@bytecode_list) {
|
||||
}
|
||||
undef @bytecode_list;
|
||||
|
||||
@opcodes = sort keys(%k_opcodes);
|
||||
@opcodes_cc = sort keys(%k_opcodes_cc);
|
||||
@opcodes = sort { $k_opcodes{$a} <=> $k_opcodes{$b} } keys(%k_opcodes);
|
||||
@opcodes_cc = sort { $k_opcodes_cc{$a} <=> $k_opcodes_cc{$b} } keys(%k_opcodes_cc);
|
||||
|
||||
if ( $output eq 'b') {
|
||||
print STDERR "Writing $oname...\n";
|
||||
|
Loading…
Reference in New Issue
Block a user