diff options
-rw-r--r-- | gcc/ChangeLog | 142 | ||||
-rw-r--r-- | gcc/config/mips/loongson.md | 25 | ||||
-rw-r--r-- | gcc/config/mips/loongson2ef.md | 7 | ||||
-rw-r--r-- | gcc/config/mips/mips-dsp.md | 72 | ||||
-rw-r--r-- | gcc/config/mips/mips-dspr2.md | 52 | ||||
-rw-r--r-- | gcc/config/mips/mips-ps-3d.md | 24 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 7 | ||||
-rw-r--r-- | gcc/config/mips/mips.h | 53 | ||||
-rw-r--r-- | gcc/config/mips/mips.md | 350 | ||||
-rw-r--r-- | gcc/config/mips/sync.md | 12 | ||||
-rw-r--r-- | gcc/doc/md.texi | 82 | ||||
-rw-r--r-- | gcc/genconstants.c | 37 | ||||
-rw-r--r-- | gcc/read-md.c | 179 | ||||
-rw-r--r-- | gcc/read-md.h | 45 |
14 files changed, 764 insertions, 323 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1aab743ff68..f4630c7c410 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,147 @@ 2010-06-10 Richard Sandiford <rdsandiford@googlemail.com> + * 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". + +2010-06-10 Richard Sandiford <rdsandiford@googlemail.com> + * configure.ac (tm_include_list): Add insn-constants.h. * configure: Regenerate. * Makefile.in (GTM_H): Move insn-constants.h here from... diff --git a/gcc/config/mips/loongson.md b/gcc/config/mips/loongson.md index f952cf672ee..10703bb7b08 100644 --- a/gcc/config/mips/loongson.md +++ b/gcc/config/mips/loongson.md @@ -18,6 +18,31 @@ ;; along with GCC; see the file COPYING3. If not see ;; <http://www.gnu.org/licenses/>. +(define_c_enum "unspec" [ + 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 +]) + ;; Mode iterators and attributes. ;; 64-bit vectors of bytes. diff --git a/gcc/config/mips/loongson2ef.md b/gcc/config/mips/loongson2ef.md index df3de33f809..1238f20ecae 100644 --- a/gcc/config/mips/loongson2ef.md +++ b/gcc/config/mips/loongson2ef.md @@ -17,6 +17,13 @@ ;; along with GCC; see the file COPYING3. If not see ;; <http://www.gnu.org/licenses/>. +(define_c_enum "unspec" [ + UNSPEC_LOONGSON_ALU1_TURN_ENABLED_INSN + UNSPEC_LOONGSON_ALU2_TURN_ENABLED_INSN + UNSPEC_LOONGSON_FALU1_TURN_ENABLED_INSN + UNSPEC_LOONGSON_FALU2_TURN_ENABLED_INSN +]) + ;; Automaton for integer instructions. (define_automaton "ls2_alu") diff --git a/gcc/config/mips/mips-dsp.md b/gcc/config/mips/mips-dsp.md index 9e02f7214f9..faa22bdd364 100644 --- a/gcc/config/mips/mips-dsp.md +++ b/gcc/config/mips/mips-dsp.md @@ -16,6 +16,78 @@ ;; along with GCC; see the file COPYING3. If not see ;; <http://www.gnu.org/licenses/>. +;; MIPS DSP ASE Revision 0.98 3/24/2005 +(define_c_enum "unspec" [ + 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 +]) + (define_constants [(CCDSP_PO_REGNUM 182) (CCDSP_SC_REGNUM 183) diff --git a/gcc/config/mips/mips-dspr2.md b/gcc/config/mips/mips-dspr2.md index 52495d43daa..9c3cbd58435 100644 --- a/gcc/config/mips/mips-dspr2.md +++ b/gcc/config/mips/mips-dspr2.md @@ -18,6 +18,58 @@ ;; ; MIPS DSP ASE REV 2 Revision 0.02 11/24/2006 +(define_c_enum "unspec" [ + 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 +]) + (define_insn "mips_absq_s_qb" [(parallel [(set (match_operand:V4QI 0 "register_operand" "=d") diff --git a/gcc/config/mips/mips-ps-3d.md b/gcc/config/mips/mips-ps-3d.md index c13c7a69b28..780fb03c706 100644 --- a/gcc/config/mips/mips-ps-3d.md +++ b/gcc/config/mips/mips-ps-3d.md @@ -17,6 +17,30 @@ ;; along with GCC; see the file COPYING3. If not see ;; <http://www.gnu.org/licenses/>. +(define_c_enum "unspec" [ + UNSPEC_MOVE_TF_PS + UNSPEC_C + + ;; MIPS64/MIPS32R2 alnv.ps + UNSPEC_ALNV_PS + + ;; MIPS-3D instructions + 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 +]) + (define_insn "*movcc_v2sf_<mode>" [(set (match_operand:V2SF 0 "register_operand" "=f,f") (if_then_else:V2SF diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index a699238ba1c..29f0f0b74f3 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -504,11 +504,11 @@ struct mips_asm_switch mips_noat = { "at", 0 }; static bool mips_branch_likely; /* The current instruction-set architecture. */ -enum processor_type mips_arch; +enum processor mips_arch; const struct mips_cpu_info *mips_arch_info; /* The processor that we should tune the code for. */ -enum processor_type mips_tune; +enum processor mips_tune; const struct mips_cpu_info *mips_tune_info; /* The ISA level associated with mips_arch. */ @@ -797,7 +797,8 @@ static const struct mips_rtx_cost_data mips_rtx_cost_optimize_size = { }; /* Costs to use when optimizing for speed, indexed by processor. */ -static const struct mips_rtx_cost_data mips_rtx_cost_data[PROCESSOR_MAX] = { +static const struct mips_rtx_cost_data + mips_rtx_cost_data[NUM_PROCESSOR_VALUES] = { { /* R3000 */ COSTS_N_INSNS (2), /* fp_add */ COSTS_N_INSNS (4), /* fp_mult_sf */ diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 5ecd59dfd74..4d791023f14 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -28,53 +28,6 @@ along with GCC; see the file COPYING3. If not see /* MIPS external variables defined in mips.c. */ -/* Which processor to schedule for. Since there is no difference between - a R2000 and R3000 in terms of the scheduler, we collapse them into - just an R3000. The elements of the enumeration must match exactly - the cpu attribute in the mips.md machine description. */ - -enum processor_type { - PROCESSOR_R3000, - PROCESSOR_4KC, - PROCESSOR_4KP, - PROCESSOR_5KC, - PROCESSOR_5KF, - PROCESSOR_20KC, - PROCESSOR_24KC, - PROCESSOR_24KF2_1, - PROCESSOR_24KF1_1, - PROCESSOR_74KC, - PROCESSOR_74KF2_1, - PROCESSOR_74KF1_1, - PROCESSOR_74KF3_2, - PROCESSOR_LOONGSON_2E, - PROCESSOR_LOONGSON_2F, - PROCESSOR_M4K, - PROCESSOR_OCTEON, - PROCESSOR_R3900, - PROCESSOR_R6000, - PROCESSOR_R4000, - PROCESSOR_R4100, - PROCESSOR_R4111, - PROCESSOR_R4120, - PROCESSOR_R4130, - PROCESSOR_R4300, - PROCESSOR_R4600, - PROCESSOR_R4650, - PROCESSOR_R5000, - PROCESSOR_R5400, - PROCESSOR_R5500, - PROCESSOR_R7000, - PROCESSOR_R8000, - PROCESSOR_R9000, - PROCESSOR_R10000, - PROCESSOR_SB1, - PROCESSOR_SB1A, - PROCESSOR_SR71000, - PROCESSOR_XLR, - PROCESSOR_MAX -}; - /* Costs of various operations on the different architectures. */ struct mips_rtx_cost_data @@ -121,7 +74,7 @@ struct mips_cpu_info { /* The internal processor number that most closely matches this entry. Several processors can have the same value, if there's no difference between them from GCC's point of view. */ - enum processor_type cpu; + enum processor cpu; /* The ISA level that the processor implements. */ int isa; @@ -3065,8 +3018,8 @@ extern int mips_dbx_regno[]; extern int mips_dwarf_regno[]; extern bool mips_split_p[]; extern bool mips_split_hi_p[]; -extern enum processor_type mips_arch; /* which cpu to codegen for */ -extern enum processor_type mips_tune; /* which cpu to schedule for */ +extern enum processor mips_arch; /* which cpu to codegen for */ +extern enum processor mips_tune; /* which cpu to schedule for */ extern int mips_isa; /* architectural level */ extern int mips_abi; /* which ABI to use */ extern const struct mips_cpu_info *mips_arch_info; diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index a8543274328..0f287755891 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -23,247 +23,119 @@ ;; along with GCC; see the file COPYING3. If not see ;; <http://www.gnu.org/licenses/>. +(define_enum "processor" [ + r3000 + 4kc + 4kp + 5kc + 5kf + 20kc + 24kc + 24kf2_1 + 24kf1_1 + 74kc + 74kf2_1 + 74kf1_1 + 74kf3_2 + loongson_2e + loongson_2f + m4k + octeon + r3900 + r6000 + r4000 + r4100 + r4111 + r4120 + r4130 + r4300 + r4600 + r4650 + r5000 + r5400 + r5500 + r7000 + r8000 + r9000 + r10000 + sb1 + sb1a + sr71000 + xlr +]) + +(define_c_enum "unspec" [ + ;; Unaligned accesses. + UNSPEC_LOAD_LEFT + UNSPEC_LOAD_RIGHT + UNSPEC_STORE_LEFT + UNSPEC_STORE_RIGHT + + ;; Floating-point moves. + UNSPEC_LOAD_LOW + UNSPEC_LOAD_HIGH + UNSPEC_STORE_WORD + UNSPEC_MFHC1 + UNSPEC_MTHC1 + + ;; HI/LO moves. + UNSPEC_MFHI + UNSPEC_MTHI + UNSPEC_SET_HILO + + ;; GP manipulation. + UNSPEC_LOADGP + UNSPEC_COPYGP + UNSPEC_MOVE_GP + UNSPEC_POTENTIAL_CPRESTORE + UNSPEC_CPRESTORE + UNSPEC_RESTORE_GP + UNSPEC_EH_RETURN + UNSPEC_GP + UNSPEC_SET_GOT_VERSION + UNSPEC_UPDATE_GOT_VERSION + + ;; Symbolic accesses. + UNSPEC_LOAD_CALL + UNSPEC_LOAD_GOT + UNSPEC_TLS_LDM + UNSPEC_TLS_GET_TP + + ;; MIPS16 constant pools. + UNSPEC_ALIGN + UNSPEC_CONSTTABLE_INT + UNSPEC_CONSTTABLE_FLOAT + + ;; Blockage and synchronisation. + UNSPEC_BLOCKAGE + UNSPEC_CLEAR_HAZARD + UNSPEC_RDHWR + UNSPEC_SYNCI + UNSPEC_SYNC + + ;; Cache manipulation. + UNSPEC_MIPS_CACHE + UNSPEC_R10K_CACHE_BARRIER + + ;; Interrupt handling. + UNSPEC_ERET + UNSPEC_DERET + UNSPEC_DI + UNSPEC_EHB + UNSPEC_RDPGPR + UNSPEC_COP0 + + ;; Used in a call expression in place of args_size. It's present for PIC + ;; indirect calls where it contains args_size and the function symbol. + UNSPEC_CALL_ATTR +]) + (define_constants - [(UNSPEC_LOAD_LOW 0) - (UNSPEC_LOAD_HIGH 1) - (UNSPEC_STORE_WORD 2) - (UNSPEC_GET_FNADDR 3) - (UNSPEC_BLOCKAGE 4) - (UNSPEC_POTENTIAL_CPRESTORE 5) - (UNSPEC_CPRESTORE 6) - (UNSPEC_RESTORE_GP 7) - (UNSPEC_MOVE_GP 8) - (UNSPEC_EH_RETURN 9) - (UNSPEC_CONSTTABLE_INT 10) - (UNSPEC_CONSTTABLE_FLOAT 11) - (UNSPEC_ALIGN 14) - (UNSPEC_HIGH 17) - (UNSPEC_LOAD_LEFT 18) - (UNSPEC_LOAD_RIGHT 19) - (UNSPEC_STORE_LEFT 20) - (UNSPEC_STORE_RIGHT 21) - (UNSPEC_LOADGP 22) - (UNSPEC_LOAD_CALL 23) - (UNSPEC_LOAD_GOT 24) - (UNSPEC_GP 25) - (UNSPEC_MFHI 26) - (UNSPEC_MTHI 27) - (UNSPEC_SET_HILO 28) - (UNSPEC_TLS_LDM 29) - (UNSPEC_TLS_GET_TP 30) - (UNSPEC_MFHC1 31) - (UNSPEC_MTHC1 32) - (UNSPEC_CLEAR_HAZARD 33) - (UNSPEC_RDHWR 34) - (UNSPEC_SYNCI 35) - (UNSPEC_SYNC 36) - (UNSPEC_COMPARE_AND_SWAP 37) - (UNSPEC_COMPARE_AND_SWAP_12 38) - (UNSPEC_SYNC_OLD_OP 39) - (UNSPEC_SYNC_NEW_OP 40) - (UNSPEC_SYNC_NEW_OP_12 41) - (UNSPEC_SYNC_OLD_OP_12 42) - (UNSPEC_SYNC_EXCHANGE 43) - (UNSPEC_SYNC_EXCHANGE_12 44) - (UNSPEC_MEMORY_BARRIER 45) - (UNSPEC_SET_GOT_VERSION 46) - (UNSPEC_UPDATE_GOT_VERSION 47) - (UNSPEC_COPYGP 48) - (UNSPEC_ERET 49) - (UNSPEC_DERET 50) - (UNSPEC_DI 51) - (UNSPEC_EHB 52) - (UNSPEC_RDPGPR 53) - (UNSPEC_COP0 54) - ;; Used in a call expression in place of args_size. It's present for PIC - ;; indirect calls where it contains args_size and the function symbol. - (UNSPEC_CALL_ATTR 55) - - (UNSPEC_ADDRESS_FIRST 100) - - (TLS_GET_TP_REGNUM 3) + [(TLS_GET_TP_REGNUM 3) (RETURN_ADDR_REGNUM 31) (CPRESTORE_SLOT_REGNUM 76) (GOT_VERSION_REGNUM 79) - ;; For MIPS Paired-Singled Floating Point Instructions. - - (UNSPEC_MOVE_TF_PS 200) - (UNSPEC_C 201) - - ;; MIPS64/MIPS32R2 alnv.ps - (UNSPEC_ALNV_PS 202) - - ;; MIPS-3D instructions - (UNSPEC_CABS 203) - - (UNSPEC_ADDR_PS 204) - (UNSPEC_CVT_PW_PS 205) - (UNSPEC_CVT_PS_PW 206) - (UNSPEC_MULR_PS 207) - (UNSPEC_ABS_PS 208) - - (UNSPEC_RSQRT1 209) - (UNSPEC_RSQRT2 210) - (UNSPEC_RECIP1 211) - (UNSPEC_RECIP2 212) - (UNSPEC_SINGLE_CC 213) - (UNSPEC_SCC 214) - - ;; MIPS DSP ASE Revision 0.98 3/24/2005 - (UNSPEC_ADDQ 300) - (UNSPEC_ADDQ_S 301) - (UNSPEC_SUBQ 302) - (UNSPEC_SUBQ_S 303) - (UNSPEC_ADDSC 304) - (UNSPEC_ADDWC 305) - (UNSPEC_MODSUB 306) - (UNSPEC_RADDU_W_QB 307) - (UNSPEC_ABSQ_S 308) - (UNSPEC_PRECRQ_QB_PH 309) - (UNSPEC_PRECRQ_PH_W 310) - (UNSPEC_PRECRQ_RS_PH_W 311) - (UNSPEC_PRECRQU_S_QB_PH 312) - (UNSPEC_PRECEQ_W_PHL 313) - (UNSPEC_PRECEQ_W_PHR 314) - (UNSPEC_PRECEQU_PH_QBL 315) - (UNSPEC_PRECEQU_PH_QBR 316) - (UNSPEC_PRECEQU_PH_QBLA 317) - (UNSPEC_PRECEQU_PH_QBRA 318) - (UNSPEC_PRECEU_PH_QBL 319) - (UNSPEC_PRECEU_PH_QBR 320) - (UNSPEC_PRECEU_PH_QBLA 321) - (UNSPEC_PRECEU_PH_QBRA 322) - (UNSPEC_SHLL 323) - (UNSPEC_SHLL_S 324) - (UNSPEC_SHRL_QB 325) - (UNSPEC_SHRA_PH 326) - (UNSPEC_SHRA_R 327) - (UNSPEC_MULEU_S_PH_QBL 328) - (UNSPEC_MULEU_S_PH_QBR 329) - (UNSPEC_MULQ_RS_PH 330) - (UNSPEC_MULEQ_S_W_PHL 331) - (UNSPEC_MULEQ_S_W_PHR 332) - (UNSPEC_DPAU_H_QBL 333) - (UNSPEC_DPAU_H_QBR 334) - (UNSPEC_DPSU_H_QBL 335) - (UNSPEC_DPSU_H_QBR 336) - (UNSPEC_DPAQ_S_W_PH 337) - (UNSPEC_DPSQ_S_W_PH 338) - (UNSPEC_MULSAQ_S_W_PH 339) - (UNSPEC_DPAQ_SA_L_W 340) - (UNSPEC_DPSQ_SA_L_W 341) - (UNSPEC_MAQ_S_W_PHL 342) - (UNSPEC_MAQ_S_W_PHR 343) - (UNSPEC_MAQ_SA_W_PHL 344) - (UNSPEC_MAQ_SA_W_PHR 345) - (UNSPEC_BITREV 346) - (UNSPEC_INSV 347) - (UNSPEC_REPL_QB 348) - (UNSPEC_REPL_PH 349) - (UNSPEC_CMP_EQ 350) - (UNSPEC_CMP_LT 351) - (UNSPEC_CMP_LE 352) - (UNSPEC_CMPGU_EQ_QB 353) - (UNSPEC_CMPGU_LT_QB 354) - (UNSPEC_CMPGU_LE_QB 355) - (UNSPEC_PICK 356) - (UNSPEC_PACKRL_PH 357) - (UNSPEC_EXTR_W 358) - (UNSPEC_EXTR_R_W 359) - (UNSPEC_EXTR_RS_W 360) - (UNSPEC_EXTR_S_H 361) - (UNSPEC_EXTP 362) - (UNSPEC_EXTPDP 363) - (UNSPEC_SHILO 364) - (UNSPEC_MTHLIP 365) - (UNSPEC_WRDSP 366) - (UNSPEC_RDDSP 367) - - ;; MIPS DSP ASE REV 2 Revision 0.02 11/24/2006 - (UNSPEC_ABSQ_S_QB 400) - (UNSPEC_ADDU_PH 401) - (UNSPEC_ADDU_S_PH 402) - (UNSPEC_ADDUH_QB 403) - (UNSPEC_ADDUH_R_QB 404) - (UNSPEC_APPEND 405) - (UNSPEC_BALIGN 406) - (UNSPEC_CMPGDU_EQ_QB 407) - (UNSPEC_CMPGDU_LT_QB 408) - (UNSPEC_CMPGDU_LE_QB 409) - (UNSPEC_DPA_W_PH 410) - (UNSPEC_DPS_W_PH 411) - (UNSPEC_MADD 412) - (UNSPEC_MADDU 413) - (UNSPEC_MSUB 414) - (UNSPEC_MSUBU 415) - (UNSPEC_MUL_PH 416) - (UNSPEC_MUL_S_PH 417) - (UNSPEC_MULQ_RS_W 418) - (UNSPEC_MULQ_S_PH 419) - (UNSPEC_MULQ_S_W 420) - (UNSPEC_MULSA_W_PH 421) - (UNSPEC_MULT 422) - (UNSPEC_MULTU 423) - (UNSPEC_PRECR_QB_PH 424) - (UNSPEC_PRECR_SRA_PH_W 425) - (UNSPEC_PRECR_SRA_R_PH_W 426) - (UNSPEC_PREPEND 427) - (UNSPEC_SHRA_QB 428) - (UNSPEC_SHRA_R_QB 429) - (UNSPEC_SHRL_PH 430) - (UNSPEC_SUBU_PH 431) - (UNSPEC_SUBU_S_PH 432) - (UNSPEC_SUBUH_QB 433) - (UNSPEC_SUBUH_R_QB 434) - (UNSPEC_ADDQH_PH 435) - (UNSPEC_ADDQH_R_PH 436) - (UNSPEC_ADDQH_W 437) - (UNSPEC_ADDQH_R_W 438) - (UNSPEC_SUBQH_PH 439) - (UNSPEC_SUBQH_R_PH 440) - (UNSPEC_SUBQH_W 441) - (UNSPEC_SUBQH_R_W 442) - (UNSPEC_DPAX_W_PH 443) - (UNSPEC_DPSX_W_PH 444) - (UNSPEC_DPAQX_S_W_PH 445) - (UNSPEC_DPAQX_SA_W_PH 446) - (UNSPEC_DPSQX_S_W_PH 447) - (UNSPEC_DPSQX_SA_W_PH 448) - - ;; ST Microelectronics Loongson-2E/2F. - (UNSPEC_LOONGSON_PAVG 500) - (UNSPEC_LOONGSON_PCMPEQ 501) - (UNSPEC_LOONGSON_PCMPGT 502) - (UNSPEC_LOONGSON_PEXTR 503) - (UNSPEC_LOONGSON_PINSR_0 504) - (UNSPEC_LOONGSON_PINSR_1 505) - (UNSPEC_LOONGSON_PINSR_2 506) - (UNSPEC_LOONGSON_PINSR_3 507) - (UNSPEC_LOONGSON_PMADD 508) - (UNSPEC_LOONGSON_PMOVMSK 509) - (UNSPEC_LOONGSON_PMULHU 510) - (UNSPEC_LOONGSON_PMULH 511) - (UNSPEC_LOONGSON_PMULL 512) - (UNSPEC_LOONGSON_PMULU 513) - (UNSPEC_LOONGSON_PASUBUB 514) - (UNSPEC_LOONGSON_BIADD 515) - (UNSPEC_LOONGSON_PSADBH 516) - (UNSPEC_LOONGSON_PSHUFH 517) - (UNSPEC_LOONGSON_PUNPCKH 518) - (UNSPEC_LOONGSON_PUNPCKL 519) - (UNSPEC_LOONGSON_PADDD 520) - (UNSPEC_LOONGSON_PSUBD 521) - - ;; Used in loongson2ef.md - (UNSPEC_LOONGSON_ALU1_TURN_ENABLED_INSN 530) - (UNSPEC_LOONGSON_ALU2_TURN_ENABLED_INSN 531) - (UNSPEC_LOONGSON_FALU1_TURN_ENABLED_INSN 532) - (UNSPEC_LOONGSON_FALU2_TURN_ENABLED_INSN 533) - - (UNSPEC_MIPS_CACHE 600) - (UNSPEC_R10K_CACHE_BARRIER 601) - ;; PIC long branch sequences are never longer than 100 bytes. (MAX_PIC_BRANCH_LENGTH 100) ] @@ -637,7 +509,7 @@ ] (const_int 4))) ;; Attribute describing the processor. This attribute must match exactly -;; with the processor_type enumeration in mips.h. +;; with the processor enumeration above. (define_attr "cpu" "r3000,4kc,4kp,5kc,5kf,20kc,24kc,24kf2_1,24kf1_1,74kc,74kf2_1,74kf1_1,74kf3_2,loongson_2e,loongson_2f,m4k,octeon,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,r10000,sb1,sb1a,sr71000,xlr" (const (symbol_ref "mips_tune_attr"))) @@ -6581,3 +6453,7 @@ ; ST-Microelectronics Loongson-2E/2F-specific patterns. (include "loongson.md") + +(define_c_enum "unspec" [ + UNSPEC_ADDRESS_FIRST +]) diff --git a/gcc/config/mips/sync.md b/gcc/config/mips/sync.md index e28f56c601a..ee41d2c9740 100644 --- a/gcc/config/mips/sync.md +++ b/gcc/config/mips/sync.md @@ -19,6 +19,18 @@ ;; along with GCC; see the file COPYING3. If not see ;; <http://www.gnu.org/licenses/>. +(define_c_enum "unspec" [ + 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 +]) + ;; Atomic fetch bitwise operations. (define_code_iterator fetchop_bit [ior xor and]) diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index fb3a4c1bc73..990863acccc 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -7902,6 +7902,88 @@ You could write: The constants that are defined with a define_constant are also output in the insn-codes.h header file as #defines. + +@cindex enumerations +@findex define_c_enum +You can also use the machine description file to define enumerations. +Like the constants defined by @code{define_constant}, these enumerations +are visible to both the machine description file and the main C code. + +The syntax is as follows: + +@smallexample +(define_c_enum "@var{name}" [ + @var{value0} + @var{value1} + @dots{} + @var{valuen} +]) +@end smallexample + +This definition causes the equivalent of the following C code to appear +in @file{insn-constants.h}: + +@smallexample +enum @var{name} @{ + @var{value0} = 0, + @var{value1} = 1, + @dots{} + @var{valuen} = @var{n} +@}; +#define NUM_@var{cname}_VALUES (@var{n} + 1) +@end smallexample + +where @var{cname} is the capitalized form of @var{name}. +It also makes each @var{valuei} available in the machine description +file, just as if it had been declared with: + +@smallexample +(define_constants [(@var{valuei} @var{i})]) +@end smallexample + +Each @var{valuei} is usually an upper-case identifier and usually +begins with @var{cname}. + +You can split the enumeration definition into as many statements as +you like. The above example is directly equivalent to: + +@smallexample +(define_c_enum "@var{name}" [@var{value0}]) +(define_c_enum "@var{name}" [@var{value1}]) +@dots{} +(define_c_enum "@var{name}" [@var{valuen}]) +@end smallexample + +Splitting the enumeration helps to improve the modularity of each +individual @code{.md} file. For example, if a port defines its +synchronization instructions in a separate @file{sync.md} file, +it is convenient to define all synchronization-specific enumeration +values in @file{sync.md} rather than in the main @file{.md} file. + +@findex define_enum +Another way of defining an enumeration is to use @code{define_enum}: + +@smallexample +(define_enum "@var{name}" [ + @var{value0} + @var{value1} + @dots{} + @var{valuen} +]) +@end smallexample + +This directive implies: + +@smallexample +(define_c_enum "@var{name}" [ + @var{cname}_@var{cvalue0} + @var{cname}_@var{cvalue1} + @dots{} + @var{cname}_@var{cvaluen} +]) +@end smallexample + +where @var{cvaluei} is the capitalized form of @var{valuei}. @end ifset @ifset INTERNALS @node Iterators diff --git a/gcc/genconstants.c b/gcc/genconstants.c index 60526bbf716..b16a88bc3ea 100644 --- a/gcc/genconstants.c +++ b/gcc/genconstants.c @@ -35,12 +35,40 @@ along with GCC; see the file COPYING3. If not see the current constant definition. */ static int -print_md_constant (void **slot, void *info) +print_md_constant (void **slot, void *info ATTRIBUTE_UNUSED) { struct md_constant *def = (struct md_constant *) *slot; - FILE *file = (FILE *) info; - fprintf (file, "#define %s %s\n", def->name, def->value); + if (!def->parent_enum) + printf ("#define %s %s\n", def->name, def->value); + return 1; +} + +/* Called via traverse_enums. Emit an enum definition for + enum_type *SLOT. */ + +static int +print_enum_type (void **slot, void *info ATTRIBUTE_UNUSED) +{ + struct enum_type *def; + struct enum_value *value; + char *value_name; + + def = (struct enum_type *) *slot; + printf ("\nenum %s {", def->name); + for (value = def->values; value; value = value->next) + { + printf ("\n %s = %s", value->def->name, value->def->value); + if (value->next) + putc (',', stdout); + } + printf ("\n};\n"); + + /* Define NUM_<enum>_VALUES to be the largest enum value + 1. */ + value_name = ACONCAT (("num_", def->name, "_values", NULL)); + upcase_string (value_name); + printf ("#define %s %d\n", value_name, def->num_values); + return 1; } @@ -60,7 +88,8 @@ main (int argc, char **argv) puts ("#ifndef GCC_INSN_CONSTANTS_H"); puts ("#define GCC_INSN_CONSTANTS_H\n"); - traverse_md_constants (print_md_constant, stdout); + traverse_md_constants (print_md_constant, 0); + traverse_enum_types (print_enum_type, 0); puts ("\n#endif /* GCC_INSN_CONSTANTS_H */"); 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 (); diff --git a/gcc/read-md.h b/gcc/read-md.h index ebe47cc3737..94a5fbbc241 100644 --- a/gcc/read-md.h +++ b/gcc/read-md.h @@ -33,12 +33,49 @@ struct md_name { char *string; }; -/* This structure represents a constant defined by define_constant. - NAME is the name of the constant and VALUE is the string it - expands to. */ +/* This structure represents a constant defined by define_constant, + define_enum, or such-like. */ struct md_constant { + /* The name of the constant. */ char *name; + + /* The string to which the constants expands. */ char *value; + + /* If the constant is associated with a enumeration, this field + points to that enumeration, otherwise it is null. */ + struct enum_type *parent_enum; +}; + +/* This structure represents one value in an enum_type. */ +struct enum_value { + /* The next value in the enum, or null if this is the last. */ + struct enum_value *next; + + /* The name of the value as it appears in the .md file. */ + char *name; + + /* The definition of the related C value. */ + struct md_constant *def; +}; + +/* This structure represents an enum defined by define_enum or the like. */ +struct enum_type { + /* The C name of the enumeration. */ + char *name; + + /* True if this is an md-style enum (DEFINE_ENUM) rather than + a C-style enum (DEFINE_C_ENUM). */ + bool md_p; + + /* The values of the enumeration. There is always at least one. */ + struct enum_value *values; + + /* A pointer to the null terminator in VALUES. */ + struct enum_value **tail_ptr; + + /* The number of enumeration values. */ + unsigned int num_values; }; /* A callback that handles a single .md-file directive, up to but not @@ -95,6 +132,8 @@ extern char *read_string (int); extern void read_skip_construct (int, int); extern int n_comma_elts (const char *); extern const char *scan_comma_elt (const char **); +extern void upcase_string (char *); extern void traverse_md_constants (htab_trav, void *); +extern void traverse_enum_types (htab_trav, void *); extern bool read_md_files (int, char **, bool (*) (const char *), directive_handler_t); |