This is the mail archive of the gcc@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]

[patch] generic simd support


hi guys.

as promised...

months ago it was discussed that we could enable certain operators on
simd types (+, -, etc), provided they conform to the valarrays 
specification.

this will provide a basis for hardware assisted valarrays.

of course, this isn't terribly interesting unless we can provide
simd support for targets that don't have simd hardware.  this patch
does both.

if the hardware doesn't have simd support, gcc will now synthesize the
instructions from the underlying type.  if we declare a variable
V4SI, and we have no hardware V4SI, gcc will implement the operation on
4 SIs.  the operators presently supported are +, -, *, /, and unary
minus.  more to come as i can find out what the corresponding
valarray implementation does.

this will provide a basis for future auto-vectorization work,
and will give us a generic mechanism for testing SIMD operations
(and vector initializers) which have been here-to mostly untested 
(except on selected platforms).  i am including a test for this as 
well.

in addition to all this wonderful stuff, the gdb folks want to start
adding generic testcases for simd extensions, and this will allow them
to do just that.

i have also revised the vector extension documentation.  thanks to the
altivec work, we can now use vectors in arguments and return values.
i have modified the documentation to reflect these and other changes.

on my TODO list are:

	- provide support for == and !=.  these are a bit trickier
	  because do_jump() synthesizes these at the tree level not
	  the rtl level and we need a new tree code and what-not.

	  (perhaps do the rest of the relational operators when i figure
	   out what the valarray counterparts do).

	- synthesize bigger SIMD types from architecture present smaller 
	  SIMD types.  for example, if we have V2SI but no V4SI and we
	  want V4SI, we should be able to use a pair of V2SI's to do
	  the operation.  presently we use 4 SIs.

and... [much later] future work should include:

	- providing generic builtins for common vector operations in
	  addition to the operations in the valarrays specs.  this way
	  we could write truly portable SIMD programs that will work
	  regardless of the hardware.

	  say, provide:

	    __builtin_simd_adds   /* add saturated */
	    __builtin_simd_select
	    __builtin_simd_splat
	    etc

enough dreaming.  on to the current patch.

tested on darwin *without* [hardware] simd support ;-).  will be testing
on x86 shortly.

how does this look for mainline?

2002-05-21  Aldy Hernandez  <aldyh@redhat.com>

	* gcc.c-torture/execute/simd-1.c: New.

	* gcc.dg/simd-1.c: New.

	* doc/extend.texi (Vector Extensions): Document that we can
	specify simd types not specifically supported by the hardware.
	Document that simd types can be used as function arguments.
	Document that signness does make a difference in SIMD types.
	Misc cleanups and revisions to the "vector extensions" section.

	* simplify-rtx.c (simplify_subreg): Simplify subregs of vector
	constants.

	* expr.c (vector_mode_valid_p): New.

	* expr.h: Add vector_mode_valid_p.

	* defaults.h (VECTOR_MODE_SUPPORTED_P): Set default.

	* c-common.c (type_for_mode): Always build vector nodes regardless
	of VECTOR_MODE_SUPPORTED_P.
	(handle_mode_attribute): Error if we can't emulate a nonexisting
	vector mode.
	(handle_vector_size_attribute): Same.

	* optabs.c (expand_binop): Open-code vector operations.
	(expand_unop): Open-code vector unops.
	(emit_no_conflict_block): Emit all the instructions regardless, if
	we have a vector type.
	
	* c-typeck.c (build_binary_op): Allow vectors in binops.
	Allow vectors in conditional operatiors.
	(build_unary_op): Allow vectors in unary minus.
	

