public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [SPARC] Enable wide-int support
@ 2015-12-12 21:11 Eric Botcazou
  0 siblings, 0 replies; only message in thread
From: Eric Botcazou @ 2015-12-12 21:11 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1586 bytes --]

On the heels of s390, this enables wide-int support in the SPARC back-end and 
removes all the obsolete code conditionalized on HOST_BITS_PER_WIDE_INT == 32.

Boostrapped/regtested on SPARC/Solaris, applied on the mainline.


2015-12-12  Eric Botcazou  <ebotcazou@adacore.com>

	* config/sparc/sparc.h (TARGET_SUPPORTS_WIDE_INT): Define to 1.
	* config/sparc/sparc.c (sparc_emit_set_const64): Remove code
	conditionalized on HOST_BITS_PER_WIDE_INT == 32.
	(sparc_cannot_force_const_mem) <CONST_WIDE_INT>: New case.
	<CONST_DOUBLE>: Remove VOIDmode test.
	(epilogue_renumber) <CONST_WIDE_INT>: New case.
	(sparc_print_operand): Remove support for CONST_DOUBLE with VOIDmode.
	(sparc_assemble_integer): Likewise.
	(set_extends): Likewise.
	(sparc_rtx_costs) <CONST_INT>: Use SMALL_INT.
	<CONST_WIDE_INT>: New case.
	<CONST_DOUBLE>: Remove support for VOIDmode.
	<MULT>: Remove support for CONST_DOUBLE with VOIDmode.
	* config/sparc/predicates.md (const_zero_operand): Add const_wide_int.
	(const_all_ones_operand): Likewise.
	(uns_small_int_operand): Remove const_double and code conditionalized
	on HOST_BITS_PER_WIDE_INT == 32.
	(arith_double_operand): Likewise.
	(arith_double_add_operand): Likewise.
	(input_operand): Remove support for CONST_DOUBLE with DImode.
	* config/sparc/sparc.md (DImode CONST_INT splitter): Remove code
	conditionalized on HOST_BITS_PER_WIDE_INT == 32.
	(DFmode CONST_DOUBLE splitter): Likewise.
	(*adddi3_insn_sp32): Likewise.
	(*subdi3_insn_sp32): Likewise.
	(DImode logical splitter): Likewise.
	(DImode CONST_DOUBLE splitter): Delete.

-- 
Eric Botcazou

