summaryrefslogtreecommitdiff
path: root/gcc/read-md.c
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2010-06-10 20:24:01 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2010-06-10 20:24:01 +0000
commit5d54fceb3ef5f9f1e2fa793d0fcf16b6c4c49ee5 (patch)
treed68eec32700e8d1f8fca78585d743d080db36970 /gcc/read-md.c
parentc50b68d29a6805c41a9c74749626756bb4f87733 (diff)
downloadgcc-5d54fceb3ef5f9f1e2fa793d0fcf16b6c4c49ee5.tar.gz
gcc/
* doc/md.texi (define_c_enum, define_enum): Document. * read-md.h (md_constant): Add a parent_enum field. (enum_value, enum_type): New structures. (upcase_string, traverse_enum_types): Declare. * read-md.c (enum_types): New variable. (upcase_string, add_constant): New functions. (handle_constants): Don't create the hash table here. Use add_constant. (traverse_md_constants): Don't check for a null md_constants. (decimal_string, handle_enum, traverse_enum_types): New functions. (read_md_files): Initialize md_constants and md_enums. * genconstants.c (print_md_constant): Ignore info argument. Only print constants that belong to no enum. (print_enum_type): New function. (main): Don't pass stdout to print_md_constant. Call print_enum_type for each defined enum type. * config/mips/mips.md (processor): New define_enum. (unspec): New define_c_enum. (UNSPEC_COMPARE_AND_SWAP, UNSPEC_COMPARE_AND_SWAP_12) (UNSPEC_SYNC_OLD_OP, UNSPEC_SYNC_NEW_OP, UNSPEC_SYNC_NEW_OP_12) (UNSPEC_SYNC_OLD_OP_12, UNSPEC_SYNC_EXCHANGE, UNSPEC_SYNC_EXCHANGE_12) (UNSPEC_MEMORY_BARRIER): Moved to sync.md. (UNSPEC_ADDQ, UNSPEC_ADDQ_S, UNSPEC_SUBQ, UNSPEC_SUBQ_S, UNSPEC_ADDSC) (UNSPEC_ADDWC, UNSPEC_MODSUB, UNSPEC_RADDU_W_QB, UNSPEC_ABSQ_S) (UNSPEC_PRECRQ_QB_PH, UNSPEC_PRECRQ_PH_W, UNSPEC_PRECRQ_RS_PH_W) (UNSPEC_PRECRQU_S_QB_PH, UNSPEC_PRECEQ_W_PHL, UNSPEC_PRECEQ_W_PHR) (UNSPEC_PRECEQU_PH_QBL, UNSPEC_PRECEQU_PH_QBR, UNSPEC_PRECEQU_PH_QBLA) (UNSPEC_PRECEQU_PH_QBRA, UNSPEC_PRECEU_PH_QBL, UNSPEC_PRECEU_PH_QBR) (UNSPEC_PRECEU_PH_QBLA, UNSPEC_PRECEU_PH_QBRA, UNSPEC_SHLL) (UNSPEC_SHLL_S, UNSPEC_SHRL_QB, UNSPEC_SHRA_PH, UNSPEC_SHRA_R) (UNSPEC_MULEU_S_PH_QBL, UNSPEC_MULEU_S_PH_QBR, UNSPEC_MULQ_RS_PH) (UNSPEC_MULEQ_S_W_PHL, UNSPEC_MULEQ_S_W_PHR, UNSPEC_DPAU_H_QBL) (UNSPEC_DPAU_H_QBR, UNSPEC_DPSU_H_QBL, UNSPEC_DPSU_H_QBR) (UNSPEC_DPAQ_S_W_PH, UNSPEC_DPSQ_S_W_PH, UNSPEC_MULSAQ_S_W_PH) (UNSPEC_DPAQ_SA_L_W, UNSPEC_DPSQ_SA_L_W, UNSPEC_MAQ_S_W_PHL) (UNSPEC_MAQ_S_W_PHR, UNSPEC_MAQ_SA_W_PHL, UNSPEC_MAQ_SA_W_PHR) (UNSPEC_BITREV, UNSPEC_INSV, UNSPEC_REPL_QB, UNSPEC_REPL_PH) (UNSPEC_CMP_EQ, UNSPEC_CMP_LT, UNSPEC_CMP_LE, UNSPEC_CMPGU_EQ_QB) (UNSPEC_CMPGU_LT_QB, UNSPEC_CMPGU_LE_QB, UNSPEC_PICK, UNSPEC_PACKRL_PH) (UNSPEC_EXTR_W, UNSPEC_EXTR_R_W, UNSPEC_EXTR_RS_W, UNSPEC_EXTR_S_H) (UNSPEC_EXTP, UNSPEC_EXTPDP, UNSPEC_SHILO, UNSPEC_MTHLIP, UNSPEC_WRDSP) (UNSPEC_RDDSP): Move to mips-dsp.md. (UNSPEC_ABSQ_S_QB, UNSPEC_ADDU_PH, UNSPEC_ADDU_S_PH, UNSPEC_ADDUH_QB) (UNSPEC_ADDUH_R_QB, UNSPEC_APPEND, UNSPEC_BALIGN, UNSPEC_CMPGDU_EQ_QB) (UNSPEC_CMPGDU_LT_QB, UNSPEC_CMPGDU_LE_QB, UNSPEC_DPA_W_PH) (UNSPEC_DPS_W_PH, UNSPEC_MADD, UNSPEC_MADDU, UNSPEC_MSUB, UNSPEC_MSUBU) (UNSPEC_MUL_PH, UNSPEC_MUL_S_PH, UNSPEC_MULQ_RS_W, UNSPEC_MULQ_S_PH) (UNSPEC_MULQ_S_W, UNSPEC_MULSA_W_PH, UNSPEC_MULT, UNSPEC_MULTU) (UNSPEC_PRECR_QB_PH, UNSPEC_PRECR_SRA_PH_W, UNSPEC_PRECR_SRA_R_PH_W) (UNSPEC_PREPEND, UNSPEC_SHRA_QB, UNSPEC_SHRA_R_QB, UNSPEC_SHRL_PH) (UNSPEC_SUBU_PH, UNSPEC_SUBU_S_PH, UNSPEC_SUBUH_QB, UNSPEC_SUBUH_R_QB) (UNSPEC_ADDQH_PH, UNSPEC_ADDQH_R_PH, UNSPEC_ADDQH_W, UNSPEC_ADDQH_R_W) (UNSPEC_SUBQH_PH, UNSPEC_SUBQH_R_PH, UNSPEC_SUBQH_W, UNSPEC_SUBQH_R_W) (UNSPEC_DPAX_W_PH, UNSPEC_DPSX_W_PH, UNSPEC_DPAQX_S_W_PH) (UNSPEC_DPAQX_SA_W_PH, UNSPEC_DPSQX_S_W_PH, UNSPEC_DPSQX_SA_W_PH): Moved to mips-dspr2.md. (UNSPEC_MOVE_TF_PS, UNSPEC_C, UNSPEC_ALNV_PS, UNSPEC_CABS) (UNSPEC_ADDR_PS, UNSPEC_CVT_PW_PS, UNSPEC_CVT_PS_PW, UNSPEC_MULR_PS) (UNSPEC_ABS_PS, UNSPEC_RSQRT1, UNSPEC_RSQRT2, UNSPEC_RECIP1) (UNSPEC_RECIP2, UNSPEC_SINGLE_CC, UNSPEC_SCC): Moved from mips-ps-3d.md. (UNSPEC_LOONGSON_PAVG, UNSPEC_LOONGSON_PCMPEQ, UNSPEC_LOONGSON_PCMPGT) (UNSPEC_LOONGSON_PEXTR, UNSPEC_LOONGSON_PINSR_0) (UNSPEC_LOONGSON_PINSR_1, UNSPEC_LOONGSON_PINSR_2) (UNSPEC_LOONGSON_PINSR_3, UNSPEC_LOONGSON_PMADD) (UNSPEC_LOONGSON_PMOVMSK, UNSPEC_LOONGSON_PMULHU) (UNSPEC_LOONGSON_PMULH, UNSPEC_LOONGSON_PMULL, UNSPEC_LOONGSON_PMULU) (UNSPEC_LOONGSON_PASUBUB, UNSPEC_LOONGSON_BIADD, UNSPEC_LOONGSON_PSADBH) (UNSPEC_LOONGSON_PSHUFH, UNSPEC_LOONGSON_PUNPCKH) (UNSPEC_LOONGSON_PUNPCKL, UNSPEC_LOONGSON_PADDD) (UNSPEC_LOONGSON_PSUBD): Move to mips-loongson.md. (UNSPEC_LOONGSON_ALU1_TURN_ENABLED_INSN) (UNSPEC_LOONGSON_ALU2_TURN_ENABLED_INSN) (UNSPEC_LOONGSON_FALU1_TURN_ENABLED_INSN) (UNSPEC_LOONGSON_FALU2_TURN_ENABLED_INSN): Moved to mips-loongson2ef.md. (cpu): Update comment. * config/mips/sync.md (UNSPEC_COMPARE_AND_SWAP) (UNSPEC_COMPARE_AND_SWAP_12, UNSPEC_SYNC_OLD_OP, UNSPEC_SYNC_NEW_OP) (UNSPEC_SYNC_NEW_OP_12, UNSPEC_SYNC_OLD_OP_12, UNSPEC_SYNC_EXCHANGE) (UNSPEC_SYNC_EXCHANGE_12, UNSPEC_MEMORY_BARRIER): Moved from mips.md. * config/mips/loongson.md (UNSPEC_LOONGSON_PAVG, UNSPEC_LOONGSON_PCMPEQ) (UNSPEC_LOONGSON_PCMPGT, UNSPEC_LOONGSON_PEXTR, UNSPEC_LOONGSON_PINSR_0) (UNSPEC_LOONGSON_PINSR_1, UNSPEC_LOONGSON_PINSR_2) (UNSPEC_LOONGSON_PINSR_3, UNSPEC_LOONGSON_PMADD) (UNSPEC_LOONGSON_PMOVMSK, UNSPEC_LOONGSON_PMULHU) (UNSPEC_LOONGSON_PMULH, UNSPEC_LOONGSON_PMULL, UNSPEC_LOONGSON_PMULU) (UNSPEC_LOONGSON_PASUBUB, UNSPEC_LOONGSON_BIADD, UNSPEC_LOONGSON_PSADBH) (UNSPEC_LOONGSON_PSHUFH, UNSPEC_LOONGSON_PUNPCKH) (UNSPEC_LOONGSON_PUNPCKL, UNSPEC_LOONGSON_PADDD) (UNSPEC_LOONGSON_PSUBD): Moved from mips.md * config/mips/loongson2ef.md (UNSPEC_LOONGSON_ALU1_TURN_ENABLED_INSN) (UNSPEC_LOONGSON_ALU2_TURN_ENABLED_INSN) (UNSPEC_LOONGSON_FALU1_TURN_ENABLED_INSN) (UNSPEC_LOONGSON_FALU2_TURN_ENABLED_INSN): Moved from mips.md * config/mips/mips-dsp.md (UNSPEC_ADDQ, UNSPEC_ADDQ_S, UNSPEC_SUBQ) (UNSPEC_SUBQ_S, UNSPEC_ADDSC, UNSPEC_ADDWC, UNSPEC_MODSUB) (UNSPEC_RADDU_W_QB, UNSPEC_ABSQ_S, UNSPEC_PRECRQ_QB_PH) (UNSPEC_PRECRQ_PH_W, UNSPEC_PRECRQ_RS_PH_W, UNSPEC_PRECRQU_S_QB_PH) (UNSPEC_PRECEQ_W_PHL, UNSPEC_PRECEQ_W_PHR, UNSPEC_PRECEQU_PH_QBL) (UNSPEC_PRECEQU_PH_QBR, UNSPEC_PRECEQU_PH_QBLA, UNSPEC_PRECEQU_PH_QBRA) (UNSPEC_PRECEU_PH_QBL, UNSPEC_PRECEU_PH_QBR, UNSPEC_PRECEU_PH_QBLA) (UNSPEC_PRECEU_PH_QBRA, UNSPEC_SHLL, UNSPEC_SHLL_S, UNSPEC_SHRL_QB) (UNSPEC_SHRA_PH, UNSPEC_SHRA_R, UNSPEC_MULEU_S_PH_QBL) (UNSPEC_MULEU_S_PH_QBR, UNSPEC_MULQ_RS_PH, UNSPEC_MULEQ_S_W_PHL) (UNSPEC_MULEQ_S_W_PHR, UNSPEC_DPAU_H_QBL, UNSPEC_DPAU_H_QBR) (UNSPEC_DPSU_H_QBL, UNSPEC_DPSU_H_QBR, UNSPEC_DPAQ_S_W_PH) (UNSPEC_DPSQ_S_W_PH, UNSPEC_MULSAQ_S_W_PH, UNSPEC_DPAQ_SA_L_W) (UNSPEC_DPSQ_SA_L_W, UNSPEC_MAQ_S_W_PHL, UNSPEC_MAQ_S_W_PHR) (UNSPEC_MAQ_SA_W_PHL, UNSPEC_MAQ_SA_W_PHR, UNSPEC_BITREV, UNSPEC_INSV) (UNSPEC_REPL_QB, UNSPEC_REPL_PH, UNSPEC_CMP_EQ, UNSPEC_CMP_LT) (UNSPEC_CMP_LE, UNSPEC_CMPGU_EQ_QB, UNSPEC_CMPGU_LT_QB) (UNSPEC_CMPGU_LE_QB, UNSPEC_PICK, UNSPEC_PACKRL_PH, UNSPEC_EXTR_W) (UNSPEC_EXTR_R_W, UNSPEC_EXTR_RS_W, UNSPEC_EXTR_S_H, UNSPEC_EXTP) (UNSPEC_EXTPDP, UNSPEC_SHILO, UNSPEC_MTHLIP, UNSPEC_WRDSP) (UNSPEC_RDDSP): Moved from mips.md. * config/mips/mips-dspr2.md (UNSPEC_ABSQ_S_QB, UNSPEC_ADDU_PH) (UNSPEC_ADDU_S_PH, UNSPEC_ADDUH_QB, UNSPEC_ADDUH_R_QB, UNSPEC_APPEND) (UNSPEC_BALIGN, UNSPEC_CMPGDU_EQ_QB, UNSPEC_CMPGDU_LT_QB) (UNSPEC_CMPGDU_LE_QB, UNSPEC_DPA_W_PH, UNSPEC_DPS_W_PH, UNSPEC_MADD) (UNSPEC_MADDU, UNSPEC_MSUB, UNSPEC_MSUBU, UNSPEC_MUL_PH) (UNSPEC_MUL_S_PH, UNSPEC_MULQ_RS_W, UNSPEC_MULQ_S_PH, UNSPEC_MULQ_S_W) (UNSPEC_MULSA_W_PH, UNSPEC_MULT, UNSPEC_MULTU, UNSPEC_PRECR_QB_PH) (UNSPEC_PRECR_SRA_PH_W, UNSPEC_PRECR_SRA_R_PH_W, UNSPEC_PREPEND) (UNSPEC_SHRA_QB, UNSPEC_SHRA_R_QB, UNSPEC_SHRL_PH, UNSPEC_SUBU_PH) (UNSPEC_SUBU_S_PH, UNSPEC_SUBUH_QB, UNSPEC_SUBUH_R_QB, UNSPEC_ADDQH_PH) (UNSPEC_ADDQH_R_PH, UNSPEC_ADDQH_W, UNSPEC_ADDQH_R_W, UNSPEC_SUBQH_PH) (UNSPEC_SUBQH_R_PH, UNSPEC_SUBQH_W, UNSPEC_SUBQH_R_W, UNSPEC_DPAX_W_PH) (UNSPEC_DPSX_W_PH, UNSPEC_DPAQX_S_W_PH, UNSPEC_DPAQX_SA_W_PH) (UNSPEC_DPSQX_S_W_PH, UNSPEC_DPSQX_SA_W_PH): Moved from mips.md. * config/mips/mips-ps-3d.md (UNSPEC_MOVE_TF_PS, UNSPEC_C) (UNSPEC_ALNV_PS, UNSPEC_CABS, UNSPEC_ADDR_PS, UNSPEC_CVT_PW_PS) (UNSPEC_CVT_PS_PW, UNSPEC_MULR_PS, UNSPEC_ABS_PS, UNSPEC_RSQRT1) (UNSPEC_RSQRT2, UNSPEC_RECIP1, UNSPEC_RECIP2, UNSPEC_SINGLE_CC) (UNSPEC_SCC): Moved from mips.md. * config/mips/mips.c (mips_arch, mips_tune): Change enum from "processor_type" to "processor". (mips_rtx_cost_data): Replace PROCESSOR_MAX with NUM_PROCESSOR_VALUES. * config/mips/mips.h (processor_type): Delete. (mips_cpu_info.cpu, mips_arch, mips_tune): Change enum from "processor_type" to "processor". git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@160580 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/read-md.c')
-rw-r--r--gcc/read-md.c179
1 files changed, 153 insertions, 26 deletions
diff --git a/gcc/read-md.c b/gcc/read-md.c
index af9800f8e2d..90707b356d3 100644
--- a/gcc/read-md.c
+++ b/gcc/read-md.c
@@ -92,6 +92,9 @@ static size_t max_include_len;
constant expansion should occur. */
static htab_t md_constants;
+/* A table of enum_type structures, hashed by name. */
+static htab_t enum_types;
+
static void handle_file (directive_handler_t);
/* Given an object that starts with a char * name field, return a hash
@@ -671,6 +674,52 @@ scan_comma_elt (const char **pstr)
return start;
}
+/* Convert STRING to uppercase. */
+
+void
+upcase_string (char *string)
+{
+ int i;
+
+ for (i = 0; string[i]; i++)
+ string[i] = TOUPPER (string[i]);
+}
+
+/* Add a NAME = VALUE definition to md_constants-style hash table DEFS,
+ where both NAME and VALUE are malloc()ed strings. PARENT_ENUM is the
+ enum to which NAME belongs, or null if NAME is a stand-alone constant. */
+
+static struct md_constant *
+add_constant (htab_t defs, char *name, char *value,
+ struct enum_type *parent_enum)
+{
+ struct md_constant *def, tmp_def;
+ void **entry_ptr;
+
+ tmp_def.name = name;
+ entry_ptr = htab_find_slot (defs, &tmp_def, INSERT);
+ if (*entry_ptr)
+ {
+ def = (struct md_constant *) *entry_ptr;
+ if (strcmp (def->value, value) != 0)
+ fatal_with_file_and_line ("redefinition of `%s', was `%s', now `%s'",
+ def->name, def->value, value);
+ else if (parent_enum || def->parent_enum)
+ fatal_with_file_and_line ("redefinition of `%s'", def->name);
+ free (name);
+ free (value);
+ }
+ else
+ {
+ def = XNEW (struct md_constant);
+ def->name = name;
+ def->value = value;
+ def->parent_enum = parent_enum;
+ *entry_ptr = def;
+ }
+ return def;
+}
+
/* Process a define_constants directive, starting with the optional space
after the "define_constants". */
@@ -680,45 +729,23 @@ handle_constants (void)
int c;
htab_t defs;
- defs = md_constants;
- if (! defs)
- defs = htab_create (32, leading_string_hash,
- leading_string_eq_p, (htab_del) 0);
-
c = read_skip_spaces ();
if (c != '[')
fatal_expected_char ('[', c);
/* Disable constant expansion during definition processing. */
+ defs = md_constants;
md_constants = 0;
while ( (c = read_skip_spaces ()) != ']')
{
struct md_name name, value;
- struct md_constant *def, tmp_def;
- void **entry_ptr;
if (c != '(')
fatal_expected_char ('(', c);
read_name (&name);
read_name (&value);
-
- tmp_def.name = name.string;
- entry_ptr = htab_find_slot (defs, &tmp_def, INSERT);
- if (*entry_ptr)
- {
- def = (struct md_constant *) *entry_ptr;
- if (strcmp (def->value, value.string) != 0)
- fatal_with_file_and_line ("redefinition of %s, was %s, now %s",
- def->name, def->value, value.string);
- }
- else
- {
- def = XNEW (struct md_constant);
- def->name = xstrdup (name.string);
- def->value = xstrdup (value.string);
- *entry_ptr = def;
- }
+ add_constant (defs, xstrdup (name.string), xstrdup (value.string), 0);
c = read_skip_spaces ();
if (c != ')')
@@ -734,8 +761,100 @@ handle_constants (void)
void
traverse_md_constants (htab_trav callback, void *info)
{
- if (md_constants)
- htab_traverse (md_constants, callback, info);
+ htab_traverse (md_constants, callback, info);
+}
+
+/* Return a malloc()ed decimal string that represents number NUMBER. */
+
+static char *
+decimal_string (int number)
+{
+ /* A safe overestimate. +1 for sign, +1 for null terminator. */
+ char buffer[sizeof (int) * CHAR_BIT + 1 + 1];
+
+ sprintf (buffer, "%d", number);
+ return xstrdup (buffer);
+}
+
+/* Process a define_enum or define_c_enum directive, starting with
+ the optional space after the "define_enum". LINENO is the line
+ number on which the directive started and MD_P is true if the
+ directive is a define_enum rather than a define_c_enum. */
+
+static void
+handle_enum (int lineno, bool md_p)
+{
+ char *enum_name, *value_name;
+ struct md_name name;
+ struct enum_type *def;
+ struct enum_value *ev;
+ void **slot;
+ int c;
+
+ enum_name = read_string (false);
+ slot = htab_find_slot (enum_types, &enum_name, INSERT);
+ if (*slot)
+ {
+ def = (struct enum_type *) *slot;
+ if (def->md_p != md_p)
+ error_with_line (lineno, "redefining `%s' as a different type of enum",
+ enum_name);
+ }
+ else
+ {
+ def = XNEW (struct enum_type);
+ def->name = enum_name;
+ def->md_p = md_p;
+ def->values = 0;
+ def->tail_ptr = &def->values;
+ def->num_values = 0;
+ *slot = def;
+ }
+
+ c = read_skip_spaces ();
+ if (c != '[')
+ fatal_expected_char ('[', c);
+
+ while ((c = read_skip_spaces ()) != ']')
+ {
+ if (c == EOF)
+ {
+ error_with_line (lineno, "unterminated construct");
+ exit (1);
+ }
+ unread_char (c);
+ read_name (&name);
+
+ ev = XNEW (struct enum_value);
+ ev->next = 0;
+ if (md_p)
+ {
+ value_name = concat (def->name, "_", name.string, NULL);
+ upcase_string (value_name);
+ ev->name = xstrdup (name.string);
+ }
+ else
+ {
+ value_name = xstrdup (name.string);
+ ev->name = value_name;
+ }
+ ev->def = add_constant (md_constants, value_name,
+ decimal_string (def->num_values), def);
+
+ *def->tail_ptr = ev;
+ def->tail_ptr = &ev->next;
+ def->num_values++;
+ }
+}
+
+/* For every enum definition, call CALLBACK with two arguments:
+ a pointer to the constant definition and INFO. Stop when CALLBACK
+ returns zero. */
+
+void
+traverse_enum_types (htab_trav callback, void *info)
+{
+ htab_traverse (enum_types, callback, info);
}
/* Process an "include" directive, starting with the optional space
@@ -834,6 +953,10 @@ handle_file (directive_handler_t handle_directive)
read_name (&directive);
if (strcmp (directive.string, "define_constants") == 0)
handle_constants ();
+ else if (strcmp (directive.string, "define_enum") == 0)
+ handle_enum (lineno, true);
+ else if (strcmp (directive.string, "define_c_enum") == 0)
+ handle_enum (lineno, false);
else if (strcmp (directive.string, "include") == 0)
handle_include (lineno, handle_directive);
else if (handle_directive)
@@ -911,6 +1034,10 @@ read_md_files (int argc, char **argv, bool (*parse_opt) (const char *),
obstack_init (&ptr_loc_obstack);
joined_conditions = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
obstack_init (&joined_conditions_obstack);
+ md_constants = htab_create (31, leading_string_hash,
+ leading_string_eq_p, (htab_del) 0);
+ enum_types = htab_create (31, leading_string_hash,
+ leading_string_eq_p, (htab_del) 0);
/* Unlock the stdio streams. */
unlock_std_streams ();