public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: [PATCH] add insn implementing signbit to middle end and s390
@ 2007-04-03 13:35 Gellerich
  2007-04-03 13:50 ` Richard Guenther
  2007-04-03 14:02 ` Paolo Bonzini
  0 siblings, 2 replies; 21+ messages in thread
From: Gellerich @ 2007-04-03 13:35 UTC (permalink / raw)
  To: gcc-patches, gellerich

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 14525 bytes --]


Here is the reworked version.

Concerning documentation: I would provide a description for the
"Standard Pattern Names..." section in a separate patch. However, I
saw that a quite similar pattern named isinf is not mentioned
there. Is this pattern intentionally omitted, or should I add a
description for that one, too?

Regards, Wolfgang

---
Dr. Wolfgang Gellerich
IBM Deutschland Entwicklung GmbH
Schönaicher Strasse 220
71032 Böblingen, Germany
Tel. +49 / 7031 / 162598
gellerich@de.ibm.com

=======================

IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Johann Weihen 
Geschäftsführung: Herbert Kircher 
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294






----------------------------------------------------------------------------------

Changelog:

2007-04-02  Wolfgang Gellerich  <gellerich@de.ibm.com>

	* optabs.h: Added declaration for signbit_optab.  
	* optabs.c: (init_optabs): Added initialization for signbit_optab.
	* genoptinit.c (optabs): Added entry for signbit insns.  
	* builtins.c (expand_builtin_signbit): Added code to use a signbit insn,
	  if available.  
	* config/s390/s390.h (S390_TDC_POSITIVE_ZERO):New constant.  
	  (S390_TDC_NEGATIVE_ZERO): New constant.
	  (S390_TDC_POSITIVE_NORMALIZED_NUMBER): New constant.
	  (S390_TDC_NEGATIVE_NORMALIZED_NUMBER): New constant.
	  (S390_TDC_POSITIVE_DENORMALIZED_NUMBER): New constant.
	  (S390_TDC_NEGATIVE_DENORMALIZED_NUMBER): New constant.
	  (S390_TDC_POSITIVE_INFINITY): New constant.
	  (S390_TDC_NEGATIVE_INFINITY): New constant.
	  (S390_TDC_POSITIVE_QUIET_NAN): New constant.
	  (S390_TDC_NEGATIVE_QUIET_NAN): New constant.
	  (S390_TDC_POSITIVE_SIGNALING_NAN): New constant.
	  (S390_TDC_NEGATIVE_SIGNALING_NAN): New constant.
	  (S390_TDC_SIGNBIT_SET): New constant.  
	* config/s390/s390.c (s390_canonicalize_comparison): Renamed
	  UNSPEC_CMPINT to UNSPEC_CCU_TO_INT, added a CCU-like
	  optimization for UNSPEC_CCZ_TO_INT.
	* config/s390/s390.md (signbit_<mode>): New expander.  
	  (TDC_insn_<mode>): New insn.  (*ccz_to_int): New insn.
	  (UNSPEC_CMPINT): Renamed to UNSPEC_CCU_TO_INT.
	  (UNSPEC_CCU_TO_INT): New constant, replaces UNSPEC_CMPINT.
	  (UNSPEC_CCZ_TO_INT): New constant.

----------------------------------------------------------------------------------




Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c	(Revision 123425)
+++ gcc/optabs.c	(Arbeitskopie)
@@ -5584,6 +5584,7 @@
   for (i = 0; i < NUM_MACHINE_MODES; i++)
     {
       movmem_optab[i] = CODE_FOR_nothing;
+      signbit_optab[i] = CODE_FOR_nothing;
       cmpstr_optab[i] = CODE_FOR_nothing;
       cmpstrn_optab[i] = CODE_FOR_nothing;
       cmpmem_optab[i] = CODE_FOR_nothing;
Index: gcc/optabs.h
===================================================================
--- gcc/optabs.h	(Revision 123425)
+++ gcc/optabs.h	(Arbeitskopie)
@@ -513,6 +513,9 @@
 /* This array records the insn_code of insns to perform block moves.  */
 extern enum insn_code movmem_optab[NUM_MACHINE_MODES];
 
+/* This array records the insn_code of insns to implement the signbit function.  */
+extern enum insn_code signbit_optab[NUM_MACHINE_MODES];
+
 /* This array records the insn_code of insns to perform block sets.  */
 extern enum insn_code setmem_optab[NUM_MACHINE_MODES];
 
Index: gcc/genopinit.c
===================================================================
--- gcc/genopinit.c	(Revision 123425)
+++ gcc/genopinit.c	(Arbeitskopie)
@@ -172,6 +172,7 @@
   "push_optab->handlers[$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$)",
+  "signbit_optab[$A] = CODE_FOR_$(signbit_$F$a$)",
   "movmem_optab[$A] = CODE_FOR_$(movmem$a$)",
   "cmpstr_optab[$A] = CODE_FOR_$(cmpstr$a$)",
   "cmpstrn_optab[$A] = CODE_FOR_$(cmpstrn$a$)",
Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c	(Revision 123425)
+++ gcc/builtins.c	(Arbeitskopie)
@@ -230,6 +230,11 @@
 			  int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
 static tree do_mpfr_sincos (tree, tree, tree);
 
+/* This array records the insn_code of insns to imlement the signbit
+   function. */
+enum insn_code signbit_optab[NUM_MACHINE_MODES];
+
+
 /* Return true if NODE should be considered for inline expansion regardless
    of the optimization level.  This means whenever a function is invoked with
    its "internal" name, which normally contains the prefix "__builtin".  */
@@ -5553,11 +5558,15 @@
   return tramp;
 }
 
-/* Expand a call to the built-in signbit, signbitf or signbitl function.
-   Return NULL_RTX if a normal call should be emitted rather than expanding
-   the function in-line.  EXP is the expression that is a call to the builtin
-   function; if convenient, the result should be placed in TARGET.  */
 
+/* Expand a call to the built-in signbit, signbitf or signbitl function.  The
+   function first checks whether the back end provides an insn to implement
+   signbit for the respective mode. If not, it checks whether the floating
+   point format of the value is such that the sign bit can be extracted. If
+   that is not the case, the function returns NULL_RTX to indicate that a
+   normal call should be emitted rather than expanding the function in-line.
+   EXP is the expression that is a call to the builtin function; if
+   convenient, the result should be placed in TARGET.  */
 static rtx
 expand_builtin_signbit (tree exp, rtx target)
 {
@@ -5566,6 +5575,7 @@
   HOST_WIDE_INT hi, lo;
   tree arg;
   int word, bitpos;
+  enum insn_code signbit_insn_code;
   rtx temp;
 
   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
@@ -5576,6 +5586,28 @@
   rmode = TYPE_MODE (TREE_TYPE (exp));
   fmt = REAL_MODE_FORMAT (fmode);
 
+  /* Expand the argument yielding a RTX expression. */
+  temp = expand_normal (arg);
+
+  /* Check if the back end provides an insn that handles signbit for the
+     argument's mode. */
+  signbit_insn_code = signbit_optab [(int) fmode];
+  if (signbit_insn_code != CODE_FOR_nothing)
+    {
+      rtx result = gen_reg_rtx (SImode);
+      rtx signbit_insn;
+
+      if (!insn_data[(int) signbit_insn_code].operand[1].predicate (temp, fmode))
+	temp = force_reg (fmode, temp);
+
+      signbit_insn = GEN_FCN (signbit_insn_code) (temp, result);
+      if (signbit_insn == NULL_RTX)
+        gcc_unreachable ();
+      emit_insn (signbit_insn);
+
+      return result;
+    }
+
   /* For floating point formats without a sign bit, implement signbit
      as "ARG < 0.0".  */
   bitpos = fmt->signbit_ro;
@@ -5590,7 +5622,6 @@
     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
   }
 
-  temp = expand_normal (arg);
   if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
     {
       imode = int_mode_for_mode (fmode);
@@ -5649,7 +5680,6 @@
       temp = expand_binop (rmode, and_optab, temp, const1_rtx,
 			   NULL_RTX, 1, OPTAB_LIB_WIDEN);
     }
-
   return temp;
 }
 
Index: gcc/config/s390/s390.c
===================================================================
--- gcc/config/s390/s390.c	(Revision 123426)
+++ gcc/config/s390/s390.c	(Arbeitskopie)
@@ -700,9 +700,9 @@
     }
 
 
-  /* Remove redundant UNSPEC_CMPINT conversions if possible.  */
+  /* Remove redundant UNSPEC_CCU_TO_INT conversions if possible.  */
   if (GET_CODE (*op0) == UNSPEC
-      && XINT (*op0, 1) == UNSPEC_CMPINT
+      && XINT (*op0, 1) == UNSPEC_CCU_TO_INT
       && XVECLEN (*op0, 0) == 1
       && GET_MODE (XVECEXP (*op0, 0, 0)) == CCUmode
       && GET_CODE (XVECEXP (*op0, 0, 0)) == REG
@@ -728,6 +728,32 @@
 	}
     }
 
+
+  /* Remove redundant UNSPEC_CCZ_TO_INT conversions if possible.  */
+  if (GET_CODE (*op0) == UNSPEC
+      && XINT (*op0, 1) == UNSPEC_CCZ_TO_INT
+      && XVECLEN (*op0, 0) == 1
+      && GET_MODE (XVECEXP (*op0, 0, 0)) == CCZmode
+      && GET_CODE (XVECEXP (*op0, 0, 0)) == REG
+      && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM
+      && *op1 == const0_rtx)
+    {
+      enum rtx_code new_code = UNKNOWN;
+      switch (*code)
+	{
+	  case EQ: new_code = EQ;  break;
+	  case NE: new_code = NE;  break;
+	  default: break;
+	}
+
+      if (new_code != UNKNOWN)
+	{
+	  *op0 = XVECEXP (*op0, 0, 0);
+	  *code = new_code;
+	}
+    }
+
+
   /* Simplify cascaded EQ, NE with const0_rtx.  */
   if ((*code == NE || *code == EQ)
       && (GET_CODE (*op0) == EQ || GET_CODE (*op0) == NE)
@@ -753,6 +779,8 @@
     }
 }
 
