summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgkm <gkm@138bc75d-0d04-0410-961f-82ee72b054a4>2000-09-12 18:40:58 +0000
committergkm <gkm@138bc75d-0d04-0410-961f-82ee72b054a4>2000-09-12 18:40:58 +0000
commitea98ee5207227717f7cd3b6a5cec6f9d00f527b5 (patch)
tree93c6f2d62aaecc62c9172d737563813c5dfe8a12
parentc87aba630389d4463e9131b703e81f45508c54f8 (diff)
downloadppe42-gcc-ea98ee5207227717f7cd3b6a5cec6f9d00f527b5.tar.gz
ppe42-gcc-ea98ee5207227717f7cd3b6a5cec6f9d00f527b5.zip
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@36371 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/mips/mips-protos.h2
-rw-r--r--gcc/config/mips/mips.c72
-rw-r--r--gcc/config/mips/mips.h3
-rw-r--r--gcc/config/mips/mips.md41
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 <greg@mcgary.org>
+
+ * 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 <bernds@redhat.co.uk>
* 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")
;;
;; ....................
OpenPOWER on IntegriCloud