diff options
author | Ulrich Drepper <drepper@redhat.com> | 2008-12-31 10:15:30 -0800 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2008-12-31 10:15:30 -0800 |
commit | 98c245eb57b7a95b8673031cb8562b36716a04f4 (patch) | |
tree | 89e3ab0baca32ca717fa636f17cf8e7cddf44de1 /libcpu | |
parent | b51abc6fc1fbde6d88c8fe02ffa0a93aa57502a4 (diff) |
Optimize x86/x86-64 disassembler a bit.
Diffstat (limited to 'libcpu')
-rw-r--r-- | libcpu/ChangeLog | 7 | ||||
-rw-r--r-- | libcpu/i386_disasm.c | 25 | ||||
-rw-r--r-- | libcpu/i386_parse.y | 2 |
3 files changed, 18 insertions, 16 deletions
diff --git a/libcpu/ChangeLog b/libcpu/ChangeLog index 90c2e588..041123e1 100644 --- a/libcpu/ChangeLog +++ b/libcpu/ChangeLog @@ -1,5 +1,12 @@ 2008-12-31 Ulrich Drepper <drepper@redhat.com> + * i386_disasm.c (i386_disasm): Minor optimizations. + + * i386_parse.y (instrtable_out): No need to emit index, the reader can + keep track. + * i386_disasm.c (i386_disasm): The index is not emitted anymore, no + need to skip it. + * i386_disasm.c (amd3dnow): Mark as const. * defs/i386: Add blendvpd and blendvps opcodes. diff --git a/libcpu/i386_disasm.c b/libcpu/i386_disasm.c index 75936356..9961e4d9 100644 --- a/libcpu/i386_disasm.c +++ b/libcpu/i386_disasm.c @@ -393,17 +393,16 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr, bufcnt = 0; size_t cnt = 0; + next_match: while (curr < match_end) { - const uint8_t *start = curr; - uint_fast8_t len = *curr++; + const uint8_t *start = curr; assert (len > 0); - assert (curr + 2 * len + 2 <= match_end); + assert (curr + 2 * len <= match_end); const uint8_t *codep = data; - size_t avail = len; int correct_prefix = 0; int opoff = 0; @@ -411,8 +410,6 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr, { /* We match a prefix byte. This is exactly one byte and is matched exactly, without a mask. */ - --avail; - --len; start += 2; opoff = 8; @@ -423,25 +420,23 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr, correct_prefix = last_prefix_bit; } + size_t avail = len; while (avail > 0) { uint_fast8_t masked = *codep++ & *curr++; if (masked != *curr++) - break; + { + not: + curr = start + 2 * len; + ++cnt; + goto next_match; + } --avail; if (codep == end && avail > 0) goto do_ret; } - if (avail != 0) - { - not: - curr = start + 1 + 2 * len + 2; - ++cnt; - continue; - } - if (len > end - data) /* There is not enough data for the entire instruction. The caller can figure this out by looking at the pointer into diff --git a/libcpu/i386_parse.y b/libcpu/i386_parse.y index ceeb12ad..6297d5d9 100644 --- a/libcpu/i386_parse.y +++ b/libcpu/i386_parse.y @@ -1296,7 +1296,7 @@ instrtable_out (void) b = b->next; } - fprintf (outfile, " %#zx, %#zx,\n", cnt & 0xff, cnt >> 8); + fputc_unlocked ('\n', outfile); } fputs ("};\n", outfile); } |