+
+
 /* Emit a compare instruction suitable to implement the comparison
    OP0 CODE OP1.  Return the correct condition RTL to be placed in
    the IF_THEN_ELSE of the conditional branch testing the result.  */
Index: gcc/config/s390/s390.h
===================================================================
--- gcc/config/s390/s390.h	(Revision 123426)
+++ gcc/config/s390/s390.h	(Arbeitskopie)
@@ -146,7 +146,27 @@
 /* Frame pointer is not used for debugging.  */
 #define CAN_DEBUG_WITHOUT_FP
 
+/* Constants needed to control the TEST DATA CLASS (TDC) instruction. */
+#define S390_TDC_POSITIVE_ZERO                (1 << 11)
+#define S390_TDC_NEGATIVE_ZERO                (1 << 10)
+#define S390_TDC_POSITIVE_NORMALIZED_NUMBER   (1 << 9)
+#define S390_TDC_NEGATIVE_NORMALIZED_NUMBER   (1 << 8)
+#define S390_TDC_POSITIVE_DENORMALIZED_NUMBER (1 << 7)
+#define S390_TDC_NEGATIVE_DENORMALIZED_NUMBER (1 << 6)
+#define S390_TDC_POSITIVE_INFINITY            (1 << 5)
+#define S390_TDC_NEGATIVE_INFINITY            (1 << 4)
+#define S390_TDC_POSITIVE_QUIET_NAN           (1 << 3)
+#define S390_TDC_NEGATIVE_QUIET_NAN           (1 << 2)
+#define S390_TDC_POSITIVE_SIGNALING_NAN       (1 << 1)
+#define S390_TDC_NEGATIVE_SIGNALING_NAN       (1 << 0)
 
+#define S390_TDC_SIGNBIT_SET (S390_TDC_NEGATIVE_ZERO \
+                          | S390_TDC_NEGATIVE_NORMALIZED_NUMBER \
+                          | S390_TDC_NEGATIVE_DENORMALIZED_NUMBER\
+                          | S390_TDC_NEGATIVE_INFINITY \
+                          | S390_TDC_NEGATIVE_QUIET_NAN \
+			  | S390_TDC_NEGATIVE_SIGNALING_NAN )
+
 /* In libgcc2, determine target settings as compile-time constants.  */
 #ifdef IN_LIBGCC2
 #undef TARGET_64BIT
Index: gcc/config/s390/s390.md
===================================================================
--- gcc/config/s390/s390.md	(Revision 123426)
+++ gcc/config/s390/s390.md	(Arbeitskopie)
@@ -59,7 +59,8 @@
 (define_constants
   [; Miscellaneous
    (UNSPEC_ROUND		1)
-   (UNSPEC_CMPINT		2)
+   (UNSPEC_CCU_TO_INT		2)
+   (UNSPEC_CCZ_TO_INT		3)
    (UNSPEC_ICM			10)
 
    ; GOT/PLT and lt-relative accesses
@@ -97,11 +98,15 @@
    ; Stack Smashing Protector
    (UNSPEC_SP_SET 		700)
    (UNSPEC_SP_TEST		701)
-
+   
    ; Copy sign instructions
    (UNSPEC_COPYSIGN             800)
+
+   ; Test Data Class (TDC)
+   (UNSPEC_TDC_INSN		900)
  ])
 
+
 ;;
 ;; UNSPEC_VOLATILE usage
 ;;
@@ -2090,7 +2095,7 @@
      (use (reg:SI 0))])
    (parallel
     [(set (match_operand:SI 0 "register_operand" "=d")
-	  (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_CMPINT))
+	  (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_CCU_TO_INT))
      (clobber (reg:CC CC_REGNUM))])]
   ""
 {
@@ -2288,7 +2293,50 @@
   [(set_attr "length" "8")
    (set_attr "type" "vs")])
 
+
+
 ;
+; Test data class.
+;
+
+(define_expand "signbit_<mode>"
+  [(set (reg:CCZ CC_REGNUM)
+        (unspec:CCZ [(match_operand:BFP 0 "register_operand" "f") 
+                     (match_dup 2)] 
+                     UNSPEC_TDC_INSN))
+   (set (match_operand:SI 1 "register_operand" "=d")
+        (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CCZ_TO_INT))]
+  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+{
+  operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
+})
+
+
+; This insn is used to generate all variants of the Test Data Class
+; instruction.  The insn's first operand is the register to be tested
+; and the second one is the bit mask specifying the required test(s).
+;
+(define_insn "*TDC_insn_<mode>"
+  [(set (reg:CCZ CC_REGNUM)
+        (unspec:CCZ [(match_operand:BFP 0 "register_operand" "f") 
+                     (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))]
+  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+  "tc<xde>b\t%0,%1"
+   [(set_attr "op_type" "RXE")
+    (set_attr "type"  "fsimp<mode>")])
+
+
+(define_insn_and_split "*ccz_to_int"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (unspec:SI [(match_operand:CCZ 1 "register_operand" "0")]
+                   UNSPEC_CCZ_TO_INT))]
+  ""
+  "#"
+  "reload_completed"
+  [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))])
+
+
+;
 ; setmemM instruction pattern(s).
 ;
 
@@ -2564,7 +2612,7 @@
 (define_insn_and_split "cmpint"
   [(set (match_operand:SI 0 "register_operand" "=d")
         (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
-                   UNSPEC_CMPINT))
+                   UNSPEC_CCU_TO_INT))
    (clobber (reg:CC CC_REGNUM))]
   ""
   "#"
@@ -2577,10 +2625,10 @@
 (define_insn_and_split "*cmpint_cc"
   [(set (reg CC_REGNUM)
         (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
-                            UNSPEC_CMPINT)
+                            UNSPEC_CCU_TO_INT)
                  (const_int 0)))
    (set (match_operand:SI 0 "register_operand" "=d")
-        (unspec:SI [(match_dup 1)] UNSPEC_CMPINT))]
+        (unspec:SI [(match_dup 1)] UNSPEC_CCU_TO_INT))]
   "s390_match_ccmode (insn, CCSmode)"
   "#"
   "&& reload_completed"
@@ -2597,7 +2645,7 @@
 (define_insn_and_split "*cmpint_sign"
   [(set (match_operand:DI 0 "register_operand" "=d")
         (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
-                                   UNSPEC_CMPINT)))
+                                   UNSPEC_CCU_TO_INT)))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_64BIT"
   "#"
@@ -2611,11 +2659,11 @@
   [(set (reg CC_REGNUM)
         (compare (ashiftrt:DI (ashift:DI (subreg:DI 
                    (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
-                              UNSPEC_CMPINT) 0)
+                              UNSPEC_CCU_TO_INT) 0)
                    (const_int 32)) (const_int 32))
                  (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=d")
-        (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_CMPINT)))]
+        (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_CCU_TO_INT)))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_64BIT"
   "#"
   "&& reload_completed"


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] add insn implementing signbit to middle end and s390
  2007-04-03 13:35 [PATCH] add insn implementing signbit to middle end and s390 Gellerich
@ 2007-04-03 13:50 ` Richard Guenther
  2007-04-11  7:46   ` gellerich
                     ` (3 more replies)
  2007-04-03 14:02 ` Paolo Bonzini
  1 sibling, 4 replies; 21+ messages in thread
From: Richard Guenther @ 2007-04-03 13:50 UTC (permalink / raw)
  To: Gellerich; +Cc: gcc-patches, gellerich

On 4/3/07, Gellerich <gelleric@tuxmaker.boeblingen.de.ibm.com> wrote:
>
> Here is the reworked version.
>
> Concerning documentation: I would provide a description for the
> "Standard Pattern Names..." section in a separate patch. However, I
> saw that a quite similar pattern named isinf is not mentioned
> there. Is this pattern intentionally omitted, or should I add a
> description for that one, too?

Probably the nitpicking please-add-documentation was missing on its addition ;)
So, if you are at it it would be nice if you can add documentation for
that one, too.

Thanks,
Richard.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] add insn implementing signbit to middle end and s390
  2007-04-03 13:35 [PATCH] add insn implementing signbit to middle end and s390 Gellerich
  2007-04-03 13:50 ` Richard Guenther
@ 2007-04-03 14:02 ` Paolo Bonzini
  2007-04-11 10:17   ` gellerich
  1 sibling, 1 reply; 21+ messages in thread
From: Paolo Bonzini @ 2007-04-03 14:02 UTC (permalink / raw)
  To: gellerich; +Cc: gcc-patches

Gellerich wrote:
> Here is the reworked version.
> 
> Concerning documentation: I would provide a description for the
> "Standard Pattern Names..." section in a separate patch. However, I
> saw that a quite similar pattern named isinf is not mentioned
> there. Is this pattern intentionally omitted, or should I add a
> description for that one, too?

I think you should call it signbit<mode>2, put it into the
common optab_table instead of defining a separate optab,
and initialize it using init_optab (in other words, mimic
what is done for isinf_optab).

Sorry for noticing it only now.

Paolo

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] add insn implementing signbit to middle end and s390
  2007-04-03 13:50 ` Richard Guenther
  2007-04-11  7:46   ` gellerich
  2007-04-11  7:46   ` gellerich
@ 2007-04-11  7:46   ` gellerich
  2007-04-11  8:54   ` gellerich
  3 siblings, 0 replies; 21+ messages in thread
From: gellerich @ 2007-04-11  7:46 UTC (permalink / raw)
  To: richard.guenther, gelleric; +Cc: gcc-patches


%% Probably the nitpicking please-add-documentation was missing on its addition ;)
%% So, if you are at it it would be nice if you can add documentation for
%% that one, too.

ok.

Regards, Wolfgang


---
Dr. Wolfgang Gellerich
IBM Deutschland Entwicklung GmbH
Schönaicher Strasse 220
71032 Böblingen, Germany
Tel. +49 / 7031 / 162598
gellerich@de.ibm.com

