c-common.c (c_common_type_for_mode): Build vector types on demand.

gcc/ChangeLog
2004-03-16  Paolo Bonzini  <bonzini@gnu.org>

	* c-common.c (c_common_type_for_mode): Build vector types on
	demand.
	(handle_mode_attribute): Deprecate using the mode attribute
	to create vector types.  Fix indentation.
	(vector_type_node_list): Remove.
	(handle_vector_size_attribute): Create vector types on demand.
	Strip a NON_LVALUE_EXPR from the attribute if there is one.
	* c-typeck.c (comptypes): Make vector types compatible if they
	have the same underlying mode.
	(convert_for_assignment): Use comptypes to convert between
	vector types.
	* tree.c (build_common_tree_nodes_2): Do not create vector types.
	* config/arm/arm.c (arm_init_iwmmxt_builtins): Create necessary
	vector types.
	* tree.h: Remove vector types.
	* config/i386/i386.c (i386_init_mmx_sse_builtins): Likewise.
	* config/rs6000/rs6000.c (rs6000_init_builtins): Likewise.
	(V16QI_type_node, V2SI_type_node, V2SF_type_node, V4HI_type_node,
	V4SI_type_node, V4SF_type_node, V8HI_type_node): New globals.
	* doc/extend.texi (Vector Types): Document how to use the
	vector_size attribute to create vectors, rather than mode.

	* config/arm/mmintrin.h: Use vector_size attribute, not mode.
	* config/i386/emmintrin.h: Likewise.
	* config/i386/mmintrin.h: Likewise.
	* config/i386/xmmintrin.h: Likewise.
	* config/sh/ushmedia.h: Likwise.

testsuite/ChangeLog
2004-03-16  Paolo Bonzini  <bonzini@gnu.org>

	* g++.dg/eh/simd-1.C: Use vector_size attribute, not mode.
	* g++.dg/eh/simd-2.C: Likewise.
	* g++.dg/init/array10.C: Likewise.
	* gcc.c-torture/compile/simd-1.c: Likewise.
	* gcc.c-torture/compile/simd-2.c: Likewise.
	* gcc.c-torture/compile/simd-3.c: Likewise.
	* gcc.c-torture/compile/simd-4.c: Likewise.
	* gcc.c-torture/compile/simd-6.c: Likewise.
	* gcc.c-torture/execute/simd-1.c: Likewise.
	* gcc.c-torture/execute/simd-2.c: Likewise.
	* gcc.dg/compat/vector-defs.h: Likewise.
	* gcc.dg/20020531-1.c: Likewise.
	* gcc.dg/altivec-3.c: Likewise.
	* gcc.dg/altivec-4.c: Likewise.
	* gcc.dg/altivec-varargs-1.c: Likewise.
	* testsuite/gcc.dg/compat/vector-defs.h: Likewise.
	* gcc.dg/i386-mmx-3.c: Likewise.
	* gcc.dg/i386-sse-4.c: Likewise.
	* gcc.dg/i386-sse-5.c: Likewise.
	* gcc.dg/i386-sse-8.c: Likewise.
	* gcc.dg/simd-1.c: Likewise.
	* gcc.dg/20030218-1.c: Likewise.  Plus, do not declare
	__ev64_opaque__ since the machine description provides it.

Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.487
diff -u -r1.487 c-common.c
--- c-common.c	26 Feb 2004 01:24:37 -0000	1.487
+++ c-common.c	10 Mar 2004 10:25:28 -0000
@@ -1874,38 +1874,12 @@
   if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
     return unsignedp ? make_unsigned_type (mode) : make_signed_type (mode);

