diff options
author | Ulrich Drepper <drepper@redhat.com> | 2008-12-31 11:34:47 -0800 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2008-12-31 11:34:47 -0800 |
commit | 71696bafdb14435b5e572b0e7639b4b42e40c671 (patch) | |
tree | 8d39e40cfbede9a5eaefa7f4c770a679dbd87dd5 /libcpu | |
parent | 54a6d4b1b6828519ea707f2ce4d8c1829c9fe595 (diff) |
Optimize x86/x86-64 disassembler some more. Avoid relocations for string
table.
Diffstat (limited to 'libcpu')
-rw-r--r-- | libcpu/ChangeLog | 10 | ||||
-rw-r--r-- | libcpu/i386_disasm.c | 9 | ||||
-rw-r--r-- | libcpu/i386_parse.y | 29 |
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); } } |