=======================

IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Johann Weihen 
Geschäftsführung: Herbert Kircher 
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] add insn implementing signbit to middle end and s390
  2007-04-03 13:50 ` Richard Guenther
  2007-04-11  7:46   ` gellerich
@ 2007-04-11  7:46   ` gellerich
  2007-04-11  7:46   ` gellerich
  2007-04-11  8:54   ` gellerich
  3 siblings, 0 replies; 21+ messages in thread
From: gellerich @ 2007-04-11  7:46 UTC (permalink / raw)
  To: richard.guenther, gelleric; +Cc: gcc-patches


%% Probably the nitpicking please-add-documentation was missing on its addition ;)
%% So, if you are at it it would be nice if you can add documentation for
%% that one, too.

ok.

Regards, Wolfgang


---
Dr. Wolfgang Gellerich
IBM Deutschland Entwicklung GmbH
Schönaicher Strasse 220
71032 Böblingen, Germany
Tel. +49 / 7031 / 162598
gellerich@de.ibm.com

=======================

IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Johann Weihen 
Geschäftsführung: Herbert Kircher 
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] add insn implementing signbit to middle end and s390
  2007-04-03 13:50 ` Richard Guenther
@ 2007-04-11  7:46   ` gellerich
  2007-04-11  7:46   ` gellerich
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 21+ messages in thread
From: gellerich @ 2007-04-11  7:46 UTC (permalink / raw)
  To: richard.guenther, gelleric; +Cc: gcc-patches


%% Probably the nitpicking please-add-documentation was missing on its addition ;)
%% So, if you are at it it would be nice if you can add documentation for
%% that one, too.

ok.

Regards, Wolfgang


---
Dr. Wolfgang Gellerich
IBM Deutschland Entwicklung GmbH
Schönaicher Strasse 220
71032 Böblingen, Germany
Tel. +49 / 7031 / 162598
gellerich@de.ibm.com

=======================

IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Johann Weihen 
Geschäftsführung: Herbert Kircher 
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] add insn implementing signbit to middle end and s390
  2007-04-03 13:50 ` Richard Guenther
                     ` (2 preceding siblings ...)
  2007-04-11  7:46   ` gellerich
@ 2007-04-11  8:54   ` gellerich
  3 siblings, 0 replies; 21+ messages in thread
From: gellerich @ 2007-04-11  8:54 UTC (permalink / raw)
  To: richard.guenther, gelleric; +Cc: gcc-patches


%% Probably the nitpicking please-add-documentation was missing on its addition ;)
%% So, if you are at it it would be nice if you can add documentation for
%% that one, too.

ok.

Regards, Wolfgang


---
Dr. Wolfgang Gellerich
IBM Deutschland Entwicklung GmbH
Schönaicher Strasse 220
71032 Böblingen, Germany
Tel. +49 / 7031 / 162598
gellerich@de.ibm.com

=======================

IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Johann Weihen 
Geschäftsführung: Herbert Kircher 
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] add insn implementing signbit to middle end and s390
  2007-04-03 14:02 ` Paolo Bonzini
@ 2007-04-11 10:17   ` gellerich
  0 siblings, 0 replies; 21+ messages in thread
From: gellerich @ 2007-04-11 10:17 UTC (permalink / raw)
  To: bonzini; +Cc: gcc-patches


%% I think you should call it signbit<mode>2, put it into the
%% common optab_table instead of defining a separate optab,
%% and initialize it using init_optab (in other words, mimic
%% what is done for isinf_optab).

Paolo, its no problem to make this change. But, now I am curious to learn what
the rule is whether to put a new pattern into optab_table or defining a
separate variable (actually, the current signbit implementation follows that
of cmpmem.)

Regards, Wolfgang


---
Dr. Wolfgang Gellerich
IBM Deutschland Entwicklung GmbH
Schönaicher Strasse 220
71032 Böblingen, Germany
Tel. +49 / 7031 / 162598
gellerich@de.ibm.com

=======================

IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Johann Weihen 
Geschäftsführung: Herbert Kircher 
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] add insn implementing signbit to middle end and s390
  2007-07-06 15:37         ` Wolfgang Gellerich
@ 2007-07-06 16:22           ` Richard Guenther
  0 siblings, 0 replies; 21+ messages in thread
From: Richard Guenther @ 2007-07-06 16:22 UTC (permalink / raw)
  To: Wolfgang Gellerich; +Cc: rth, gcc-patches

On 7/6/07, Wolfgang Gellerich <gellerich@de.ibm.com> wrote:
>
> OK. Here is the versin with added call to builtin_save_expr for the
> argument. It bootstraps on Intel and on s390, and does not introduce new
> unexpected failures in the regression tests.

This is ok.

Thanks,
Richard.

> Changelog:
>
> 2007-06-07  Wolfgang Gellerich  <gellerich@de.ibm.com>
>
>         * optabs.h: Added declaration for signbit_optab.
>         * optabs.c: (init_optabs): Added initialization for signbit_optab.
>         * genoptinit.c (optabs): Added entry for signbit insns.
>         * builtins.c (expand_builtin_signbit): Added code to use a signbit insn,
>         if available.
>         * config/s390/s390.h (S390_TDC_SIGNBIT_SET): New constant.
>         * config/s390/s390.md (signbit<mode>2): New expander.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] add insn implementing signbit to middle end and s390
  2007-06-11  9:25       ` Richard Guenther
  2007-07-06 15:02         ` Wolfgang Gellerich
@ 2007-07-06 15:37         ` Wolfgang Gellerich
  2007-07-06 16:22           ` Richard Guenther
  1 sibling, 1 reply; 21+ messages in thread
From: Wolfgang Gellerich @ 2007-07-06 15:37 UTC (permalink / raw)
  To: richard.guenther; +Cc: rth, gcc-patches


OK. Here is the versin with added call to builtin_save_expr for the
argument. It bootstraps on Intel and on s390, and does not introduce new
unexpected failures in the regression tests.

With best regards,

  Wolfgang Gellerich


---
Dr. Wolfgang Gellerich
IBM Deutschland Entwicklung GmbH
Schönaicher Strasse 220
71032 Böblingen, Germany
Tel. +49 / 7031 / 162598
gellerich@de.ibm.com

=======================

IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Johann Weihen 
Geschäftsführung: Herbert Kircher 
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

----------------------------------------------------------------------------------

Changelog:

2007-06-07  Wolfgang Gellerich  <gellerich@de.ibm.com>

	* optabs.h: Added declaration for signbit_optab.  
	* optabs.c: (init_optabs): Added initialization for signbit_optab.
	* genoptinit.c (optabs): Added entry for signbit insns.  
	* builtins.c (expand_builtin_signbit): Added code to use a signbit insn,
	if available.  
	* config/s390/s390.h (S390_TDC_SIGNBIT_SET): New constant.  
	* config/s390/s390.md (signbit<mode>2): New expander.  

----------------------------------------------------------------------------------






Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c	(Revision 126365)
+++ gcc/optabs.c	(Arbeitskopie)
@@ -5628,6 +5628,7 @@
   for (i = 0; i < NUM_MACHINE_MODES; i++)
     {
       movmem_optab[i] = CODE_FOR_nothing;
+      signbit_optab[i] = CODE_FOR_nothing;
       cmpstr_optab[i] = CODE_FOR_nothing;
       cmpstrn_optab[i] = CODE_FOR_nothing;
       cmpmem_optab[i] = CODE_FOR_nothing;
Index: gcc/optabs.h
===================================================================
--- gcc/optabs.h	(Revision 126365)
+++ gcc/optabs.h	(Arbeitskopie)
@@ -553,6 +553,9 @@
 /* This array records the insn_code of insns to perform block moves.  */
 extern enum insn_code movmem_optab[NUM_MACHINE_MODES];
 
+/* This array records the insn_code of insns to implement the signbit function.  */
+extern enum insn_code signbit_optab[NUM_MACHINE_MODES];
+
 /* This array records the insn_code of insns to perform block sets.  */
 extern enum insn_code setmem_optab[NUM_MACHINE_MODES];
 
Index: gcc/genopinit.c
===================================================================
--- gcc/genopinit.c	(Revision 126365)
+++ gcc/genopinit.c	(Arbeitskopie)
@@ -177,6 +177,7 @@
   "push_optab->handlers[$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$)",
+  "signbit_optab[$A] = CODE_FOR_$(signbit$F$a2$)",
   "movmem_optab[$A] = CODE_FOR_$(movmem$a$)",
   "cmpstr_optab[$A] = CODE_FOR_$(cmpstr$a$)",
   "cmpstrn_optab[$A] = CODE_FOR_$(cmpstrn$a$)",
Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c	(Revision 126365)
+++ gcc/builtins.c	(Arbeitskopie)
@@ -240,6 +240,11 @@
 static tree do_mpfr_lgamma_r (tree, tree, tree);
 #endif
 
+/* This array records the insn_code of insns to imlement the signbit
+   function.  */
+enum insn_code signbit_optab[NUM_MACHINE_MODES];
+
+
 /* Return true if NODE should be considered for inline expansion regardless
    of the optimization level.  This means whenever a function is invoked with
    its "internal" name, which normally contains the prefix "__builtin".  */
@@ -5590,12 +5595,15 @@
   return tramp;
 }
 