Index: testsuite/gcc.c-torture/execute/simd-1.c
===================================================================
RCS file: testsuite/gcc.c-torture/execute/simd-1.c
diff -N testsuite/gcc.c-torture/execute/simd-1.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.c-torture/execute/simd-1.c	22 May 2002 00:42:53 -0000
***************
*** 0 ****
--- 1,54 ----
+ /* Origin: Aldy Hernandez <aldyh@redhat.com>
+ 
+    Purpose: Test generic SIMD support.  This test should work
+    regardless of if the target has SIMD instructions.
+ */
+ 
+ typedef int __attribute__((mode(V4SI))) vecint;
+ 
+ vecint i = { 150, 100, 150, 200 };
+ vecint j = { 10, 13, 20, 30 };
+ vecint k;
+ 
+ union {
+   vecint v;
+   int i[4];
+ } res;
+ 
+ /* This should go away once we can use == and != on vector types.  */
+ void
+ verify (int a1, int a2, int a3, int a4,
+ 	int b1, int b2, int b3, int b4)
+ {
+   if (a1 != b1
+       || a2 != b2
+       || a3 != b3
+       || a4 != b4)
+     abort ();
+ }
+ 
+ int
+ main ()
+ {
+   k = i + j;
+   res.v = k;
+ 
+   verify (res.i[0], res.i[1], res.i[2], res.i[3], 160, 113, 170, 230);
+ 
+   k = i * j;
+   res.v = k;
+ 
+   verify (res.i[0], res.i[1], res.i[2], res.i[3], 1500, 1300, 3000, 6000);
+ 
+   k = i / j;
+   res.v = k;
+ 
+   verify (res.i[0], res.i[1], res.i[2], res.i[3], 15, 7, 7, 6);
+ 
+   k = -i;
+   res.v = k;
+   verify (res.i[0], res.i[1], res.i[2], res.i[3],
+ 	  -150, -100, -150, -200);
+ 
+   exit (0);
+ }
Index: testsuite/gcc.dg/simd-1.c
===================================================================
RCS file: testsuite/gcc.dg/simd-1.c
diff -N testsuite/gcc.dg/simd-1.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/simd-1.c	22 May 2002 00:42:53 -0000
***************
*** 0 ****
--- 1,61 ----
+ /* { dg-do compile } */
+ /* { dg-options "-Wall" } */
+ 
+ /* Origin: Aldy Hernandez <aldyh@redhat.com>.  */
+ /* Purpose: Program to test generic SIMD support.  */
+ 
+ typedef int __attribute__((mode(V4SI))) v4si;
+ typedef int __attribute__((mode(V8HI))) v8hi;
+ typedef int __attribute__((mode(V2SI))) v2si;
+ typedef unsigned int __attribute__((mode(V4SI))) uv4si;
+ 
+ v4si a, b;
+ v2si c, d;
+ v8hi e;
+ uv4si f;
+ 
+ int foo __attribute__((mode(DI)));
+ int foo1 __attribute__((mode(SI)));
+ int foo2 __attribute__((mode(V4HI)));
+ 
+ void
+ hanneke ()
+ {
+   /* Assignment.  */
+   a = b;
+ 
+   /* Assignment of different types.  */
+   b = c; /* { dg-error "incompatible types in assignment" } */
+   d = a; /* { dg-error "incompatible types in assignment" } */
+ 
+   /* Casting between SIMDs of the same size.  */
+   e = (typeof (e)) a;
+ 
+   /* Different signed SIMD assignment.  */
+   f = a; /* { dg-error "incompatible types in assignment" } */
+ 
+   /* Casted different signed SIMD assignment.  */
+   f = (uv4si) a;
+ 
+   /* Assignment between scalar and SIMD of different size.  */
+   foo = a; /* { dg-error "incompatible types in assignment" } */
+ 
+   /* Casted assignment between scalar and SIMD of same size.  */
+   foo = (typeof (foo)) foo2;
+ 
+   /* Casted assignment between scalar and SIMD of different size.  */
+   foo1 = (typeof (foo1)) foo2; /* { dg-error "can't convert between vector values of different size" } */
+ 
+   /* Operators on compatible SIMD types.  */
+   a += b + b;
+   a -= b;
+   a *= b;
+   a /= b;
+   a = -b;
+ 
+   /* Operators on incompatible SIMD types.  */
+   a = b + c; /* { dg-error "can't convert between vector values of different size" } */
+   a = b - c; /* { dg-error "can't convert between vector values of different size" } */
+   a = b * c; /* { dg-error "can't convert between vector values of different size" } */
+   a = b / c; /* { dg-error "can't convert between vector values of different size" } */
+ }
Index: doc/extend.texi
===================================================================
RCS file: /cvs/uberbaum/gcc/doc/extend.texi,v
retrieving revision 1.70
diff -c -p -r1.70 extend.texi
*** doc/extend.texi	11 May 2002 16:25:04 -0000	1.70
--- doc/extend.texi	22 May 2002 00:42:59 -0000
*************** A floating point value, as wide as a SI 
*** 4300,4327 ****
  A floating point value, as wide as a DI mode integer, usually 64 bits.
  @end table
  
