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]
Other format: [Raw text]

[cond-optab] Point of no return


This patch makes cbranch/cstore the only valid way to implement branches
and stores.  I left in the cmov optab for now, but it's not used (and
can_compare_p's ccp_cmov value for the last parameter is also not used);
I'll decide on its fate later.  movcc and addcc are actually a much
nicer design than bCC/sCC because they pass the comparison in the
operands, so there is no hurry to delete it.

With this patch in, all targets are broken.  I'll send the patch to
reenable i386 soon.

Paolo
2009-03-16  Paolo Bonzini  <bonzini@gnu.org>

	* dojump.c (compare_from_rtx): Delete.
	* expmed.c (emit_store_flag): Only try cstore_optab.
	* expr.h (compare_from_rtx): Delete.
	* optabs.c (bcc_gen_fctn, setcc_gen_code, trap_rtx,
	emit_cmp_insn): Delete.
	(can_compare_p): Delete cmp_optab case.
	(emit_cmp_and_jump_insn_1): Only try cbranch_optab.
	(emit_cmp_and_jump_insns): Fix comment.
	(emit_conditional_move, emit_conditional_add): Inline
	what's needed of compare_from_rtx.
	(init_optabs): Init cmp_optab with UNKNOWN, cbranch_optab
	with COMPARE.  Move cmov_optab and cstore_optab above
	with cbranch_optab, move cmp_optab down with ucmp_optab,
	remove tst_otpab.  Do not initialize trap_rtx.
	(gen_cond_trap): Do it here.  Use ctrap_optab.
	* optabs.h (OTI_cmp): Mark as used only for libcalls.
	(OTI_ctrap, ctrap_optab): New.
	(tst_optab): Delete.
	(bcc_gen_fctn, setcc_gen_code, emit_cmp_insn): Delete.
	* genopinit.c (cmp_optab, tst_optab, bcc_gen_fctn,
	setcc_gen_code): Delete.
	(ctrap_optab): New.

	* doc/md.texi (bCC, sCC): Delete.
	(cstoreMM4): Document.
	(sync_compare_and_swapMM): Refer to cbranchcc4.
	(Jump Patterns): Remove text about storing operands in cmpMM.
	(Canonicalization): Include cbranchcc4 case.

Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c	(branch cond-optab)
+++ gcc/optabs.c	(working copy)
@@ -79,17 +79,6 @@ struct convert_optab convert_optab_table
 /* Contains the optab used for each rtx code.  */
 optab code_to_optab[NUM_RTX_CODE + 1];
 
-/* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
-   gives the gen_function to make a branch to test that condition.  */
-
-rtxfun bcc_gen_fctn[NUM_RTX_CODE];
-
-/* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
-   gives the insn code to make a store-condition insn
-   to test that condition.  */
-
-enum insn_code setcc_gen_code[NUM_RTX_CODE];
-
 #ifdef HAVE_conditional_move
 /* Indexed by the machine mode, gives the insn code to make a conditional
    move insn.  This is not indexed by the rtx-code like bcc_gen_fctn and
@@ -105,11 +94,6 @@ enum insn_code movcc_gen_code[NUM_MACHIN
 enum insn_code vcond_gen_code[NUM_MACHINE_MODES];
 enum insn_code vcondu_gen_code[NUM_MACHINE_MODES];
 
-/* The insn generating function can not take an rtx_code argument.
-   TRAP_RTX is used as an rtx argument.  Its code is replaced with
-   the code to be used in the trap insn and all other fields are ignored.  */
-static GTY(()) rtx trap_rtx;
-
 static void prepare_float_lib_cmp (rtx *, rtx *, enum rtx_code *,
 				   enum machine_mode *, int *);
 static rtx expand_unop_direct (enum machine_mode, optab, rtx, rtx, int);