[-- Attachment #2: sparc_wide_int.diff --]
[-- Type: text/x-patch, Size: 15167 bytes --]

Index: config/sparc/predicates.md
===================================================================
--- config/sparc/predicates.md	(revision 231562)
+++ config/sparc/predicates.md	(working copy)
@@ -21,13 +21,12 @@
 
 ;; Return true if OP is the zero constant for MODE.
 (define_predicate "const_zero_operand"
-  (and (match_code "const_int,const_double,const_vector")
+  (and (match_code "const_int,const_wide_int,const_double,const_vector")
        (match_test "op == CONST0_RTX (mode)")))
 
-;; Return true if the integer representation of OP is
-;; all-ones.
+;; Return true if the integer representation of OP is all ones.
 (define_predicate "const_all_ones_operand"
-  (and (match_code "const_int,const_double,const_vector")
+  (and (match_code "const_int,const_wide_int,const_double,const_vector")
        (match_test "INTEGRAL_MODE_P (GET_MODE (op))")
        (match_test "op == CONSTM1_RTX (GET_MODE (op))")))
 
@@ -47,20 +46,10 @@ (define_predicate "small_int_operand"
 ;; instruction sign-extends immediate values just like all other SPARC
 ;; instructions, but interprets the extended result as an unsigned number.
 (define_predicate "uns_small_int_operand"
-  (match_code "const_int,const_double")
-{
-#if HOST_BITS_PER_WIDE_INT == 32
-  return ((GET_CODE (op) == CONST_INT && (unsigned) INTVAL (op) < 0x1000)
-	  || (GET_CODE (op) == CONST_DOUBLE
-	      && CONST_DOUBLE_HIGH (op) == 0
-	      && (unsigned) CONST_DOUBLE_LOW (op) - 0xFFFFF000 < 0x1000));
-#else
-  return (GET_CODE (op) == CONST_INT
-	  && ((INTVAL (op) >= 0 && INTVAL (op) < 0x1000)
-	      || (INTVAL (op) >= 0xFFFFF000
-                  && INTVAL (op) <= 0xFFFFFFFF)));
-#endif
-})
+  (and (match_code "const_int")
+       (match_test "((INTVAL (op) >= 0 && INTVAL (op) < 0x1000)
+		    || (INTVAL (op) >= 0xFFFFF000
+			&& INTVAL (op) <= 0xFFFFFFFF))")))
 
 ;; Return true if OP is a constant that can be loaded by the sethi instruction.
 ;; The first test avoids emitting sethi to load zero for example.
@@ -308,7 +297,7 @@ (define_predicate "arith_operand"
 ;; representable by a couple of 13-bit signed fields.  This is an
 ;; acceptable operand for most 3-address splitters.
 (define_predicate "arith_double_operand"
-  (match_code "const_int,const_double,reg,subreg")
+  (match_code "const_int,reg,subreg")
 {
   bool arith_simple_operand = arith_operand (op, mode);
   HOST_WIDE_INT m1, m2;
@@ -316,17 +305,11 @@ (define_predicate "arith_double_operand"
   if (TARGET_ARCH64 || arith_simple_operand)
     return arith_simple_operand;
 
-#if HOST_BITS_PER_WIDE_INT == 32
-  if (GET_CODE (op) != CONST_DOUBLE)
-    return false;
-  m1 = CONST_DOUBLE_LOW (op);
-  m2 = CONST_DOUBLE_HIGH (op);
-#else
   if (GET_CODE (op) != CONST_INT)
     return false;
+
   m1 = trunc_int_for_mode (INTVAL (op), SImode);
   m2 = trunc_int_for_mode (INTVAL (op) >> 32, SImode);
-#endif
 
   return SPARC_SIMM13_P (m1) && SPARC_SIMM13_P (m2);
 })
@@ -338,11 +321,9 @@ (define_predicate "arith_add_operand"
 
 ;; Return true if OP is suitable as second double operand for add/sub.
 (define_predicate "arith_double_add_operand"
-  (match_code "const_int,const_double,reg,subreg")
+  (match_code "const_int,reg,subreg")
 {
-  bool _arith_double_operand = arith_double_operand (op, mode);
-
-  if (_arith_double_operand)
+  if (arith_double_operand (op, mode))
     return true;
 
   return TARGET_ARCH64 && const_4096_operand (op, mode);
@@ -395,8 +376,8 @@ (define_predicate "compare_operand"
 		|| (TARGET_ARCH64
 		    && mode == DImode
 		    && INTVAL (XEXP (op, 2)) > 51)));
-  else
-    return register_operand (op, mode);
+
+  return register_operand (op, mode);
 })
 
 ;; Return true if OP is a valid operand for the source of a move insn.
@@ -419,9 +400,7 @@ (define_predicate "input_operand"
 
   /* If 32-bit mode and this is a DImode constant, allow it
      so that the splits can be generated.  */
-  if (TARGET_ARCH32
-      && mode == DImode
-      && (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT))
+  if (TARGET_ARCH32 && mode == DImode && GET_CODE (op) == CONST_INT)
     return true;
 
   if (mclass == MODE_FLOAT && GET_CODE (op) == CONST_DOUBLE)
Index: config/sparc/sparc.c
===================================================================
--- config/sparc/sparc.c	(revision 231562)
+++ config/sparc/sparc.c	(working copy)
@@ -2086,13 +2086,6 @@ sparc_emit_set_symbolic_const64 (rtx op0
     }
 }
 
-#if HOST_BITS_PER_WIDE_INT == 32
-static void
-sparc_emit_set_const64 (rtx op0 ATTRIBUTE_UNUSED, rtx op1 ATTRIBUTE_UNUSED)
-{
-  gcc_unreachable ();
-}
-#else
 /* These avoid problems when cross compiling.  If we do not
    go through all this hair then the optimizer will see
    invalid REG_EQUAL notes or in some cases none at all.  */
@@ -2636,8 +2629,7 @@ sparc_emit_set_const64 (rtx op0, rtx op1
    *    sllx	%reg, 32, %reg
    *	or	%reg, low_bits, %reg
    */
-  if (SPARC_SIMM13_P(low_bits)
-      && ((int)low_bits > 0))
+  if (SPARC_SIMM13_P (low_bits) && ((int)low_bits > 0))
     {
       sparc_emit_set_const64_quick2 (op0, temp, high_bits, low_bits, 32);
       return;
@@ -2646,7 +2638,6 @@ sparc_emit_set_const64 (rtx op0, rtx op1
   /* The easiest way when all else fails, is full decomposition.  */
   sparc_emit_set_const64_longway (op0, temp, high_bits, low_bits);
 }
-#endif /* HOST_BITS_PER_WIDE_INT == 32 */
 
 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
    return the mode to be used for the comparison.  For floating-point,
@@ -3675,6 +3666,7 @@ sparc_cannot_force_const_mem (machine_mo
   switch (GET_CODE (x))
     {
     case CONST_INT:
+    case CONST_WIDE_INT:
     case CONST_DOUBLE:
     case CONST_VECTOR:
       /* Accept all non-symbolic constants.  */
@@ -3775,9 +3767,6 @@ sparc_legitimate_constant_p (machine_mod
       break;
 
     case CONST_DOUBLE:
-      if (GET_MODE (x) == VOIDmode)
-        return true;
-
       /* Floating point constants are generally not ok.
 	 The only exception is 0.0 and all-ones in VIS.  */
       if (TARGET_VIS
@@ -3832,7 +3821,7 @@ constant_address_p (rtx x)
 
 /* Nonzero if the constant value X is a legitimate general operand
    when generating PIC code.  It is given that flag_pic is on and
-   that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
+   that X satisfies CONSTANT_P.  */
 
 bool
 legitimate_pic_operand_p (rtx x)
@@ -8351,6 +8340,7 @@ epilogue_renumber (register rtx *where,
     case CC0:
     case PC:
     case CONST_INT:
+    case CONST_WIDE_INT:
     case CONST_DOUBLE:
       return 0;
 
@@ -8896,8 +8886,6 @@ sparc_print_operand (FILE *file, rtx x,
 	HOST_WIDE_INT i;
 	if (GET_CODE(x) == CONST_INT)
 	  i = INTVAL (x);
-	else if (GET_CODE(x) == CONST_DOUBLE)
-	  i = CONST_DOUBLE_LOW (x);
 	else
 	  {
 	    output_operand_lossage ("invalid %%s operand");
@@ -8944,21 +8932,10 @@ sparc_print_operand (FILE *file, rtx x,
       output_addr_const (file, XEXP (x, 1));
       fputc (')', file);
     }
-  else if (GET_CODE (x) == CONST_DOUBLE
-	   && (GET_MODE (x) == VOIDmode
-	       || GET_MODE_CLASS (GET_MODE (x)) == MODE_INT))
-    {
-      if (CONST_DOUBLE_HIGH (x) == 0)
-	fprintf (file, "%u", (unsigned int) CONST_DOUBLE_LOW (x));
-      else if (CONST_DOUBLE_HIGH (x) == -1
-	       && CONST_DOUBLE_LOW (x) < 0)
-	fprintf (file, "%d", (int) CONST_DOUBLE_LOW (x));
-      else
-	output_operand_lossage ("long long constant not a valid immediate operand");
-    }
   else if (GET_CODE (x) == CONST_DOUBLE)
-    output_operand_lossage ("floating point constant not a valid immediate operand");
-  else { output_addr_const (file, x); }
+    output_operand_lossage ("floating-point constant not a valid immediate operand");
+  else
+    output_addr_const (file, x);
 }
 
 /* Implement TARGET_PRINT_OPERAND_ADDRESS.  */
@@ -9052,8 +9029,7 @@ sparc_assemble_integer (rtx x, unsigned
 {
   /* ??? We only output .xword's for symbols and only then in environments
      where the assembler can handle them.  */
-  if (aligned_p && size == 8
-      && (GET_CODE (x) != CONST_INT && GET_CODE (x) != CONST_DOUBLE))
+  if (aligned_p && size == 8 && GET_CODE (x) != CONST_INT)
     {
       if (TARGET_V9)
 	{
@@ -9602,10 +9578,8 @@ set_extends (rtx_insn *insn)
     case LSHIFTRT:
       return GET_MODE (SET_SRC (pat)) == SImode;
       /* Positive integers leave the high bits zero.  */
-    case CONST_DOUBLE:
-      return ! (CONST_DOUBLE_LOW (SET_SRC (pat)) & 0x80000000);
     case CONST_INT:
-      return ! (INTVAL (SET_SRC (pat)) & 0x80000000);
+      return !(INTVAL (SET_SRC (pat)) & 0x80000000);
     case ASHIFTRT:
     case SIGN_EXTEND:
       return - (GET_MODE (SET_SRC (pat)) == SImode);
@@ -10903,12 +10877,19 @@ sparc_rtx_costs (rtx x, machine_mode mod
   switch (code)
     {
     case CONST_INT:
-      if (INTVAL (x) < 0x1000 && INTVAL (x) >= -0x1000)
-	{
-	  *total = 0;
-	  return true;
-	}
-      /* FALLTHRU */
+      if (SMALL_INT (x))
+	*total = 0;
+      else
+	*total = 2;
+      return true;
+
+    case CONST_WIDE_INT:
+      *total = 0;
+      if (!SPARC_SIMM13_P (CONST_WIDE_INT_ELT (x, 0)))
+	*total += 2;
+      if (!SPARC_SIMM13_P (CONST_WIDE_INT_ELT (x, 1)))
+	*total += 2;
+      return true;
 
     case HIGH:
       *total = 2;
@@ -10921,15 +10902,7 @@ sparc_rtx_costs (rtx x, machine_mode mod
       return true;
 
     case CONST_DOUBLE:
-      if (mode == VOIDmode
-	  && ((CONST_DOUBLE_HIGH (x) == 0
-	       && CONST_DOUBLE_LOW (x) < 0x1000)
-	      || (CONST_DOUBLE_HIGH (x) == -1
-		  && CONST_DOUBLE_LOW (x) < 0
-		  && CONST_DOUBLE_LOW (x) >= -0x1000)))
-	*total = 0;
-      else
-	*total = 8;
+      *total = 8;
       return true;
 
     case MEM:
@@ -11002,18 +10975,6 @@ sparc_rtx_costs (rtx x, machine_mode mod
 		  for (nbits = 0; value != 0; value &= value - 1)
 		    nbits++;
 		}
-	      else if (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
-		       && GET_MODE (XEXP (x, 1)) == VOIDmode)
-		{
-		  rtx x1 = XEXP (x, 1);
-		  unsigned HOST_WIDE_INT value1 = CONST_DOUBLE_LOW (x1);
-		  unsigned HOST_WIDE_INT value2 = CONST_DOUBLE_HIGH (x1);
-
-		  for (nbits = 0; value1 != 0; value1 &= value1 - 1)
-		    nbits++;
-		  for (; value2 != 0; value2 &= value2 - 1)
-		    nbits++;
-		}
 	      else
 		nbits = 7;
 
Index: config/sparc/sparc.h
===================================================================
--- config/sparc/sparc.h	(revision 231562)
+++ config/sparc/sparc.h	(working copy)
@@ -506,6 +506,7 @@ extern enum cmodel sparc_cmodel;
 /* FIXME, this is wrong when TARGET_ARCH64 and TARGET_STACK_BIAS, because
    then %sp+2047 is 128-bit aligned so %sp is really only byte-aligned.  */
 #define STACK_BOUNDARY (TARGET_ARCH64 ? 128 : 64)
+
 /* Temporary hack until the FIXME above is fixed.  */
 #define SPARC_STACK_BOUNDARY_HACK (TARGET_ARCH64 && TARGET_STACK_BIAS)
 
@@ -1801,3 +1802,5 @@ extern int sparc_indent_opcode;
 
 /* Define this to 1 if the FE_EXCEPT values defined in fenv.h start at 1.  */
 #define SPARC_LOW_FE_EXCEPT_VALUES 0
+
+#define TARGET_SUPPORTS_WIDE_INT 1
Index: config/sparc/sparc.md
===================================================================
--- config/sparc/sparc.md	(revision 231562)
+++ config/sparc/sparc.md	(working copy)
@@ -1880,14 +1880,6 @@ (define_split
    && reload_completed"
   [(clobber (const_int 0))]
 {
-#if HOST_BITS_PER_WIDE_INT == 32
-  emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
-			(INTVAL (operands[1]) < 0) ?
-			constm1_rtx :
-			const0_rtx));
-  emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
-			operands[1]));
-#else
   HOST_WIDE_INT low, high;
 
   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
@@ -1903,40 +1895,7 @@ (define_split
 			  gen_highpart (SImode, operands[0])));
   else
     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
-#endif
-  DONE;
-})
 
-(define_split
-  [(set (match_operand:DI 0 "register_operand" "")
-        (match_operand:DI 1 "const_double_operand" ""))]
-  "reload_completed
-   && (! TARGET_V9
-       || (! TARGET_ARCH64
-           && ((GET_CODE (operands[0]) == REG
-                && SPARC_INT_REG_P (REGNO (operands[0])))
-               || (GET_CODE (operands[0]) == SUBREG
-                   && GET_CODE (SUBREG_REG (operands[0])) == REG
-                   && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))))"
-  [(clobber (const_int 0))]
-{
-  emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
-			GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
-
-  /* Slick... but this trick loses if this subreg constant part
-     can be done in one insn.  */
-  if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
-      && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
-      && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
-    {
-      emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
-			    gen_highpart (SImode, operands[0])));
-    }
-  else
-    {
-      emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
-			    GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
-    }
   DONE;
 })
 
@@ -2358,13 +2317,9 @@ (define_split
 
   if (TARGET_ARCH64)
     {
-#if HOST_BITS_PER_WIDE_INT == 32
-      gcc_unreachable ();
-#else
       machine_mode mode = GET_MODE (operands[1]);
       rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
       emit_insn (gen_movdi (operands[0], tem));
-#endif
     }
   else
     {
@@ -3682,17 +3637,7 @@ (define_insn_and_split "*adddi3_insn_sp3
   operands[5] = gen_lowpart (SImode, operands[2]);
   operands[6] = gen_highpart (SImode, operands[0]);
   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
-#if HOST_BITS_PER_WIDE_INT == 32
-  if (GET_CODE (operands[2]) == CONST_INT)
-    {
-      if (INTVAL (operands[2]) < 0)
-	operands[8] = constm1_rtx;
-      else
-	operands[8] = const0_rtx;
-    }
-  else
-#endif
-    operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
+  operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
 }
   [(set_attr "length" "2")])
 
@@ -3872,17 +3817,7 @@ (define_insn_and_split "*subdi3_insn_sp3
   operands[5] = gen_lowpart (SImode, operands[2]);
   operands[6] = gen_highpart (SImode, operands[0]);
   operands[7] = gen_highpart (SImode, operands[1]);
-#if HOST_BITS_PER_WIDE_INT == 32
-  if (GET_CODE (operands[2]) == CONST_INT)
-    {
-      if (INTVAL (operands[2]) < 0)
-	operands[8] = constm1_rtx;
-      else
-	operands[8] = const0_rtx;
-    }
-  else
-#endif
-    operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
+  operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
 }
   [(set_attr "length" "2")])
 
@@ -5034,17 +4969,7 @@ (define_split
   operands[5] = gen_lowpart (SImode, operands[0]);
   operands[6] = gen_highpart (SImode, operands[2]);
   operands[7] = gen_lowpart (SImode, operands[2]);
-#if HOST_BITS_PER_WIDE_INT == 32
-  if (GET_CODE (operands[3]) == CONST_INT)
-    {
-      if (INTVAL (operands[3]) < 0)
-	operands[8] = constm1_rtx;
-      else
-	operands[8] = const0_rtx;
-    }
-  else
-#endif
-    operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
+  operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
   operands[9] = gen_lowpart (SImode, operands[3]);
 })
 

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2015-12-12 21:11 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-12 21:11 [SPARC] Enable wide-int support Eric Botcazou

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).