- Not all base types or combinations are always valid; which modes can be used
- is determined by the target machine.  For example, if targetting the i386 MMX
- extensions, only @code{V8QI}, @code{V4HI} and @code{V2SI} are allowed modes.
- 
  There are no @code{V1xx} vector modes - they would be identical to the
  corresponding base mode.
  
! There is no distinction between signed and unsigned vector modes.  This
! distinction is made by the operations that perform on the vectors, not
! by the data type.
! 
! The types defined in this manner are somewhat special, they cannot be
! used with most normal C operations (i.e., a vector addition can @emph{not}
! be represented by a normal addition of two vector type variables).  You
! can declare only variables and use them in function calls and returns, as
! well as in assignments and some casts.  It is possible to cast from one
! vector type to another, provided they are of the same size (in fact, you
! can also cast vectors to and from other datatypes of the same size).
! 
! A port that supports vector operations provides a set of built-in functions
! that can be used to operate on vectors.  For example, a function to add two
! vectors and multiply the result by a third could look like this:
  
  @example
  v4si f (v4si a, v4si b, v4si c)
--- 4300,4351 ----
  A floating point value, as wide as a DI mode integer, usually 64 bits.
  @end table
  
  There are no @code{V1xx} vector modes - they would be identical to the
  corresponding base mode.
  
! Specifying a combination that is not valid for the current architecture
! will cause gcc to synthesize the instructions using a narrower mode.
! For example, if you specify a variable of type @code{V4SI} and your
! architecture does not allow for this specific SIMD type, gcc will
! produce code that uses 4 @code{SIs}.
! 
! The types defined in this manner can be used with a subset of normal C
! operations.  Currently, gcc will allow using the following operators on
! these types: @code{+, -, *, /, unary minus}@.
! 
! The operations behave like C++ @code{valarrays}.  Addition is defined as
! the addition of the corresponding elements of the operands.  For
! example, in the code below, each of the 4 elements in @var{a} will be
! added to the corresponding 4 elements in @var{b} and the resulting
! vector will be stored in @var{c}.
! 
! @example
! typedef int v4si __attribute__ ((mode(V4SI)));
! 
! v4si a, b, c;
! 
! c = a + b;
! @end example
! 
! Subtraction, multiplication, and division operate in a similar manner.
! Likewise, the result of using the unary minus operator on a vector type
! is a vector whose elements are the negative value of the corresponding
! elements in the operand.
! 
! You can declare variables and use them in function calls and returns, as
! well as in assignments and some casts.  You can specify a vector type as
! a return type for a function.  Vector types can also be used as function
! arguments.  It is possible to cast from one vector type to another,
! provided they are of the same size (in fact, you can also cast vectors
! to and from other datatypes of the same size).
! 
! You cannot operate between vectors of different lengths or different
! signness without a cast.
! 
! A port that supports hardware vector operations, usually provides a set
! of built-in functions that can be used to operate on vectors.  For
! example, a function to add two vectors and multiply the result by a
! third could look like this:
  
  @example
  v4si f (v4si a, v4si b, v4si c)