-/* Expand a call to the built-in signbit, signbitf, signbitl, signbitd32,
-   signbitd64, or signbitd128 function.
-   Return NULL_RTX if a normal call should be emitted rather than expanding
-   the function in-line.  EXP is the expression that is a call to the builtin
-   function; if convenient, the result should be placed in TARGET.  */
-
+/* Expand the call EXP to the built-in signbit, signbitf or signbitl
+   function.  The function first checks whether the back end provides
+   an insn to implement signbit for the respective mode.  If not, it
+   checks whether the floating point format of the value is such that
+   the sign bit can be extracted.  If that is not the case, the
+   function returns NULL_RTX to indicate that a normal call should be
+   emitted rather than expanding the function in-line.  EXP is the
+   expression that is a call to the builtin function; if convenient,
+   the result should be placed in TARGET.  */
 static rtx
 expand_builtin_signbit (tree exp, rtx target)
 {
@@ -5604,6 +5612,7 @@
   HOST_WIDE_INT hi, lo;
   tree arg;
   int word, bitpos;
+  enum insn_code signbit_insn_code;
   rtx temp;
 
   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
@@ -5614,6 +5623,21 @@
   rmode = TYPE_MODE (TREE_TYPE (exp));
   fmt = REAL_MODE_FORMAT (fmode);
 
+  arg = builtin_save_expr (arg);
+
+  /* Expand the argument yielding a RTX expression. */
+  temp = expand_normal (arg);
+
+  /* Check if the back end provides an insn that handles signbit for the
+     argument's mode. */
+  signbit_insn_code = signbit_optab [(int) fmode];
+  if (signbit_insn_code != CODE_FOR_nothing)
+    {
+      target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
+      emit_unop_insn (signbit_insn_code, target, temp, UNKNOWN);
+      return target;
+    }
+
   /* For floating point formats without a sign bit, implement signbit
      as "ARG < 0.0".  */
   bitpos = fmt->signbit_ro;
@@ -5628,7 +5652,6 @@
     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
   }
 
-  temp = expand_normal (arg);
   if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
     {
       imode = int_mode_for_mode (fmode);
Index: gcc/config/s390/s390.h
===================================================================
--- gcc/config/s390/s390.h	(Revision 126365)
+++ gcc/config/s390/s390.h	(Arbeitskopie)
@@ -156,6 +156,13 @@
 #define S390_TDC_POSITIVE_SIGNALING_NAN       (1 << 1)
 #define S390_TDC_NEGATIVE_SIGNALING_NAN       (1 << 0)
 
+#define S390_TDC_SIGNBIT_SET (S390_TDC_NEGATIVE_ZERO \
+                          | S390_TDC_NEGATIVE_NORMALIZED_NUMBER \
+                          | S390_TDC_NEGATIVE_DENORMALIZED_NUMBER\
+                          | S390_TDC_NEGATIVE_INFINITY \
+                          | S390_TDC_NEGATIVE_QUIET_NAN \
+			  | S390_TDC_NEGATIVE_SIGNALING_NAN )
+
 #define S390_TDC_INFINITY (S390_TDC_POSITIVE_INFINITY \
 			  | S390_TDC_NEGATIVE_INFINITY )
 
Index: gcc/config/s390/s390.md
===================================================================
--- gcc/config/s390/s390.md	(Revision 126365)
+++ gcc/config/s390/s390.md	(Arbeitskopie)
@@ -2308,6 +2308,18 @@
 ; Test data class.
 ;
 
