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] Documentation improvements and optabs.c fixlet


The fix in optabs.c is to look at the cbranch/cstore's predicates in
can_compare_p just like it's done for bcc and setcc.  This is needed by
dojump.c.

The documentation improvements are to not talk too much of cc0 (and
despise it at the same time...).

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

	* gcc/optabs.c (can_compare_p): Test the predicate of a
	cbranch and cstore pattern.

	* doc/md.texi (Jump Patterns): Refer to MODE_CC jump
	patterns preferably, avoiding references to cc0.

Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c	(branch cond-optab)
+++ gcc/optabs.c	(working copy)
@@ -3980,28 +3964,35 @@ int
 can_compare_p (enum rtx_code code, enum machine_mode mode,
 	       enum can_compare_purpose purpose)
 {
+  rtx test;
+  test = gen_rtx_fmt_ee (code, mode, const0_rtx, const0_rtx);
   do
     {
+      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
-	  && optab_handler (cbranch_optab, mode)->insn_code != CODE_FOR_nothing)
-	return 1;
-      if (purpose == ccp_cmov
-	  && optab_handler (cmov_optab, mode)->insn_code != CODE_FOR_nothing)
-	return 1;
+          && (icode = optab_handler (cbranch_optab, mode)->insn_code) != CODE_FOR_nothing
+          && insn_data[icode].operand[0].predicate (test, mode))
+        return 1;
       if (purpose == ccp_store_flag
-	  && optab_handler (cstore_optab, mode)->insn_code != CODE_FOR_nothing)
-	return 1;
+          && (icode = optab_handler (cstore_optab, mode)->insn_code) != CODE_FOR_nothing
+          && insn_data[icode].operand[0].predicate (test, mode))
+        return 1;
+      if (purpose == ccp_cmov
+          && optab_handler (cmov_optab, mode)->insn_code != CODE_FOR_nothing)
+        return 1;
       mode = GET_MODE_WIDER_MODE (mode);
+      PUT_MODE (test, mode);
     }
   while (mode != VOIDmode);
 
Index: gcc/doc/md.texi
===================================================================
--- gcc/doc/md.texi	(branch cond-optab)
+++ gcc/doc/md.texi	(working copy)
@@ -5401,36 +5352,27 @@ instructions earlier than the conditiona
 scheduler cannot perform this optimization if it is not permitted to
 separate the definition and use of the condition code register.
 
-On these machines, do not use @code{(cc0)}, but instead use a register
+The old way to represent a condition code register using the special
+RTL expression @code{(cc0)} did not extend well to newer processors.
+For this reason, it is possible and suggested to use a register
 to represent the condition code.  If there is a specific condition code
 register in the machine, use a hard register.  If the condition code or
 comparison result can be placed in any general register, or if there are
 multiple condition registers, use a pseudo register.
 
-@findex prev_cc0_setter
-@findex next_cc0_user
-On some machines, the type of branch instruction generated may depend on
-the way the condition code was produced; for example, on the 68k and
-SPARC, setting the condition code directly from an add or subtract
-instruction does not clear the overflow bit the way that a test
-instruction does, so a different branch instruction must be used for
-some conditional branches.  For machines that use @code{(cc0)}, the set
-and use of the condition code must be adjacent (separated only by
-@code{note} insns) allowing flags in @code{cc_status} to be used.
-(@xref{Condition Code}.)  Also, the comparison and branch insns can be
-located from each other by using the functions @code{prev_cc0_setter}
-and @code{next_cc0_user}.
-
-However, this is not true on machines that do not use @code{(cc0)}.  On
-those machines, no assumptions can be made about the adjacency of the
-compare and branch insns and the above methods cannot be used.  Instead,
-we use the machine mode of the condition code register to record
-different formats of the condition code register.
+On many machines, the condition code may be produced by other instructions
+than compares, for example the branch can use directly the condition
+code set by a subtract instruction.  However, on some machines
+when the condition code is set this way some bits (such as the overflow
+bit) are not set in the same way as a test instruction, so that a different
+branch instruction must be used for some conditional branches.  When
+this happens, use the machine mode of the condition code register to
+record different formats of the condition code register.
 
 Registers used to store the condition code value should have a mode that
 is in class @code{MODE_CC}.  Normally, it will be @code{CCmode}.  If
-additional modes are required (as for the add example mentioned above in
-the SPARC), define them in @file{@var{machine}-modes.def}
+additional modes are required (as for the add example mentioned above,
+which happens on the SPARC), define them in @file{@var{machine}-modes.def}
 (@pxref{Condition Code}).  Also define @code{SELECT_CC_MODE} to choose
 a mode given an operand of a compare.
 

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