Index: simplify-rtx.c
===================================================================
RCS file: /cvs/uberbaum/gcc/simplify-rtx.c,v
retrieving revision 1.103
diff -c -p -r1.103 simplify-rtx.c
*** simplify-rtx.c	9 May 2002 12:02:28 -0000	1.103
--- simplify-rtx.c	22 May 2002 00:43:01 -0000
*************** simplify_subreg (outermode, op, innermod
*** 2238,2243 ****
--- 2238,2261 ----
    if (outermode == innermode && !byte)
      return op;
  
+   /* Simplify subregs of vector constants.  */
+   if (GET_CODE (op) == CONST_VECTOR)
+     {
+       int offset = byte / UNITS_PER_WORD;
+       rtx elt, new;
+ 
+       /* This shouldn't happen, but let's not do anything stupid.  */
+       if (GET_MODE_INNER (innermode) != outermode)
+ 	return NULL_RTX;
+ 
+       elt = CONST_VECTOR_ELT (op, offset);
+ 
+       /* ?? We probably don't need this copy_rtx because constants
+ 	 can be shared.  ?? */
+ 
+       return copy_rtx (elt);
+     }
+ 
    /* Attempt to simplify constant to non-SUBREG expression.  */
    if (CONSTANT_P (op))
      {
Index: expr.c
===================================================================
RCS file: /cvs/uberbaum/gcc/expr.c,v
retrieving revision 1.456
diff -c -p -r1.456 expr.c
*** expr.c	17 May 2002 22:46:22 -0000	1.456
--- expr.c	22 May 2002 00:43:14 -0000
*************** try_tablejump (index_type, index_expr, m
*** 10759,10761 ****
--- 10759,10793 ----
  		table_label, default_label);
    return 1;
  }
+ 
+ 
+ /* Nonzero if the mode is a valid vector mode for this architecture.
+    This returns nonzero even if there is no hardware support for the
+    vector mode, but we can emulate with narrower modes.  */
+ 
+ int
+ vector_mode_valid_p (mode)
+      enum machine_mode mode;
+ {
+   enum mode_class class = GET_MODE_CLASS (mode);
+   enum machine_mode innermode;
+ 
+   /* Doh!  What's going on?  */
+   if (class != MODE_VECTOR_INT
+       && class != MODE_VECTOR_FLOAT)
+     return 0;
+ 
+   /* Hardware support.  Woo hoo!  */
+   if (VECTOR_MODE_SUPPORTED_P (mode))
+     return 1;
+ 
+   innermode = GET_MODE_INNER (mode);
+ 
+   /* We should probably return 1 if requesting V4DI and we have no DI,
+      but we have V2DI, but this is probably very unlikely.  */
+ 
+   /* If we have support for the inner mode, we can safely emulate it.
+      We may not have V2DI, but me can emulate with a pair of DIs.  */
+   return mov_optab->handlers[innermode].insn_code != CODE_FOR_nothing;
+ }
+ 
Index: expr.h
===================================================================
RCS file: /cvs/uberbaum/gcc/expr.h,v
retrieving revision 1.113
diff -c -p -r1.113 expr.h
*** expr.h	31 Mar 2002 09:52:33 -0000	1.113
--- expr.h	22 May 2002 00:43:14 -0000
*************** extern void do_jump_by_parts_greater_rtx
*** 789,791 ****
--- 789,793 ----
  extern void mark_seen_cases			PARAMS ((tree, unsigned char *,
  							 HOST_WIDE_INT, int));
  #endif
+ 
+ extern int vector_mode_valid_p		PARAMS ((enum machine_mode));
Index: defaults.h
===================================================================
RCS file: /cvs/uberbaum/gcc/defaults.h,v
retrieving revision 1.75
diff -c -p -r1.75 defaults.h
*** defaults.h	17 May 2002 23:25:19 -0000	1.75
--- defaults.h	22 May 2002 00:43:15 -0000
*************** You Lose!  You must define PREFERRED_DEB
*** 503,506 ****
--- 503,510 ----
  #define UNLIKELY_EXECUTED_TEXT_SECTION_NAME "text.unlikely"
  #endif
  
+ #ifndef VECTOR_MODE_SUPPORTED_P
+ #define VECTOR_MODE_SUPPORTED_P(MODE) 0
+ #endif
+ 
  #endif  /* ! GCC_DEFAULTS_H */
Index: c-common.c
===================================================================
RCS file: /cvs/uberbaum/gcc/c-common.c,v
retrieving revision 1.327
diff -c -p -r1.327 c-common.c
*** c-common.c	19 May 2002 21:53:52 -0000	1.327
--- c-common.c	22 May 2002 00:43:18 -0000
*************** c_common_type_for_mode (mode, unsignedp)
*** 1573,1610 ****
    if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
      return build_pointer_type (integer_type_node);
  
! #ifdef VECTOR_MODE_SUPPORTED_P
!   if (VECTOR_MODE_SUPPORTED_P (mode))
      {
!       switch (mode)
! 	{
! 	case V16QImode:
! 	  return unsignedp ? unsigned_V16QI_type_node : V16QI_type_node;
! 	case V8HImode:
! 	  return unsignedp ? unsigned_V8HI_type_node : V8HI_type_node;
! 	case V4SImode:
! 	  return unsignedp ? unsigned_V4SI_type_node : V4SI_type_node;
! 	case V2DImode:
! 	  return unsignedp ? unsigned_V2DI_type_node : V2DI_type_node;
! 	case V2SImode:
! 	  return unsignedp ? unsigned_V2SI_type_node : V2SI_type_node;
! 	case V4HImode:
! 	  return unsignedp ? unsigned_V4HI_type_node : V4HI_type_node;
! 	case V8QImode:
! 	  return unsignedp ? unsigned_V8QI_type_node : V8QI_type_node;
! 	case V16SFmode:
! 	  return V16SF_type_node;
! 	case V4SFmode:
! 	  return V4SF_type_node;
! 	case V2SFmode:
! 	  return V2SF_type_node;
! 	case V2DFmode:
! 	  return V2DF_type_node;
! 	default:
! 	  break;
! 	}
      }
- #endif
  
    return 0;
  }
