X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=opcodes%2Fia64-gen.c;h=eefa81c6ac25f6037b6927669850e45efced0cd3;hb=432233b3596b5ec50b6bfc84ce7458106d7afd7b;hp=e12c145bea142b758f4c9caf8cf6eb2033cc79ab;hpb=0fd3a4776c8f607cc778cde80f9215089d36387e;p=binutils-gdb.git diff --git a/opcodes/ia64-gen.c b/opcodes/ia64-gen.c index e12c145bea1..eefa81c6ac2 100644 --- a/opcodes/ia64-gen.c +++ b/opcodes/ia64-gen.c @@ -1,25 +1,26 @@ /* ia64-gen.c -- Generate a shrunk set of opcode tables - Copyright 1999, 2000, 2001, 2002, 2004, 2005 + Copyright 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Written by Bob Manson, Cygnus Solutions, - This file is part of GDB, GAS, and the GNU binutils. + This file is part of the GNU opcodes library. - GDB, GAS, and the GNU binutils are free software; you can redistribute - them and/or modify them under the terms of the GNU General Public - License as published by the Free Software Foundation; either version - 2, or (at your option) any later version. + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. - GDB, GAS, and the GNU binutils are distributed in the hope that they - will be useful, but WITHOUT ANY WARRANTY; without even the implied - warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - the GNU General Public License for more details. + It is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. You should have received a copy of the GNU General Public License along with this file; see the file COPYING. If not, write to the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + /* While the ia64-opc-* set of opcode tables are easy to maintain, they waste a tremendous amount of space. ia64-gen rearranges the instructions into a directed acyclic graph (DAG) of instruction opcodes and @@ -54,6 +55,15 @@ #include #define _(String) gettext (String) +/* This is a copy of fprintf_vma from bfd/bfd-in2.h. We have to use this + always, because we might be compiled without BFD64 defined, if configured + for a 32-bit target and --enable-targets=all is used. This will work for + both 32-bit and 64-bit hosts. */ +#define _opcode_int64_low(x) ((unsigned long) (((x) & 0xffffffff))) +#define _opcode_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff)) +#define opcode_fprintf_vma(s,x) \ + fprintf ((s), "%08lx%08lx", _opcode_int64_high (x), _opcode_int64_low (x)) + const char * program_name = NULL; int debug = 0; @@ -458,7 +468,7 @@ fetch_insn_class (const char *full_name, int create) int ind; int is_class = 0; - if (strncmp (full_name, "IC:", 3) == 0) + if (CONST_STRNEQ (full_name, "IC:")) { name = xstrdup (full_name + 3); is_class = 1; @@ -684,11 +694,8 @@ load_insn_classes (void) /* Extract the insn classes from the given line. */ static void -parse_resource_users (ref, usersp, nusersp, notesp) - const char *ref; - int **usersp; - int *nusersp; - int **notesp; +parse_resource_users (const char *ref, int **usersp, int *nusersp, + int **notesp) { int c; char *line = xstrdup (ref); @@ -740,7 +747,7 @@ parse_resource_users (ref, usersp, nusersp, notesp) are read. Only create new classes if it's *not* an insn class, or if it's a composite class (which wouldn't necessarily be in the IC table). */ - if (strncmp (name, "IC:", 3) != 0 || xsect != NULL) + if (! CONST_STRNEQ (name, "IC:") || xsect != NULL) create = 1; iclass = fetch_insn_class (name, create); @@ -1025,7 +1032,7 @@ in_iclass (struct ia64_opcode *idesc, struct iclass *ic, if (ic->comment) { - if (!strncmp (ic->comment, "Format", 6)) + if (CONST_STRNEQ (ic->comment, "Format")) { /* Assume that the first format seen is the most restrictive, and only keep a later one if it looks like it's more restrictive. */ @@ -1041,7 +1048,7 @@ in_iclass (struct ia64_opcode *idesc, struct iclass *ic, else format = ic->comment; } - else if (!strncmp (ic->comment, "Field", 5)) + else if (CONST_STRNEQ (ic->comment, "Field")) { if (field) warn (_("overlapping field %s->%s\n"), @@ -1055,7 +1062,7 @@ in_iclass (struct ia64_opcode *idesc, struct iclass *ic, instructions. */ if (ic->nsubs == 0 && ic->nxsubs == 0) { - int is_mov = strncmp (idesc->name, "mov", 3) == 0; + int is_mov = CONST_STRNEQ (idesc->name, "mov"); int plain_mov = strcmp (idesc->name, "mov") == 0; int len = strlen(ic->name); @@ -1114,32 +1121,32 @@ in_iclass (struct ia64_opcode *idesc, struct iclass *ic, if (resolved && format) { - if (strncmp (idesc->name, "dep", 3) == 0 + if (CONST_STRNEQ (idesc->name, "dep") && strstr (format, "I13") != NULL) resolved = idesc->operands[1] == IA64_OPND_IMM8; - else if (strncmp (idesc->name, "chk", 3) == 0 + else if (CONST_STRNEQ (idesc->name, "chk") && strstr (format, "M21") != NULL) resolved = idesc->operands[0] == IA64_OPND_F2; - else if (strncmp (idesc->name, "lfetch", 6) == 0) + else if (CONST_STRNEQ (idesc->name, "lfetch")) resolved = (strstr (format, "M14 M15") != NULL && (idesc->operands[1] == IA64_OPND_R2 || idesc->operands[1] == IA64_OPND_IMM9b)); - else if (strncmp (idesc->name, "br.call", 7) == 0 + else if (CONST_STRNEQ (idesc->name, "br.call") && strstr (format, "B5") != NULL) resolved = idesc->operands[1] == IA64_OPND_B2; - else if (strncmp (idesc->name, "br.call", 7) == 0 + else if (CONST_STRNEQ (idesc->name, "br.call") && strstr (format, "B3") != NULL) resolved = idesc->operands[1] == IA64_OPND_TGT25c; - else if (strncmp (idesc->name, "brp", 3) == 0 + else if (CONST_STRNEQ (idesc->name, "brp") && strstr (format, "B7") != NULL) resolved = idesc->operands[0] == IA64_OPND_B2; else if (strcmp (ic->name, "invala") == 0) resolved = strcmp (idesc->name, ic->name) == 0; - else if (strncmp (idesc->name, "st", 2) == 0 + else if (CONST_STRNEQ (idesc->name, "st") && (strstr (format, "M5") != NULL || strstr (format, "M10") != NULL)) resolved = idesc->flags & IA64_OPCODE_POSTINC; - else if (strncmp (idesc->name, "ld", 2) == 0 + else if (CONST_STRNEQ (idesc->name, "ld") && (strstr (format, "M2 M3") != NULL || strstr (format, "M12") != NULL || strstr (format, "M7 M8") != NULL)) @@ -1152,7 +1159,7 @@ in_iclass (struct ia64_opcode *idesc, struct iclass *ic, plain brl matches brl.cond. */ if (!resolved && (strcmp (idesc->name, "brl") == 0 - || strncmp (idesc->name, "brl.", 4) == 0) + || CONST_STRNEQ (idesc->name, "brl.")) && strcmp (ic->name, "brl.cond") == 0) { resolved = 1; @@ -1161,7 +1168,7 @@ in_iclass (struct ia64_opcode *idesc, struct iclass *ic, /* Misc br variations ('.cond' is optional). */ if (!resolved && (strcmp (idesc->name, "br") == 0 - || strncmp (idesc->name, "br.", 3) == 0) + || CONST_STRNEQ (idesc->name, "br.")) && strcmp (ic->name, "br.cond") == 0) { if (format) @@ -1174,7 +1181,7 @@ in_iclass (struct ia64_opcode *idesc, struct iclass *ic, } /* probe variations. */ - if (!resolved && strncmp (idesc->name, "probe", 5) == 0) + if (!resolved && CONST_STRNEQ (idesc->name, "probe")) { resolved = strcmp (ic->name, "probe") == 0 && !((strstr (idesc->name, "fault") != NULL) @@ -1208,7 +1215,7 @@ in_iclass (struct ia64_opcode *idesc, struct iclass *ic, } /* Some variants of mov and mov.[im]. */ - if (!resolved && strncmp (ic->name, "mov_", 4) == 0) + if (!resolved && CONST_STRNEQ (ic->name, "mov_")) resolved = in_iclass_mov_x (idesc, ic, format, field); } @@ -1286,6 +1293,8 @@ lookup_regindex (const char *name, int specifier) return 32; else if (strstr (name, "[ITC]")) return 44; + else if (strstr (name, "[RUC]")) + return 45; else if (strstr (name, "[PFS]")) return 64; else if (strstr (name, "[LC]")) @@ -1400,6 +1409,8 @@ lookup_regindex (const char *name, int specifier) return 44; else if (strstr (name, ".ia")) return 45; + else if (strstr (name, ".vm")) + return 46; else abort (); default: @@ -1423,6 +1434,8 @@ lookup_specifier (const char *name) return IA64_RS_ARb; if (strstr (name, "BR%") != NULL) return IA64_RS_BR; + if (strstr (name, "CR[IIB%]") != NULL) + return IA64_RS_CR_IIB; if (strstr (name, "CR[IRR%]") != NULL) return IA64_RS_CR_IRR; if (strstr (name, "CR[LRR%]") != NULL) @@ -1465,13 +1478,13 @@ lookup_specifier (const char *name) warn (_("Don't know how to specify # dependency %s\n"), name); } - else if (strncmp (name, "AR[FPSR]", 8) == 0) + else if (CONST_STRNEQ (name, "AR[FPSR]")) return IA64_RS_AR_FPSR; - else if (strncmp (name, "AR[", 3) == 0) + else if (CONST_STRNEQ (name, "AR[")) return IA64_RS_ARX; - else if (strncmp (name, "CR[", 3) == 0) + else if (CONST_STRNEQ (name, "CR[")) return IA64_RS_CRX; - else if (strncmp (name, "PSR.", 4) == 0) + else if (CONST_STRNEQ (name, "PSR.")) return IA64_RS_PSR; else if (strcmp (name, "InService*") == 0) return IA64_RS_INSERVICE; @@ -1488,7 +1501,7 @@ lookup_specifier (const char *name) } static void -print_dependency_table () +print_dependency_table (void) { int i, j; @@ -1538,9 +1551,14 @@ print_dependency_table () static const char *mode_str[] = { "RAW", "WAW", "WAR" }; if (rdeps[i]->total_chks == 0) - warn (_("Warning: rsrc %s (%s) has no chks%s\n"), - rdeps[i]->name, mode_str[rdeps[i]->mode], - rdeps[i]->total_regs ? "" : " or regs"); + { + if (rdeps[i]->total_regs) + warn (_("Warning: rsrc %s (%s) has no chks\n"), + rdeps[i]->name, mode_str[rdeps[i]->mode]); + else + warn (_("Warning: rsrc %s (%s) has no chks or regs\n"), + rdeps[i]->name, mode_str[rdeps[i]->mode]); + } else if (rdeps[i]->total_regs == 0) warn (_("rsrc %s (%s) has no regs\n"), rdeps[i]->name, mode_str[rdeps[i]->mode]); @@ -1560,7 +1578,20 @@ print_dependency_table () rdeps[i]->name, specifier, (int)rdeps[i]->mode, (int)rdeps[i]->semantics, regindex); if (rdeps[i]->semantics == IA64_DVS_OTHER) - printf ("\"%s\", ", rdeps[i]->extra); + { + const char *quote, *rest; + + putchar ('\"'); + rest = rdeps[i]->extra; + quote = strchr (rest, '\"'); + while (quote != NULL) + { + printf ("%.*s\\\"", (int) (quote - rest), rest); + rest = quote + 1; + quote = strchr (rest, '\"'); + } + printf ("%s\", ", rest); + } else printf ("NULL, "); printf("},\n"); @@ -1692,11 +1723,8 @@ make_bittree_entry (void) static struct disent * -add_dis_table_ent (which, insn, order, completer_index) - struct disent *which; - int insn; - int order; - int completer_index; +add_dis_table_ent (struct disent *which, int insn, int order, + int completer_index) { int ci = 0; struct disent *ent; @@ -1733,7 +1761,7 @@ add_dis_table_ent (which, insn, order, completer_index) } static void -finish_distable () +finish_distable (void) { struct disent *ent = disinsntable; struct disent *prev = ent; @@ -1747,15 +1775,9 @@ finish_distable () } static void -insert_bit_table_ent (curr_ent, bit, opcode, mask, - opcodenum, order, completer_index) - struct bittree *curr_ent; - int bit; - ia64_insn opcode; - ia64_insn mask; - int opcodenum; - int order; - int completer_index; +insert_bit_table_ent (struct bittree *curr_ent, int bit, ia64_insn opcode, + ia64_insn mask, int opcodenum, int order, + int completer_index) { ia64_insn m; int b; @@ -1788,13 +1810,8 @@ insert_bit_table_ent (curr_ent, bit, opcode, mask, } static void -add_dis_entry (first, opcode, mask, opcodenum, ent, completer_index) - struct bittree *first; - ia64_insn opcode; - ia64_insn mask; - int opcodenum; - struct completer_entry *ent; - int completer_index; +add_dis_entry (struct bittree *first, ia64_insn opcode, ia64_insn mask, + int opcodenum, struct completer_entry *ent, int completer_index) { if (completer_index & (1 << 20)) abort (); @@ -1818,8 +1835,7 @@ add_dis_entry (first, opcode, mask, opcodenum, ent, completer_index) /* This optimization pass combines multiple "don't care" nodes. */ static void -compact_distree (ent) - struct bittree *ent; +compact_distree (struct bittree *ent) { #define IS_SKIP(ent) \ ((ent->bits[2] !=NULL) \ @@ -1870,8 +1886,7 @@ static int tot_insn_list_len = 0; /* Generate the disassembler state machine corresponding to the tree in ENT. */ static void -gen_dis_table (ent) - struct bittree *ent; +gen_dis_table (struct bittree *ent) { int x; int our_offset = insn_list_len; @@ -2195,8 +2210,8 @@ static int glisttotlen = 0; /* If the completer trees ENT1 and ENT2 are equal, return 1. */ static int -completer_entries_eq (ent1, ent2) - struct completer_entry *ent1, *ent2; +completer_entries_eq (struct completer_entry *ent1, + struct completer_entry *ent2) { while (ent1 != NULL && ent2 != NULL) { @@ -2313,8 +2328,7 @@ insert_gclist (struct completer_entry *ent) } static int -get_prefix_len (name) - const char *name; +get_prefix_len (const char *name) { char *c; @@ -2329,9 +2343,7 @@ get_prefix_len (name) } static void -compute_completer_bits (ment, ent) - struct main_entry *ment; - struct completer_entry *ent; +compute_completer_bits (struct main_entry *ment, struct completer_entry *ent) { while (ent != NULL) { @@ -2404,9 +2416,8 @@ collapse_redundant_completers (void) 2) all resources which must be marked in use when this opcode is used (regs). */ static int -insert_opcode_dependencies (opc, cmp) - struct ia64_opcode *opc; - struct completer_entry *cmp ATTRIBUTE_UNUSED; +insert_opcode_dependencies (struct ia64_opcode *opc, + struct completer_entry *cmp ATTRIBUTE_UNUSED) { /* Note all resources which point to this opcode. rfi has the most chks (79) and cmpxchng has the most regs (54) so 100 here should be enough. */ @@ -2424,7 +2435,7 @@ insert_opcode_dependencies (opc, cmp) int j; if (strcmp (opc->name, "cmp.eq.and") == 0 - && strncmp (rs->name, "PR%", 3) == 0 + && CONST_STRNEQ (rs->name, "PR%") && rs->mode == 1) no_class_found = 99; @@ -2435,7 +2446,7 @@ insert_opcode_dependencies (opc, cmp) if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note)) { /* We can ignore ic_note 11 for non PR resources. */ - if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0) + if (ic_note == 11 && ! CONST_STRNEQ (rs->name, "PR")) ic_note = 0; if (ic_note != 0 && rs->regnotes[j] != 0 @@ -2463,7 +2474,7 @@ insert_opcode_dependencies (opc, cmp) if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note)) { /* We can ignore ic_note 11 for non PR resources. */ - if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0) + if (ic_note == 11 && ! CONST_STRNEQ (rs->name, "PR")) ic_note = 0; if (ic_note != 0 && rs->chknotes[j] != 0 @@ -2491,10 +2502,8 @@ insert_opcode_dependencies (opc, cmp) } static void -insert_completer_entry (opc, tabent, order) - struct ia64_opcode *opc; - struct main_entry *tabent; - int order; +insert_completer_entry (struct ia64_opcode *opc, struct main_entry *tabent, + int order) { struct completer_entry **ptr = &tabent->completers; struct completer_entry *parent = NULL; @@ -2565,8 +2574,7 @@ insert_completer_entry (opc, tabent, order) } static void -print_completer_entry (ent) - struct completer_entry *ent; +print_completer_entry (struct completer_entry *ent) { int moffset = 0; ia64_insn mask = ent->mask, bits = ent->bits; @@ -2596,7 +2604,7 @@ print_completer_entry (ent) } static void -print_completer_table () +print_completer_table (void) { int x; @@ -2607,9 +2615,7 @@ print_completer_table () } static int -opcodes_eq (opc1, opc2) - struct ia64_opcode *opc1; - struct ia64_opcode *opc2; +opcodes_eq (struct ia64_opcode *opc1, struct ia64_opcode *opc2) { int x; int plen1, plen2; @@ -2633,8 +2639,7 @@ opcodes_eq (opc1, opc2) } static void -add_opcode_entry (opc) - struct ia64_opcode *opc; +add_opcode_entry (struct ia64_opcode *opc) { struct main_entry **place; struct string_entry *name; @@ -2692,7 +2697,7 @@ static void print_main_table (void) { struct main_entry *ptr = maintable; - int index = 0; + int tindex = 0; printf ("static const struct ia64_main_table\nmain_table[] = {\n"); while (ptr != NULL) @@ -2701,9 +2706,9 @@ print_main_table (void) ptr->name->num, ptr->opcode->type, ptr->opcode->num_outputs); - fprintf_vma (stdout, ptr->opcode->opcode); + opcode_fprintf_vma (stdout, ptr->opcode->opcode); printf ("ull, 0x"); - fprintf_vma (stdout, ptr->opcode->mask); + opcode_fprintf_vma (stdout, ptr->opcode->mask); printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n", ptr->opcode->operands[0], ptr->opcode->operands[1], @@ -2713,7 +2718,7 @@ print_main_table (void) ptr->opcode->flags, ptr->completers->num); - ptr->main_index = index++; + ptr->main_index = tindex++; ptr = ptr->next; } @@ -2721,8 +2726,7 @@ print_main_table (void) } static void -shrink (table) - struct ia64_opcode *table; +shrink (struct ia64_opcode *table) { int curr_opcode; @@ -2830,6 +2834,25 @@ main (int argc, char **argv) collapse_redundant_completers (); printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n"); + printf ("/* Copyright 2007 Free Software Foundation, Inc.\n\ +\n\ + This file is part of the GNU opcodes library.\n\ +\n\ + This library is free software; you can redistribute it and/or modify\n\ + it under the terms of the GNU General Public License as published by\n\ + the Free Software Foundation; either version 3, or (at your option)\n\ + any later version.\n\ +\n\ + It is distributed in the hope that it will be useful, but WITHOUT\n\ + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\ + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\ + License for more details.\n\ +\n\ + You should have received a copy of the GNU General Public License\n\ + along with this program; see the file COPYING. If not, write to the\n\ + Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA\n\ + 02110-1301, USA. */\n"); + print_string_table (); print_dependency_table (); print_completer_table ();