@@ -3986,16 +3970,6 @@ can_compare_p (enum rtx_code code, enum 
     {
       int icode;
 
-      if (optab_handler (cmp_optab, mode)->insn_code != CODE_FOR_nothing)
-	{
-	  if (purpose == ccp_jump)
-	    return bcc_gen_fctn[(int) code] != NULL;
-	  else if (purpose == ccp_store_flag)
-	    return setcc_gen_code[(int) code] != CODE_FOR_nothing;
-	  else
-	    /* There's only one cmov entry point, and it's allowed to fail.  */
-	    return 1;
-	}
       if (purpose == ccp_jump
           && (icode = optab_handler (cbranch_optab, mode)->insn_code) != CODE_FOR_nothing
           && insn_data[icode].operand[0].predicate (test, mode))
@@ -4232,48 +4206,20 @@ emit_cmp_and_jump_insn_1 (rtx x, rtx y, 
   enum mode_class mclass = GET_MODE_CLASS (mode);
   enum machine_mode wider_mode = mode;
 
-  /* Try combined insns first.  */
   do
     {
       enum machine_mode optab_mode = mclass == MODE_CC ? CCmode : wider_mode;
       enum insn_code icode;
       PUT_MODE (test, wider_mode);
 
-      if (label)
-	{
-	  icode = optab_handler (cbranch_optab, optab_mode)->insn_code;
-
-	  if (icode != CODE_FOR_nothing
-	      && insn_data[icode].operand[0].predicate (test, wider_mode))
-	    {
-	      x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
-	      y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
-	      emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
-	      return;
-	    }
-	}
-
-      /* Handle some compares against zero.  */
-      icode = (int) optab_handler (tst_optab, optab_mode)->insn_code;
-      if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
-	{
-	  x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
-	  emit_insn (GEN_FCN (icode) (x));
-	  if (label)
-	    emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
-	  return;
-	}
-
-      /* Handle compares for which there is a directly suitable insn.  */
+      icode = optab_handler (cbranch_optab, optab_mode)->insn_code;
 
-      icode = (int) optab_handler (cmp_optab, optab_mode)->insn_code;
-      if (icode != CODE_FOR_nothing)
+      if (icode != CODE_FOR_nothing
+	  && insn_data[icode].operand[0].predicate (test, wider_mode))
 	{
-	  x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
-	  y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
-	  emit_insn (GEN_FCN (icode) (x, y));
-	  if (label)
-	    emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
+	  x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
+	  y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
+	  emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
 	  return;
 	}
 
@@ -4293,16 +4239,16 @@ emit_cmp_and_jump_insn_1 (rtx x, rtx y, 
    ensure that the comparison RTL has the canonical form.
 
    UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
-   need to be widened by emit_cmp_insn.  UNSIGNEDP is also used to select
-   the proper branch condition code.
+   need to be widened.  UNSIGNEDP is also used to select the proper
+   branch condition code.
 
    If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
 
    MODE is the mode of the inputs (in case they are const_int).
 
-   COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  It will
-   be passed unchanged to emit_cmp_insn, then potentially converted into an
-   unsigned variant based on UNSIGNEDP to select a proper jump instruction.  */
+   COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
+   It will be potentially converted into an unsigned variant based on
+   UNSIGNEDP to select a proper jump instruction.  */
 
 void
 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
@@ -4338,14 +4284,6 @@ emit_cmp_and_jump_insns (rtx x, rtx y, e
   emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
 }
 
-/* Like emit_cmp_and_jump_insns, but generate only the comparison.  */
-
-void
-emit_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
-	       enum machine_mode mode, int unsignedp)
-{
-  emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
-}
 
 /* Emit a library call comparison between floating point X and Y.
    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */
@@ -4572,19 +4510,18 @@ emit_conditional_move (rtx target, enum 
       (op3, insn_data[icode].operand[3].mode))
     op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
 
-  /* Everything should now be in the suitable form, so emit the compare insn
-     and then the conditional move.  */
+  /* Everything should now be in the suitable form.  */
 
-  comparison
-    = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
+  code = unsignedp ? unsigned_condition (code) : code;
+  comparison = simplify_gen_relational (code, VOIDmode, mode, op0, op1);
 
-  /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
   /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
      return NULL and let the caller figure out how best to deal with this
      situation.  */
-  if (GET_CODE (comparison) != code)
+  if (!COMPARISON_P (comparison))
     return NULL_RTX;
 
+  do_pending_stack_adjust ();
   insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
 
   /* If that failed, then give up.  */
@@ -4700,19 +4637,18 @@ emit_conditional_add (rtx target, enum r
       (op3, insn_data[icode].operand[3].mode))
     op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
 
-  /* Everything should now be in the suitable form, so emit the compare insn
-     and then the conditional move.  */
+  /* Everything should now be in the suitable form.  */
 
-  comparison
-    = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
+  code = unsignedp ? unsigned_condition (code) : code;
+  comparison = simplify_gen_relational (code, VOIDmode, mode, op0, op1);
 
-  /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
   /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
      return NULL and let the caller figure out how best to deal with this
      situation.  */
-  if (GET_CODE (comparison) != code)
+  if (!COMPARISON_P (comparison))
     return NULL_RTX;
 
+  do_pending_stack_adjust ();
   insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
 
   /* If that failed, then give up.  */
@@ -6150,9 +6086,6 @@ init_optabs (void)
   libfunc_hash = htab_create_ggc (10, hash_libfunc, eq_libfunc, NULL);
   /* Start by initializing all tables to contain CODE_FOR_nothing.  */
 
-  for (i = 0; i < NUM_RTX_CODE; i++)
-    setcc_gen_code[i] = CODE_FOR_nothing;
-
 #ifdef HAVE_conditional_move
   for (i = 0; i < NUM_MACHINE_MODES; i++)
     movcc_gen_code[i] = CODE_FOR_nothing;
@@ -6230,12 +6163,16 @@ init_optabs (void)
      have_insn_for.  */
   init_optab (mov_optab, SET);
   init_optab (movstrict_optab, STRICT_LOW_PART);
-  init_optab (cmp_optab, COMPARE);
+  init_optab (cbranch_optab, COMPARE);
+
+  init_optab (cmov_optab, UNKNOWN);
+  init_optab (cstore_optab, UNKNOWN);
+  init_optab (ctrap_optab, UNKNOWN);
 
   init_optab (storent_optab, UNKNOWN);
 
+  init_optab (cmp_optab, UNKNOWN);
   init_optab (ucmp_optab, UNKNOWN);
-  init_optab (tst_optab, UNKNOWN);
 
   init_optab (eq_optab, EQ);
   init_optab (ne_optab, NE);
@@ -6291,9 +6228,6 @@ init_optabs (void)
   init_optab (isinf_optab, UNKNOWN);
 
   init_optab (strlen_optab, UNKNOWN);
-  init_optab (cbranch_optab, UNKNOWN);
-  init_optab (cmov_optab, UNKNOWN);
-  init_optab (cstore_optab, UNKNOWN);
   init_optab (push_optab, UNKNOWN);
 
   init_optab (reduc_smax_optab, UNKNOWN);
@@ -6643,9 +6577,6 @@ init_optabs (void)
 
   gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
 
-  if (HAVE_conditional_trap)
-    trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
-
   /* Allow the target to add more libcalls or rename some, etc.  */
   targetm.init_libfuncs ();
 
@@ -6714,6 +6645,7 @@ gen_cond_trap (enum rtx_code code ATTRIB
   enum machine_mode mode = GET_MODE (op1);
   enum insn_code icode;
   rtx insn;
+  rtx trap_rtx;
 
   if (!HAVE_conditional_trap)
     return 0;
@@ -6721,7 +6653,7 @@ gen_cond_trap (enum rtx_code code ATTRIB
   if (mode == VOIDmode)
     return 0;
 
-  icode = optab_handler (cmp_optab, mode)->insn_code;
+  icode = optab_handler (ctrap_optab, mode)->insn_code;
   if (icode == CODE_FOR_nothing)
     return 0;
 
@@ -6733,16 +6665,8 @@ gen_cond_trap (enum rtx_code code ATTRIB
       end_sequence ();
       return 0;
     }
-  emit_insn (GEN_FCN (icode) (op1, op2));
-
-  PUT_CODE (trap_rtx, code);
-  gcc_assert (HAVE_conditional_trap);
-  insn = gen_conditional_trap (trap_rtx, tcode);
-  if (insn)
-    {
-      emit_insn (insn);
-      insn = get_insns ();
-    }
+  trap_rtx = gen_rtx_fmt_ee (code, mode, op1, op2);
+  insn = GEN_FCN (icode) (trap_rtx, op1, op2, tcode);
   end_sequence ();
 
   return insn;
Index: gcc/doc/md.texi
===================================================================
--- gcc/doc/md.texi	(branch cond-optab)
+++ gcc/doc/md.texi	(working copy)
@@ -4514,16 +4514,13 @@ move operand 2 or (operands 2 + operand 
 comparison in operand 1.  If the comparison is true, operand 2 is moved into
 operand 0, otherwise (operand 2 + operand 3) is moved.
 
-@cindex @code{s@var{cond}} instruction pattern
-@item @samp{s@var{cond}}
-Store zero or nonzero in the operand according to the condition codes.
-Value stored is nonzero iff the condition @var{cond} is true.
-@var{cond} is the name of a comparison operation expression code, such
-as @code{eq}, @code{lt} or @code{leu}.
-
-You specify the mode that the operand must have when you write the
-@code{match_operand} expression.  The compiler automatically sees
-which mode you have used and supplies an operand of that mode.
+@cindex @code{cstore@var{mode}4} instruction pattern
+@item @samp{cstore@var{mode}4}
+Store zero or nonzero in operand 0 according to the comparison in operand
+1 is true.  The comparison's operands are in @samp{cstore@var{mode}4}'s
+operands 2 and 3.  You specify the mode that operand 0 must have when you
+write the @code{match_operand} expression.  The compiler automatically
+sees which mode you have used and supplies an operand of that mode.
 
 The value stored for a true condition must have 1 as its low bit, or
 else must be negative.  Otherwise the instruction is not suitable and
@@ -4540,33 +4537,11 @@ integer comparisons, it is best to omit 
 If these operations are omitted, the compiler will usually generate code
 that copies the constant one to the target and branches around an
 assignment of zero to the target.  If this code is more efficient than
-the potential instructions used for the @samp{s@var{cond}} pattern
+the potential instructions used for the @samp{cstore@var{mode}4} pattern
 followed by those required to convert the result into a 1 or a zero in
-@code{SImode}, you should omit the @samp{s@var{cond}} operations from
+@code{SImode}, you should omit the @samp{cstore@var{mode}4} operations from
 the machine description.
 
-@cindex @code{b@var{cond}} instruction pattern
-@item @samp{b@var{cond}}
-Conditional branch instruction.  Operand 0 is a @code{label_ref} that
-refers to the label to jump to.  Jump if the condition codes meet
-condition @var{cond}.
-
-Some machines do not follow the model assumed here where a comparison
-instruction is followed by a conditional branch instruction.  In that
-case, the @samp{cmp@var{m}} (and @samp{tst@var{m}}) patterns should
-simply store the operands away and generate all the required insns in a
-@code{define_expand} (@pxref{Expander Definitions}) for the conditional
-branch operations.  All calls to expand @samp{b@var{cond}} patterns are
-immediately preceded by calls to expand either a @samp{cmp@var{m}}
-pattern or a @samp{tst@var{m}} pattern.
-
-Machines that use a pseudo register for the condition code value, or
-where the mode used for the comparison depends on the condition being
-tested, should also use the above mechanism.  @xref{Jump Patterns}.
-
-The above discussion also applies to the @samp{mov@var{mode}cc} and
-@samp{s@var{cond}} patterns.
-
 @cindex @code{cbranch@var{mode}4} instruction pattern
 @item @samp{cbranch@var{mode}4}
 Conditional branch instruction combined with a compare instruction.
@@ -5084,14 +5059,15 @@ operation and all memory operations afte
 after the atomic operation.
 
 For targets where the success or failure of the compare-and-swap
-operation is available via the status flags, it is possible
-to avoid a separate compare operation and issue the subsequent
-setcc or branch immediately after the compare-and-swap.  To this
-end, GCC will look for a @code{MODE_CC} set in the output of
-@code{sync_compare_and_swap@var{mode}}; if the machine description
-includes such a set, the target should also define a special @code{cmpcc}
-instruction.  GCC will then be able to take the destination of the
-@code{MODE_CC} set and use it as the first operand of @code{cmpcc}.
+operation is available via the status flags, it is possible to
+avoid a separate compare operation and issue the subsequent
+setcc or branch immediately after the compare-and-swap.
+To this end, GCC will look for a @code{MODE_CC} set in the
+output of @code{sync_compare_and_swap@var{mode}}; if the machine
+description includes such a set, the target should also define special
+@code{cbranchcc4} and/or @code{cstorecc4} instructions.  GCC will then
+be able to take the destination of the @code{MODE_CC} set and use it as
+the first operand of @code{cbranchcc4}.
 
 @cindex @code{sync_add@var{mode}} instruction pattern
 @cindex @code{sync_sub@var{mode}} instruction pattern
@@ -5351,45 +5327,20 @@ generating the appropriate machine instr
 @cindex jump instruction patterns
 @cindex defining jump instruction patterns
 
-For most machines, GCC assumes that the machine has a condition code.
-A comparison insn sets the condition code, recording the results of both
-signed and unsigned comparison of the given operands.  A separate branch
-insn tests the condition code and branches or not according its value.
-The branch insns come in distinct signed and unsigned flavors.  Many
-common machines, such as the VAX, the 68000 and the 32000, work this
-way.
-
-Some machines have distinct signed and unsigned compare instructions, and
-only one set of conditional branch instructions.  The easiest way to handle
-these machines is to treat them just like the others until the final stage
-where assembly code is written.  At this time, when outputting code for the
-compare instruction, peek ahead at the following branch using
-@code{next_cc0_user (insn)}.  (The variable @code{insn} refers to the insn
-being output, in the output-writing code in an instruction pattern.)  If
-the RTL says that is an unsigned branch, output an unsigned compare;
-otherwise output a signed compare.  When the branch itself is output, you
-can treat signed and unsigned branches identically.
-
-The reason you can do this is that GCC always generates a pair of
-consecutive RTL insns, possibly separated by @code{note} insns, one to
-set the condition code and one to test it, and keeps the pair inviolate
-until the end.
-
-To go with this technique, you must define the machine-description macro
-@code{NOTICE_UPDATE_CC} to do @code{CC_STATUS_INIT}; in other words, no
-compare instruction is superfluous.
-
-Some machines have compare-and-branch instructions and no condition code.
-A similar technique works for them.  When it is time to ``output'' a
-compare instruction, record its operands in two static variables.  When
-outputting the branch-on-condition-code instruction that follows, actually
-output a compare-and-branch instruction that uses the remembered operands.
-
-It also works to define patterns for compare-and-branch instructions.
-In optimizing compilation, the pair of compare and branch instructions
-will be combined according to these patterns.  But this does not happen
-if optimization is not requested.  So you must use one of the solutions
-above in addition to any special patterns you define.
+GCC does not assume anything about how the machine realizes jumps.
+The machine description should define a single pattern, usually
+a @code{define_expand}, which expands to all the required insns.
+Usually, this would be a comparison insn to set the condition code
+and a separate branch insn testing the condition code and branching
+or not according its value.
+
+This scheme works well, independent of whether the comparison instruction
+records the results of both signed and unsigned comparison of the given
+operands (with the branch insns coming in distinct signed and unsigned
+flavors) as in the x86 or SPARC, or rather there are distinct signed
+and unsigned compare instructions and only one set of conditional branch
+instructions as in the PowerPC.  It also works for instructions that
+have compare-and-branch instructions and no condition code.
 
 In many RISC machines, most instructions do not affect the condition
 code and there may not even be a separate condition code register.  On
@@ -5610,13 +5561,9 @@ the operations as far as possible.  For 
 @cindex @code{compare}, canonicalization of
 @item
 For the @code{compare} operator, a constant is always the second operand
-on machines where @code{cc0} is used (@pxref{Jump Patterns}).  On other
-machines, there are rare cases where the compiler might want to construct
-a @code{compare} with a constant as the first operand.  However, these
-cases are not common enough for it to be worthwhile to provide a pattern
-matching a constant as the first operand unless the machine actually has
-such an instruction.
+if the first argument is a condition code register or @code{(cc0)}.
 
+@item
 An operand of @code{neg}, @code{not}, @code{mult}, @code{plus}, or
 @code{minus} is made the first operand under the same conditions as
 above.
Index: gcc/genopinit.c
===================================================================
--- gcc/genopinit.c	(branch cond-optab)
+++ gcc/genopinit.c	(working copy)
@@ -198,15 +198,12 @@ static const char * const optabs[] =
   "optab_handler (movstrict_optab, $A)->insn_code = CODE_FOR_$(movstrict$a$)",
   "optab_handler (movmisalign_optab, $A)->insn_code = CODE_FOR_$(movmisalign$a$)",
   "optab_handler (storent_optab, $A)->insn_code = CODE_FOR_$(storent$a$)",
-  "optab_handler (cmp_optab, $A)->insn_code = CODE_FOR_$(cmp$a$)",
-  "optab_handler (tst_optab, $A)->insn_code = CODE_FOR_$(tst$a$)",
   "optab_handler (addcc_optab, $A)->insn_code = CODE_FOR_$(add$acc$)",
-  "bcc_gen_fctn[$C] = gen_$(b$c$)",
-  "setcc_gen_code[$C] = CODE_FOR_$(s$c$)",
   "movcc_gen_code[$A] = CODE_FOR_$(mov$acc$)",
   "optab_handler (cbranch_optab, $A)->insn_code = CODE_FOR_$(cbranch$a4$)",
   "optab_handler (cmov_optab, $A)->insn_code = CODE_FOR_$(cmov$a6$)",
   "optab_handler (cstore_optab, $A)->insn_code = CODE_FOR_$(cstore$a4$)",
+  "optab_handler (ctrap_optab, $A)->insn_code = CODE_FOR_$(ctrap$a4$)",
   "optab_handler (push_optab, $A)->insn_code = CODE_FOR_$(push$a1$)",
   "reload_in_optab[$A] = CODE_FOR_$(reload_in$a$)",
   "reload_out_optab[$A] = CODE_FOR_$(reload_out$a$)",
Index: gcc/optabs.h
===================================================================
--- gcc/optabs.h	(branch cond-optab)
+++ gcc/optabs.h	(working copy)
@@ -36,8 +36,7 @@ along with GCC; see the file COPYING3.  
    The `lib_call' slot is the name of the library function that
    can be used to perform the operation.
 
-   A few optabs, such as move_optab and cmp_optab, are used
-   by special code.  */
+   A few optabs, such as move_optab, are used by special code.  */
 
 struct optab_handlers
 {
@@ -271,12 +270,9 @@ enum optab_index
   /* Test for infinite value */
   OTI_isinf,
 
-  /* Compare insn; two operands.  */
+  /* Compare insn; two operands.  Used only for libcalls.  */
   OTI_cmp,
-  /* Used only for libcalls for unsigned comparisons.  */
   OTI_ucmp,
-  /* tst insn; compare one operand against 0 */
-  OTI_tst,
 
   /* Floating point comparison optabs - used primarily for libfuncs */
   OTI_eq,
@@ -290,10 +286,11 @@ enum optab_index
   /* String length */
   OTI_strlen,
 
-  /* Combined compare & jump/store flags/move operations.  */
+  /* Combined compare & jump/move/store flags/trap operations.  */
   OTI_cbranch,
   OTI_cmov,
   OTI_cstore,
+  OTI_ctrap,
 
   /* Push instruction.  */
   OTI_push,
@@ -484,7 +481,6 @@ extern struct optab optab_table[OTI_MAX]
 
 #define cmp_optab (&optab_table[OTI_cmp])
 #define ucmp_optab (&optab_table[OTI_ucmp])
-#define tst_optab (&optab_table[OTI_tst])
 
 #define eq_optab (&optab_table[OTI_eq])
 #define ne_optab (&optab_table[OTI_ne])
@@ -499,6 +495,8 @@ extern struct optab optab_table[OTI_MAX]
 #define cbranch_optab (&optab_table[OTI_cbranch])
 #define cmov_optab (&optab_table[OTI_cmov])
 #define cstore_optab (&optab_table[OTI_cstore])
+#define ctrap_optab (&optab_table[OTI_ctrap])
+
 #define push_optab (&optab_table[OTI_push])
 #define addcc_optab (&optab_table[OTI_addcc])
 
@@ -605,17 +603,6 @@ extern optab code_to_optab[NUM_RTX_CODE 
 
 typedef rtx (*rtxfun) (rtx);
 
-/* Indexed by the rtx-code for a conditional (e.g. EQ, LT,...)
-   gives the gen_function to make a branch to test that condition.  */
-
-extern rtxfun bcc_gen_fctn[NUM_RTX_CODE];
-
-/* Indexed by the rtx-code for a conditional (e.g. EQ, LT,...)
-   gives the insn code to make a store-condition insn
-   to test that condition.  */
-
-extern enum insn_code setcc_gen_code[NUM_RTX_CODE];
-
 #ifdef HAVE_conditional_move
 /* Indexed by the machine mode, gives the insn code to make a conditional
    move insn.  */
@@ -723,10 +710,6 @@ extern rtx expand_copysign (rtx, rtx, rt
 extern void emit_unop_insn (int, rtx, rtx, enum rtx_code);
 extern bool maybe_emit_unop_insn (int, rtx, rtx, enum rtx_code);
 
-/* Emit one rtl insn to compare two rtx's.  */
-extern void emit_cmp_insn (rtx, rtx, enum rtx_code, rtx, enum machine_mode,
-			   int);
-
 /* An extra flag to control optab_for_tree_code's behavior.  This is needed to
    distinguish between machines with a vector shift that takes a scalar for the
    shift amount vs. machines that take a vector for the shift amount.  */
Index: gcc/dojump.c
===================================================================
--- gcc/dojump.c	(branch cond-optab)
+++ gcc/dojump.c	(working copy)
@@ -755,64 +755,6 @@ do_jump_by_parts_equality (tree exp, rtx
 				 if_true_label);
 }
 
-/* Generate code for a comparison of OP0 and OP1 with rtx code CODE.
-   MODE is the machine mode of the comparison, not of the result.
-   (including code to compute the values to be compared) and set CC0
-   according to the result.  The decision as to signed or unsigned
-   comparison must be made by the caller.
-
-   We force a stack adjustment unless there are currently
-   things pushed on the stack that aren't yet used.
-
-   If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
-   compared.  */
-
-rtx
-compare_from_rtx (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
-		  enum machine_mode mode, rtx size)
-{
-  rtx tem;
-
-  /* If one operand is constant, make it the second one.  Only do this
-     if the other operand is not constant as well.  */
-
-  if (swap_commutative_operands_p (op0, op1))
-    {
-      tem = op0;
-      op0 = op1;
-      op1 = tem;
-      code = swap_condition (code);
-    }
-
-  do_pending_stack_adjust ();
-
-  code = unsignedp ? unsigned_condition (code) : code;
-  tem = simplify_relational_operation (code, VOIDmode, mode, op0, op1);
-  if (tem)
-    {
-      if (CONSTANT_P (tem))
-	return tem;
-
-      if (COMPARISON_P (tem))
-	{
-	  code = GET_CODE (tem);
-	  op0 = XEXP (tem, 0);
-	  op1 = XEXP (tem, 1);
-	  mode = GET_MODE (op0);
-	  unsignedp = (code == GTU || code == LTU
-		       || code == GEU || code == LEU);
-	}
-    }
-
-  emit_cmp_insn (op0, op1, code, size, mode, unsignedp);
-
-#if HAVE_cc0
-  return gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
-#else
-  return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
-#endif
-}
-
 /* Like do_compare_and_jump but expects the values to compare as two rtx's.
    The decision as to signed or unsigned comparison must be made by the caller.
 
Index: gcc/expmed.c
===================================================================
--- gcc/expmed.c	(branch cond-optab)
+++ gcc/expmed.c	(working copy)
@@ -5280,82 +5280,11 @@ emit_store_flag (rtx target, enum rtx_co
       return op0;
     }
 
-  icode = setcc_gen_code[(int) code];
-
-  if (icode != CODE_FOR_nothing)
+  for (compare_mode = mode; compare_mode != VOIDmode;
+       compare_mode = GET_MODE_WIDER_MODE (compare_mode))
     {
-      insn_operand_predicate_fn pred;
-
-      /* We think we may be able to do this with a scc insn.  Emit the
-	 comparison and then the scc insn.  */
-
-      do_pending_stack_adjust ();
-      last = get_last_insn ();
-
-      comparison
-	= compare_from_rtx (op0, op1, code, unsignedp, mode, NULL_RTX);
-      if (CONSTANT_P (comparison))
-	{
-	  switch (GET_CODE (comparison))
-	    {
-	    case CONST_INT:
-	      if (comparison == const0_rtx)
-		return const0_rtx;
-	      break;
-	      
-#ifdef FLOAT_STORE_FLAG_VALUE
-	    case CONST_DOUBLE:
-	      if (comparison == CONST0_RTX (GET_MODE (comparison)))
-		return const0_rtx;
-	      break;
-#endif
-	    default:
-	      gcc_unreachable ();
-	    }
-	  
-	  if (normalizep == 1)
-	    return const1_rtx;
-	  if (normalizep == -1)
-	    return constm1_rtx;
-	  return const_true_rtx;
-	}
-
-      /* The code of COMPARISON may not match CODE if compare_from_rtx
-	 decided to swap its operands and reverse the original code.
-
-	 We know that compare_from_rtx returns either a CONST_INT or
-	 a new comparison code, so it is safe to just extract the
-	 code from COMPARISON.  */
-      code = GET_CODE (comparison);
-
-      /* Get a reference to the target in the proper mode for this insn.  */
-      compare_mode = insn_data[(int) icode].operand[0].mode;
-      subtarget = target;
-      pred = insn_data[(int) icode].operand[0].predicate;
-      if (optimize || ! (*pred) (subtarget, compare_mode))
-	subtarget = gen_reg_rtx (compare_mode);
-
-      pattern = GEN_FCN (icode) (subtarget);
-      if (pattern)
-	{
-	  emit_insn (pattern);
-	  return emit_store_flag_1 (target, subtarget, compare_mode,
-				    normalizep);
-	}
-    }
-  else
-    {
-      /* We don't have an scc insn, so try a cstore insn.  */
-
-      for (compare_mode = mode; compare_mode != VOIDmode;
-	   compare_mode = GET_MODE_WIDER_MODE (compare_mode))
-	{
-	  icode = optab_handler (cstore_optab, compare_mode)->insn_code;
-	  if (icode != CODE_FOR_nothing)
-	    break;
-	}
-
-      if (icode != CODE_FOR_nothing)
+     icode = optab_handler (cstore_optab, compare_mode)->insn_code;
+     if (icode != CODE_FOR_nothing)
 	{
 	  enum machine_mode result_mode
 	    = insn_data[(int) icode].operand[0].mode;
Index: gcc/expr.h
===================================================================
--- gcc/expr.h	(branch cond-optab)
+++ gcc/expr.h	(working copy)
@@ -573,9 +573,6 @@ extern void jumpif (tree, rtx);
    the result is zero, or IF_TRUE_LABEL if the result is one.  */
 extern void do_jump (tree, rtx, rtx);
 
-/* Generate rtl to compare two rtx's, will call emit_cmp_insn.  */
-extern rtx compare_from_rtx (rtx, rtx, enum rtx_code, int, enum machine_mode,
-			     rtx);
 extern void do_compare_rtx_and_jump (rtx, rtx, enum rtx_code, int,
 				     enum machine_mode, rtx, rtx, rtx);
 

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