/* Support routines for the various generation passes.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This file is part of GCC.
static void process_include (rtx, int);
static char *save_string (const char *, int);
static void init_predicate_table (void);
+static void record_insn_name (int, const char *);
\f
void
message_with_line (int lineno, const char *msg, ...)
case DEFINE_PREDICATE:
case DEFINE_SPECIAL_PREDICATE:
+ case DEFINE_CONSTRAINT:
+ case DEFINE_REGISTER_CONSTRAINT:
+ case DEFINE_MEMORY_CONSTRAINT:
+ case DEFINE_ADDRESS_CONSTRAINT:
queue_pattern (desc, &define_pred_tail, read_rtx_filename, lineno);
break;
message_with_line (elem->lineno,
"attribute `predicable' is not a boolean");
errors = 1;
+ if (p_false)
+ free (p_false);
return;
}
p_true[-1] = '\0';
message_with_line (elem->lineno,
"attribute `predicable' cannot be const");
errors = 1;
+ if (p_false)
+ free (p_false);
return;
default:
message_with_line (elem->lineno,
"attribute `predicable' must have a constant default");
errors = 1;
+ if (p_false)
+ free (p_false);
return;
}
"unknown value `%s' for `predicable' attribute",
value);
errors = 1;
+ if (p_false)
+ free (p_false);
}
}
sequence_num++;
else if (insn_elision)
goto discard;
+
+ /* *seqnr is used here so the name table will match caller's
+ idea of insn numbering, whether or not elision is active. */
+ record_insn_name (*seqnr, XSTR (desc, 0));
break;
case DEFINE_SPLIT:
add_predicate (pred);
}
}
+\f
+/* These functions allow linkage with print-rtl.c. Also, some generators
+ like to annotate their output with insn names. */
+
+/* Holds an array of names indexed by insn_code_number. */
+static char **insn_name_ptr = 0;
+static int insn_name_ptr_size = 0;
+
+const char *
+get_insn_name (int code)
+{
+ if (code < insn_name_ptr_size)
+ return insn_name_ptr[code];
+ else
+ return NULL;
+}
+
+static void
+record_insn_name (int code, const char *name)
+{
+ static const char *last_real_name = "insn";
+ static int last_real_code = 0;
+ char *new;
+
+ if (insn_name_ptr_size <= code)
+ {
+ int new_size;
+ new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
+ insn_name_ptr = xrealloc (insn_name_ptr, sizeof(char *) * new_size);
+ memset (insn_name_ptr + insn_name_ptr_size, 0,
+ sizeof(char *) * (new_size - insn_name_ptr_size));
+ insn_name_ptr_size = new_size;
+ }
+
+ if (!name || name[0] == '\0')
+ {
+ new = xmalloc (strlen (last_real_name) + 10);
+ sprintf (new, "%s+%d", last_real_name, code - last_real_code);
+ }
+ else
+ {
+ last_real_name = new = xstrdup (name);
+ last_real_code = code;
+ }
+
+ insn_name_ptr[code] = new;
+}