+(define_expand "signbit<mode>2"
+  [(set (reg:CCZ CC_REGNUM)
+        (unspec:CCZ [(match_operand:BFP 1 "register_operand" "f") 
+                     (match_dup 2)] 
+                     UNSPEC_TDC_INSN))
+   (set (match_operand:SI 0 "register_operand" "=d")
+        (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CCZ_TO_INT))]
+  "TARGET_HARD_FLOAT"
+{
+  operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
+})
+
 (define_expand "isinf<mode>2"
   [(set (reg:CCZ CC_REGNUM)
         (unspec:CCZ [(match_operand:BFP 1 "register_operand" "f") 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] add insn implementing signbit to middle end and s390
  2007-06-11  9:25       ` Richard Guenther
@ 2007-07-06 15:02         ` Wolfgang Gellerich
  2007-07-06 15:37         ` Wolfgang Gellerich
  1 sibling, 0 replies; 21+ messages in thread
From: Wolfgang Gellerich @ 2007-07-06 15:02 UTC (permalink / raw)
  To: richard.guenther; +Cc: rth, gcc-patches

rr signbit-Patch-V4.txt

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] add insn implementing signbit to middle end and s390
  2007-04-30 17:02     ` Wolfgang Gellerich
@ 2007-06-11  9:25       ` Richard Guenther
  2007-07-06 15:02         ` Wolfgang Gellerich
  2007-07-06 15:37         ` Wolfgang Gellerich
  0 siblings, 2 replies; 21+ messages in thread
From: Richard Guenther @ 2007-06-11  9:25 UTC (permalink / raw)
  To: Wolfgang Gellerich; +Cc: rth, gcc-patches

On 4/30/07, Wolfgang Gellerich <gellerich@de.ibm.com> wrote:
>
> ...reworked version.
>
> With best regards,
>

>
> 2007-04-27  Wolfgang Gellerich  <gellerich@de.ibm.com>
>
>         * optabs.h: Added declaration for signbit_optab.
>         * optabs.c: (init_optabs): Added initialization for signbit_optab.
>         * genoptinit.c (optabs): Added entry for signbit insns.
>         * builtins.c (expand_builtin_signbit): Added code to use a signbit insn,
>         if available.
>         * config/s390/s390.h (S390_TDC_SIGNBIT_SET): New constant.
>         * config/s390/s390.md (signbit<mode>2): New expander.
>
> ----------------------------------------------------------------------------------
>
>

> Index: builtins.c
> ===================================================================
> --- builtins.c  (Revision 124147)
> +++ builtins.c  (Arbeitskopie)
> @@ -230,6 +230,11 @@
>                           int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
>  static tree do_mpfr_sincos (tree, tree, tree);
>
> +/* This array records the insn_code of insns to imlement the signbit
> +   function.  */
> +enum insn_code signbit_optab[NUM_MACHINE_MODES];
> +
> +
>  /* Return true if NODE should be considered for inline expansion regardless
>     of the optimization level.  This means whenever a function is invoked with
>     its "internal" name, which normally contains the prefix "__builtin".  */
> @@ -5553,12 +5558,15 @@
>    return tramp;
>  }
>
> -/* Expand a call to the built-in signbit, signbitf, signbitl, signbitd32,
> -   signbitd64, or signbitd128 function.
> -   Return NULL_RTX if a normal call should be emitted rather than expanding
> -   the function in-line.  EXP is the expression that is a call to the builtin
> -   function; if convenient, the result should be placed in TARGET.  */
> -
> +/* Expand the call EXP to the built-in signbit, signbitf or signbitl
> +   function.  The function first checks whether the back end provides
> +   an insn to implement signbit for the respective mode.  If not, it
> +   checks whether the floating point format of the value is such that
> +   the sign bit can be extracted.  If that is not the case, the
> +   function returns NULL_RTX to indicate that a normal call should be
> +   emitted rather than expanding the function in-line.  EXP is the
> +   expression that is a call to the builtin function; if convenient,
> +   the result should be placed in TARGET.  */
>  static rtx
>  expand_builtin_signbit (tree exp, rtx target)
>  {
> @@ -5567,6 +5575,7 @@
>    HOST_WIDE_INT hi, lo;
>    tree arg;
>    int word, bitpos;
> +  enum insn_code signbit_insn_code;
>    rtx temp;
>
>    if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
> @@ -5577,6 +5586,19 @@
>    rmode = TYPE_MODE (TREE_TYPE (exp));
>    fmt = REAL_MODE_FORMAT (fmode);
>
> +  /* Expand the argument yielding a RTX expression. */
> +  temp = expand_normal (arg);

You need to guard this agains multiple expansions.  See other uses of
builtin_save_expr in builtins.c.

The middle-end parts are ok with this change.

Thanks,
Richard.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] add insn implementing signbit to middle end and s390
  2007-04-02  7:57   ` Wolfgang Gellerich
@ 2007-04-30 17:02     ` Wolfgang Gellerich
  2007-06-11  9:25       ` Richard Guenther
  0 siblings, 1 reply; 21+ messages in thread
From: Wolfgang Gellerich @ 2007-04-30 17:02 UTC (permalink / raw)
  To: rth; +Cc: gcc-patches


...reworked version.

With best regards,

  Wolfgang Gellerich


---
Dr. Wolfgang Gellerich
IBM Deutschland Entwicklung GmbH
Schönaicher Strasse 220
71032 Böblingen, Germany
Tel. +49 / 7031 / 162598
gellerich@de.ibm.com

=======================

IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Johann Weihen 
Geschäftsführung: Herbert Kircher 
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

----------------------------------------------------------------------------------

Changelog:

2007-04-27  Wolfgang Gellerich  <gellerich@de.ibm.com>

	* optabs.h: Added declaration for signbit_optab.  
	* optabs.c: (init_optabs): Added initialization for signbit_optab.
	* genoptinit.c (optabs): Added entry for signbit insns.  
	* builtins.c (expand_builtin_signbit): Added code to use a signbit insn,
	if available.  
	* config/s390/s390.h (S390_TDC_SIGNBIT_SET): New constant.  
	* config/s390/s390.md (signbit<mode>2): New expander.  

----------------------------------------------------------------------------------


Index: optabs.c
===================================================================
--- optabs.c	(Revision 124147)
+++ optabs.c	(Arbeitskopie)
@@ -5587,6 +5587,7 @@
   for (i = 0; i < NUM_MACHINE_MODES; i++)
     {
       movmem_optab[i] = CODE_FOR_nothing;
+      signbit_optab[i] = CODE_FOR_nothing;
       cmpstr_optab[i] = CODE_FOR_nothing;
       cmpstrn_optab[i] = CODE_FOR_nothing;
       cmpmem_optab[i] = CODE_FOR_nothing;
Index: optabs.h
===================================================================
--- optabs.h	(Revision 124147)
+++ optabs.h	(Arbeitskopie)
@@ -523,6 +523,9 @@
 /* This array records the insn_code of insns to perform block moves.  */
 extern enum insn_code movmem_optab[NUM_MACHINE_MODES];
 
+/* This array records the insn_code of insns to implement the signbit function.  */
+extern enum insn_code signbit_optab[NUM_MACHINE_MODES];
+
 /* This array records the insn_code of insns to perform block sets.  */
 extern enum insn_code setmem_optab[NUM_MACHINE_MODES];
 
Index: genopinit.c
===================================================================
--- genopinit.c	(Revision 124147)
+++ genopinit.c	(Arbeitskopie)
@@ -174,6 +174,7 @@
   "push_optab->handlers[$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$)",
+  "signbit_optab[$A] = CODE_FOR_$(signbit$F$a2$)",
   "movmem_optab[$A] = CODE_FOR_$(movmem$a$)",
   "cmpstr_optab[$A] = CODE_FOR_$(cmpstr$a$)",
   "cmpstrn_optab[$A] = CODE_FOR_$(cmpstrn$a$)",
Index: builtins.c
===================================================================
--- builtins.c	(Revision 124147)
+++ builtins.c	(Arbeitskopie)
@@ -230,6 +230,11 @@
 			  int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
 static tree do_mpfr_sincos (tree, tree, tree);
 
+/* This array records the insn_code of insns to imlement the signbit
+   function.  */
+enum insn_code signbit_optab[NUM_MACHINE_MODES];
+
+
 /* Return true if NODE should be considered for inline expansion regardless
    of the optimization level.  This means whenever a function is invoked with
    its "internal" name, which normally contains the prefix "__builtin".  */
@@ -5553,12 +5558,15 @@
   return tramp;
 }
 
-/* Expand a call to the built-in signbit, signbitf, signbitl, signbitd32,
-   signbitd64, or signbitd128 function.
-   Return NULL_RTX if a normal call should be emitted rather than expanding
-   the function in-line.  EXP is the expression that is a call to the builtin
-   function; if convenient, the result should be placed in TARGET.  */
-
+/* Expand the call EXP to the built-in signbit, signbitf or signbitl
+   function.  The function first checks whether the back end provides
+   an insn to implement signbit for the respective mode.  If not, it
+   checks whether the floating point format of the value is such that
+   the sign bit can be extracted.  If that is not the case, the
+   function returns NULL_RTX to indicate that a normal call should be
+   emitted rather than expanding the function in-line.  EXP is the
+   expression that is a call to the builtin function; if convenient,
+   the result should be placed in TARGET.  */
 static rtx
 expand_builtin_signbit (tree exp, rtx target)
 {
@@ -5567,6 +5575,7 @@
   HOST_WIDE_INT hi, lo;
   tree arg;
   int word, bitpos;
+  enum insn_code signbit_insn_code;
   rtx temp;
 
   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
@@ -5577,6 +5586,19 @@
   rmode = TYPE_MODE (TREE_TYPE (exp));
   fmt = REAL_MODE_FORMAT (fmode);
 
+  /* Expand the argument yielding a RTX expression. */
+  temp = expand_normal (arg);
+
+  /* Check if the back end provides an insn that handles signbit for the
+     argument's mode. */
+  signbit_insn_code = signbit_optab [(int) fmode];
+  if (signbit_insn_code != CODE_FOR_nothing)
+    {
+      target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
+      emit_unop_insn (signbit_insn_code, target, temp, UNKNOWN);
+      return target;
+    }
+
   /* For floating point formats without a sign bit, implement signbit
      as "ARG < 0.0".  */
   bitpos = fmt->signbit_ro;
@@ -5591,7 +5613,6 @@
     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
   }
 
-  temp = expand_normal (arg);
   if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
     {
       imode = int_mode_for_mode (fmode);
Index: config/s390/s390.h
===================================================================
--- config/s390/s390.h	(Revision 124147)
+++ config/s390/s390.h	(Arbeitskopie)
@@ -156,6 +156,13 @@
 #define S390_TDC_POSITIVE_SIGNALING_NAN       (1 << 1)
 #define S390_TDC_NEGATIVE_SIGNALING_NAN       (1 << 0)
 
+#define S390_TDC_SIGNBIT_SET (S390_TDC_NEGATIVE_ZERO \
+                          | S390_TDC_NEGATIVE_NORMALIZED_NUMBER \
+                          | S390_TDC_NEGATIVE_DENORMALIZED_NUMBER\
+                          | S390_TDC_NEGATIVE_INFINITY \
+                          | S390_TDC_NEGATIVE_QUIET_NAN \
+			  | S390_TDC_NEGATIVE_SIGNALING_NAN )
+
 #define S390_TDC_INFINITY (S390_TDC_POSITIVE_INFINITY \
 			  | S390_TDC_NEGATIVE_INFINITY )
 
Index: config/s390/s390.md
===================================================================
--- config/s390/s390.md	(Revision 124147)
+++ config/s390/s390.md	(Arbeitskopie)
@@ -2274,6 +2274,18 @@
 ; Test data class.
 ;
 
+(define_expand "signbit<mode>2"
+  [(set (reg:CCZ CC_REGNUM)
+        (unspec:CCZ [(match_operand:BFP 1 "register_operand" "f") 
+                     (match_dup 2)] 
+                     UNSPEC_TDC_INSN))
+   (set (match_operand:SI 0 "register_operand" "=d")
+        (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CCZ_TO_INT))]
+  "TARGET_HARD_FLOAT"
+{
+  operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
+})
+
 (define_expand "isinf<mode>2"
   [(set (reg:CCZ CC_REGNUM)
         (unspec:CCZ [(match_operand:BFP 1 "register_operand" "f") 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] add insn implementing signbit to middle end and s390
  2007-04-12  6:59   ` Uros Bizjak
@ 2007-04-30 15:05     ` Wolfgang Gellerich
  0 siblings, 0 replies; 21+ messages in thread
From: Wolfgang Gellerich @ 2007-04-30 15:05 UTC (permalink / raw)
  To: ubizjak; +Cc: gelleric, gcc-patches

%% > However, I am uncertain as far as putting parts of the implementation of
%% > expand_builtin_signbit() into expand_builtin_interclass_mathfn() given that
%% > expand_builtin() has already identified the signbit builtin as such. That test
%% > would have to be repeated. Since that the primary purpose of my patch is to
%% > introduce the signbit pattern I would prefer to keep it in
%% > expand_builtin_signbit() for now.  This does, of course, not prevent a later
%% > reorganization.

%% Perhaps I was too terse on my proposal. My thinking was, that from
%% expand_builtin() function, we should call
%% expand_builtin_interclass_mathfn() also for BUILT_IN_SIGNBIT case.
%% e_b_i_m() function will check, if there is an appropriate optab
%% present (please note the check for icode). In case this optab is not
%% present we call expand_builtin_signbit(), just before expand_call.
%% Something like this:

%% expand_builtin_interclass_mathfn()
%% {
%% ...
%%   switch (DECL_FUNCTION_CODE (fndecl))
%%     {
%%      ...
%%     CASE_FLT_FN (BUILT_IN_SIGNBIT):
%%       builtin_optab = signbit_optab; break;
%%      ...
%%     }

%%   if (icode != CODE_FOR_nothing)
%%     {
%%       ...
%%       return target;
%%     }

%%    switch (DECL_FUNCTION_CODE (fndecl))
%%     {
%%      ...
%%     CASE_FLT_FN (BUILT_IN_SIGNBIT):
%%       rtx target1 = expand_builtin_signbit (exp, target);
%%       if (target1)
%%         return target1;
%%      ...
%%     }

%%   target = expand_call (exp, target, target == const0_rtx);

%%   return target;
%% }

I understand what you mean.  However, given that expand_builtin_signbit does a
lot of optimizations special to signbit() only, and will in fact always do
something special and never issue a call to expand_call() as found at the end
of expand_builtin_interclass_mathfn, a combined function would probably
require a lot of code to distinguish between cases. Note also that the new
version of my patch will only add very few lines.


%% > By the way, there is a chance for a new optimization. The s390 instruction I
%% > am going to exploit with this and some future patches is able to test the
%% > contents of a float register for all those IEEE special values like infinity,
%% > different kinds of NaN etc. A bit mask controls what the instruction actually
%% > looks for. This means, one instruction with an appropriate bit mask is
%% > sufficient to implement an expression like
%% >
%% >   (isnan(x) || isinf(x))
%% >

%% IMO, you can simply expand the sequence of

%% read_status
%% and_status_with_constant
%% cond_set_value

%% for each optab.  Optimizers should resolve IOR of masked values to
%% just one AND, like in following case:
%% --cut here--
%% void check(void)
%% {
%%   int a = foo();
%%   int x,y;

%%   x = a & 2;
%%   y = a & 8;

%%   if (x || y)
%%     bar();
%% }
%% --cut here--

Would surely work, however, my idea is to introduce the combined test quite
early. I'll send a patch showing the details.

With best regards, 

  Wolfgang Gellerich


---
Dr. Wolfgang Gellerich
IBM Deutschland Entwicklung GmbH
Schönaicher Strasse 220
71032 Böblingen, Germany
Tel. +49 / 7031 / 162598
gellerich@de.ibm.com

=======================

IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Johann Weihen 
Geschäftsführung: Herbert Kircher 
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] add insn implementing signbit to middle end and s390
  2007-04-11 12:58 ` gellerich
@ 2007-04-12  6:59   ` Uros Bizjak
  2007-04-30 15:05     ` Wolfgang Gellerich
  0 siblings, 1 reply; 21+ messages in thread
From: Uros Bizjak @ 2007-04-12  6:59 UTC (permalink / raw)
  To: gellerich; +Cc: gcc-patches, gelleric

On 4/11/07, gellerich@de.ibm.com <gellerich@de.ibm.com> wrote:

> However, I am uncertain as far as putting parts of the implementation of
> expand_builtin_signbit() into expand_builtin_interclass_mathfn() given that
> expand_builtin() has already identified the signbit builtin as such. That test
> would have to be repeated. Since that the primary purpose of my patch is to
> introduce the signbit pattern I would prefer to keep it in
> expand_builtin_signbit() for now.  This does, of course, not prevent a later
> reorganization.

Perhaps I was too terse on my proposal. My thinking was, that from
expand_builtin() function, we should call
expand_builtin_interclass_mathfn() also for BUILT_IN_SIGNBIT case.
e_b_i_m() function will check, if there is an appropriate optab
present (please note the check for icode). In case this optab is not
present we call expand_builtin_signbit(), just before expand_call.
Something like this:

expand_builtin_interclass_mathfn()
{
...
  switch (DECL_FUNCTION_CODE (fndecl))
    {
     ...
    CASE_FLT_FN (BUILT_IN_SIGNBIT):
      builtin_optab = signbit_optab; break;
     ...
    }

  if (icode != CODE_FOR_nothing)
    {
      ...
      return target;
    }

   switch (DECL_FUNCTION_CODE (fndecl))
    {
     ...
    CASE_FLT_FN (BUILT_IN_SIGNBIT):
      rtx target1 = expand_builtin_signbit (exp, target);
      if (target1)
        return target1;
     ...
    }

  target = expand_call (exp, target, target == const0_rtx);

  return target;
}


> By the way, there is a chance for a new optimization. The s390 instruction I
> am going to exploit with this and some future patches is able to test the
> contents of a float register for all those IEEE special values like infinity,
> different kinds of NaN etc. A bit mask controls what the instruction actually
> looks for. This means, one instruction with an appropriate bit mask is
> sufficient to implement an expression like
>
>   (isnan(x) || isinf(x))
>

IMO, you can simply expand the sequence of

read_status
and_status_with_constant
cond_set_value

for each optab.  Optimizers should resolve IOR of masked values to
just one AND, like in following case:
--cut here--
void check(void)
{
  int a = foo();
  int x,y;

  x = a & 2;
  y = a & 8;

  if (x || y)
    bar();
}
--cut here--

> I know of at least one other processor (gcc target spu) that has a similar
> instruction, and probably there are more.  Isn't the i386 FXAM organized like
> this, too?

Unfortunatelly, fxam is not a simple bit check of status bits. It
returns a value that describes what is in %st(0). So we also rely on
the above optimization to CSE FXAM and various OR and AND sequences.

> Exploiting such instruction would, of course, suggest that all the
> respective builtin functions cases are handled together, plus some support in
> earlier phases.

All the infrastructure is already in place, just the expanders and
optabs are missing...

Uros.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] add insn implementing signbit to middle end and s390
  2007-04-03 14:18 Uros Bizjak
@ 2007-04-11 12:58 ` gellerich
  2007-04-12  6:59   ` Uros Bizjak
  0 siblings, 1 reply; 21+ messages in thread
From: gellerich @ 2007-04-11 12:58 UTC (permalink / raw)
  To: ubizjak, gcc-patches; +Cc: gelleric

%% Regadring your patch: It looks to me you are somehow reinventing
%% expand_builtin_interclass_mathfn() functionality. The patch for isinf
%% (please look at my ChangeLog entry from 2007-01-31) added
%% infrastructure that handles builtins with FP mode arguments and SImode
%% outputs using generic optab handling.

%% Perhaps you could enhance expand_builtin_interclass_mathfn() to
%% fallback to generic signbit handling (expand_builtin_signbit) in case
%% named pattern is not available?

%% BTW: You could implement isinf() just by adding appropriate named
%% pattern to s390.md. Please look at "isinf<mode>2" expander in
%% config/i386/i386.md

Hello Uros,

Many thanks for your detailed comments! Actually, I already defined isinf this
way and currently do some testing.

I agree that very similar things are usually best handled in the same
function. One of the next enhancements I plan is an implementation for isnan
and it will probably be a straight-forward extension of
expand_builtin_interclass_mathfn(), similar to isinf. 

However, I am uncertain as far as putting parts of the implementation of
expand_builtin_signbit() into expand_builtin_interclass_mathfn() given that
expand_builtin() has already identified the signbit builtin as such. That test
would have to be repeated. Since that the primary purpose of my patch is to
introduce the signbit pattern I would prefer to keep it in
expand_builtin_signbit() for now.  This does, of course, not prevent a later
reorganization. 

By the way, there is a chance for a new optimization. The s390 instruction I
am going to exploit with this and some future patches is able to test the
contents of a float register for all those IEEE special values like infinity,
different kinds of NaN etc. A bit mask controls what the instruction actually
looks for. This means, one instruction with an appropriate bit mask is
sufficient to implement an expression like

  (isnan(x) || isinf(x))
  
I know of at least one other processor (gcc target spu) that has a similar
instruction, and probably there are more.  Isn't the i386 FXAM organized like
this, too?  Exploiting such instruction would, of course, suggest that all the
respective builtin functions cases are handled together, plus some support in
earlier phases.

Best regards, Wolfgang


---
Dr. Wolfgang Gellerich
IBM Deutschland Entwicklung GmbH
Schönaicher Strasse 220
71032 Böblingen, Germany
Tel. +49 / 7031 / 162598
gellerich@de.ibm.com

=======================

IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Johann Weihen 
Geschäftsführung: Herbert Kircher 
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] add insn implementing signbit to middle end and s390
@ 2007-04-03 14:18 Uros Bizjak
  2007-04-11 12:58 ` gellerich
  0 siblings, 1 reply; 21+ messages in thread
From: Uros Bizjak @ 2007-04-03 14:18 UTC (permalink / raw)
  To: GCC Patches; +Cc: Gellerich

Hello!

> Here is the reworked version.

> Concerning documentation: I would provide a description for the
> "Standard Pattern Names..." section in a separate patch. However, I
> saw that a quite similar pattern named isinf is not mentioned
> there. Is this pattern intentionally omitted, or should I add a
> description for that one, too?

I forgot to add documentation...

Regadring your patch: It looks to me you are somehow reinventing
expand_builtin_interclass_mathfn() functionality. The patch for isinf
(please look at my ChangeLog entry from 2007-01-31) added
infrastructure that handles builtins with FP mode arguments and SImode
outputs using generic optab handling.

Perhaps you could enhance expand_builtin_interclass_mathfn() to
fallback to generic signbit handling (expand_builtin_signbit) in case
named pattern is not available?

BTW: You could implement isinf() just by adding appropriate named
pattern to s390.md. Please look at "isinf<mode>2" expander in
config/i386/i386.md

> +(define_expand "signbit_<mode>"

I belive that correct name for the named pattern is "signbit<mode>2"
as it has two operands. Underscore is usually not needed.

Uros.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] add insn implementing signbit to middle end and s390
  2007-03-30 17:24 ` Richard Henderson
@ 2007-04-02  7:57   ` Wolfgang Gellerich
  2007-04-30 17:02     ` Wolfgang Gellerich
  0 siblings, 1 reply; 21+ messages in thread
From: Wolfgang Gellerich @ 2007-04-02  7:57 UTC (permalink / raw)
  To: Richard Henderson; +Cc: gcc-patches

>
> You'll probably also want to implement the isinf optab,
> but that can certainly come as a separate patch.

Yes, I will provide separate patches for all the other functions that test
for IEEE special values.

Regards, Wolfgang

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] add insn implementing signbit to middle end and s390
  2007-03-30  9:36 Wolfgang Gellerich
  2007-03-30 14:49 ` Ulrich Weigand
@ 2007-03-30 17:24 ` Richard Henderson
  2007-04-02  7:57   ` Wolfgang Gellerich
  1 sibling, 1 reply; 21+ messages in thread
From: Richard Henderson @ 2007-03-30 17:24 UTC (permalink / raw)
  To: Wolfgang Gellerich; +Cc: gcc-patches

On Fri, Mar 30, 2007 at 10:24:34AM +0200, Wolfgang Gellerich wrote:
> +/* This array records the insn_code of insns to imlement the signbit function. */

Wrap long lines.

>    int word, bitpos;
> +
> +  enum insn_code signbit_insn_code;
> +
>    rtx temp;

Remove extra whitespace.

> @@ -5653,6 +5685,7 @@
>    return temp;
>  }
>  
> +

Likewise.

> @@ -753,6 +779,8 @@
>      }
>  }
>  
> +
> +

Likewise.

> +#define s390_TDC_positive_quite_NaN           (1 << 3)
> +#define s390_TDC_negative_quite_NaN           (1 << 2)

s/quite/quiet/

You'll probably also want to implement the isinf optab,
but that can certainly come as a separate patch.


r~

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] add insn implementing signbit to middle end and s390
  2007-03-30  9:36 Wolfgang Gellerich
@ 2007-03-30 14:49 ` Ulrich Weigand
  2007-03-30 17:24 ` Richard Henderson
  1 sibling, 0 replies; 21+ messages in thread
From: Ulrich Weigand @ 2007-03-30 14:49 UTC (permalink / raw)
  To: Wolfgang Gellerich; +Cc: gcc-patches

Wolfgang Gellerich wrote:

> 	* optabs.h: added declaration for signbit_optab.
Should start with captital letter:  "Added declaration ..."
In fact, should call out the changed element
	* optabs.h (signbit_optab): Add declaration.

> 	* s390.h.c: Added named constants for bit masks controllong the test
> 	  data class instruction
Typo in file name and "controllong".  Sentence should end in '.'.  Files
in subdirectories should be specified with relative path: config/s390/s390.h.
Also, the added constants should be listed in parenthesis, like so:

	* config/s390/s390.h (s390_TDC_positive_Zero): New constant.
	(s390_TDC_negative_Zero): Likewise.
	(s390_TDC_positive_normalized_Number): Likewise.
	(s390_TDC_negative_normalized_Number): Likewise.
	(s390_TDC_positive_denormalized_Number): Likewise.
	(s390_TDC_negative_denormalized_Number): Likewise.
	(s390_TDC_positive_Infinity): Likewise.
	(s390_TDC_negative_Infinity): Likewise.
	(s390_TDC_positive_quite_NaN): Likewise.
	(s390_TDC_negative_quite_NaN): Likewise.
	(s390_TDC_positive_signaling_NaN): Likewise.
	(s390_TDC_negative_signaling_NaN): Likewise.
	(s390_TDC_signbit_set): Likewise.

> 	* s390.c (s390_canonicalize_comparison): renamed CMPINT to CCU_TO_INT,
> 	  added a CCU-like optimization for CCU_TO_INT 
	This should be UNSPEC_..., the second CCU_TO_INT should presumably
	refer to UNSPEC_CCZ_TO_INT.

>  	* s390.md: added insns signbit_<mode>, TDC_insn_<mode>, 
> 	  ccz_to_int, renamed UNSPEC_CMPINT to UNSPEC_CCU_TO_INT, added 
>           UNSPEC_CCZ_TO_INT

The changed elements need to be specified, like so:

	* config/s390/s390.md ("signbit_<mode>"): New expander.
	("*TDC_insn_<mode>"): New insn pattern.
	(UNSPEC_CMPINT): Rename constant to ...
	(UNSPEC_CCU_TO_INT): ... this.
	(UNSPEC_CCZ_TO_INT): New constant.
	(UNSPEC_TDC_INSN): New constant.


I cannot approve the optabs/genopinit/builtin change, although they look
good to me.  We should add documentation of the new named pattern to
doc/md.texi, though.


> +(define_expand "signbit_<mode>"
> +  [(set (reg:CCZ CC_REGNUM)
> +        (unspec:CCZ [(match_operand:BFP 0 "register_operand" "f") 
> +                     (match_dup 2)] 
> +                     UNSPEC_TDC_INSN))
> +   (parallel
> +    [ (set (match_operand:SI 1 "register_operand" "=d")
> +        (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CCZ_TO_INT))
> +      (clobber (reg:CC CC_REGNUM))])
> +  ]
Common coding style in s390.md is to have closing brackets/parenthesis
at the end of the line, not on a line by themselves.  (Three other
locations with same issue.)

> +  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
> +  {
> +    operands[2] = GEN_INT (s390_TDC_signbit_set);
> +  }
Coding style is to have the { } for embedded C code sequences start 
in the first column.  Alternatively, for code that is just a single
line, you can use the old "" syntax.
> +)

> +; instruction. The insn's first operand is the register to be tested
Two spaces after '.'.

> +(define_insn "*TDC_insn_<mode>"
> +  [(set (reg:CCZ CC_REGNUM)
> +        (unspec:CCZ [(match_operand:BFP 0 "register_operand" "f") 
> +                     (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))
> +  ]
> +  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
> +  "tc<xde>b\t%0,%1"
> +)
You definitely need the op_type, and possibly the type attribute here,
to allow for correct length computation and scheduling.

> +(define_insn_and_split "*ccz_to_int"
> +  [(set (match_operand:SI 0 "register_operand" "=d")
> +        (unspec:SI [(match_operand:CCZ 1 "register_operand" "0")]
> +                   UNSPEC_CCZ_TO_INT))
> +   (clobber (reg:CC CC_REGNUM))]
This doesn't actually clobber CC, so you shouldn't have it in
the pattern ...

s390 parts OK with the above changes, provided the middle-end changes
have been approved.

Thanks,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH] add insn implementing signbit to middle end and s390
@ 2007-03-30  9:36 Wolfgang Gellerich
  2007-03-30 14:49 ` Ulrich Weigand
  2007-03-30 17:24 ` Richard Henderson
  0 siblings, 2 replies; 21+ messages in thread
From: Wolfgang Gellerich @ 2007-03-30  9:36 UTC (permalink / raw)
  To: gcc-patches

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 14396 bytes --]


Some platforms like s390 and spu provide instructions that implement the
math.h:signbit function. Using this instruction is faster and shorter than
making a lib call, or using the optimization currently performend by
builtins.c:expand_builtin_signbit. The signbit instruction also has the
advantage that it avoids the local variable currently introduced by
expand_builtin_signbit.

This patch enhances the middle end with an interface via optabs so that back
ends can provide insns named signbit_<FLOAT MODE> if they like, and it also
contains an appropriate implementation for s390. For s390, I also introduced a
CCZ to INTEGER conversion and renamed the CMPINT UNSPEC to CCU_TO_INT.

Verification: the patched compiler bootstraps and does not introduce new
reg.test failures on s390 (which now has signbit insns) and on i686 (without
signbit insn). I also checked the generated assembler code manually for some
example programs using signbit on s390.

Here is a suggestion for the Changelog:

2007-03-29  Wolfgang Gellerich  <gellerich@de.ibm.com>

	* optabs.h: added declaration for signbit_optab.
	* optabs.c (init_optabs): added initialization for
          signbit_optab.
	* genoptinit.c: added handling of signbit insns.
	* builtins.c (expand_builtin_signbit): Added code to use a
          signbit insn, if available.
	* s390.h.c: Added named constants for bit masks controllong the test
	  data class instruction
	* s390.c (s390_canonicalize_comparison): renamed CMPINT to CCU_TO_INT,
	  added a CCU-like optimization for CCU_TO_INT 
 	* s390.md: added insns signbit_<mode>, TDC_insn_<mode>, 
	  ccz_to_int, renamed UNSPEC_CMPINT to UNSPEC_CCU_TO_INT, added 
          UNSPEC_CCZ_TO_INT


Regards, Wolfgang

---
Dr. Wolfgang Gellerich
IBM Deutschland Entwicklung GmbH
Schönaicher Strasse 220
71032 Böblingen, Germany
Tel. +49 / 7031 / 162598
gellerich@de.ibm.com

=======================

IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Johann Weihen 
Geschäftsführung: Herbert Kircher 
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294



Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c	(Revision 123324)
+++ gcc/optabs.c	(Arbeitskopie)
@@ -5584,6 +5584,7 @@
   for (i = 0; i < NUM_MACHINE_MODES; i++)
     {
       movmem_optab[i] = CODE_FOR_nothing;
+      signbit_optab[i] = CODE_FOR_nothing;
       cmpstr_optab[i] = CODE_FOR_nothing;
       cmpstrn_optab[i] = CODE_FOR_nothing;
       cmpmem_optab[i] = CODE_FOR_nothing;
Index: gcc/optabs.h
===================================================================
--- gcc/optabs.h	(Revision 123324)
+++ gcc/optabs.h	(Arbeitskopie)
@@ -513,6 +513,9 @@
 /* This array records the insn_code of insns to perform block moves.  */
 extern enum insn_code movmem_optab[NUM_MACHINE_MODES];
 
+/* This array records the insn_code of insns to implement the signbit function.  */
+extern enum insn_code signbit_optab[NUM_MACHINE_MODES];
+
 /* This array records the insn_code of insns to perform block sets.  */
 extern enum insn_code setmem_optab[NUM_MACHINE_MODES];
 
Index: gcc/genopinit.c
===================================================================
--- gcc/genopinit.c	(Revision 123324)
+++ gcc/genopinit.c	(Arbeitskopie)
@@ -172,6 +172,7 @@
   "push_optab->handlers[$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$)",
+  "signbit_optab[$A] = CODE_FOR_$(signbit_$F$a$)",
   "movmem_optab[$A] = CODE_FOR_$(movmem$a$)",
   "cmpstr_optab[$A] = CODE_FOR_$(cmpstr$a$)",
   "cmpstrn_optab[$A] = CODE_FOR_$(cmpstrn$a$)",
Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c	(Revision 123324)
+++ gcc/builtins.c	(Arbeitskopie)
@@ -230,6 +230,10 @@
 			  int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
 static tree do_mpfr_sincos (tree, tree, tree);
 
+/* This array records the insn_code of insns to imlement the signbit function. */
+enum insn_code signbit_optab[NUM_MACHINE_MODES];
+
+
 /* Return true if NODE should be considered for inline expansion regardless
    of the optimization level.  This means whenever a function is invoked with
    its "internal" name, which normally contains the prefix "__builtin".  */
@@ -5553,11 +5557,15 @@
   return tramp;
 }
 
-/* Expand a call to the built-in signbit, signbitf or signbitl function.
-   Return NULL_RTX if a normal call should be emitted rather than expanding
-   the function in-line.  EXP is the expression that is a call to the builtin
-   function; if convenient, the result should be placed in TARGET.  */
 
+/* Expand a call to the built-in signbit, signbitf or signbitl function.  The
+   function first checks whether the back end provides an insn to implement
+   signbit for the respective mode. If not, it checks whether the floating
+   point format of the value is such that the sign bit can be extracted. If
+   that is not the case, the function returns NULL_RTX to indicate that a
+   normal call should be emitted rather than expanding the function in-line.
+   EXP is the expression that is a call to the builtin function; if
+   convenient, the result should be placed in TARGET.  */
 static rtx
 expand_builtin_signbit (tree exp, rtx target)
 {
@@ -5566,6 +5574,9 @@
   HOST_WIDE_INT hi, lo;
   tree arg;
   int word, bitpos;
+
+  enum insn_code signbit_insn_code;
+
   rtx temp;
 
   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
@@ -5576,6 +5587,28 @@
   rmode = TYPE_MODE (TREE_TYPE (exp));
   fmt = REAL_MODE_FORMAT (fmode);
 
+  /* Expand the argument yielding a RTX expression. */
+  temp = expand_normal (arg);
+
+  /* Check if the back end provides an insn that handles signbit for the
+     argument's mode. */
+  signbit_insn_code = signbit_optab [(int) fmode];
+  if (signbit_insn_code != CODE_FOR_nothing)
+    {
+      rtx result = gen_reg_rtx (SImode);
+      rtx signbit_insn;
+
+      if (!insn_data[(int) signbit_insn_code].operand[1].predicate (temp, fmode))
+	temp = force_reg (fmode, temp);
+
+      signbit_insn = GEN_FCN (signbit_insn_code) (temp, result);
+      if (signbit_insn == NULL_RTX)
+        gcc_unreachable ();
+      emit_insn (signbit_insn);
+
+      return result;
+    }
+
   /* For floating point formats without a sign bit, implement signbit
      as "ARG < 0.0".  */
   bitpos = fmt->signbit_ro;
@@ -5590,7 +5623,6 @@
     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
   }
 
-  temp = expand_normal (arg);
   if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
     {
       imode = int_mode_for_mode (fmode);
@@ -5653,6 +5685,7 @@
   return temp;
 }
 
+
 /* Expand fork or exec calls.  TARGET is the desired target of the
    call.  EXP is the call. FN is the
    identificator of the actual function.  IGNORE is nonzero if the
Index: gcc/config/s390/s390.c
===================================================================
--- gcc/config/s390/s390.c	(Revision 123324)
+++ gcc/config/s390/s390.c	(Arbeitskopie)
@@ -700,9 +700,9 @@
     }
 
 
-  /* Remove redundant UNSPEC_CMPINT conversions if possible.  */
+  /* Remove redundant UNSPEC_CCU_TO_INT conversions if possible.  */
   if (GET_CODE (*op0) == UNSPEC
-      && XINT (*op0, 1) == UNSPEC_CMPINT
+      && XINT (*op0, 1) == UNSPEC_CCU_TO_INT
       && XVECLEN (*op0, 0) == 1
       && GET_MODE (XVECEXP (*op0, 0, 0)) == CCUmode
       && GET_CODE (XVECEXP (*op0, 0, 0)) == REG
@@ -728,6 +728,32 @@
 	}
     }
 
+
+  /* Remove redundant UNSPEC_CCZ_TO_INT conversions if possible.  */
+  if (GET_CODE (*op0) == UNSPEC
+      && XINT (*op0, 1) == UNSPEC_CCZ_TO_INT
+      && XVECLEN (*op0, 0) == 1
+      && GET_MODE (XVECEXP (*op0, 0, 0)) == CCZmode
+      && GET_CODE (XVECEXP (*op0, 0, 0)) == REG
+      && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM
+      && *op1 == const0_rtx)
+    {
+      enum rtx_code new_code = UNKNOWN;
+      switch (*code)
+	{
+	  case EQ: new_code = EQ;  break;
+	  case NE: new_code = NE;  break;
+	  default: break;
+	}
+
+      if (new_code != UNKNOWN)
+	{
+	  *op0 = XVECEXP (*op0, 0, 0);
+	  *code = new_code;
+	}
+    }
+
+
   /* Simplify cascaded EQ, NE with const0_rtx.  */
   if ((*code == NE || *code == EQ)
       && (GET_CODE (*op0) == EQ || GET_CODE (*op0) == NE)
@@ -753,6 +779,8 @@
     }
 }
 
+
+
 /* Emit a compare instruction suitable to implement the comparison
    OP0 CODE OP1.  Return the correct condition RTL to be placed in
    the IF_THEN_ELSE of the conditional branch testing the result.  */
Index: gcc/config/s390/s390.h
===================================================================
--- gcc/config/s390/s390.h	(Revision 123324)
+++ gcc/config/s390/s390.h	(Arbeitskopie)
@@ -146,7 +146,27 @@
 /* Frame pointer is not used for debugging.  */
 #define CAN_DEBUG_WITHOUT_FP
 
+/* Constants needed to control the TEST DATA CLASS (TDC) instruction. */
+#define s390_TDC_positive_Zero                (1 << 11)
+#define s390_TDC_negative_Zero                (1 << 10)
+#define s390_TDC_positive_normalized_Number   (1 << 9)
+#define s390_TDC_negative_normalized_Number   (1 << 8)
+#define s390_TDC_positive_denormalized_Number (1 << 7)
+#define s390_TDC_negative_denormalized_Number (1 << 6)
+#define s390_TDC_positive_Infinity            (1 << 5)
+#define s390_TDC_negative_Infinity            (1 << 4)
+#define s390_TDC_positive_quite_NaN           (1 << 3)
+#define s390_TDC_negative_quite_NaN           (1 << 2)
+#define s390_TDC_positive_signaling_NaN       (1 << 1)
+#define s390_TDC_negative_signaling_NaN       (1 << 0)
 
+#define s390_TDC_signbit_set (s390_TDC_negative_Zero \
+                          | s390_TDC_negative_normalized_Number \
+                          | s390_TDC_negative_denormalized_Number\
+                          | s390_TDC_negative_Infinity \
+                          | s390_TDC_negative_quite_NaN \
+			  | s390_TDC_negative_signaling_NaN )
+
 /* In libgcc2, determine target settings as compile-time constants.  */
 #ifdef IN_LIBGCC2
 #undef TARGET_64BIT
