/* 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, <manson@cygnus.com>
- 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
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;
/* 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);
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);
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. */
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"),
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);
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))
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;
/* 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)
}
/* 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)
}
/* 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);
}
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]"))
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)
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;
}
static void
-print_dependency_table ()
+print_dependency_table (void)
{
int i, j;
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]);
\f
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;
}
\f
static void
-finish_distable ()
+finish_distable (void)
{
struct disent *ent = disinsntable;
struct disent *prev = ent;
}
\f
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;
}
\f
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 ();
\f
/* 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) \
/* 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;
/* 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)
{
}
\f
static int
-get_prefix_len (name)
- const char *name;
+get_prefix_len (const char *name)
{
char *c;
}
\f
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)
{
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. */
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;
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
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
}
\f
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;
}
\f
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;
}
\f
static void
-print_completer_table ()
+print_completer_table (void)
{
int x;
}
\f
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;
}
\f
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;
}
\f
static void
-shrink (table)
- struct ia64_opcode *table;
+shrink (struct ia64_opcode *table)
{
int curr_opcode;
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 ();