-  switch (mode)
+  if (VECTOR_MODE_P (mode))
     {
-    case V16QImode:

From-SVN: r79544
This commit is contained in:
Paolo Bonzini 2004-03-16 20:37:31 +00:00 committed by Paolo Bonzini
parent 7de53bcaa3
commit 4a5eab38a4
36 changed files with 275 additions and 310 deletions

View File

@ -1,3 +1,33 @@
2004-03-16 Paolo Bonzini <bonzini@gnu.org>
* c-common.c (c_common_type_for_mode): Build vector types on
demand.
(handle_mode_attribute): Deprecate using the mode attribute
to create vector types. Fix indentation.
(vector_type_node_list): Remove.
(handle_vector_size_attribute): Create vector types on demand.
Strip a NON_LVALUE_EXPR from the attribute if there is one.
* c-typeck.c (comptypes): Make vector types compatible if they
have the same underlying mode.
(convert_for_assignment): Use comptypes to convert between
vector types.
* tree.c (build_common_tree_nodes_2): Do not create vector types.
* config/arm/arm.c (arm_init_iwmmxt_builtins): Create necessary
vector types.
* tree.h: Remove vector types.
* config/i386/i386.c (i386_init_mmx_sse_builtins): Likewise.
* config/rs6000/rs6000.c (rs6000_init_builtins): Likewise.
(V16QI_type_node, V2SI_type_node, V2SF_type_node, V4HI_type_node,
V4SI_type_node, V4SF_type_node, V8HI_type_node): New globals.
* doc/extend.texi (Vector Types): Document how to use the
vector_size attribute to create vectors, rather than mode.
* config/arm/mmintrin.h: Use vector_size attribute, not mode.
* config/i386/emmintrin.h: Likewise.
* config/i386/mmintrin.h: Likewise.
* config/i386/xmmintrin.h: Likewise.
* config/sh/ushmedia.h: Likewise.
2004-03-16 Kazu Hirata <kazu@cs.umass.edu>
* config/freebsd-spec.h, config/arc/arc-protos.h,

View File

@ -1874,38 +1874,12 @@ c_common_type_for_mode (enum machine_mode mode, int unsignedp)
if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
return unsignedp ? make_unsigned_type (mode) : make_signed_type (mode);
switch (mode)
if (VECTOR_MODE_P (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 V2HImode:
return unsignedp ? unsigned_V2HI_type_node : V2HI_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 V1DImode:
return unsignedp ? unsigned_V1DI_type_node : V1DI_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;
case V4DFmode:
return V4DF_type_node;
default:
break;
enum machine_mode inner_mode = GET_MODE_INNER (mode);
tree inner_type = c_common_type_for_mode (inner_mode, unsignedp);
if (inner_type != NULL_TREE)
return build_vector_type_for_mode (inner_type, mode);
}
for (t = registered_builtin_types; t; t = TREE_CHAIN (t))
@ -4628,10 +4602,22 @@ handle_mode_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
mode = (enum machine_mode) j;
if (mode == VOIDmode)
error ("unknown machine mode `%s'", p);
else if (0 == (typefm = lang_hooks.types.type_for_mode
(mode, TREE_UNSIGNED (type))))
{
error ("unknown machine mode `%s'", p);
return NULL_TREE;
}
if (VECTOR_MODE_P (mode))
{
warning ("specifying vector types with __attribute__ ((mode)) "
"is deprecated");
warning ("use __attribute__ ((vector_size)) instead");
}
typefm = lang_hooks.types.type_for_mode (mode, TREE_UNSIGNED (type));
if (typefm == NULL_TREE)
error ("no data type for mode `%s'", p);
else if ((TREE_CODE (type) == POINTER_TYPE
|| TREE_CODE (type) == REFERENCE_TYPE)
&& !(*targetm.valid_pointer_mode) (mode))
@ -4659,7 +4645,7 @@ handle_mode_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
*node = ptr_type;
}
else
*node = typefm;
*node = typefm;
/* No need to layout the type here. The caller should do this. */
}
}
@ -5090,13 +5076,6 @@ handle_deprecated_attribute (tree *node, tree name,
return NULL_TREE;
}
/* Keep a list of vector type nodes we created in handle_vector_size_attribute,
to prevent us from duplicating type nodes unnecessarily.
The normal mechanism to prevent duplicates is to use type_hash_canon, but
since we want to distinguish types that are essentially identical (except
for their debug representation), we use a local list here. */
static GTY(()) tree vector_type_node_list = 0;
/* Handle a "vector_size" attribute; arguments as in
struct attribute_spec.handler. */
@ -5107,19 +5086,24 @@ handle_vector_size_attribute (tree *node, tree name, tree args,
{
unsigned HOST_WIDE_INT vecsize, nunits;
enum machine_mode mode, orig_mode, new_mode;
tree type = *node, new_type = NULL_TREE;
tree type_list_node;
tree type = *node, new_type, size;
*no_add_attrs = true;
if (! host_integerp (TREE_VALUE (args), 1))
/* Stripping NON_LVALUE_EXPR allows declarations such as
typedef short v4si __attribute__((vector_size (4 * sizeof(short)))). */
size = TREE_VALUE (args);
if (TREE_CODE (size) == NON_LVALUE_EXPR)
size = TREE_OPERAND (size, 0);
if (! host_integerp (size, 1))
{
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
return NULL_TREE;
}
/* Get the vector size (in bytes). */
vecsize = tree_low_cst (TREE_VALUE (args), 1);
vecsize = tree_low_cst (size, 1);
/* We need to provide for vector pointers, vector arrays, and
functions returning vectors. For example:
@ -5165,73 +5149,13 @@ handle_vector_size_attribute (tree *node, tree name, tree args,
break;
}
if (new_mode == VOIDmode)
if (new_mode == VOIDmode)
{
error ("no vector mode with the size and type specified could be found");
return NULL_TREE;
}
for (type_list_node = vector_type_node_list; type_list_node;
type_list_node = TREE_CHAIN (type_list_node))
{
tree other_type = TREE_VALUE (type_list_node);
tree record = TYPE_DEBUG_REPRESENTATION_TYPE (other_type);
tree fields = TYPE_FIELDS (record);
tree field_type = TREE_TYPE (fields);
tree array_type = TREE_TYPE (field_type);
if (TREE_CODE (fields) != FIELD_DECL
|| TREE_CODE (field_type) != ARRAY_TYPE)
abort ();
if (TYPE_MODE (other_type) == mode && type == array_type)
{
new_type = other_type;
break;
}
}
if (new_type == NULL_TREE)
{
tree index, array, rt, list_node;
new_type = lang_hooks.types.type_for_mode (new_mode,
TREE_UNSIGNED (type));
if (!new_type)
{
error ("no vector mode with the size and type specified could be found");
return NULL_TREE;
}
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
with vector_size. For debugging purposes we pretend a vector
is an array within a structure. */
index = build_int_2 (TYPE_VECTOR_SUBPARTS (new_type) - 1, 0);
array = build_array_type (type, build_index_type (index));
rt = make_node (RECORD_TYPE);
TYPE_FIELDS (rt) = build_decl (FIELD_DECL, get_identifier ("f"), array);
DECL_CONTEXT (TYPE_FIELDS (rt)) = rt;
layout_type (rt);
TYPE_DEBUG_REPRESENTATION_TYPE (new_type) = rt;
list_node = build_tree_list (NULL, new_type);
TREE_CHAIN (list_node) = vector_type_node_list;
vector_type_node_list = list_node;
}
new_type = build_vector_type_for_mode (type, new_mode);
/* Build back pointers if needed. */
*node = reconstruct_complex_type (*node, new_type);

View File

@ -578,7 +578,8 @@ comptypes (tree type1, tree type2, int flags)
case VECTOR_TYPE:
/* The target might allow certain vector types to be compatible. */
val = (*targetm.vector_opaque_p) (t1)
|| (*targetm.vector_opaque_p) (t2);
|| (*targetm.vector_opaque_p) (t2)
|| TYPE_MODE (t1) == TYPE_MODE (t2);
break;
default:
@ -3277,9 +3278,8 @@ convert_for_assignment (tree type, tree rhs, const char *errtype,
return rhs;
}
/* Some types can interconvert without explicit casts. */
else if (codel == VECTOR_TYPE && coder == VECTOR_TYPE
&& ((*targetm.vector_opaque_p) (type)
|| (*targetm.vector_opaque_p) (rhstype)))
else if (codel == VECTOR_TYPE
&& comptypes (type, TREE_TYPE (rhs), COMPARE_STRICT) == 1)
return convert (type, rhs);
/* Arithmetic types all interconvert, and enum is treated like int. */
else if ((codel == INTEGER_TYPE || codel == REAL_TYPE

View File

@ -11519,6 +11519,10 @@ arm_init_iwmmxt_builtins (void)
size_t i;
tree endlink = void_list_node;
tree V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
tree V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
tree V8QI_type_node = build_vector_type_for_mode (intQI_type_node, V8QImode);
tree int_ftype_int
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, integer_type_node, endlink));

View File

@ -31,9 +31,9 @@
typedef unsigned long long __m64, __int64;
/* Internal data types for implementing the intrinsics. */
typedef int __v2si __attribute__ ((__mode__ (__V2SI__)));
typedef int __v4hi __attribute__ ((__mode__ (__V4HI__)));
typedef int __v8qi __attribute__ ((__mode__ (__V8QI__)));
typedef int __v2si __attribute__ ((vector_size (8)));
typedef short __v4hi __attribute__ ((vector_size (8)));
typedef char __v8qi __attribute__ ((vector_size (8)));
/* "Convert" __m64 and __int64 into each other. */
static __inline __m64

View File

@ -34,11 +34,11 @@
#include <xmmintrin.h>
/* SSE2 */
typedef int __v2df __attribute__ ((mode (V2DF)));
typedef int __v2di __attribute__ ((mode (V2DI)));
typedef int __v4si __attribute__ ((mode (V4SI)));
typedef int __v8hi __attribute__ ((mode (V8HI)));
typedef int __v16qi __attribute__ ((mode (V16QI)));
typedef double __v2df __attribute__ ((vector_size (16)));
typedef long long __v2di __attribute__ ((vector_size (16)));
typedef int __v4si __attribute__ ((vector_size (16)));
typedef short __v8hi __attribute__ ((vector_size (16)));
typedef char __v16qi __attribute__ ((vector_size (16)));
/* Create a selector for use with the SHUFPD instruction. */
#define _MM_SHUFFLE2(fp1,fp0) \

View File

@ -12932,6 +12932,17 @@ ix86_init_mmx_sse_builtins (void)
const struct builtin_description * d;
size_t i;
tree V16QI_type_node = build_vector_type_for_mode (intQI_type_node, V16QImode);
tree V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
tree V2SF_type_node = build_vector_type_for_mode (float_type_node, V2SFmode);
tree V2DI_type_node = build_vector_type_for_mode (intDI_type_node, V2DImode);
tree V2DF_type_node = build_vector_type_for_mode (double_type_node, V2DFmode);
tree V4SF_type_node = build_vector_type_for_mode (float_type_node, V4SFmode);
tree V4SI_type_node = build_vector_type_for_mode (intSI_type_node, V4SImode);
tree V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
tree V8QI_type_node = build_vector_type_for_mode (intQI_type_node, V8QImode);
tree V8HI_type_node = build_vector_type_for_mode (intHI_type_node, V8HImode);
tree pchar_type_node = build_pointer_type (char_type_node);
tree pcchar_type_node = build_pointer_type (
build_type_variant (char_type_node, 1, 0));
@ -14877,25 +14888,54 @@ ix86_rtx_costs (rtx x, int code, int outer_code, int *total)
case MULT:
if (FLOAT_MODE_P (mode))
*total = COSTS_N_INSNS (ix86_cost->fmul);
else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
{
unsigned HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
int nbits;
for (nbits = 0; value != 0; value >>= 1)
nbits++;
*total = COSTS_N_INSNS (ix86_cost->mult_init[MODE_INDEX (mode)]
+ nbits * ix86_cost->mult_bit);
*total = COSTS_N_INSNS (ix86_cost->fmul);
return false;
}
else
{
/* This is arbitrary */
*total = COSTS_N_INSNS (ix86_cost->mult_init[MODE_INDEX (mode)]
+ 7 * ix86_cost->mult_bit);
rtx op0 = XEXP (x, 0);
rtx op1 = XEXP (x, 1);
int nbits;
if (GET_CODE (XEXP (x, 1)) == CONST_INT)
{
unsigned HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
for (nbits = 0; value != 0; value &= value - 1)
nbits++;
}
else
/* This is arbitrary. */
nbits = 7;
/* Compute costs correctly for widening multiplication. */
if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op1) == ZERO_EXTEND)
&& GET_MODE_SIZE (GET_MODE (XEXP (op0, 0))) * 2
== GET_MODE_SIZE (mode))
{
int is_mulwiden = 0;
enum machine_mode inner_mode = GET_MODE (op0);
if (GET_CODE (op0) == GET_CODE (op1))
is_mulwiden = 1, op1 = XEXP (op1, 0);
else if (GET_CODE (op1) == CONST_INT)
{
if (GET_CODE (op0) == SIGN_EXTEND)
is_mulwiden = trunc_int_for_mode (INTVAL (op1), inner_mode)
== INTVAL (op1);
else
is_mulwiden = !(INTVAL (op1) & ~GET_MODE_MASK (inner_mode));
}
if (is_mulwiden)
op0 = XEXP (op0, 0), mode = GET_MODE (op0);
}
*total = COSTS_N_INSNS (ix86_cost->mult_init[MODE_INDEX (mode)]
+ nbits * ix86_cost->mult_bit)
+ rtx_cost (op0, outer_code) + rtx_cost (op1, outer_code);
return true;
}
return false;
case DIV:
case UDIV:

View File

@ -34,12 +34,12 @@
# error "MMX instruction set not enabled"
#else
/* The data type intended for user use. */
typedef int __m64 __attribute__ ((__mode__ (__V2SI__)));
typedef int __m64 __attribute__ ((vector_size (8)));
/* Internal data types for implementing the intrinsics. */
typedef int __v2si __attribute__ ((__mode__ (__V2SI__)));
typedef int __v4hi __attribute__ ((__mode__ (__V4HI__)));
typedef int __v8qi __attribute__ ((__mode__ (__V8QI__)));
typedef int __v2si __attribute__ ((vector_size (8)));
typedef short __v4hi __attribute__ ((vector_size (8)));
typedef char __v8qi __attribute__ ((vector_size (8)));
/* Empty the multimedia state. */
static __inline void

View File

@ -38,10 +38,10 @@
#include <mmintrin.h>
/* The data type intended for user use. */
typedef int __m128 __attribute__ ((__mode__(__V4SF__)));
typedef float __m128 __attribute__ ((vector_size (16)));
/* Internal data types for implementing the intrinsics. */
typedef int __v4sf __attribute__ ((__mode__(__V4SF__)));
typedef float __v4sf __attribute__ ((vector_size (16)));
/* Create a selector for use with the SHUFPS instruction. */
#define _MM_SHUFFLE(fp3,fp2,fp1,fp0) \