Index: gcc/config/s390/s390.md
===================================================================
--- gcc/config/s390/s390.md	(Revision 123324)
+++ gcc/config/s390/s390.md	(Arbeitskopie)
@@ -59,7 +59,8 @@
 (define_constants
   [; Miscellaneous
    (UNSPEC_ROUND		1)
-   (UNSPEC_CMPINT		2)
+   (UNSPEC_CCU_TO_INT		2)
+   (UNSPEC_CCZ_TO_INT		3)
    (UNSPEC_ICM			10)
 
    ; GOT/PLT and lt-relative accesses
@@ -97,11 +98,15 @@
    ; Stack Smashing Protector
    (UNSPEC_SP_SET 		700)
    (UNSPEC_SP_TEST		701)
-
+   
    ; Copy sign instructions
    (UNSPEC_COPYSIGN             800)
+
+   ; Test Data Class (TDC)
+   (UNSPEC_TDC_INSN		900)
  ])
 
+
 ;;
 ;; UNSPEC_VOLATILE usage
 ;;
@@ -2090,7 +2095,7 @@
      (use (reg:SI 0))])
    (parallel
     [(set (match_operand:SI 0 "register_operand" "=d")
-	  (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_CMPINT))
+	  (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_CCU_TO_INT))
      (clobber (reg:CC CC_REGNUM))])]
   ""
 {
@@ -2288,7 +2293,56 @@
   [(set_attr "length" "8")
    (set_attr "type" "vs")])
 
