summaryrefslogtreecommitdiffstats
path: root/libcpu
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2008-12-31 10:15:30 -0800
committerUlrich Drepper <drepper@redhat.com>2008-12-31 10:15:30 -0800
commit98c245eb57b7a95b8673031cb8562b36716a04f4 (patch)
tree89e3ab0baca32ca717fa636f17cf8e7cddf44de1 /libcpu
parentb51abc6fc1fbde6d88c8fe02ffa0a93aa57502a4 (diff)
Optimize x86/x86-64 disassembler a bit.
Diffstat (limited to 'libcpu')
-rw-r--r--libcpu/ChangeLog7
-rw-r--r--libcpu/i386_disasm.c25
-rw-r--r--libcpu/i386_parse.y2
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);
}