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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

powerpc support for TARGET_SUPPORTS_WIDE_INT.


This patch makes the PPC the first public target to use the CONST_WIDE_INT representation rather than CONST_DOUBLES to represent larger integers. There are two parts to this patch. The changes to genrecog.c represent fixes that would be needed for any port that supports CONST_WIDE_INTS and the rest are changes specific to the rs6000 port. Bootstrapped and tested on a ppc64.

Committed as revision 204710.

Kenny
Index: gcc/genrecog.c
===================================================================
--- gcc/genrecog.c	(revision 203701)
+++ gcc/genrecog.c	(working copy)
@@ -588,6 +588,7 @@ validate_pattern (rtx pattern, rtx insn,
 		 && GET_CODE (src) != PC
 		 && GET_CODE (src) != CC0
 		 && !CONST_INT_P (src)
+		 && !CONST_WIDE_INT_P (src)
 		 && GET_CODE (src) != CALL)
 	  {
 	    const char *which;
@@ -772,13 +773,14 @@ add_to_sequence (rtx pattern, struct dec
 
 	       We can optimize the generated code a little if either
 	       (a) the predicate only accepts one code, or (b) the
-	       predicate does not allow CONST_INT, in which case it
-	       can match only if the modes match.  */
+	       predicate does not allow CONST_INT or CONST_WIDE_INT,
+	       in which case it can match only if the modes match.  */
 	    pred = lookup_predicate (pred_name);
 	    if (pred)
 	      {
 		test->u.pred.data = pred;
-		allows_const_int = pred->codes[CONST_INT];
+		allows_const_int = (pred->codes[CONST_INT]
+				    || pred->codes[CONST_WIDE_INT]);
 		if (was_code == MATCH_PARALLEL
 		    && pred->singleton != PARALLEL)
 		  message_with_line (pattern_lineno,
Index: gcc/recog.c
===================================================================
--- gcc/recog.c	(revision 203701)
+++ gcc/recog.c	(working copy)
@@ -1198,7 +1198,8 @@ const_scalar_int_operand (rtx op, enum m
 
 /* Returns 1 if OP is an operand that is a CONST_WIDE_INT of mode
    MODE.  This most likely is not as useful as
-   const_scalar_int_operand, but is here for consistancy.  */
+   const_scalar_int_operand since it does not accept CONST_INTs, but
+   is here for consistancy.  */
 int
 const_wide_int_operand (rtx op, enum machine_mode mode)
 {
Index: gcc/config/rs6000/predicates.md
===================================================================
--- gcc/config/rs6000/predicates.md	(revision 203701)
+++ gcc/config/rs6000/predicates.md	(working copy)
@@ -19,7 +19,7 @@
 
 ;; Return 1 for anything except PARALLEL.
 (define_predicate "any_operand"
-  (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,mem"))
+  (match_code "const_int,const_double,const_wide_int,const,symbol_ref,label_ref,subreg,reg,mem"))
 
 ;; Return 1 for any PARALLEL.
 (define_predicate "any_parallel_operand"
@@ -596,7 +596,7 @@ (define_predicate "easy_vector_constant_
 
 ;; Return 1 if operand is constant zero (scalars and vectors).
 (define_predicate "zero_constant"
-  (and (match_code "const_int,const_double,const_vector")
+  (and (match_code "const_int,const_double,const_wide_int,const_vector")
        (match_test "op == CONST0_RTX (mode)")))
 
 ;; Return 1 if operand is 0.0.
@@ -790,7 +790,7 @@ (define_predicate "logical_operand"
 ;; Return 1 if op is a constant that is not a logical operand, but could
 ;; be split into one.
 (define_predicate "non_logical_cint_operand"
-  (and (match_code "const_int,const_double")
+  (and (match_code "const_int,const_wide_int")
        (and (not (match_operand 0 "logical_operand"))
 	    (match_operand 0 "reg_or_logical_cint_operand"))))
 
@@ -1058,7 +1058,7 @@ (define_predicate "current_file_function
 ;; Return 1 if this operand is a valid input for a move insn.
 (define_predicate "input_operand"
   (match_code "symbol_ref,const,reg,subreg,mem,
-	       const_double,const_vector,const_int")
+	       const_double,const_wide_int,const_vector,const_int")
 {
   /* Memory is always valid.  */
   if (memory_operand (op, mode))
@@ -1071,8 +1071,7 @@ (define_predicate "input_operand"
 
   /* Allow any integer constant.  */
   if (GET_MODE_CLASS (mode) == MODE_INT
-      && (GET_CODE (op) == CONST_INT
-	  || GET_CODE (op) == CONST_DOUBLE))
+      && CONST_SCALAR_INT_P (op))
     return 1;
 
   /* Allow easy vector constants.  */
@@ -1111,7 +1110,7 @@ (define_predicate "input_operand"
 ;; Return 1 if this operand is a valid input for a vsx_splat insn.
 (define_predicate "splat_input_operand"
   (match_code "symbol_ref,const,reg,subreg,mem,
-	       const_double,const_vector,const_int")
+	       const_double,const_wide_int,const_vector,const_int")
 {
   if (MEM_P (op))
     {
Index: gcc/config/rs6000/darwin.h
===================================================================
--- gcc/config/rs6000/darwin.h	(revision 203701)
+++ gcc/config/rs6000/darwin.h	(working copy)
@@ -421,3 +421,4 @@ do {									\
 /* So far, there is no rs6000_fold_builtin, if one is introduced, then
    this will need to be modified similar to the x86 case.  */
 #define TARGET_FOLD_BUILTIN SUBTARGET_FOLD_BUILTIN
+
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 203701)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -4597,6 +4597,15 @@ num_insns_constant (rtx op, enum machine
       else
 	return num_insns_constant_wide (INTVAL (op));
 
+    case CONST_WIDE_INT:
+      {
+	int i;
+	int ins = CONST_WIDE_INT_NUNITS (op) - 1;
+	for (i = 0; i < CONST_WIDE_INT_NUNITS (op); i++)
+	  ins += num_insns_constant_wide (CONST_WIDE_INT_ELT (op, i));
+	return ins;
+      }
+
       case CONST_DOUBLE:
 	if (mode == SFmode || mode == SDmode)
 	  {
@@ -4770,8 +4779,8 @@ easy_altivec_constant (rtx op, enum mach
 
   if (mode == V2DImode)
     {
-      /* In case the compiler is built 32-bit, CONST_DOUBLE constants are not
-	 easy.  */
+      /* In case the compiler is built 32-bit, CONST_WIDE_INT
+	 constants are not easy.  */
       if (GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT
 	  || GET_CODE (CONST_VECTOR_ELT (op, 1)) != CONST_INT)
 	return false;
@@ -4932,9 +4941,7 @@ paired_expand_vector_init (rtx target, r
   for (i = 0; i < n_elts; ++i)
     {
       x = XVECEXP (vals, 0, i);
-      if (!(CONST_INT_P (x)
-	    || GET_CODE (x) == CONST_DOUBLE
-	    || GET_CODE (x) == CONST_FIXED))
+      if (!CONSTANT_P (x))
 	++n_var;
     }
   if (n_var == 0)
@@ -5086,9 +5093,7 @@ rs6000_expand_vector_init (rtx target, r
   for (i = 0; i < n_elts; ++i)
     {
       x = XVECEXP (vals, 0, i);
-      if (!(CONST_INT_P (x)
-	    || GET_CODE (x) == CONST_DOUBLE
-	    || GET_CODE (x) == CONST_FIXED))
+      if (!CONSTANT_P (x))
 	++n_var, one_var = i;
       else if (x != CONST0_RTX (inner_mode))
 	all_const_zero = false;
@@ -6284,6 +6289,7 @@ rs6000_legitimize_address (rtx x, rtx ol
 	   && TARGET_NO_TOC
 	   && ! flag_pic
 	   && GET_CODE (x) != CONST_INT
+	   && GET_CODE (x) != CONST_WIDE_INT
 	   && GET_CODE (x) != CONST_DOUBLE
 	   && CONSTANT_P (x)
 	   && GET_MODE_NUNITS (mode) == 1
@@ -7633,21 +7639,12 @@ rs6000_emit_move (rtx dest, rtx source,
     }
 
   /* Sanity checks.  Check that we get CONST_DOUBLE only when we should.  */
-  if (GET_CODE (operands[1]) == CONST_DOUBLE
-      && ! FLOAT_MODE_P (mode)
+  if (CONST_WIDE_INT_P (operands[1])
       && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
     {
-      /* FIXME.  This should never happen.  */
-      /* Since it seems that it does, do the safe thing and convert
-	 to a CONST_INT.  */
-      operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
-    }
-  gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
-	      || FLOAT_MODE_P (mode)
-	      || ((CONST_DOUBLE_HIGH (operands[1]) != 0
-		   || CONST_DOUBLE_LOW (operands[1]) < 0)
-		  && (CONST_DOUBLE_HIGH (operands[1]) != -1
-		      || CONST_DOUBLE_LOW (operands[1]) >= 0)));
+      /* This should be fixed with the introduction of CONST_WIDE_INT.  */
+      gcc_unreachable ();
+    }
 
   /* Check if GCC is setting up a block move that will end up using FP
      registers as temporaries.  We must make sure this is acceptable.  */
@@ -15969,6 +15966,7 @@ rs6000_output_move_128bit (rtx operands[
   /* Constants.  */
   else if (dest_regno >= 0
 	   && (GET_CODE (src) == CONST_INT
+	       || GET_CODE (src) == CONST_WIDE_INT
 	       || GET_CODE (src) == CONST_DOUBLE
 	       || GET_CODE (src) == CONST_VECTOR))
     {
@@ -16982,8 +16980,7 @@ rs6000_assemble_integer (rtx x, unsigned
       if (TARGET_RELOCATABLE
 	  && in_section != toc_section
 	  && !recurse
-	  && GET_CODE (x) != CONST_INT
-	  && GET_CODE (x) != CONST_DOUBLE
+	  && !CONST_SCALAR_INT_P (x)
 	  && CONSTANT_P (x))
 	{
 	  char buf[256];
@@ -23371,6 +23368,15 @@ rs6000_hash_constant (rtx k)
     case LABEL_REF:
       return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
 
+    case CONST_WIDE_INT:
+      {
+	int i;
+	flen = CONST_WIDE_INT_NUNITS (k);
+	for (i = 0; i < flen; i++)
+	  result = result * 613 + CONST_WIDE_INT_ELT (k, i);
+	return result;
+      }
+
     case CONST_DOUBLE:
       if (mode != VOIDmode)
 	return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
@@ -23575,7 +23581,7 @@ output_toc (FILE *file, rtx x, int label
 
   /* If we're going to put a double constant in the TOC, make sure it's
      aligned properly when strict alignment is on.  */
-  if (GET_CODE (x) == CONST_DOUBLE
+  if ((CONST_DOUBLE_P (x) || CONST_WIDE_INT_P (x))
       && STRICT_ALIGNMENT
       && GET_MODE_BITSIZE (mode) >= 64
       && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
@@ -27577,6 +27583,7 @@ rs6000_rtx_costs (rtx x, int code, int o
       /* FALLTHRU */
 
     case CONST_DOUBLE:
+    case CONST_WIDE_INT:
     case CONST:
     case HIGH:
     case SYMBOL_REF:
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(revision 203701)
+++ gcc/config/rs6000/rs6000.h	(working copy)
@@ -2626,3 +2626,4 @@ enum rs6000_builtin_type_index
 extern GTY(()) tree rs6000_builtin_types[RS6000_BTI_MAX];
 extern GTY(()) tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
 
+#define TARGET_SUPPORTS_WIDE_INT 1
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(revision 203701)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -10437,7 +10437,7 @@ (define_split
 
 (define_split
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
-	(match_operand:DI 1 "const_double_operand" ""))]
+	(match_operand:DI 1 "const_scalar_int_operand" ""))]
   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
   [(set (match_dup 0) (match_dup 2))
    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
@@ -10503,7 +10503,7 @@ (define_insn "*mov<mode>_ppc64"
 
 (define_split
   [(set (match_operand:TI2 0 "int_reg_operand" "")
-	(match_operand:TI2 1 "const_double_operand" ""))]
+	(match_operand:TI2 1 "const_scalar_int_operand" ""))]
   "TARGET_POWERPC64
    && (VECTOR_MEM_NONE_P (<MODE>mode)
        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
@@ -10515,12 +10515,12 @@ (define_split
 				       <MODE>mode);
   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
 				       <MODE>mode);
-  if (GET_CODE (operands[1]) == CONST_DOUBLE)
+  if (CONST_WIDE_INT_P (operands[1]))
     {
-      operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
-      operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
+      operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
+      operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
     }
-  else if (GET_CODE (operands[1]) == CONST_INT)
+  else if (CONST_INT_P (operands[1]))
     {
       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
       operands[5] = operands[1];
Index: gcc/config/darwin.c
===================================================================
--- gcc/config/darwin.c	(revision 203701)
+++ gcc/config/darwin.c	(working copy)
@@ -1709,16 +1709,19 @@ machopic_select_rtx_section (enum machin
 {
   if (GET_MODE_SIZE (mode) == 8
       && (GET_CODE (x) == CONST_INT
+	  || GET_CODE (x) == CONST_WIDE_INT
 	  || GET_CODE (x) == CONST_DOUBLE))
     return darwin_sections[literal8_section];
   else if (GET_MODE_SIZE (mode) == 4
 	   && (GET_CODE (x) == CONST_INT
+	       || GET_CODE (x) == CONST_WIDE_INT
 	       || GET_CODE (x) == CONST_DOUBLE))
     return darwin_sections[literal4_section];
   else if (HAVE_GAS_LITERAL16
 	   && TARGET_64BIT
 	   && GET_MODE_SIZE (mode) == 16
 	   && (GET_CODE (x) == CONST_INT
+	       || GET_CODE (x) == CONST_WIDE_INT
 	       || GET_CODE (x) == CONST_DOUBLE
 	       || GET_CODE (x) == CONST_VECTOR))
     return darwin_sections[literal16_section];

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