summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--asm/assemble.c4
-rw-r--r--asm/parser.c4
-rw-r--r--common/common.c58
-rw-r--r--include/insns.h72
-rw-r--r--x86/insns.dat4
-rwxr-xr-xx86/insns.pl15
6 files changed, 81 insertions, 76 deletions
diff --git a/asm/assemble.c b/asm/assemble.c
index 1a784560..73d2e171 100644
--- a/asm/assemble.c
+++ b/asm/assemble.c
@@ -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) {
diff --git a/asm/parser.c b/asm/parser.c
index d701d7fd..62104e12 100644
--- a/asm/parser.c
+++ b/asm/parser.c
@@ -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;
diff --git a/common/common.c b/common/common.c
index 5a546207..13237994 100644
--- a/common/common.c
+++ b/common/common.c
@@ -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;
- }
-}
diff --git a/include/insns.h b/include/insns.h
index 0a1cd741..7c1896bc 100644
--- a/include/insns.h
+++ b/include/insns.h
@@ -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 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)
{
- return resv_bytes(opcode) > 0;
+ 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 */
diff --git a/x86/insns.dat b/x86/insns.dat
index 00f25711..73b0a85a 100644
--- a/x86/insns.dat
+++ b/x86/insns.dat
@@ -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
diff --git a/x86/insns.pl b/x86/insns.pl
index e6d3eee1..5845ed89 100755
--- a/x86/insns.pl
+++ b/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";