diff options
author | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-06-10 20:24:01 +0000 |
---|---|---|
committer | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-06-10 20:24:01 +0000 |
commit | 5d54fceb3ef5f9f1e2fa793d0fcf16b6c4c49ee5 (patch) | |
tree | d68eec32700e8d1f8fca78585d743d080db36970 /gcc/read-md.c | |
parent | c50b68d29a6805c41a9c74749626756bb4f87733 (diff) | |
download | gcc-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.c | 179 |
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 (); |