summaryrefslogtreecommitdiffstats
path: root/libcpu
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2008-12-31 11:34:47 -0800
committerUlrich Drepper <drepper@redhat.com>2008-12-31 11:34:47 -0800
commit71696bafdb14435b5e572b0e7639b4b42e40c671 (patch)
tree8d39e40cfbede9a5eaefa7f4c770a679dbd87dd5 /libcpu
parent54a6d4b1b6828519ea707f2ce4d8c1829c9fe595 (diff)
Optimize x86/x86-64 disassembler some more. Avoid relocations for string
table.
Diffstat (limited to 'libcpu')
-rw-r--r--libcpu/ChangeLog10
-rw-r--r--libcpu/i386_disasm.c9
-rw-r--r--libcpu/i386_parse.y29
3 files changed, 41 insertions, 7 deletions
diff --git a/libcpu/ChangeLog b/libcpu/ChangeLog
index c562ff54..b3abff7b 100644
--- a/libcpu/ChangeLog
+++ b/libcpu/ChangeLog
@@ -1,5 +1,15 @@
2008-12-31 Ulrich Drepper <drepper@redhat.com>
+ * i386_parse.y (struct argstring): Add off element.
+ (off_op_str): New global variable.
+ (print_op_str): Print strings as concatenated strings. Keep track
+ of index and length. Update ->off element.
+ (print_op_str_idx): New function.
+ (instrtable_out): Mark op%d_fct as const.
+ Emit two tables for the strings: the string itself (op%d_str) and the
+ index table (op%d_str_idx).
+ * i386_disasm.c (i386_disasm): Adjust for new op%d_str definition.
+
* i386_disasm.c [X86_64] (i386_disasm): Handle rex prefix when
printing only prefix.
diff --git a/libcpu/i386_disasm.c b/libcpu/i386_disasm.c
index b99748b6..3ba513b4 100644
--- a/libcpu/i386_disasm.c
+++ b/libcpu/i386_disasm.c
@@ -860,7 +860,8 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr,
{
/* First parameter. */
if (instrtab[cnt].str1 != 0)
- ADD_STRING (op1_str[instrtab[cnt].str1]);
+ ADD_STRING (op1_str
+ + op1_str_idx[instrtab[cnt].str1 - 1]);
output_data.opoff1 = (instrtab[cnt].off1_1
+ OFF1_1_BIAS - opoff);
@@ -880,7 +881,8 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr,
{
/* Second parameter. */
if (instrtab[cnt].str2 != 0)
- ADD_STRING (op2_str[instrtab[cnt].str2]);
+ ADD_STRING (op2_str
+ + op2_str_idx[instrtab[cnt].str2 - 1]);
output_data.opoff1 = (instrtab[cnt].off2_1
+ OFF2_1_BIAS - opoff);
@@ -900,7 +902,8 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr,
{
/* Third parameter. */
if (instrtab[cnt].str3 != 0)
- ADD_STRING (op3_str[instrtab[cnt].str3]);
+ ADD_STRING (op3_str
+ + op3_str_idx[instrtab[cnt].str3 - 1]);
output_data.opoff1 = (instrtab[cnt].off3_1
+ OFF3_1_BIAS - opoff);
diff --git a/libcpu/i386_parse.y b/libcpu/i386_parse.y
index 6297d5d9..f850de77 100644
--- a/libcpu/i386_parse.y
+++ b/libcpu/i386_parse.y
@@ -145,6 +145,7 @@ struct argstring
{
char *str;
int idx;
+ int off;
};
@@ -1066,19 +1067,33 @@ compare_suf (const void *p1, const void *p2)
static int count_op_str;
+static int off_op_str;
static void
print_op_str (const void *nodep, VISIT value,
int level __attribute__ ((unused)))
{
if (value == leaf || value == postorder)
{
- fprintf (outfile, " \"%s\",\n", (*(struct argstring **) nodep)->str);
+ const char *str = (*(struct argstring **) nodep)->str;
+ fprintf (outfile, "%s\n \"%s",
+ count_op_str == 0 ? "" : "\\0\"", str);
(*(struct argstring **) nodep)->idx = ++count_op_str;
+ (*(struct argstring **) nodep)->off = off_op_str;
+ off_op_str += strlen (str) + 1;
}
}
static void
+print_op_str_idx (const void *nodep, VISIT value,
+ int level __attribute__ ((unused)))
+{
+ if (value == leaf || value == postorder)
+ printf (" %d,\n", (*(struct argstring **) nodep)->off);
+}
+
+
+static void
print_op_fct (const void *nodep, VISIT value,
int level __attribute__ ((unused)))
{
@@ -1149,7 +1164,8 @@ instrtable_out (void)
{
/* Functions. */
count_op_str = 0;
- fprintf (outfile, "static opfct_t op%d_fct[] =\n{\n NULL,\n", i + 1);
+ fprintf (outfile, "static const opfct_t op%d_fct[] =\n{\n NULL,\n",
+ i + 1);
twalk (fct_names[i], print_op_fct);
fputs ("};\n", outfile);
@@ -1157,9 +1173,14 @@ instrtable_out (void)
if (nbitstr[i] != 0)
{
count_op_str = 0;
- fprintf (outfile, "static const char *op%d_str[] =\n{\n NULL,\n",
- i + 1);
+ off_op_str = 0;
+ fprintf (outfile, "static const char op%d_str[] =", i + 1);
twalk (strs[i], print_op_str);
+ fputs ("\"\n;\n", outfile);
+
+ fprintf (outfile, "static const uint8_t op%d_str_idx[] = {\n",
+ i + 1);
+ twalk (strs[i], print_op_str_idx);
fputs ("};\n", outfile);
}
}