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]

Re: Sign-extend CONST_INTs within their modes


On Apr  2, 2001, Geoff Keating <geoffk@geoffk.org> wrote:

> This is OK, please commit it.

It turned out that my pre-commit bootstrap detected a few problems on
x86.  Dunno if it's from new code that wasn't present in the 3.0
branch, in which I had originally tested the patch because of
brokenness in mainline, or if I still had the *_operand checking
disabled (I may have moved it from RTL to MISC checks only after
running the bootstrap, in which case you may have gone undetected).

The changes needed for i386 to bootstrap are below.  Ok to check them
in along with the rest of the patch?

I've also had to turn the `abort()'s in the new misc-checking tests in
the recog predicates to `return 0'.  Having the *_operand() functions
abort() would fail in a number of attempts to recognize insns, usually
involving compares, generated by various optimization passes.
Something like:

  (compare:<M1> (const_int <I>) (reg:<M2> ...))

would abort() if the recognizer tested the first operand of the
compare with a mode narrower than that of M2.  This actually happens
with the recognizers generated for x86 and, apparently, for sparc,
that failed similarly when the tests were enabled.

Also, since the predicates no longer abort(), the change to combine.c
is no longer needed, so I pulled it out.  The abort()s were useful to
find a number of errors in codegen, but they apparently can't be used
in practice.  Which is probably not such a bad thing: if the insn
survives long enough, recog will eventually fail to match the insn to
existing patterns and will abort().  But we won't be detecting lack of
sign-extension of CONST_INTs are early as possible, and other
optimization passes may end up hiding the errors.  Suggestions?

Here are the revised patches, bootstrapped yesterday on alpha, sparc
and x86, built alpha-x-ppc (except for David's patch, that I didn't
have when I started testing).  I didn't re-run tests on pa, because my
local pa box is very slow, but there haven't been any significant
changes that might affect it, and I'm pretty sure I did test it after
moving the tests from RTL to MISC checking.

Ok to install the revised patch?

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* recog.c (general_operand, immediate_operand,
	nonmemory_operand): Require CONST_INTs to be sign-extended
	values for their modes.
	* expmed.c (store_bit_field): Truncate CONST_INTs.
	(expand_mult_highpart, expand_divmod): Likewise.
	* expr.c (convert_modes, store_field): Likewise.
	* integrate.c (expand_inline_function): Use promote_mode() to
	determine whether to convert_modes() an argument as signed
	or unsigned.
	* optabs.c (expand_binop): Get CONST_INT operands
	sign-extended for their appropriate modes.
	* stmt.c (emit_case_nodes): Convert node values to the
	appropriate mode.
	(expand_end_case): Convert minval and range to the appropriate
	mode.
	* unroll.c (loop_iterations): Truncate abs_diff to the mode of
	the iteration variable.
	* varasm.c (immed_double_const): Don't require words to be
	narrower than host wide ints to properly sign-extend
	CONST_INTs.

Index: gcc/recog.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/recog.c,v
retrieving revision 1.95
diff -u -p -r1.95 recog.c
--- gcc/recog.c 2001/04/04 05:03:29 1.95
+++ gcc/recog.c 2001/04/04 15:07:16
@@ -1108,6 +1108,12 @@ general_operand (op, mode)
       && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
     return 0;
 
+#ifdef ENABLE_CHECKING
+  if (GET_CODE (op) == CONST_INT
+      && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
+    return 0;
+#endif
+
   if (CONSTANT_P (op))
     return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode
 	     || mode == VOIDmode)
@@ -1284,6 +1290,12 @@ immediate_operand (op, mode)
       && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
     return 0;
 
+#ifdef ENABLE_CHECKING
+  if (GET_CODE (op) == CONST_INT
+      && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
+    return 0;
+#endif
+
   /* Accept CONSTANT_P_RTX, since it will be gone by CSE1 and
      result in 0/1.  It seems a safe assumption that this is
      in range for everyone.  */
@@ -1354,6 +1366,12 @@ nonmemory_operand (op, mode)
 	  && GET_MODE_CLASS (mode) != MODE_INT
 	  && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
 	return 0;
+
+#ifdef ENABLE_CHECKING
+      if (GET_CODE (op) == CONST_INT
+	  && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
+	return 0;
+#endif
 
       return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode
 	      || mode == VOIDmode)
Index: gcc/expmed.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/expmed.c,v
retrieving revision 1.77
diff -u -p -r1.77 expmed.c
--- gcc/expmed.c 2001/03/22 18:48:28 1.77
+++ gcc/expmed.c 2001/03/30 07:58:16
@@ -587,6 +587,8 @@ store_bit_field (str_rtx, bitsize, bitnu
 	      else
 		value1 = gen_lowpart (maxmode, value1);
 	    }
+	  else if (GET_CODE (value) == CONST_INT)
+	    value1 = GEN_INT (trunc_int_for_mode (INTVAL (value), maxmode));
 	  else if (!CONSTANT_P (value))
 	    /* Parse phase is supposed to make VALUE's data type
 	       match that of the component reference, which is a type
@@ -2780,7 +2782,7 @@ expand_mult_highpart (mode, op0, cnst1, 
   if (size > HOST_BITS_PER_WIDE_INT)
     abort ();
 
-  op1 = GEN_INT (cnst1);
+  op1 = GEN_INT (trunc_int_for_mode (cnst1, mode));
 
   if (GET_MODE_BITSIZE (wider_mode) <= HOST_BITS_PER_INT)
     wide_op1 = op1;
@@ -3267,7 +3269,7 @@ expand_divmod (rem_flag, code, mode, op0
 		if (rem_flag && d < 0)
 		  {
 		    d = abs_d;
-		    op1 = GEN_INT (abs_d);
+		    op1 = GEN_INT (trunc_int_for_mode (abs_d, compute_mode));
 		  }
 
 		if (d == 1)
@@ -3297,7 +3299,8 @@ expand_divmod (rem_flag, code, mode, op0
 			t1 = copy_to_mode_reg (compute_mode, op0);
 			do_cmp_and_jump (t1, const0_rtx, GE,
 					 compute_mode, label);
-			expand_inc (t1, GEN_INT (abs_d - 1));
+			expand_inc (t1, GEN_INT (trunc_int_for_mode
+						 (abs_d - 1, compute_mode)));
 			emit_label (label);
 			quotient = expand_shift (RSHIFT_EXPR, compute_mode, t1,
 						 build_int_2 (lgup, 0),
@@ -3334,7 +3337,10 @@ expand_divmod (rem_flag, code, mode, op0
 			  		       REG_EQUAL,
 					       gen_rtx_DIV (compute_mode,
 							    op0,
-							    GEN_INT (abs_d)));
+							    GEN_INT
+							    (trunc_int_for_mode
+							     (abs_d,
+							      compute_mode))));
 
 			quotient = expand_unop (compute_mode, neg_optab,
 						quotient, quotient, 0);
@@ -3833,8 +3839,10 @@ expand_divmod (rem_flag, code, mode, op0
 	    ml = invert_mod2n (d >> pre_shift, size);
 	    t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
 			       build_int_2 (pre_shift, 0), NULL_RTX, unsignedp);
-	    quotient = expand_mult (compute_mode, t1, GEN_INT (ml), NULL_RTX,
-			      	    0);
+	    quotient = expand_mult (compute_mode, t1,
+				    GEN_INT (trunc_int_for_mode
+					     (ml, compute_mode)),
+				    NULL_RTX, 0);
 
 	    insn = get_last_insn ();
 	    set_unique_reg_note (insn,
Index: gcc/expr.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/expr.c,v
retrieving revision 1.307
diff -u -p -r1.307 expr.c
--- gcc/expr.c 2001/03/28 11:03:51 1.307
+++ gcc/expr.c 2001/03/30 07:58:18
@@ -1360,7 +1360,7 @@ convert_modes (mode, oldmode, x, unsigne
 	      && (val & ((HOST_WIDE_INT) 1 << (width - 1))))
 	    val |= (HOST_WIDE_INT) (-1) << width;
 
-	  return GEN_INT (val);
+	  return GEN_INT (trunc_int_for_mode (val, mode));
 	}
 
       return gen_lowpart (mode, x);
@@ -5268,7 +5268,13 @@ store_field (target, bitsize, bitpos, mo
 	      enum machine_mode tmode;
 
 	      if (unsignedp)
-		return expand_and (temp, GEN_INT (width_mask), NULL_RTX);
+		return expand_and (temp,
+				   GEN_INT
+				   (trunc_int_for_mode
+				    (width_mask,
+				     GET_MODE (temp) == VOIDmode
+				     ? value_mode
+				     : GET_MODE (temp))), NULL_RTX);
 	      tmode = GET_MODE (temp);
 	      if (tmode == VOIDmode)
 		tmode = value_mode;
Index: gcc/integrate.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/integrate.c,v
retrieving revision 1.137
diff -u -p -r1.137 integrate.c
--- gcc/integrate.c 2001/03/28 11:03:54 1.137
+++ gcc/integrate.c 2001/03/30 07:58:19
@@ -702,13 +702,24 @@ expand_inline_function (fndecl, parms, t
       else if (GET_CODE (loc) != MEM)
 	{
 	  if (GET_MODE (loc) != TYPE_MODE (TREE_TYPE (arg)))
-	    /* The mode if LOC and ARG can differ if LOC was a variable
-	       that had its mode promoted via PROMOTED_MODE.  */
-	    arg_vals[i] = convert_modes (GET_MODE (loc),
-					 TYPE_MODE (TREE_TYPE (arg)),
-					 expand_expr (arg, NULL_RTX, mode,
-						      EXPAND_SUM),
-					 TREE_UNSIGNED (TREE_TYPE (formal)));
+	    {
+	      int unsignedp = TREE_UNSIGNED (TREE_TYPE (formal));
+	      enum machine_mode pmode = TYPE_MODE (TREE_TYPE (formal));
+
+	      pmode = promote_mode (TREE_TYPE (formal), pmode,
+				    &unsignedp, 0);
+
+	      if (GET_MODE (loc) != pmode)
+		abort ();
+
+	      /* The mode if LOC and ARG can differ if LOC was a variable
+		 that had its mode promoted via PROMOTED_MODE.  */
+	      arg_vals[i] = convert_modes (pmode,
+					   TYPE_MODE (TREE_TYPE (arg)),
+					   expand_expr (arg, NULL_RTX, mode,
+							EXPAND_SUM),
+					   unsignedp);
+	    }
 	  else
 	    arg_vals[i] = expand_expr (arg, NULL_RTX, mode, EXPAND_SUM);
 	}
Index: gcc/optabs.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/optabs.c,v
retrieving revision 1.91
diff -u -p -r1.91 optabs.c
--- gcc/optabs.c 2001/03/28 11:03:56 1.91
+++ gcc/optabs.c 2001/03/30 07:58:19
@@ -723,17 +723,25 @@ expand_binop (mode, binoptab, op0, op1, 
 	}
 
       /* In case the insn wants input operands in modes different from
-	 the result, convert the operands.  */
+	 the result, convert the operands.  It would seem that we
+	 don't need to convert CONST_INTs, but we do, so that they're
+	 a properly sign-extended for their modes.  */
 
-      if (GET_MODE (op0) != VOIDmode
-	  && GET_MODE (op0) != mode0
+      if (GET_MODE (op0) != mode0
 	  && mode0 != VOIDmode)
-	xop0 = convert_to_mode (mode0, xop0, unsignedp);
+	xop0 = convert_modes (mode0,
+			      GET_MODE (op0) != VOIDmode
+			      ? GET_MODE (op0)
+			      : mode0,
+			      xop0, unsignedp);
 
-      if (GET_MODE (xop1) != VOIDmode
-	  && GET_MODE (xop1) != mode1
+      if (GET_MODE (xop1) != mode1
 	  && mode1 != VOIDmode)
-	xop1 = convert_to_mode (mode1, xop1, unsignedp);
+	xop1 = convert_modes (mode1,
+			      GET_MODE (op1) != VOIDmode
+			      ? GET_MODE (op1)
+			      : mode1,
+			      xop1, unsignedp);
 
       /* Now, if insn's predicates don't allow our operands, put them into
 	 pseudo regs.  */
@@ -4295,7 +4303,9 @@ expand_fix (to, from, unsignedp)
 				 NULL_RTX, 0, OPTAB_LIB_WIDEN);
 	  expand_fix (to, target, 0);
 	  target = expand_binop (GET_MODE (to), xor_optab, to,
-				 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
+				 GEN_INT (trunc_int_for_mode
+					  ((HOST_WIDE_INT) 1 << (bitsize - 1),
+					   GET_MODE (to))),
 				 to, 1, OPTAB_LIB_WIDEN);
 
 	  if (target != to)
Index: gcc/stmt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/stmt.c,v
retrieving revision 1.190
diff -u -p -r1.190 stmt.c
--- gcc/stmt.c 2001/03/28 11:03:58 1.190
+++ gcc/stmt.c 2001/03/30 08:12:44
@@ -1,6 +1,6 @@
 /* Expands front end tree to back end RTL for GNU C-Compiler
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000 Free Software Foundation, Inc.
+   1998, 1999, 2000, 2001 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -5474,6 +5474,8 @@ expand_end_case (orig_index)
 	      op1 = expand_expr (minval, NULL_RTX, VOIDmode, 0);
 
 	      op_mode = insn_data[(int) CODE_FOR_casesi].operand[1].mode;
+	      op1 = convert_modes (op_mode, TYPE_MODE (TREE_TYPE (minval)),
+				   op1, TREE_UNSIGNED (TREE_TYPE (minval)));
 	      if (! (*insn_data[(int) CODE_FOR_casesi].operand[1].predicate)
 		  (op1, op_mode))
 		op1 = copy_to_mode_reg (op_mode, op1);
@@ -5481,6 +5483,8 @@ expand_end_case (orig_index)
 	      op2 = expand_expr (range, NULL_RTX, VOIDmode, 0);
 
 	      op_mode = insn_data[(int) CODE_FOR_casesi].operand[2].mode;
+	      op2 = convert_modes (op_mode, TYPE_MODE (TREE_TYPE (range)),
+				   op2, TREE_UNSIGNED (TREE_TYPE (range)));
 	      if (! (*insn_data[(int) CODE_FOR_casesi].operand[2].predicate)
 		  (op2, op_mode))
 		op2 = copy_to_mode_reg (op_mode, op2);
@@ -5503,7 +5507,11 @@ expand_end_case (orig_index)
 	      do_pending_stack_adjust ();
 
 	      do_tablejump (index, TYPE_MODE (index_type),
-			    expand_expr (range, NULL_RTX, VOIDmode, 0),
+			    convert_modes (TYPE_MODE (index_type),
+					   TYPE_MODE (TREE_TYPE (range)),
+					   expand_expr (range, NULL_RTX,
+							VOIDmode, 0),
+					   TREE_UNSIGNED (TREE_TYPE (range))),
 			    table_label, default_label);
 	      win = 1;
 	    }
@@ -6027,6 +6035,7 @@ emit_case_nodes (index, node, default_la
   /* If INDEX has an unsigned type, we must make unsigned branches.  */
   int unsignedp = TREE_UNSIGNED (index_type);
   enum machine_mode mode = GET_MODE (index);
+  enum machine_mode imode = TYPE_MODE (index_type);
 
   /* See if our parents have already tested everything for us.
      If they have, emit an unconditional jump for this node.  */
@@ -6038,7 +6047,11 @@ emit_case_nodes (index, node, default_la
       /* Node is single valued.  First see if the index expression matches
 	 this node and then check our children, if any.  */
 
-      do_jump_if_equal (index, expand_expr (node->low, NULL_RTX, VOIDmode, 0),
+      do_jump_if_equal (index,
+			convert_modes (mode, imode,
+				       expand_expr (node->low, NULL_RTX,
+						    VOIDmode, 0),
+				       unsignedp),
 			label_rtx (node->code_label), unsignedp);
 
       if (node->right != 0 && node->left != 0)
@@ -6052,8 +6065,11 @@ emit_case_nodes (index, node, default_la
 	  if (node_is_bounded (node->right, index_type))
 	    {
 	      emit_cmp_and_jump_insns (index,
-				       expand_expr (node->high, NULL_RTX,
-						    VOIDmode, 0),
+				       convert_modes
+				       (mode, imode,
+					expand_expr (node->high, NULL_RTX,
+						     VOIDmode, 0),
+					unsignedp),
 				       GT, NULL_RTX, mode, unsignedp, 0,
 				       label_rtx (node->right->code_label));
 	      emit_case_nodes (index, node->left, default_label, index_type);
@@ -6062,8 +6078,11 @@ emit_case_nodes (index, node, default_la
 	  else if (node_is_bounded (node->left, index_type))
 	    {
 	      emit_cmp_and_jump_insns (index,
-				       expand_expr (node->high, NULL_RTX,
-						    VOIDmode, 0),
+				       convert_modes
+				       (mode, imode,
+					expand_expr (node->high, NULL_RTX,
+						     VOIDmode, 0),
+					unsignedp),
 				       LT, NULL_RTX, mode, unsignedp, 0,
 				       label_rtx (node->left->code_label));
 	      emit_case_nodes (index, node->right, default_label, index_type);
@@ -6078,8 +6097,11 @@ emit_case_nodes (index, node, default_la
 
 	      /* See if the value is on the right.  */
 	      emit_cmp_and_jump_insns (index,
-				       expand_expr (node->high, NULL_RTX,
-						    VOIDmode, 0),
+				       convert_modes
+				       (mode, imode,
+					expand_expr (node->high, NULL_RTX,
+						     VOIDmode, 0),
+					unsignedp),
 				       GT, NULL_RTX, mode, unsignedp, 0,
 				       label_rtx (test_label));
 
@@ -6110,8 +6132,11 @@ emit_case_nodes (index, node, default_la
 	      if (!node_has_low_bound (node, index_type))
 		{
 		  emit_cmp_and_jump_insns (index,
-					   expand_expr (node->high, NULL_RTX,
-							VOIDmode, 0),
+					   convert_modes
+					   (mode, imode,
+					    expand_expr (node->high, NULL_RTX,
+							 VOIDmode, 0),
+					    unsignedp),
 					   LT, NULL_RTX, mode, unsignedp, 0,
 					   default_label);
 		}
@@ -6123,8 +6148,11 @@ emit_case_nodes (index, node, default_la
 	       since we haven't ruled out the numbers less than
 	       this node's value.  So handle node->right explicitly.  */
 	    do_jump_if_equal (index,
-			      expand_expr (node->right->low, NULL_RTX,
-					   VOIDmode, 0),
+			      convert_modes
+			      (mode, imode,
+			       expand_expr (node->right->low, NULL_RTX,
+					    VOIDmode, 0),
+			       unsignedp),
 			      label_rtx (node->right->code_label), unsignedp);
 	}
 
@@ -6150,9 +6178,12 @@ emit_case_nodes (index, node, default_la
 	    {
 	      if (!node_has_high_bound (node, index_type))
 		{
-		  emit_cmp_and_jump_insns (index, expand_expr (node->high,
-							       NULL_RTX,
-							       VOIDmode, 0),
+		  emit_cmp_and_jump_insns (index,
+					   convert_modes
+					   (mode, imode,
+					    expand_expr (node->high, NULL_RTX,
+							 VOIDmode, 0),
+					    unsignedp),
 					   GT, NULL_RTX, mode, unsignedp, 0,
 					   default_label);
 		}
@@ -6164,8 +6195,11 @@ emit_case_nodes (index, node, default_la
 	       since we haven't ruled out the numbers less than
 	       this node's value.  So handle node->left explicitly.  */
 	    do_jump_if_equal (index,
-			      expand_expr (node->left->low, NULL_RTX,
-					   VOIDmode, 0),
+			      convert_modes
+			      (mode, imode,
+			       expand_expr (node->left->low, NULL_RTX,
+					    VOIDmode, 0),
+			       unsignedp),
 			      label_rtx (node->left->code_label), unsignedp);
 	}
     }
@@ -6187,8 +6221,12 @@ emit_case_nodes (index, node, default_la
 	  if (node_is_bounded (node->right, index_type))
 	    /* Right hand node is fully bounded so we can eliminate any
 	       testing and branch directly to the target code.  */
-	    emit_cmp_and_jump_insns (index, expand_expr (node->high, NULL_RTX,
-							 VOIDmode, 0),
+	    emit_cmp_and_jump_insns (index,
+				     convert_modes
+				     (mode, imode,
+				      expand_expr (node->high, NULL_RTX,
+						   VOIDmode, 0),
+				      unsignedp),
 				     GT, NULL_RTX, mode, unsignedp, 0,
 				     label_rtx (node->right->code_label));
 	  else
@@ -6198,16 +6236,23 @@ emit_case_nodes (index, node, default_la
 
 	      test_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
 	      emit_cmp_and_jump_insns (index,
-				       expand_expr (node->high, NULL_RTX,
-						    VOIDmode, 0),
+				       convert_modes
+				       (mode, imode,
+					expand_expr (node->high, NULL_RTX,
+						     VOIDmode, 0),
+					unsignedp),
 				       GT, NULL_RTX, mode, unsignedp, 0,
 				       label_rtx (test_label));
 	    }
 
 	  /* Value belongs to this node or to the left-hand subtree.  */
 
-	  emit_cmp_and_jump_insns (index, expand_expr (node->low, NULL_RTX,
-						       VOIDmode, 0),
+	  emit_cmp_and_jump_insns (index,
+				   convert_modes
+				   (mode, imode,
+				    expand_expr (node->low, NULL_RTX,
+						 VOIDmode, 0),
+				    unsignedp),
 				   GE, NULL_RTX, mode, unsignedp, 0,
 				   label_rtx (node->code_label));
 
@@ -6234,16 +6279,23 @@ emit_case_nodes (index, node, default_la
 	  if (!node_has_low_bound (node, index_type))
 	    {
 	      emit_cmp_and_jump_insns (index,
-				       expand_expr (node->low, NULL_RTX,
-						    VOIDmode, 0),
+				       convert_modes
+				       (mode, imode,
+					expand_expr (node->low, NULL_RTX,
+						     VOIDmode, 0),
+					unsignedp),
 				       LT, NULL_RTX, mode, unsignedp, 0,
 				       default_label);
 	    }
 
 	  /* Value belongs to this node or to the right-hand subtree.  */
 
-	  emit_cmp_and_jump_insns (index, expand_expr (node->high, NULL_RTX,
-						       VOIDmode, 0),
+	  emit_cmp_and_jump_insns (index,
+				   convert_modes
+				   (mode, imode,
+				    expand_expr (node->high, NULL_RTX,
+						 VOIDmode, 0),
+				    unsignedp),
 				   LE, NULL_RTX, mode, unsignedp, 0,
 				   label_rtx (node->code_label));
 
@@ -6257,8 +6309,11 @@ emit_case_nodes (index, node, default_la
 	  if (!node_has_high_bound (node, index_type))
 	    {
 	      emit_cmp_and_jump_insns (index,
-				       expand_expr (node->high, NULL_RTX,
-						    VOIDmode, 0),
+				       convert_modes
+				       (mode, imode,
+					expand_expr (node->high, NULL_RTX,
+						     VOIDmode, 0),
+					unsignedp),
 				       GT, NULL_RTX, mode, unsignedp, 0,
 				       default_label);
 	    }
@@ -6266,8 +6321,11 @@ emit_case_nodes (index, node, default_la
 	  /* Value belongs to this node or to the left-hand subtree.  */
 
 	  emit_cmp_and_jump_insns (index,
-				   expand_expr (node->low, NULL_RTX,
-						VOIDmode, 0),
+				   convert_modes
+				   (mode, imode,
+				    expand_expr (node->low, NULL_RTX,
+						 VOIDmode, 0),
+				    unsignedp),
 				   GE, NULL_RTX, mode, unsignedp, 0,
 				   label_rtx (node->code_label));
 
@@ -6283,8 +6341,11 @@ emit_case_nodes (index, node, default_la
 	  if (!node_has_high_bound (node, index_type))
 	    {
 	      emit_cmp_and_jump_insns (index,
-				       expand_expr (node->high, NULL_RTX,
-						    VOIDmode, 0),
+				       convert_modes
+				       (mode, imode,
+					expand_expr (node->high, NULL_RTX,
+						     VOIDmode, 0),
+					unsignedp),
 				       GT, NULL_RTX, mode, unsignedp, 0,
 				       default_label);
 	    }
@@ -6292,8 +6353,11 @@ emit_case_nodes (index, node, default_la
 	  if (!node_has_low_bound (node, index_type))
 	    {
 	      emit_cmp_and_jump_insns (index,
-				       expand_expr (node->low, NULL_RTX,
-						    VOIDmode, 0),
+				       convert_modes
+				       (mode, imode,
+					expand_expr (node->low, NULL_RTX,
+						     VOIDmode, 0),
+					unsignedp),
 				       LT, NULL_RTX, mode, unsignedp, 0,
 				       default_label);
 	    }
Index: gcc/unroll.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/unroll.c,v
retrieving revision 1.125
diff -u -p -r1.125 unroll.c
--- gcc/unroll.c 2001/01/25 09:28:55 1.125
+++ gcc/unroll.c 2001/03/30 07:58:21
@@ -3962,6 +3962,8 @@ loop_iterations (loop)
   else
     abort ();
 
+  abs_diff = trunc_int_for_mode (abs_diff, GET_MODE (iteration_var));
+
   /* For NE tests, make sure that the iteration variable won't miss
      the final value.  If abs_diff mod abs_incr is not zero, then the
      iteration variable will overflow before the loop exits, and we
Index: gcc/varasm.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/varasm.c,v
retrieving revision 1.170
diff -u -p -r1.170 varasm.c
--- gcc/varasm.c 2001/03/23 22:00:40 1.170
+++ gcc/varasm.c 2001/03/30 07:58:22
@@ -1984,7 +1984,7 @@ immed_double_const (i0, i1, mode)
 	 represented as a 64 bit value -1, and not as 0x00000000ffffffff.
 	 The later confuses the sparc backend.  */
 
-      if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
+      if (width < HOST_BITS_PER_WIDE_INT
 	  && (i0 & ((HOST_WIDE_INT) 1 << (width - 1))))
 	i0 |= ((HOST_WIDE_INT) (-1) << width);
 
Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* config/rs6000/rs6000.c (logical_operand): CONST_INTs are
	already sign-extended.
	(rs6000_emit_prologue): Make register iterator signed.
	(rs6000_emit_epilogue): Likewise.
	* config/rs6000/rs6000.md (addsi3, adddi3): Sign-extend high
	and low.
	(movsf split, movdf split): Sign-extend CONST_INTs.
	(movdi splits): Likewise.

Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.172
diff -u -p -r1.172 rs6000.c
--- gcc/config/rs6000/rs6000.c 2001/03/28 11:19:20 1.172
+++ gcc/config/rs6000/rs6000.c 2001/03/30 13:39:15
@@ -965,7 +965,7 @@ add_operand (op, mode)
 {
   return (reg_or_short_operand (op, mode)
 	  || (GET_CODE (op) == CONST_INT
-	      && CONST_OK_FOR_LETTER_P (INTVAL(op), 'L')));
+	      && CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')));
 }
 
 /* Return 1 if OP is a constant but not a valid add_operand.  */
@@ -977,7 +977,7 @@ non_add_cint_operand (op, mode)
 {
   return (GET_CODE (op) == CONST_INT
 	  && (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) >= 0x10000
-	  && ! CONST_OK_FOR_LETTER_P (INTVAL(op), 'L'));
+	  && ! CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
 }
 
 /* Return 1 if the operand is a non-special register or a constant that
@@ -995,13 +995,7 @@ logical_operand (op, mode)
     return 1;
 
   if (GET_CODE (op) == CONST_INT)
-    {
-      opl = INTVAL (op) & GET_MODE_MASK (mode);
-      if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
-	oph = 0;
-      else
-	oph = INTVAL (op) >> (HOST_BITS_PER_WIDE_INT - 1);
-    }
+    opl = INTVAL (op);
   else if (GET_CODE (op) == CONST_DOUBLE)
     {
       if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
@@ -1009,13 +1003,21 @@ logical_operand (op, mode)
 
       opl = CONST_DOUBLE_LOW (op);
       oph = CONST_DOUBLE_HIGH (op);
+
+      if (oph != ((unsigned HOST_WIDE_INT)0
+		  - ((opl & ((unsigned HOST_WIDE_INT)1
+			     << (HOST_BITS_PER_WIDE_INT - 1))) != 0)))
+	return 0;
     }
   else
     return 0;
+
+  /* This must really be SImode, not MODE.  */
+  if (opl != trunc_int_for_mode (opl, SImode))
+    return 0;
 
-  return (oph == 0
-	  && ((opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0
-	      || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000) == 0));
+  return ((opl & 0xffff) == 0
+	  || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0);
 }
 
 /* Return 1 if C is a constant that is not a logical operand (as
@@ -5762,7 +5762,7 @@ rs6000_emit_prologue ()
      easiest way to get the frame unwind information emitted.  */
   if (current_function_calls_eh_return)
     {
-      unsigned int i, regno;
+      int i, regno;
       for (i = 0; ; ++i)
 	{
 	  rtx addr, reg, mem;
@@ -6006,7 +6006,7 @@ rs6000_emit_epilogue (sibcall)
   /* Load exception handler data registers, if needed.  */
   if (current_function_calls_eh_return)
     {
-      unsigned int i, regno;
+      int i, regno;
       for (i = 0; ; ++i)
 	{
 	  rtx addr, mem;
Index: gcc/config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.111
diff -u -p -r1.111 rs6000.md
--- gcc/config/rs6000/rs6000.md 2001/03/28 12:22:48 1.111
+++ gcc/config/rs6000/rs6000.md 2001/03/30 13:39:19
@@ -1426,7 +1426,10 @@
       HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
 
       if (low & 0x8000)
-        high += 0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
+	{
+	  high = trunc_int_for_mode (high + 0x10000, SImode);
+	  low = trunc_int_for_mode (low, HImode);
+	}
 
       /* The ordering here is important for the prolog expander.
 	 When space is allocated from the stack, adding 'low' first may
@@ -1529,7 +1532,10 @@
   HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
 
   if (low & 0x8000)
-    high += 0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
+    {
+      high = trunc_int_for_mode (high + 0x10000, SImode);
+      low = trunc_int_for_mode (low, HImode);
+    }
 
   operands[3] = GEN_INT (high);
   operands[4] = GEN_INT (low);
@@ -5759,7 +5765,10 @@
 	HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
 
 	if (low & 0x8000)
-	  high += 0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
+	  {
+	    high = trunc_int_for_mode (high + 0x10000, SImode);
+	    low = trunc_int_for_mode (low, HImode);
+	  }
 
 	emit_insn (gen_adddi3 (tmp, operands[1], GEN_INT (high)));
 	emit_insn (gen_adddi3 (operands[0], tmp, GEN_INT (low)));
@@ -5858,7 +5867,10 @@
   HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
 
   if (low & 0x8000)
-    high+=0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
+    {
+      high = trunc_int_for_mode (high + 0x10000, SImode);
+      low = trunc_int_for_mode (low, HImode);
+    }
 
   operands[3] = GEN_INT (high);
   operands[4] = GEN_INT (low);
@@ -7573,7 +7585,7 @@
   else
     operands[2] = gen_lowpart (SImode, operands[0]);
 
-  operands[3] = GEN_INT(l);
+  operands[3] = GEN_INT (trunc_int_for_mode (l, SImode));
 }")
 
 (define_insn "*movsf_hardfloat"
@@ -7663,8 +7675,8 @@
 
   operands[2] = operand_subword (operands[0], endian, 0, DFmode);
   operands[3] = operand_subword (operands[0], 1 - endian, 0, DFmode);
-  operands[4] = GEN_INT (l[endian]);
-  operands[5] = GEN_INT (l[1 - endian]);
+  operands[4] = GEN_INT (trunc_int_for_mode (l[endian], SImode));
+  operands[5] = GEN_INT (trunc_int_for_mode (l[1 - endian], SImode));
 }")
 
 (define_split
@@ -8009,7 +8021,7 @@
 		(match_dup 3)))]
   "
 {
-  operands[2] = GEN_INT (INTVAL (operands[1]) & 0xffff0000);
+  operands[2] = GEN_INT (INTVAL (operands[1]) & (~ (HOST_WIDE_INT) 0xffff));
   operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff);
 }")
 
@@ -8029,7 +8041,7 @@
 		(match_dup 3)))]
   "
 {
-  operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xffff0000);
+  operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & (~ (HOST_WIDE_INT) 0xffff));
   operands[3] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xffff);
 }")
 
@@ -8050,7 +8062,7 @@
 		(match_dup 3)))]
   "
 {
-  operands[2] = GEN_INT (INTVAL (operands[1]) & 0xffff0000);
+  operands[2] = GEN_INT (INTVAL (operands[1]) & (~ (HOST_WIDE_INT) 0xffff));
   operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff);
 }")
 
Index: gcc/ChangeLog
from  David Edelsohn  <dje@watson.ibm.com>

	* config/rs6000/rs6000.c (rs6000_emit_move): Adjust for 64-bit
	HOST_WIDE_INT.

Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.166
diff -c -p -r1.166 rs6000.c
*************** rs6000_emit_move (dest, source, mode)
*** 1688,1698 ****
  	}
        else if (mode == Pmode
  	       && CONSTANT_P (operands[1])
!  	       && (((HOST_BITS_PER_WIDE_INT != 32 
!  		     || GET_CODE (operands[1]) != CONST_INT)
!  		    && ! easy_fp_constant (operands[1], mode))
!  		   || (GET_CODE (operands[0]) == REG
!  		       && FP_REGNO_P (REGNO (operands[0]))))
  	       && GET_CODE (operands[1]) != HIGH
  	       && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
  	       && ! TOC_RELATIVE_EXPR_P (operands[1]))
--- 1688,1699 ----
  	}
        else if (mode == Pmode
  	       && CONSTANT_P (operands[1])
! 	       && ((GET_CODE (operands[1]) != CONST_INT
! 		    && ! easy_fp_constant (operands[1], mode))
! 		   || (GET_CODE (operands[1]) == CONST_INT
! 		       && num_insns_constant (operands[1], mode) > 2)
! 		   || (GET_CODE (operands[0]) == REG
! 		       && FP_REGNO_P (REGNO (operands[0]))))
  	       && GET_CODE (operands[1]) != HIGH
  	       && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
  	       && ! TOC_RELATIVE_EXPR_P (operands[1]))
Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* config/i386/i386.md: Apply trunc_int_for_mode() to GEN_INT
	operands that make it to RTL.

Index: gcc/config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.253
diff -u -p -r1.253 i386.md
--- gcc/config/i386/i386.md 2001/04/01 09:50:06 1.253
+++ gcc/config/i386/i386.md 2001/04/04 14:56:20
@@ -7929,7 +7929,8 @@
   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
 
-  operands[3] = gen_rtx_AND (mode, operands[0], GEN_INT (mask));
+  operands[3] = gen_rtx_AND (mode, operands[0],
+			     GEN_INT (trunc_int_for_mode (mask, mode)));
 }")
 
 ;; %%% This used to optimize known byte-wide and operations to memory,
@@ -9150,7 +9151,7 @@
   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
 	      (clobber (reg:CC 17))])]
-  "operands[1] = GEN_INT (0x80000000);
+  "operands[1] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
    operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
 
 (define_split
@@ -9169,7 +9170,7 @@
     size = 10;
   operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
   operands[0] = adj_offsettable_operand (operands[0], size - 1);
-  operands[1] = GEN_INT (0x80);
+  operands[1] = GEN_INT (trunc_int_for_mode (0x80, QImode));
 }")
 
 (define_expand "negdf2"
@@ -9205,7 +9206,7 @@
   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
   [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
 	      (clobber (reg:CC 17))])]
-  "operands[4] = GEN_INT (0x80000000);
+  "operands[4] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
    split_di (operands+0, 1, operands+2, operands+3);")
 
 (define_expand "negxf2"
@@ -9466,7 +9467,7 @@
   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
 	      (clobber (reg:CC 17))])]
-  "operands[1] = GEN_INT (~0x80000000);
+  "operands[1] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
    operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
 
 (define_split
@@ -9485,7 +9486,7 @@
     size = 10;
   operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
   operands[0] = adj_offsettable_operand (operands[0], size - 1);
-  operands[1] = GEN_INT (~0x80);
+  operands[1] = GEN_INT (trunc_int_for_mode (~0x80, QImode));
 }")
 
 (define_expand "absdf2"
@@ -9588,7 +9589,7 @@
   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
   [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
 	      (clobber (reg:CC 17))])]
-  "operands[4] = GEN_INT (~0x80000000);
+  "operands[4] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
    split_di (operands+0, 1, operands+2, operands+3);")
 
 (define_expand "absxf2"
@@ -9632,7 +9633,7 @@
   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
 	      (clobber (reg:CC 17))])]
-  "operands[1] = GEN_INT (~0x8000);
+  "operands[1] = GEN_INT (trunc_int_for_mode (~0x8000, SImode));
    operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
 
 (define_insn "*abstf2_if"
@@ -9658,7 +9659,7 @@
   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
 	      (clobber (reg:CC 17))])]
-  "operands[1] = GEN_INT (~0x8000);
+  "operands[1] = GEN_INT (trunc_int_for_mode (~0x8000, SImode));
    operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
 
 (define_insn "*abssf2_1"
@@ -10040,7 +10041,8 @@
   [(set (match_dup 0)
 	(mult:DI (match_dup 1)
 		 (match_dup 2)))]
-  "operands[2] = GEN_INT (1 << INTVAL (operands[2]));")
+  "operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
+					      DImode));")
 
 ;; This pattern can't accept a variable shift count, since shifts by
 ;; zero don't affect the flags.  We assume that shifts by constant
@@ -10251,7 +10253,8 @@
   rtx pat;
   operands[0] = gen_lowpart (SImode, operands[0]);
   operands[1] = gen_lowpart (Pmode, operands[1]);
-  operands[2] = GEN_INT (1 << INTVAL (operands[2]));
+  operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
+					     Pmode));
   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
   if (Pmode != SImode)
     pat = gen_rtx_SUBREG (SImode, pat, 0);
@@ -10311,7 +10314,8 @@
   "
 {
   operands[1] = gen_lowpart (Pmode, operands[1]);
-  operands[2] = GEN_INT (1 << INTVAL (operands[2]));
+  operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
+					     Pmode));
 }")
 
 ;; This pattern can't accept a variable shift count, since shifts by
@@ -15894,7 +15898,9 @@
 	      (set (match_dup 0)
 		   (and:SI (match_dup 1) (match_dup 2)))])]
   "operands[2]
-     = GEN_INT (INTVAL (operands[2]) & GET_MODE_MASK (GET_MODE (operands[0])));
+     = GEN_INT (trunc_int_for_mode (INTVAL (operands[2])
+				    & GET_MODE_MASK (GET_MODE (operands[0])),
+				    SImode));
    operands[0] = gen_lowpart (SImode, operands[0]);
    operands[1] = gen_lowpart (SImode, operands[1]);")
 
@@ -15912,7 +15918,9 @@
 	(compare:CCNO (and:SI (match_dup 0) (match_dup 1))
 		      (const_int 0)))]
   "operands[1]
-     = GEN_INT (INTVAL (operands[1]) & GET_MODE_MASK (GET_MODE (operands[0])));
+     = GEN_INT (trunc_int_for_mode (INTVAL (operands[1])
+				    & GET_MODE_MASK (GET_MODE (operands[0])),
+				    SImode));
    operands[0] = gen_lowpart (SImode, operands[0]);")
 
 (define_split

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                  aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist    *Please* write to mailing lists, not to me

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