summaryrefslogtreecommitdiff
path: root/disasm.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-09-18 15:08:20 -0700
committerH. Peter Anvin <hpa@zytor.com>2007-09-18 15:08:20 -0700
commit19e201053689be68d0e45077fa86e9538d74daa1 (patch)
tree49c9bbd3d44939e9795951e72d700c83224e6f13 /disasm.c
parent0edc309505e659345cf353f81fb77793f8f5c291 (diff)
downloadnasm-19e201053689be68d0e45077fa86e9538d74daa1.tar.gz
Speed up the disassembler by allowing prefixed instruction tables
Modify the disassembler so that we can have separate instruction tables for prefixed instructions. As it was, all instructions which started with 0F were linearly searched, and that is by now more than half the instruction set.
Diffstat (limited to 'disasm.c')
-rw-r--r--disasm.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/disasm.c b/disasm.c
index 3a8f710d..a6c1c729 100644
--- a/disasm.c
+++ b/disasm.c
@@ -671,9 +671,11 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
int32_t offset, int autosync, uint32_t prefer)
{
const struct itemplate * const *p, * const *best_p;
+ const struct disasm_index *ix;
+ uint8_t *dp;
int length, best_length = 0;
char *segover;
- int i, slen, colon;
+ int i, slen, colon, n;
uint8_t *origdata;
int works;
insn tmp_ins, ins;
@@ -728,7 +730,14 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
best_p = NULL;
best_pref = INT_MAX;
- for (p = itable[*data]; *p; p++) {
+ dp = data;
+ ix = itable + *dp++;
+ while (ix->n == (size_t)-1) {
+ ix = (const struct disasm_index *)ix->p + *dp++;
+ }
+
+ p = (const struct itemplate * const *)ix->p;
+ for (n = ix->n; n; n--, p++) {
if ((length = matches(*p, data, &prefix, segsize, &tmp_ins))) {
works = TRUE;
/*