--- 1573,1605 ----
    if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
      return build_pointer_type (integer_type_node);
  
!   switch (mode)
      {
!     case V16QImode:
!       return unsignedp ? unsigned_V16QI_type_node : V16QI_type_node;
!     case V8HImode:
!       return unsignedp ? unsigned_V8HI_type_node : V8HI_type_node;
!     case V4SImode:
!       return unsignedp ? unsigned_V4SI_type_node : V4SI_type_node;
!     case V2DImode:
!       return unsignedp ? unsigned_V2DI_type_node : V2DI_type_node;
!     case V2SImode:
!       return unsignedp ? unsigned_V2SI_type_node : V2SI_type_node;
!     case V4HImode:
!       return unsignedp ? unsigned_V4HI_type_node : V4HI_type_node;
!     case V8QImode:
!       return unsignedp ? unsigned_V8QI_type_node : V8QI_type_node;
!     case V16SFmode:
!       return V16SF_type_node;
!     case V4SFmode:
!       return V4SF_type_node;
!     case V2SFmode:
!       return V2SF_type_node;
!     case V2DFmode:
!       return V2DF_type_node;
!     default:
!       break;
      }
  
    return 0;
  }
*************** handle_mode_attribute (node, name, args,
*** 4988,4995 ****
  		     (mode, TREE_UNSIGNED (type))))
  	error ("no data type for mode `%s'", p);
        else
! 	*node = typefm;
!         /* No need to layout the type here.  The caller should do this.  */
      }
  
    return NULL_TREE;
--- 4983,5003 ----
  		     (mode, TREE_UNSIGNED (type))))
  	error ("no data type for mode `%s'", p);
        else
! 	{
! 	  /* If this is a vector, make sure we either have hardware
! 	     support, or we can emulate it.  */
! 	  if ((GET_MODE_CLASS (mode) == MODE_VECTOR_INT
! 	       || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
! 	      && !vector_mode_valid_p (mode))
! 	    {
! 	      error ("architecture does not support `%s' and I am unable to emulate it",
! 		     GET_MODE_NAME (mode));
! 	      return NULL_TREE;
! 	    }
! 
! 	  *node = typefm;
! 	  /* No need to layout the type here.  The caller should do this.  */
! 	}
      }
  
    return NULL_TREE;
*************** handle_vector_size_attribute (node, name
*** 5533,5538 ****
--- 5541,5557 ----
  	}
  
        new_type = build_type_copy (new_type);