+
+
+
 ;
+; Test data class.
+;
+
+(define_expand "signbit_<mode>"
+  [(set (reg:CCZ CC_REGNUM)
+        (unspec:CCZ [(match_operand:BFP 0 "register_operand" "f") 
+                     (match_dup 2)] 
+                     UNSPEC_TDC_INSN))
+   (parallel
+    [ (set (match_operand:SI 1 "register_operand" "=d")
+        (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CCZ_TO_INT))
+      (clobber (reg:CC CC_REGNUM))])
+  ]
+  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+  {
+    operands[2] = GEN_INT (s390_TDC_signbit_set);
+  }
+)
+
+
+; This insn is used to generate all variants of the Test Data Class
+; instruction. The insn's first operand is the register to be tested
+; and the second one is the bit mask specifying the required test(s).
+;
+(define_insn "*TDC_insn_<mode>"
+  [(set (reg:CCZ CC_REGNUM)
+        (unspec:CCZ [(match_operand:BFP 0 "register_operand" "f") 
+                     (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))
+  ]
+  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+  "tc<xde>b\t%0,%1"
+)
+
+
+(define_insn_and_split "*ccz_to_int"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (unspec:SI [(match_operand:CCZ 1 "register_operand" "0")]
+                   UNSPEC_CCZ_TO_INT))
+   (clobber (reg:CC CC_REGNUM))]
+  ""
+  "#"
+  "reload_completed"
+  [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))])
+
+
+;
 ; setmemM instruction pattern(s).
 ;
 
