From a0b6cdee336967a6723b43438f567def4e86730e Mon Sep 17 00:00:00 2001 From: Greg McGary Date: Tue, 12 Sep 2000 18:40:58 +0000 Subject: [PATCH] * config/mips/mips-protos.h (trap_cmp_op, mips_gen_conditional_trap): New func decls. * config/mips/mips.h (ISA_HAS_COND_TRAP): New macro. (PREDICATE_CODES): Add "trap_cmp_op". * config/mips/mips.c (trap_cmp_op, mips_gen_conditional_trap): New functions. * config/mips/mips.md (trap, conditional_trap): New patterns. From-SVN: r36371 --- gcc/ChangeLog | 10 +++++ gcc/config/mips/mips-protos.h | 2 + gcc/config/mips/mips.c | 72 ++++++++++++++++++++++++++++++++++- gcc/config/mips/mips.h | 3 ++ gcc/config/mips/mips.md | 41 ++++++++++++++++++++ 5 files changed, 126 insertions(+), 2 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d6e3caabe32..1520949961e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2000-09-12 Greg McGary + + * config/mips/mips-protos.h + (trap_cmp_op, mips_gen_conditional_trap): New func decls. + * config/mips/mips.h (ISA_HAS_COND_TRAP): New macro. + (PREDICATE_CODES): Add "trap_cmp_op". + * config/mips/mips.c + (trap_cmp_op, mips_gen_conditional_trap): New functions. + * config/mips/mips.md (trap, conditional_trap): New patterns. + 2000-09-12 Bernd Schmidt * flow.c (try_pre_increment_1): Don't do anything to sets of the stack diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index 126ca1d3933..826cd5e1b6a 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -67,6 +67,7 @@ extern void mips_select_section PARAMS ((tree, int)); extern int arith32_operand PARAMS ((rtx, enum machine_mode)); extern int arith_operand PARAMS ((rtx, enum machine_mode)); extern int cmp_op PARAMS ((rtx, enum machine_mode)); +extern int trap_cmp_op PARAMS ((rtx, enum machine_mode)); extern int const_float_1_operand PARAMS ((rtx, enum machine_mode)); extern void expand_block_move PARAMS ((rtx [])); extern int equality_op PARAMS ((rtx, enum machine_mode)); @@ -77,6 +78,7 @@ extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *c, tree, rtx)); #endif /* TREE_CODE */ extern void gen_conditional_branch PARAMS ((rtx[], enum rtx_code)); extern void gen_conditional_move PARAMS ((rtx *)); +extern void mips_gen_conditional_trap PARAMS ((rtx *)); extern int large_int PARAMS ((rtx, enum machine_mode)); extern void machine_dependent_reorg PARAMS ((rtx)); extern int mips_address_cost PARAMS ((rtx)); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index f059dddd616..860ce956d7b 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -188,8 +188,8 @@ int num_refs[3]; /* registers to check for load delay */ rtx mips_load_reg, mips_load_reg2, mips_load_reg3, mips_load_reg4; -/* Cached operands, and operator to compare for use in set/branch on - condition codes. */ +/* Cached operands, and operator to compare for use in set/branch/trap + on condition codes. */ rtx branch_cmp[2]; /* what type of branch to use */ @@ -964,6 +964,34 @@ cmp_op (op, mode) return GET_RTX_CLASS (GET_CODE (op)) == '<'; } +/* Return nonzero if the code is a relational operation suitable for a + conditional trap instructuion (only EQ, NE, LT, LTU, GE, GEU). + We need this in the insn that expands `trap_if' in order to prevent + combine from erroneously altering the condition. */ + +int +trap_cmp_op (op, mode) + rtx op; + enum machine_mode mode; +{ + if (mode != GET_MODE (op)) + return 0; + + switch (GET_CODE (op)) + { + case EQ: + case NE: + case LT: + case LTU: + case GE: + case GEU: + return 1; + + default: + return 0; + } +} + /* Return nonzero if the operand is either the PC or a label_ref. */ int @@ -3139,6 +3167,46 @@ gen_conditional_move (operands) CONST0_RTX (SImode)), operands[2], operands[3]))); } + +/* Emit the common code for conditional moves. OPERANDS is the array + of operands passed to the conditional move defined_expand. */ + +void +mips_gen_conditional_trap (operands) + rtx operands[]; +{ + rtx op0, op1; + enum rtx_code cmp_code = GET_CODE (operands[0]); + enum machine_mode mode = GET_MODE (branch_cmp[0]); + + /* MIPS conditional trap machine instructions don't have GT or LE + flavors, so we must invert the comparison and convert to LT and + GE, respectively. */ + switch (cmp_code) + { + case GT: cmp_code = LT; break; + case LE: cmp_code = GE; break; + case GTU: cmp_code = LTU; break; + case LEU: cmp_code = GEU; break; + default: break; + } + if (cmp_code == GET_CODE (operands[0])) + { + op0 = force_reg (mode, branch_cmp[0]); + op1 = branch_cmp[1]; + } + else + { + op0 = force_reg (mode, branch_cmp[1]); + op1 = branch_cmp[0]; + } + if (GET_CODE (op1) == CONST_INT && ! SMALL_INT (op1)) + op1 = force_reg (mode, op1); + + emit_insn (gen_rtx_TRAP_IF (VOIDmode, + gen_rtx (cmp_code, GET_MODE (operands[0]), op0, op1), + operands[1])); +} /* Write a loop to move a constant number of bytes. Generate load/stores as follows: diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 531af1790e9..98c046b8cea 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -607,6 +607,8 @@ extern void sbss_section PARAMS ((void)); #define ISA_HAS_FP4 (mips_isa == 4 \ ) +/* ISA has conditional trap instructions. */ +#define ISA_HAS_COND_TRAP (mips_isa >= 2) /* CC1_SPEC causes -mips3 and -mips4 to set -mfp64 and -mgp64; -mips1 or @@ -3713,6 +3715,7 @@ while (0) {"equality_op", { EQ, NE }}, \ {"cmp_op", { EQ, NE, GT, GE, GTU, GEU, LT, LE, \ LTU, LEU }}, \ + {"trap_cmp_op", { EQ, NE, GE, GEU, LT, LTU }}, \ {"pc_or_label_operand", { PC, LABEL_REF }}, \ {"call_insn_operand", { CONST_INT, CONST, SYMBOL_REF, REG}}, \ {"move_operand", { CONST_INT, CONST_DOUBLE, CONST, \ diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index b34189ab2fe..cf93964a039 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -495,7 +495,48 @@ ;; ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF")) 54 0) ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0) + +;; +;; .................... +;; +;; CONDITIONAL TRAPS +;; +;; .................... +;; + +(define_insn "trap" + [(trap_if (const_int 1) (const_int 0))] + "" + "* +{ + if (ISA_HAS_COND_TRAP) + return \"teq\\t$0,$0\"; + else + return \"break\"; +}") + +(define_expand "conditional_trap" + [(trap_if (match_operator 0 "cmp_op" + [(match_dup 2) (match_dup 3)]) + (match_operand 1 "const_int_operand" ""))] + "ISA_HAS_COND_TRAP" + " +{ + mips_gen_conditional_trap (operands); + DONE; +}") +;; Match a TRAP_IF with 2nd arg of 0. The div_trap_* insns match a +;; 2nd arg of any CONST_INT, so this insn must appear first. +;; gen_div_trap always generates TRAP_IF with 2nd arg of 6 or 7. + +(define_insn "" + [(trap_if (match_operator 0 "trap_cmp_op" + [(match_operand:SI 1 "reg_or_0_operand" "d") + (match_operand:SI 2 "nonmemory_operand" "dI")]) + (const_int 0))] + "ISA_HAS_COND_TRAP" + "t%C0\\t%z1,%z2") ;; ;; .................... -- 2.30.2