This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH: conditional traps for MIPS (good patch)


Greg McGary <greg@mcgary.org> writes:

> This works for SImode operands (test program that compiles & assembles
> appended), but I have low confidence that it is the proper way to do
> it.  Please advise on how it can be improved.

I advised myself, since no else volunteered. 8^)

GCC still generates sub-optimal code for some conditions with
immediate operands because the condition has been mangled by fold and
the jump optimizer, but I'm not going to sweat that because the
interesting cases (notably BPs) don't use immediate operands.

I believe this is a reasonable patch.

OK?

2000-09-06  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.

Index: gcc/config/mips/mips-protos.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/mips/mips-protos.h,v
retrieving revision 1.4
diff -u -p -r1.4 mips-protos.h
--- mips-protos.h	2000/08/08 01:17:06	1.4
+++ mips-protos.h	2000/09/06 07:48:40
@@ -67,6 +67,7 @@ extern void		mips_select_section PARAMS 
 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
 #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));
Index: gcc/config/mips/mips.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/mips/mips.c,v
retrieving revision 1.98
diff -u -p -r1.98 mips.c
--- mips.c	2000/08/24 20:31:35	1.98
+++ mips.c	2000/09/06 07:48:43
@@ -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
@@ -3138,6 +3166,46 @@ gen_conditional_move (operands)
 							 cmp_reg,
 							 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.
Index: gcc/config/mips/mips.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/mips/mips.h,v
retrieving revision 1.102
diff -u -p -r1.102 mips.h
--- mips.h	2000/08/21 14:35:29	1.102
+++ mips.h	2000/09/06 07:48:45
@@ -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,	\
Index: gcc/config/mips/mips.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/mips/mips.md,v
retrieving revision 1.84
diff -u -p -r1.84 mips.md
--- mips.md	2000/08/08 22:40:49	1.84
+++ mips.md	2000/09/06 07:48:46
@@ -10455,3 +10455,34 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\;j
   [(set_attr "type"	"arith")
    (set_attr "mode"	"DI")
    (set_attr "length"	"40")])
+
+
+(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;
+}")
+
+(define_insn ""
+  [(trap_if (match_operator 0 "trap_cmp_op"
+                            [(match_operand:SI 1 "reg_or_0_operand" "d,d")
+                             (match_operand:SI 2 "general_operand" "d,I")])
+	    (const_int 0))]
+  "ISA_HAS_COND_TRAP"
+  "t%C0\\t%z1,%z2")

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]