@@ -2564,7 +2618,7 @@
 (define_insn_and_split "cmpint"
   [(set (match_operand:SI 0 "register_operand" "=d")
         (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
-                   UNSPEC_CMPINT))
+                   UNSPEC_CCU_TO_INT))
    (clobber (reg:CC CC_REGNUM))]
   ""
   "#"
@@ -2577,10 +2631,10 @@
 (define_insn_and_split "*cmpint_cc"
   [(set (reg CC_REGNUM)
         (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
-                            UNSPEC_CMPINT)
+                            UNSPEC_CCU_TO_INT)
                  (const_int 0)))
    (set (match_operand:SI 0 "register_operand" "=d")
-        (unspec:SI [(match_dup 1)] UNSPEC_CMPINT))]
+        (unspec:SI [(match_dup 1)] UNSPEC_CCU_TO_INT))]
   "s390_match_ccmode (insn, CCSmode)"
   "#"
   "&& reload_completed"
@@ -2597,7 +2651,7 @@
 (define_insn_and_split "*cmpint_sign"
   [(set (match_operand:DI 0 "register_operand" "=d")
         (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
-                                   UNSPEC_CMPINT)))
+                                   UNSPEC_CCU_TO_INT)))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_64BIT"
   "#"
@@ -2611,11 +2665,11 @@
   [(set (reg CC_REGNUM)
         (compare (ashiftrt:DI (ashift:DI (subreg:DI 
                    (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
-                              UNSPEC_CMPINT) 0)
+                              UNSPEC_CCU_TO_INT) 0)
                    (const_int 32)) (const_int 32))
                  (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=d")
-        (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_CMPINT)))]
+        (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_CCU_TO_INT)))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_64BIT"
   "#"
   "&& reload_completed"



^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2007-07-06 15:58 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-04-03 13:35 [PATCH] add insn implementing signbit to middle end and s390 Gellerich
2007-04-03 13:50 ` Richard Guenther
2007-04-11  7:46   ` gellerich
2007-04-11  7:46   ` gellerich
2007-04-11  7:46   ` gellerich
2007-04-11  8:54   ` gellerich
2007-04-03 14:02 ` Paolo Bonzini
2007-04-11 10:17   ` gellerich
  -- strict thread matches above, loose matches on Subject: below --
2007-04-03 14:18 Uros Bizjak
2007-04-11 12:58 ` gellerich
2007-04-12  6:59   ` Uros Bizjak
2007-04-30 15:05     ` Wolfgang Gellerich
2007-03-30  9:36 Wolfgang Gellerich
2007-03-30 14:49 ` Ulrich Weigand
2007-03-30 17:24 ` Richard Henderson
2007-04-02  7:57   ` Wolfgang Gellerich
2007-04-30 17:02     ` Wolfgang Gellerich
2007-06-11  9:25       ` Richard Guenther
2007-07-06 15:02         ` Wolfgang Gellerich
2007-07-06 15:37         ` Wolfgang Gellerich
2007-07-06 16:22           ` Richard Guenther

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).