+ 
+       /* If this is a vector, make sure we either have hardware
+          support, or we can emulate it.  */
+       if ((GET_MODE_CLASS (mode) == MODE_VECTOR_INT
+ 	   || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
+ 	  && !vector_mode_valid_p (mode))
+ 	{
+ 	  error ("architecture does not support `%s' and I am unable to emulate it",
+ 		 GET_MODE_NAME (mode));
+ 	  return NULL_TREE;
+ 	}
  
        /* Set the debug information here, because this is the only
  	 place where we know the underlying type for a vector made
Index: optabs.c
===================================================================
RCS file: /cvs/uberbaum/gcc/optabs.c,v
retrieving revision 1.132
diff -c -p -r1.132 optabs.c
*** optabs.c	20 May 2002 08:30:03 -0000	1.132
--- optabs.c	22 May 2002 00:43:21 -0000
*************** expand_binop (mode, binoptab, op0, op1, 
*** 1503,1508 ****
--- 1503,1565 ----
        delete_insns_since (last);
      }
  
+   /* Open-code the vector operations if we have no hardware support
+      for them.  */
+   if (class == MODE_VECTOR_INT || class == MODE_VECTOR_FLOAT)
+     {
+       enum machine_mode submode;
+       int elts, i;
+       rtx t, a, b, res, seq;
+ 
+       submode = GET_MODE_INNER (mode);
+       elts = GET_MODE_NUNITS (mode);
+ 
+       if (!target)
+ 	target = gen_reg_rtx (mode);
+ 
+       start_sequence ();
+ 
+       /* FIXME: Optimally, we should try to do this in narrower vector
+          modes if available.  E.g. When trying V8SI, try V4SI, else
+          V2SI, else cascade to SI.  */
+ 
+       switch (binoptab->code)
+ 	{
+ 	case PLUS:
+ 	case MINUS:
+ 	case MULT:
+ 	case DIV:
+ 	  for (i = 0; i < elts; ++i)
+ 	    {
+ 	      t = simplify_gen_subreg (submode, target, mode,
+ 				       i * UNITS_PER_WORD);
+ 	      a = simplify_gen_subreg (submode, op0, mode,
+ 				       i * UNITS_PER_WORD);
+ 	      b = simplify_gen_subreg (submode, op1, mode,
+ 				       i * UNITS_PER_WORD);
+ 
+ 	      res = expand_binop (submode, binoptab, a, b, t,
+ 				  unsignedp, methods);
+ 
+ 	      if (res == 0)
+ 		break;
+ 
+ 	      emit_move_insn (t, res);
+ 	    }
+ 	  break;
+ 
+ 	default:
+ 	  abort ();
+ 	}
+ 
+       seq = get_insns ();
+       end_sequence ();
+ 
+       emit_no_conflict_block (seq, target, op0, op1, NULL);
+ 
+       return target;
+     }
+ 
    /* We need to open-code the complex type operations: '+, -, * and /' */
  
    /* At this point we allow operations between two similar complex
*************** expand_unop (mode, unoptab, op0, target,
*** 2296,2301 ****
--- 2353,2394 ----
        return target;
      }
  
+   if (class == MODE_VECTOR_FLOAT || class == MODE_VECTOR_INT)
+     {
+       enum machine_mode submode;
+       int elts, i;
+       rtx t, a, res, seq;
+ 
+       submode = GET_MODE_INNER (mode);
+       elts = GET_MODE_NUNITS (mode);
+ 
+       if (!target)
+ 	target = gen_reg_rtx (mode);
+ 
+       start_sequence ();
+ 
+       /* FIXME: Optimally, we should try to do this in narrower vector
+          modes if available.  E.g. When trying V8SI, try V4SI, else
+          V2SI, else cascade to SI.  */
+ 
+       for (i = 0; i < elts; ++i)
+ 	{
+ 	  t = simplify_gen_subreg (submode, target, mode, i * UNITS_PER_WORD);
+ 	  a = simplify_gen_subreg (submode, op0, mode, i * UNITS_PER_WORD);
+ 
+ 	  res = expand_unop (submode, unoptab, a, t, unsignedp);
+ 
+ 	  emit_move_insn (t, res);
+ 	}
+ 
+       seq = get_insns ();
+       end_sequence ();
+ 
+       emit_no_conflict_block (seq, target, op0, 0, NULL);
+ 
+       return target;
+     }
+ 
    /* It can't be done in this mode.  Can we do it in a wider mode?  */
  
    if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