View File

@ -216,9 +216,16 @@ int rs6000_debug_arg; /* debug argument handling */
static GTY(()) tree opaque_V2SI_type_node;
static GTY(()) tree opaque_V2SF_type_node;
static GTY(()) tree opaque_p_V2SI_type_node;
/* AltiVec requires a few more basic types in addition to the vector
types already defined in tree.c. */
static GTY(()) tree V16QI_type_node;
static GTY(()) tree V2SI_type_node;
static GTY(()) tree V2SF_type_node;
static GTY(()) tree V4HI_type_node;
static GTY(()) tree V4SI_type_node;
static GTY(()) tree V4SF_type_node;
static GTY(()) tree V8HI_type_node;
static GTY(()) tree unsigned_V16QI_type_node;
static GTY(()) tree unsigned_V8HI_type_node;
static GTY(()) tree unsigned_V4SI_type_node;
static GTY(()) tree bool_char_type_node; /* __bool char */
static GTY(()) tree bool_short_type_node; /* __bool short */
static GTY(()) tree bool_int_type_node; /* __bool int */
@ -6568,6 +6575,18 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
static void
rs6000_init_builtins (void)
{
V2SI_type_node = build_vector_type (intSI_type_node, 2);
V2SF_type_node = build_vector_type (float_type_node, 2);
V4HI_type_node = build_vector_type (intHI_type_node, 4);
V4SI_type_node = build_vector_type (intSI_type_node, 4);
V4SF_type_node = build_vector_type (float_type_node, 4);
V8HI_type_node = build_vector_type (intQI_type_node, 8);
V16QI_type_node = build_vector_type (intQI_type_node, 16);
unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
opaque_V2SI_type_node = copy_node (V2SI_type_node);
opaque_V2SF_type_node = copy_node (V2SF_type_node);
opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
@ -6598,10 +6617,10 @@ rs6000_init_builtins (void)
get_identifier ("__pixel"),
pixel_type_node));
bool_V16QI_type_node = make_vector (V16QImode, bool_char_type_node, 1);
bool_V8HI_type_node = make_vector (V8HImode, bool_short_type_node, 1);
bool_V4SI_type_node = make_vector (V4SImode, bool_int_type_node, 1);
pixel_V8HI_type_node = make_vector (V8HImode, pixel_type_node, 1);
bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
(*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
get_identifier ("__vector unsigned char"),

View File

@ -32,8 +32,8 @@ Boston, MA 02111-1307, USA. */
#if __SHMEDIA__
#if ! __SH4_NO_FPU
typedef float __GCC_FV __attribute__ ((mode (V4SF)));
typedef float __GCC_MTRX __attribute__ ((mode (V16SF)));
typedef float __GCC_FV __attribute__ ((vector_size (4 * sizeof (float))));
typedef float __GCC_MTRX __attribute__ ((vector_size (16 * sizeof (float))));
#endif
__inline__ static

View File

@ -4631,30 +4631,24 @@ The first step in using these extensions is to provide the necessary data
types. This should be done using an appropriate @code{typedef}:
@smallexample
typedef int v4si __attribute__ ((mode(V4SI)));
typedef int v4si __attribute__ ((vector_size (16)));
@end smallexample
The base type @code{int} is effectively ignored by the compiler, the
actual properties of the new type @code{v4si} are defined by the
@code{__attribute__}. It defines the machine mode to be used; for vector
types these have the form @code{V@var{n}@var{B}}; @var{n} should be the
number of elements in the vector, and @var{B} should be the base mode of the
individual elements. The following can be used as base modes:
The @code{int} type specifies the base type, while the attribute specifies
the vector size for the variable, measured in bytes. For example, the
declaration above causes the compiler to set the mode for the @code{v4si}
type to be 16 bytes wide and divided into @code{int} sized units. For
a 32-bit @code{int} this means a vector of 4 units of 4 bytes, and the
corresponding mode of @code{foo} will be @acronym{V4SI}.
@table @code
@item QI
An integer that is as wide as the smallest addressable unit, usually 8 bits.
@item HI
An integer, twice as wide as a QI mode integer, usually 16 bits.
@item SI
An integer, four times as wide as a QI mode integer, usually 32 bits.
@item DI
An integer, eight times as wide as a QI mode integer, usually 64 bits.
@item SF
A floating point value, as wide as a SI mode integer, usually 32 bits.
@item DF
A floating point value, as wide as a DI mode integer, usually 64 bits.
@end table
The @code{vector_size} attribute is only applicable to integral and
float scalars, although arrays, pointers, and function return values
are allowed in conjunction with this construct.
All the basic integer types can be used as base types, both as signed
and as unsigned: @code{char}, @code{short}, @code{int}, @code{long},
@code{long long}. In addition, @code{float} and @code{double} can be
used to build floating-point vector types.
Specifying a combination that is not valid for the current architecture
will cause GCC to synthesize the instructions using a narrower mode.
@ -4673,7 +4667,7 @@ added to the corresponding 4 elements in @var{b} and the resulting
vector will be stored in @var{c}.
@smallexample
typedef int v4si __attribute__ ((mode(V4SI)));
typedef int v4si __attribute__ ((vector_size (16)));
v4si a, b, c;

View File

@ -1,3 +1,29 @@
2004-03-16 Paolo Bonzini <bonzini@gnu.org>
* g++.dg/eh/simd-1.C: Use vector_size attribute, not mode.
* g++.dg/eh/simd-2.C: Likewise.
* g++.dg/init/array10.C: Likewise.
* gcc.c-torture/compile/simd-1.c: Likewise.
* gcc.c-torture/compile/simd-2.c: Likewise.
* gcc.c-torture/compile/simd-3.c: Likewise.
* gcc.c-torture/compile/simd-4.c: Likewise.
* gcc.c-torture/compile/simd-6.c: Likewise.
* gcc.c-torture/execute/simd-1.c: Likewise.
* gcc.c-torture/execute/simd-2.c: Likewise.
* gcc.dg/compat/vector-defs.h: Likewise.
* gcc.dg/20020531-1.c: Likewise.
* gcc.dg/altivec-3.c: Likewise.
* gcc.dg/altivec-4.c: Likewise.
* gcc.dg/altivec-varargs-1.c: Likewise.
* testsuite/gcc.dg/compat/vector-defs.h: Likewise.
* gcc.dg/i386-mmx-3.c: Likewise.
* gcc.dg/i386-sse-4.c: Likewise.
* gcc.dg/i386-sse-5.c: Likewise.
* gcc.dg/i386-sse-8.c: Likewise.
* gcc.dg/simd-1.c: Likewise.
* gcc.dg/20030218-1.c: Likewise. Plus, do not declare
__ev64_opaque__ since the machine description provides it.
2004-03-16 Eric Botcazou <ebotcazou@libertysurf.fr>
* lib/compat.exp (skip_list): New global variable.

View File

@ -4,7 +4,7 @@
// { dg-options "-O -w" { target i?86-*-* } }
// { dg-do run }
typedef int __attribute__((mode(V2SI))) vecint;
typedef int __attribute__((vector_size (8))) vecint;
vecint vecfunc (vecint beachbum)
{

View File

@ -5,7 +5,7 @@
// { dg-options "-O -w -maltivec" { target powerpc64-*-linux* } }
// { dg-do run { xfail "powerpc64-*-linux*"} }
typedef int __attribute__((mode(V4SI))) vecint;
typedef int __attribute__((vector_size (16))) vecint;
vecint vecfunc (vecint beachbum)
{

View File

@ -1,6 +1,6 @@
// { dg-do compile }
// { dg-options "" }
typedef int __attribute__((mode(V2SI))) vec;
typedef int __attribute__((vector_size (8))) vec;
vec foo[] = { (vec) {1, 2} };

View File

@ -1,4 +1,4 @@
typedef int v2si __attribute__ ((mode(V2SI)));
typedef int v2si __attribute__ ((vector_size (8)));
typedef unsigned di __attribute__ ((mode(DI)));
void foo(unsigned long);
void bar() {

View File

@ -1,4 +1,4 @@
typedef float floatvect2 __attribute__((mode(V2SF)));
typedef float floatvect2 __attribute__((vector_size (8)));
typedef union
{

View File

@ -3,7 +3,7 @@
/* If double is not wider than float, we probably don't have DFmode,
or at least it's not as wide as double. */
#if DBL_MANT_DIG > FLT_MANT_DIG
typedef float floatvect2 __attribute__((mode(V2DF)));
typedef double floatvect2 __attribute__((vector_size (16)));
typedef union
{

View File

@ -1,4 +1,4 @@
typedef float floatvect2 __attribute__((mode(V4SF)));
typedef float floatvect2 __attribute__((vector_size (16)));
typedef union
{

View File

@ -1,3 +1,3 @@
typedef int __attribute__((mode(V2SI))) vec;
typedef int __attribute__((vector_size (8))) vec;
vec a[] = {(vec) {1, 2}, {3, 4}};

View File

@ -4,7 +4,7 @@
regardless of if the target has SIMD instructions.
*/
typedef int __attribute__((mode(V4SI))) vecint;
typedef int __attribute__((vector_size (16))) vecint;
typedef int __attribute__((mode(SI))) siint;
vecint i = { 150, 100, 150, 200 };

View File

@ -3,7 +3,7 @@
regardless of if the target has SIMD instructions.
*/
typedef int __attribute__((mode(V8HI))) vecint;
typedef short __attribute__((vector_size (16))) vecint;
vecint i = { 150, 100, 150, 200, 0, 0, 0, 0 };
vecint j = { 10, 13, 20, 30, 1, 1, 1, 1 };

View File

@ -4,7 +4,7 @@
/* { dg-do compile { target i?86-*-* } } */
/* { dg-options "-O2 -mmmx" } */
typedef int __v8qi __attribute__ ((__mode__ (__V8QI__)));
typedef unsigned char __v8qi __attribute__ ((vector_size (8)));
extern void abort (void);
extern void exit (int);

View File

@ -1,14 +1,12 @@
/* { dg-do compile { target powerpc-*-eabi* } } */
/* { dg-options "-mcpu=8540" } */
/* { dg-options "-mspe=yes" } */
/* Test vectors that can interconvert without a cast. */
typedef int __attribute__((mode(V2SI))) __ev64_opaque__;
__ev64_opaque__ opp;
int vint __attribute__((mode(V2SI)));
int vshort __attribute__((mode(V4HI)));
int vfloat __attribute__((mode(V2SF)));
int vint __attribute__((vector_size (8)));
short vshort __attribute__((vector_size (8)));
float vfloat __attribute__((vector_size (8)));
int
main (void)

View File

@ -3,8 +3,8 @@
#include "altivec_check.h"
typedef int int4 __attribute__ ((mode(V4SI)));
typedef float float4 __attribute__ ((mode(V4SF)));
typedef int int4 __attribute__ ((vector_size (16)));
typedef float float4 __attribute__ ((vector_size (16)));
int4 a1 = (int4) { 100, 200, 300, 400 };
int4 a2 = (int4) { 500, 600, 700, 800 };

View File

@ -3,7 +3,7 @@
#define vector __attribute__((vector_size(16)))
static int __attribute__((mode(V4SI))) x, y;
static int vector x, y;
static vector signed int i,j;
static vector signed short s,t;

View File

@ -6,7 +6,7 @@
#include "altivec_check.h"
#define vector __attribute__((mode(V4SI)))
#define vector __attribute__((vector_size (16)))
const vector unsigned int v1 = {10,11,12,13};
const vector unsigned int v2 = {20,21,22,23};

View File

@ -2,45 +2,45 @@
c_common_type_for_mode, grouped by base mode. */
typedef int __attribute__((mode(QI))) qi;
typedef int __attribute__((mode(V8QI))) v8qi;
typedef int __attribute__((mode(V16QI))) v16qi;
typedef qi __attribute__((vector_size (8))) v8qi;
typedef qi __attribute__((vector_size (16))) v16qi;
typedef union U8QI { v8qi v; qi a[8]; } u8qi;
typedef union U16QI { v16qi v; qi a[16]; } u16qi;
typedef int __attribute__((mode(HI))) hi;
typedef int __attribute__((mode(V2HI))) v2hi;
typedef int __attribute__((mode(V4HI))) v4hi;
typedef int __attribute__((mode(V8HI))) v8hi;
typedef hi __attribute__((vector_size (4))) v2hi;
typedef hi __attribute__((vector_size (8))) v4hi;
typedef hi __attribute__((vector_size (16))) v8hi;
typedef union U2HI { v2hi v; hi a[2]; } u2hi;
typedef union U4HI { v4hi v; hi a[4]; } u4hi;
typedef union U8HI { v8hi v; hi a[8]; } u8hi;
typedef int __attribute__((mode(SI))) si;
typedef int __attribute__((mode(V2SI))) v2si;
typedef int __attribute__((mode(V4SI))) v4si;
typedef si __attribute__((vector_size (8))) v2si;
typedef si __attribute__((vector_size (16))) v4si;
typedef union U2SI { v2si v; si a[2]; } u2si;
typedef union U4SI { v4si v; si a[4]; } u4si;
typedef int __attribute__((mode(DI))) di;
typedef int __attribute__((mode(V1DI))) v1di;
typedef int __attribute__((mode(V2DI))) v2di;
typedef di __attribute__((vector_size (8))) v1di;
typedef di __attribute__((vector_size (16))) v2di;
typedef union U1DI { v1di v; di a[1]; } u1di;
typedef union U2DI { v2di v; di a[2]; } u2di;
typedef float __attribute__((mode(SF))) sf;
typedef float __attribute__((mode(V2SF))) v2sf;
typedef float __attribute__((mode(V4SF))) v4sf;
typedef float __attribute__((mode(V16SF))) v16sf;
typedef sf __attribute__((vector_size (8))) v2sf;
typedef sf __attribute__((vector_size (16))) v4sf;
typedef sf __attribute__((vector_size (64))) v16sf;
typedef union U2SF { v2sf v; sf a[2]; } u2sf;
typedef union U4SF { v4sf v; sf a[4]; } u4sf;
typedef union U16SF { v16sf v; sf a[16]; } u16sf;
typedef float __attribute__((mode(DF))) df;
typedef float __attribute__((mode(V2DF))) v2df;
typedef df __attribute__((vector_size (16))) v2df;
typedef union U2DF { v2df v; df a[2]; } u2df;

View File

@ -3,7 +3,7 @@
/* { dg-do compile { target i?86-*-* x86_64-*-*} } */
/* { dg-options "-O1 -mmmx -march=k8" } */
typedef int v4hi __attribute__ ((mode (V4HI)));
typedef short v4hi __attribute__ ((vector_size (8)));
static inline v4hi cvtsi_v4hi (int i)
{

View File

@ -1,7 +1,7 @@
/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O0 -msse" } */
typedef void __vr __attribute__ ((__mode__ (__V4SF__)));
typedef float __vr __attribute__ ((vector_size (16)));
struct vector
{

View File

@ -1,6 +1,6 @@
/* { dg-do compile { target i?86-*-* } } */
/* { dg-options "-Winline -O2 -march=i386" } */
typedef int v2df __attribute__ ((mode(V2DF)));
typedef double v2df __attribute__ ((vector_size (16)));
v2df p;
q(v2df t)
{ /* { dg-warning "SSE" "" } */

View File

@ -6,7 +6,7 @@
int main()
{
typedef int v __attribute__ ((mode(V2DI)));
typedef long long int v __attribute__ ((vector_size (16)));
v a, b;
a = b;
return 0;

View File

@ -4,10 +4,10 @@
/* 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;
typedef int __attribute__((vector_size (16))) v4si;
typedef short __attribute__((vector_size (16))) v8hi;
typedef int __attribute__((vector_size (8))) v2si;
typedef unsigned int __attribute__((vector_size (16))) uv4si;
v4si a, b;
v2si c, d;
@ -16,7 +16,7 @@ uv4si f;
int foo __attribute__((mode(DI)));
int foo1 __attribute__((mode(SI)));
int foo2 __attribute__((mode(V4HI)));
short foo2 __attribute__((vector_size (8)));
void
hanneke ()
@ -32,7 +32,7 @@ hanneke ()
e = (typeof (e)) a;
/* Different signed SIMD assignment. */
f = a; /* { dg-error "incompatible types in assignment" } */
f = a;
/* Casted different signed SIMD assignment. */
f = (uv4si) a;

View File

@ -5115,40 +5115,6 @@ build_common_tree_nodes_2 (int short_double)
va_list_type_node = t;
}
unsigned_V4SI_type_node
= make_vector (V4SImode, unsigned_intSI_type_node, 1);
unsigned_V2HI_type_node
= make_vector (V2HImode, unsigned_intHI_type_node, 1);
unsigned_V2SI_type_node
= make_vector (V2SImode, unsigned_intSI_type_node, 1);
unsigned_V2DI_type_node
= make_vector (V2DImode, unsigned_intDI_type_node, 1);
unsigned_V4HI_type_node
= make_vector (V4HImode, unsigned_intHI_type_node, 1);
unsigned_V8QI_type_node
= make_vector (V8QImode, unsigned_intQI_type_node, 1);
unsigned_V8HI_type_node
= make_vector (V8HImode, unsigned_intHI_type_node, 1);
unsigned_V16QI_type_node
= make_vector (V16QImode, unsigned_intQI_type_node, 1);
unsigned_V1DI_type_node
= make_vector (V1DImode, unsigned_intDI_type_node, 1);
V16SF_type_node = make_vector (V16SFmode, float_type_node, 0);
V4SF_type_node = make_vector (V4SFmode, float_type_node, 0);
V4SI_type_node = make_vector (V4SImode, intSI_type_node, 0);
V2HI_type_node = make_vector (V2HImode, intHI_type_node, 0);
V2SI_type_node = make_vector (V2SImode, intSI_type_node, 0);
V2DI_type_node = make_vector (V2DImode, intDI_type_node, 0);
V4HI_type_node = make_vector (V4HImode, intHI_type_node, 0);
V8QI_type_node = make_vector (V8QImode, intQI_type_node, 0);
V8HI_type_node = make_vector (V8HImode, intHI_type_node, 0);
V2SF_type_node = make_vector (V2SFmode, float_type_node, 0);
V2DF_type_node = make_vector (V2DFmode, double_type_node, 0);
V16QI_type_node = make_vector (V16QImode, intQI_type_node, 0);
V1DI_type_node = make_vector (V1DImode, intDI_type_node, 0);
V4DF_type_node = make_vector (V4DFmode, double_type_node, 0);
}
/* HACK. GROSS. This is absolutely disgusting. I wish there was a
@ -5197,26 +5163,41 @@ reconstruct_complex_type (tree type, tree bottom)
return outer;
}
/* Returns a vector tree node given a vector mode, the inner type, and
the signness. */
/* Returns a vector tree node given a vector mode and inner type. */
tree
make_vector (enum machine_mode mode, tree innertype, int unsignedp)
build_vector_type_for_mode (tree innertype, enum machine_mode mode)
{
tree t;
t = make_node (VECTOR_TYPE);
TREE_TYPE (t) = innertype;
TYPE_MODE (t) = mode;
TREE_UNSIGNED (TREE_TYPE (t)) = unsignedp;
TREE_UNSIGNED (t) = TREE_UNSIGNED (innertype);
finish_vector_type (t);
return t;
}
/* Similarly, but takes inner type and units. */
tree
build_vector_type (tree innertype, int nunits)
{
enum machine_mode innermode = TYPE_MODE (innertype);
enum machine_mode mode;
if (GET_MODE_CLASS (innermode) == MODE_FLOAT)
mode = MIN_MODE_VECTOR_FLOAT;
else
mode = MIN_MODE_VECTOR_INT;
for (; mode != VOIDmode ; mode = GET_MODE_WIDER_MODE (mode))
if (GET_MODE_NUNITS (mode) == nunits && GET_MODE_INNER (mode) == innermode)
return build_vector_type_for_mode (innertype, mode);
return NULL_TREE;
}
/* Given an initializer INIT, return TRUE if INIT is zero or some
aggregate of zeros. Otherwise return FALSE. */
bool
initializer_zerop (tree init)
{

View File

@ -1871,33 +1871,6 @@ enum tree_index
TI_VOID_LIST_NODE,
TI_UV4SF_TYPE,
TI_UV4SI_TYPE,
TI_UV8HI_TYPE,
TI_UV8QI_TYPE,
TI_UV4HI_TYPE,
TI_UV2HI_TYPE,
TI_UV2SI_TYPE,
TI_UV2SF_TYPE,
TI_UV2DI_TYPE,
TI_UV1DI_TYPE,
TI_UV16QI_TYPE,
TI_V4SF_TYPE,
TI_V16SF_TYPE,
TI_V4SI_TYPE,
TI_V8HI_TYPE,
TI_V8QI_TYPE,
TI_V4HI_TYPE,
TI_V2HI_TYPE,
TI_V2SI_TYPE,
TI_V2SF_TYPE,
TI_V2DF_TYPE,
TI_V2DI_TYPE,
TI_V1DI_TYPE,
TI_V16QI_TYPE,
TI_V4DF_TYPE,
TI_MAIN_IDENTIFIER,
TI_MAX
@ -1973,31 +1946,6 @@ extern GTY(()) tree global_trees[TI_MAX];
#define main_identifier_node global_trees[TI_MAIN_IDENTIFIER]
#define MAIN_NAME_P(NODE) (IDENTIFIER_NODE_CHECK (NODE) == main_identifier_node)
#define unsigned_V16QI_type_node global_trees[TI_UV16QI_TYPE]
#define unsigned_V4SI_type_node global_trees[TI_UV4SI_TYPE]
#define unsigned_V8QI_type_node global_trees[TI_UV8QI_TYPE]
#define unsigned_V8HI_type_node global_trees[TI_UV8HI_TYPE]
#define unsigned_V4HI_type_node global_trees[TI_UV4HI_TYPE]
#define unsigned_V2HI_type_node global_trees[TI_UV2HI_TYPE]
#define unsigned_V2SI_type_node global_trees[TI_UV2SI_TYPE]
#define unsigned_V2DI_type_node global_trees[TI_UV2DI_TYPE]
#define unsigned_V1DI_type_node global_trees[TI_UV1DI_TYPE]
#define V16QI_type_node global_trees[TI_V16QI_TYPE]
#define V4SF_type_node global_trees[TI_V4SF_TYPE]
#define V4SI_type_node global_trees[TI_V4SI_TYPE]
#define V8QI_type_node global_trees[TI_V8QI_TYPE]
#define V8HI_type_node global_trees[TI_V8HI_TYPE]
#define V4HI_type_node global_trees[TI_V4HI_TYPE]
#define V2HI_type_node global_trees[TI_V2HI_TYPE]
#define V2SI_type_node global_trees[TI_V2SI_TYPE]
#define V2SF_type_node global_trees[TI_V2SF_TYPE]
#define V2DI_type_node global_trees[TI_V2DI_TYPE]
#define V2DF_type_node global_trees[TI_V2DF_TYPE]
#define V16SF_type_node global_trees[TI_V16SF_TYPE]
#define V1DI_type_node global_trees[TI_V1DI_TYPE]
#define V4DF_type_node global_trees[TI_V4DF_TYPE]
/* An enumeration of the standard C integer types. These must be
ordered so that shorter types appear before longer ones, and so
that signed types appear before unsigned ones, for the correct
@ -2186,6 +2134,8 @@ extern tree build_pointer_type_for_mode (tree, enum machine_mode);
extern tree build_pointer_type (tree);
extern tree build_reference_type_for_mode (tree, enum machine_mode);
extern tree build_reference_type (tree);
extern tree build_vector_type_for_mode (tree, enum machine_mode);
extern tree build_vector_type (tree innertype, int nunits);
extern tree build_type_no_quals (tree);
extern tree build_index_type (tree);
extern tree build_index_2_type (tree, tree);
@ -2909,7 +2859,6 @@ extern void dump_tree_statistics (void);
extern void expand_function_end (void);
extern void expand_function_start (tree, int);
extern void expand_pending_sizes (tree);
extern tree make_vector (enum machine_mode, tree, int);
extern tree reconstruct_complex_type (tree, tree);
extern int real_onep (tree);