This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch] generic simd support
- From: Aldy Hernandez <aldyh at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>, gcc-patches at gcc dot gnu dot org, gcc at gcc dot gnu dot org, gdb at sources dot redhat dot com
- Date: Sun, 16 Jun 2002 19:10:00 +1000
- Subject: Re: [patch] generic simd support
- References: <20020522004429.GA26426@redhat.com> <20020530154256.F5362@redhat.com>
hi richard.
sorry i took so long. i wanted to do some more testing of the patch,
but got sidetracked by that day job of mine.
> > ! error ("architecture does not support `%s' and I am unable to emulate it",
>
> Better just "unable to emulate %s".
done.
> > + /* Open-code the vector operations if we have no hardware support
> > + for them. */
>
> This function is way too big already. Please move your code
> out into a subroutine.
done.
> > ! /* ?? 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)
>
> Maybe you should just avoid the no-conflict block entirely?
done.
i also found a buglet on darwin because they have TARGET_ALTIVEC_ABI turned on
always, so the port was insisting on using v2-v13 to pass arguments
even when there was no -maltivec ;-). fixed this by conditionalizing
ALTIVEC_VECTOR_MODE on TARGET_ALTIVEC as well.
> Otherwise it looks reasonable.
you said it was ok before, but since i took so long to revise the patch
i'd like a nod before i commit.
bootstrapped and regtested on powerpc-unknown-linux-gnu
bootstrapped and regtested on i686-pc-linux-gnu
(...but, there was a comparison failure with and without my patch
on x86)
regtested on darwin.
ok?
aldy
2002-06-16 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.
(expand_vector_binop): New.
(expand_vector_unop): New.
* c-typeck.c (build_binary_op): Allow vectors in binops.
Allow vectors in conditional operatiors.
(build_unary_op): Allow vectors in unary minus.
* config/rs6000/rs6000.h (ALTIVEC_VECTOR_MODE): Conditionalize on
TARGET_ALTIVEC.
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 16 Jun 2002 09:01:44 -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 16 Jun 2002 09:01:44 -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.80
diff -c -p -r1.80 extend.texi
*** doc/extend.texi 12 Jun 2002 02:56:59 -0000 1.80
--- doc/extend.texi 16 Jun 2002 09:01:50 -0000
*************** A floating point value, as wide as a SI
*** 4373,4400 ****
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)
--- 4373,4424 ----
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.106
diff -c -p -r1.106 simplify-rtx.c
*** simplify-rtx.c 10 Jun 2002 22:29:14 -0000 1.106
--- simplify-rtx.c 16 Jun 2002 09:01:51 -0000
*************** simplify_subreg (outermode, op, innermod
*** 2268,2273 ****
--- 2268,2291 ----
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;
+
+ /* 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.466
diff -c -p -r1.466 expr.c
*** expr.c 15 Jun 2002 20:21:22 -0000 1.466
--- expr.c 16 Jun 2002 09:01:58 -0000
*************** try_tablejump (index_type, index_expr, m
*** 10791,10794 ****
--- 10791,10824 ----
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;
+ }
+
#include "gt-expr.h"
Index: expr.h
===================================================================
RCS file: /cvs/uberbaum/gcc/expr.h,v
retrieving revision 1.116
diff -c -p -r1.116 expr.h
*** expr.h 4 Jun 2002 07:07:36 -0000 1.116
--- expr.h 16 Jun 2002 09:01:59 -0000
*************** extern void do_jump_by_parts_greater_rtx
*** 786,788 ****
--- 786,790 ----
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.79
diff -c -p -r1.79 defaults.h
*** defaults.h 14 Jun 2002 00:50:30 -0000 1.79
--- defaults.h 16 Jun 2002 09:01:59 -0000
*************** You Lose! You must define PREFERRED_DEB
*** 513,518 ****
--- 513,522 ----
#define UNLIKELY_EXECUTED_TEXT_SECTION_NAME "text.unlikely"
#endif
+ #ifndef VECTOR_MODE_SUPPORTED_P
+ #define VECTOR_MODE_SUPPORTED_P(MODE) 0
+ #endif
+
/* Determine whether __cxa_atexit, rather than atexit, is used to
register C++ destructors for local statics and global objects. */
#ifndef DEFAULT_USE_CXA_ATEXIT
Index: c-common.c
===================================================================
RCS file: /cvs/uberbaum/gcc/c-common.c,v
retrieving revision 1.342
diff -c -p -r1.342 c-common.c
*** c-common.c 12 Jun 2002 03:06:09 -0000 1.342
--- c-common.c 16 Jun 2002 09:02:03 -0000
*************** c_common_type_for_mode (mode, unsignedp)
*** 1599,1636 ****
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;
}
--- 1599,1631 ----
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,
*** 5055,5062 ****
(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;
--- 5050,5069 ----
(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 ("unable to emulate '%s'", 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
*** 5600,5605 ****
--- 5607,5622 ----
}
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 ("unable to emulate '%s'", 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.136
diff -c -p -r1.136 optabs.c
*** optabs.c 11 Jun 2002 12:21:45 -0000 1.136
--- optabs.c 16 Jun 2002 09:02:05 -0000
*************** static void emit_cmp_and_jump_insn_1 PAR
*** 120,125 ****
--- 120,130 ----
enum rtx_code, int, rtx));
static void prepare_float_lib_cmp PARAMS ((rtx *, rtx *, enum rtx_code *,
enum machine_mode *, int *));
+ static rtx expand_vector_binop PARAMS ((enum machine_mode, optab,
+ rtx, rtx, rtx, int,
+ enum optab_methods));
+ static rtx expand_vector_unop PARAMS ((enum machine_mode, optab, rtx, rtx,
+ int));
/* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
the result of operation CODE applied to OP0 (and OP1 if it is a binary
*************** expand_binop (mode, binoptab, op0, op1,
*** 1531,1536 ****
--- 1536,1547 ----
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)
+ return expand_vector_binop (mode, binoptab, op0, op1, target,
+ unsignedp, methods);
+
/* We need to open-code the complex type operations: '+, -, * and /' */
/* At this point we allow operations between two similar complex
*************** expand_binop (mode, binoptab, op0, op1,
*** 1900,1905 ****
--- 1911,2022 ----
delete_insns_since (entry_last);
return 0;
}
+
+ /* Like expand_binop, but for open-coding vectors binops. */
+
+ static rtx
+ expand_vector_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
+ enum machine_mode mode;
+ optab binoptab;
+ rtx op0, op1;
+ rtx target;
+ int unsignedp;
+ enum optab_methods methods;
+ {
+ 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 decay into 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_insn (seq);
+
+ return target;
+ }
+
+ /* Like expand_unop but for open-coding vector unops. */
+
+ static rtx
+ expand_vector_unop (mode, unoptab, op0, target, unsignedp)
+ enum machine_mode mode;
+ optab unoptab;
+ rtx op0;
+ rtx target;
+ int unsignedp;
+ {
+ 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 decay into 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_insn (seq);
+
+ return target;
+ }
/* Expand a binary operator which has both signed and unsigned forms.
UOPTAB is the optab for unsigned operations, and SOPTAB is for
*************** expand_unop (mode, unoptab, op0, target,
*** 2323,2328 ****
--- 2440,2448 ----
return target;
}
+
+ if (class == MODE_VECTOR_FLOAT || class == MODE_VECTOR_INT)
+ return expand_vector_unop (mode, unoptab, op0, target, unsignedp);
/* It can't be done in this mode. Can we do it in a wider mode? */
Index: c-typeck.c
===================================================================
RCS file: /cvs/uberbaum/gcc/c-typeck.c,v
retrieving revision 1.195
diff -c -p -r1.195 c-typeck.c
*** c-typeck.c 23 May 2002 15:47:58 -0000 1.195
--- c-typeck.c 16 Jun 2002 09:02:10 -0000
*************** build_binary_op (code, orig_op0, orig_op
*** 2046,2054 ****
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;
--- 2046,2054 ----
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
*** 2197,2205 ****
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)
{
--- 2197,2207 ----
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
*** 2342,2350 ****
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);
--- 2344,2354 ----
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)
*** 2763,2769 ****
case NEGATE_EXPR:
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
! || typecode == COMPLEX_TYPE))
{
error ("wrong type argument to unary minus");
return error_mark_node;
--- 2767,2774 ----
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
*** 4079,4085 ****
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);
--- 4084,4090 ----
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: config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.209
diff -c -p -r1.209 rs6000.h
*** config/rs6000/rs6000.h 11 Jun 2002 23:14:47 -0000 1.209
--- config/rs6000/rs6000.h 16 Jun 2002 09:02:12 -0000
*************** extern int rs6000_default_long_calls;
*** 817,826 ****
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
#define ALTIVEC_VECTOR_MODE(MODE) \
! ((MODE) == V16QImode \
! || (MODE) == V8HImode \
! || (MODE) == V4SFmode \
! || (MODE) == V4SImode)
/* Define this macro to be nonzero if the port is prepared to handle
insns involving vector mode MODE. At the very least, it must have
--- 817,827 ----
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
#define ALTIVEC_VECTOR_MODE(MODE) \
! (TARGET_ALTIVEC && \
! ((MODE) == V16QImode \
! || (MODE) == V8HImode \
! || (MODE) == V4SFmode \
! || (MODE) == V4SImode))
/* Define this macro to be nonzero if the port is prepared to handle
insns involving vector mode MODE. At the very least, it must have