*************** emit_no_conflict_block (insns, target, o
*** 2747,2753 ****
  {
    rtx prev, next, first, last, insn;
  
!   if (GET_CODE (target) != REG || reload_in_progress)
      return emit_insns (insns);
    else
      for (insn = insns; insn; insn = NEXT_INSN (insn))
--- 2840,2855 ----
  {
    rtx prev, next, first, last, insn;
  
!   if (GET_CODE (target) != REG
!       /* ?? I'm not sure whether this is right.  This is the path we
!   	    take on synthetic complex types because the target is a
!   	    CONCAT of register, not a register per se.  However, for
!   	    synthetic vector types, we don't have a CONCAT, but an
!   	    entire pseudo.  Get out here to avoid removing needed
!   	    instructions.
!          ?? */
!       || vector_mode_valid_p (GET_MODE (target))
!       || reload_in_progress)
      return emit_insns (insns);
    else
      for (insn = insns; insn; insn = NEXT_INSN (insn))
Index: c-typeck.c
===================================================================
RCS file: /cvs/uberbaum/gcc/c-typeck.c,v
retrieving revision 1.194
diff -c -p -r1.194 c-typeck.c
*** c-typeck.c	26 Apr 2002 21:56:55 -0000	1.194
--- c-typeck.c	22 May 2002 00:43:25 -0000
*************** build_binary_op (code, orig_op0, orig_op
*** 2047,2055 ****
  	warning ("division by zero");
  
        if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
! 	   || code0 == COMPLEX_TYPE)
  	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
! 	      || code1 == COMPLEX_TYPE))
  	{
  	  if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
  	    resultcode = RDIV_EXPR;
--- 2047,2055 ----
  	warning ("division by zero");
  
        if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
! 	   || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
  	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
! 	      || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
  	{
  	  if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
  	    resultcode = RDIV_EXPR;
*************** build_binary_op (code, orig_op0, orig_op
*** 2198,2206 ****
  	 but don't convert the args to int!  */
        build_type = integer_type_node;
        if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
! 	   || code0 == COMPLEX_TYPE)
  	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
! 	      || code1 == COMPLEX_TYPE))
  	short_compare = 1;
        else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
  	{
--- 2198,2208 ----
  	 but don't convert the args to int!  */
        build_type = integer_type_node;
        if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
! 	   || code0 == COMPLEX_TYPE
! 	   || code0 == VECTOR_TYPE)
  	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
! 	      || code1 == COMPLEX_TYPE
! 	      || code1 == VECTOR_TYPE))
  	short_compare = 1;
        else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
  	{
*************** build_binary_op (code, orig_op0, orig_op
*** 2343,2351 ****
        break;
      }
  
!   if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
        &&
!       (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
      {
        int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
  
--- 2345,2355 ----
        break;
      }
  
!   if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
!        || code0 == VECTOR_TYPE)
        &&
!       (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE
!        || code1 == VECTOR_TYPE))
      {
        int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
  
*************** build_unary_op (code, xarg, flag)
*** 2764,2770 ****
  
      case NEGATE_EXPR:
        if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
! 	    || typecode == COMPLEX_TYPE))
  	{
  	  error ("wrong type argument to unary minus");
  	  return error_mark_node;
--- 2768,2775 ----
  
      case NEGATE_EXPR:
        if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
! 	    || typecode == COMPLEX_TYPE
! 	    || typecode == VECTOR_TYPE))
  	{
  	  error ("wrong type argument to unary minus");
  	  return error_mark_node;
*************** convert_for_assignment (type, rhs, errty
*** 4080,4086 ****
    else if ((codel == INTEGER_TYPE || codel == REAL_TYPE 
  	    || codel == ENUMERAL_TYPE || codel == COMPLEX_TYPE
  	    || codel == BOOLEAN_TYPE)
! 	   && (coder == INTEGER_TYPE || coder == REAL_TYPE 
  	       || coder == ENUMERAL_TYPE || coder == COMPLEX_TYPE
  	       || coder == BOOLEAN_TYPE))
      return convert_and_check (type, rhs);
--- 4085,4091 ----
    else if ((codel == INTEGER_TYPE || codel == REAL_TYPE 
  	    || codel == ENUMERAL_TYPE || codel == COMPLEX_TYPE
  	    || codel == BOOLEAN_TYPE)
! 	   && (coder == INTEGER_TYPE || coder == REAL_TYPE
  	       || coder == ENUMERAL_TYPE || coder == COMPLEX_TYPE
  	       || coder == BOOLEAN_TYPE))
      return convert_and_check (type, rhs);


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