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


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

[PATCH] backport AltiVec interface changes from mainline to 3.4


The patch backports from mainline to 3.4-branch changes to support the
AltiVec high-level language interface.  It includes several different
patches and has been tested as a single patch on powerpc64-linux.  In
addition to the AltiVec tests that are already in the branch and that
this patch brings up to date, I've also tested this with all other
altivec* tests in the GCC testsuite, plus gcc.dg/vmx.  I'd like to copy
those tests to the branch but will do that in a separate patch.

Changes to the files doc/extend.texi and config/rs6000/altivec.h are
huge, so they are attached as bzip2 files.  This version of altivec.h
includes a change that I had expected to be in mainline by now but
isn't, which is replacement of 'pixel' and 'bool' with '__pixel' and
'__bool'.  I'll start testing that change for mainline to get it in
there first, unless Ben Elliston beats me to it.  Or, if folks prefer,
I'll remove that change from this patch and retest.

Some of these changes affect Darwin, so I'd appreciate it if someone
can test this on powerpc-apple-darwin.

OK for 3.4-branch, after testing on Darwin?

2004-08-17  Janis Johnson  <janis187@us.ibm.com>

	Backports from mainline:

	2004-02-11  Ziemowit Laski  <zlaski@apple.com>
	2004-02-21  Ziemowit Laski  <zlaski@apple.com>
	2004-02-27  Ziemowit Laski  <zlaski@apple.com>
	2004-03-04  Ziemowit Laski  <zlaski@apple.com>
	2004-03-20  Ziemowit Laski  <zlaski@apple.com>
	2004-03-24  Ziemowit Laski  <zlaski@apple.com>
	2004-05-11  Fariborz Jahanian <fjahanian@apple.com>
 	2004-07-23  Janis Johnson  <janis187@us.ibm.com>
 	2004-08-12  Janis Johnson  <janis187@us.ibm.com>
	2004-08-12  Ben Elliston <bje@au.ibm.com>
 	2004-08-16  Janis Johnson  <janis187@us.ibm.com>

	* c-common.c (vector_size_helper): Remove; call
	reconstruct_complex_type() instead.
	* hooks.c (hook_constcharptr_tree_null): New hook.
        * hooks.h (hook_constcharptr_tree_null): New prototype.
        * target-def.h (TARGET_MANGLE_FUNDAMENTAL_TYPE): New target hook.
        * target.h (mangle_fundamental_type): New target hook.
	* tree.c (reconstruct_complex_type): New function
	(formerly vector_size_helper() in c-common.c).
	(make_vector): Make externally visible.
	* tree.h (reconstruct_complex_type, make_vector): Add prototypes.
	* doc/extend.texi (AltiVec builtins): Document additional differences
	from the Motorola AltiVec PIM.
	* doc/tm.texi (TARGET_MANGLE_FUNDAMENTAL_TYPE): Document.
	* config/darwin.h (TARGET_OPTION_TRANSLATE_TABLE): Refer to
	SUBTARGET_OPTION_TRANSLATE_TABLE for architecture-specific options.
	* config/i386/darwin.h (SUBTARGET_OPTION_TRANSLATE_TABLE): Define it.
	* config/rs6000/altivec.h: #error out if '-maltivec' not specified.
	(vector, pixel, bool): #define to __vector, __pixel and __bool.
	Change vector to __vector (except for the `vector' macro itself).
	(__un_args_eq, __bin_args_eq, __tern_args_eq): Move to C-specific
	portion of header.
	(__altivec_link_error_invalid_argument): Remove prototype; will use
	__builtin_altivec_compiletime_error("vec_*") instead.
	(vec_*): Fix/complete set of available operation overloads given the
	existence of distinct 'vector bool ...' and 'vector pixel' types;
	tighten cv-correctness of pointer arguments; in C, always check for
	correct argument types before macro expansion.
	(vec_splat_s8, vec_splat_s16, vec_splat_s32, vec_splat_u8,
	vec_splat_u16, vec_splat_u32): Change C++ definitions to accept a
	'const int' argument; the prototypes already do.
	(vec_dst, vec_dstst, vec_dststt, vec_dstt, vec_sld, vec_splat): Add
	prototypes, marked with always_inline attribute.
	* config/rs6000/darwin.h (SUBTARGET_OPTION_TRANSLATE_TABLE): New macro
	defining Darwin/PowerPC-specific '-f[no-]altivec' and
	'-W[no-]altivec-long-deprecated' switches.
	* config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Pre-define
	'__vector', '__pixel' and '__bool' macros using
	'__attribute__((altivec(...)))' types.
	* config/rs6000/rs6000.c (bool_char_type_node, bool_short_type_node,
	bool_int_type_node, pixel_type_node, bool_V16QI_type_node,
	bool_V8HI_type_node, bool_V4SI_type_node, pixel_V8HI_type_node):
	New type nodes.
	(rs6000_warn_altivec_long, rs6000_warn_altivec_long_switch): New, for
	handling '-W[no-]altivec-long-deprecated'.
	(rs6000_override_options): Handle '-W[no-]altivec-long-deprecated'.
	(rs6000_expand_binop_builtin, rs6000_expand_ternop_builtin,
	altivec_expand_dst_builtin): Remove casts from integer literals.
	(altivec_expand_builtin): Likewise; handle expansion of new
	'__builtin_altivec_compiletime_error' function.
	(rs6000_init_builtins): Initialize 'vector bool ...' and 'vector pixel'
	types, and make them distinct from other vector types; register
	'__builtin_altivec_compiletime_error' function.
	(print_operand): For 'P', print a full target register name instead of
	merely its number.
	(rs6000_attribute_table): Add "altivec" attribute.
	(rs6000_handle_altivec_attribute): New function.
	(rs6000_common_init_builtins): Rename v4si_ftype_char, v8hi_ftype_char,
	v16qi_ftype_char, v4sf_ftype_v4si_char, v4si_ftype_v4sf_char,
	v4si_ftype_v4si_char, v8hi_ftype_v8hi_char, v16qi_ftype_v16qi_char,
        v16qi_ftype_v16qi_v16qi_char, v8hi_ftype_v8hi_v8hi_char,
        v4si_ftype_v4si_v4si_char and v4sf_ftype_v4sf_v4sf_char to
        end in ..._int; change them to accept an int instead of a char
        as the last parameter.
	(altivec_expand_dst_builtin): Treat expansion as completed even if
	literal argument is invalid (so that other expansions are not tried
	in vain).
	(TARGET_MANGLE_FUNDAMENTAL_TYPE): Point target hook at
	rs6000_mangle_fundamental_type.
        (rs6000_mangle_fundamental_type): New function.
	* config/rs6000/rs6000.h (TARGET_OPTIONS): Describe
	'-m[no-]-warn-altivec-long' (which '-W[no-]altivec-long-deprecated'
	maps to).
	(rs6000_warn_altivec_long, rs6000_warn_altivec_long_switch): Forward
	declare.
	(ALTIVEC_BUILTIN_COMPILETIME_ERROR): New built-in enumeration.

cp:

	* Make-lang.in (cp/mangle.o): Depend on $(TARGET_H).
        * mangle.c (write_type): Add call to 'mangle_fundamental_type'
        target hook.
	* tree.c (pod_type_p): Treat VECTOR_TYPEs as PODs.

testsuite:

	* lib/target-supports.exp (check_vmx_hw_available): New.
	* g++.dg/ext/altivec-1.C: XFAIL powerpc-ibm-aix. Correct dg syntax.
	* gcc.dg/altivec-1.c: XFAIL powerpc-ibm-aix, powerpc-eabispe.
	* gcc.dg/altivec-2.c: Generalize target.
	* gcc.dg/altivec-3.c: XFAIL powerpc-ibm-aix, powerpc-eabispe.
	Use vector_size attribute.  Do runtime check for VMX hardware.
	* gcc.dg/altivec-4.c: XFAIL powerpc-ibm-aix, powerpc-eabispe.
	Use vector size attribute.
	* gcc.dg/altivec-5.c: Generalize target.
	* gcc.dg/altivec-7.c: XFAIL powerpc-ibm-aix.  Replace long* with int*.
	* gcc.dg/altivec-8.c: XFAIL powerpc-ibm-aix.
	* gcc.dg/altivec-9.c: Generalize target.
	* gcc.dg/altivec-10.c: XFAIL powerpc-ibm-aix and powerpc-eabispe.
	* gcc.dg/altivec-11.c: Ditto.
	* gcc.dg/altivec-varargs-1.c: Ditto.

Index: c-common.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.476.4.7
diff -u -p -r1.476.4.7 c-common.c
--- c-common.c	7 Jun 2004 15:52:05 -0000	1.476.4.7
+++ c-common.c	17 Aug 2004 01:09:49 -0000
@@ -767,7 +767,6 @@ static tree handle_nothrow_attribute (tr
 static tree handle_cleanup_attribute (tree *, tree, tree, int, bool *);
 static tree handle_warn_unused_result_attribute (tree *, tree, tree, int,
 						 bool *);
-static tree vector_size_helper (tree, tree);
 
 static void check_function_nonnull (tree, tree);
 static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT);
@@ -5246,57 +5245,11 @@ handle_vector_size_attribute (tree *node
     }
 
   /* Build back pointers if needed.  */
-  *node = vector_size_helper (*node, new_type);
+  *node = reconstruct_complex_type (*node, new_type);
 
   return NULL_TREE;
 }
 
-/* HACK.  GROSS.  This is absolutely disgusting.  I wish there was a
-   better way.
-
-   If we requested a pointer to a vector, build up the pointers that
-   we stripped off while looking for the inner type.  Similarly for
-   return values from functions.
-
-   The argument "type" is the top of the chain, and "bottom" is the
-   new type which we will point to.  */
-
-static tree
-vector_size_helper (tree type, tree bottom)
-{
-  tree inner, outer;
-
-  if (POINTER_TYPE_P (type))
-    {
-      inner = vector_size_helper (TREE_TYPE (type), bottom);
-      outer = build_pointer_type (inner);
-    }
-  else if (TREE_CODE (type) == ARRAY_TYPE)
-    {
-      inner = vector_size_helper (TREE_TYPE (type), bottom);
-      outer = build_array_type (inner, TYPE_DOMAIN (type));
-    }
-  else if (TREE_CODE (type) == FUNCTION_TYPE)
-    {
-      inner = vector_size_helper (TREE_TYPE (type), bottom);
-      outer = build_function_type (inner, TYPE_ARG_TYPES (type));
-    }
-  else if (TREE_CODE (type) == METHOD_TYPE)
-    {
-      inner = vector_size_helper (TREE_TYPE (type), bottom);
-      outer = build_method_type_directly (TYPE_METHOD_BASETYPE (type),
-					  inner, 
-					  TYPE_ARG_TYPES (type));
-    }
-  else
-    return bottom;
-
-  TREE_READONLY (outer) = TREE_READONLY (type);
-  TREE_THIS_VOLATILE (outer) = TREE_THIS_VOLATILE (type);
-
-  return outer;
-}
-
 /* Handle the "nonnull" attribute.  */
 static tree
 handle_nonnull_attribute (tree *node, tree name ATTRIBUTE_UNUSED,
Index: hooks.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/hooks.c,v
retrieving revision 1.22.10.1
diff -u -p -r1.22.10.1 hooks.c
--- hooks.c	12 Feb 2004 15:30:45 -0000	1.22.10.1
+++ hooks.c	17 Aug 2004 01:09:49 -0000
@@ -227,3 +227,10 @@ hook_bool_voidp_size_t_false (void * a A
 {
   return false;
 }
+
+/* Generic hook that takes a tree and returns a NULL string.  */
+const char *
+hook_constcharptr_tree_null (tree t ATTRIBUTE_UNUSED)
+{
+  return NULL;
+}
Index: hooks.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/hooks.h,v
retrieving revision 1.23.10.1
diff -u -p -r1.23.10.1 hooks.h
--- hooks.h	12 Feb 2004 15:30:45 -0000	1.23.10.1
+++ hooks.h	17 Aug 2004 01:09:49 -0000
@@ -60,5 +60,5 @@ extern rtx hook_rtx_rtx_null (rtx);
 extern rtx hook_rtx_tree_int_null (tree, int);
 extern void * hook_voidp_size_t_null (size_t);
 extern bool hook_bool_voidp_size_t_false (void *, size_t);
-
+extern const char *hook_constcharptr_tree_null (tree);
 #endif
Index: target-def.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/target-def.h,v
retrieving revision 1.63.4.2
diff -u -p -r1.63.4.2 target-def.h
--- target-def.h	15 Mar 2004 23:22:48 -0000	1.63.4.2
+++ target-def.h	17 Aug 2004 01:09:49 -0000
@@ -301,6 +301,7 @@ Foundation, 59 Temple Place - Suite 330,
 #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_tree_false
 #define TARGET_MS_BITFIELD_LAYOUT_P hook_bool_tree_false
 #define TARGET_RTX_COSTS hook_bool_rtx_int_int_intp_false
+#define TARGET_MANGLE_FUNDAMENTAL_TYPE hook_constcharptr_tree_null
 
 #ifndef TARGET_INIT_LIBFUNCS
 #define TARGET_INIT_LIBFUNCS hook_void_void
@@ -369,6 +370,7 @@ Foundation, 59 Temple Place - Suite 330,
   TARGET_MS_BITFIELD_LAYOUT_P,			\
   TARGET_INIT_BUILTINS,				\
   TARGET_EXPAND_BUILTIN,			\
+  TARGET_MANGLE_FUNDAMENTAL_TYPE,		\
   TARGET_INIT_LIBFUNCS,				\
   TARGET_SECTION_TYPE_FLAGS,			\
   TARGET_CANNOT_MODIFY_JUMPS_P,			\
Index: target.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/target.h,v
retrieving revision 1.74.2.3
diff -u -p -r1.74.2.3 target.h
--- target.h	15 Mar 2004 23:22:48 -0000	1.74.2.3
+++ target.h	17 Aug 2004 01:09:49 -0000
@@ -302,6 +302,11 @@ struct gcc_target
   rtx (* expand_builtin) (tree exp, rtx target, rtx subtarget,
 			  enum machine_mode mode, int ignore);
 
+  /* For a vendor-specific fundamental TYPE, return a pointer to
+     a statically-allocated string containing the C++ mangling for
+     TYPE.  In all other cases, return NULL.  */
+  const char * (* mangle_fundamental_type) (tree type);
+
   /* Make any adjustments to libfunc names needed for this target.  */
   void (* init_libfuncs) (void);
 
Index: tree.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/tree.c,v
retrieving revision 1.342.2.4
diff -u -p -r1.342.2.4 tree.c
--- tree.c	21 Jun 2004 06:30:15 -0000	1.342.2.4
+++ tree.c	17 Aug 2004 01:09:50 -0000
@@ -106,7 +106,6 @@ static int type_hash_eq (const void *, c
 static hashval_t type_hash_hash (const void *);
 static void print_type_hash_statistics (void);
 static void finish_vector_type (tree);
-static tree make_vector (enum machine_mode, tree, int);
 static int type_hash_marked_p (const void *);
 
 tree global_trees[TI_MAX];
@@ -4984,10 +4983,56 @@ build_common_tree_nodes_2 (int short_dou
   V4DF_type_node = make_vector (V4DFmode, double_type_node, 0);
 }
 
+/* HACK.  GROSS.  This is absolutely disgusting.  I wish there was a
+   better way.
+
+   If we requested a pointer to a vector, build up the pointers that
+   we stripped off while looking for the inner type.  Similarly for
+   return values from functions.
+
+   The argument TYPE is the top of the chain, and BOTTOM is the
+   new type which we will point to.  */
+
+tree
+reconstruct_complex_type (tree type, tree bottom)
+{
+  tree inner, outer;
+
+  if (POINTER_TYPE_P (type))
+    {
+      inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
+      outer = build_pointer_type (inner);
+    }
+  else if (TREE_CODE (type) == ARRAY_TYPE)
+    {
+      inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
+      outer = build_array_type (inner, TYPE_DOMAIN (type));
+    }
+  else if (TREE_CODE (type) == FUNCTION_TYPE)
+    {
+      inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
+      outer = build_function_type (inner, TYPE_ARG_TYPES (type));
+    }
+  else if (TREE_CODE (type) == METHOD_TYPE)
+    {
+      inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
+      outer = build_method_type_directly (TYPE_METHOD_BASETYPE (type),
+					 inner,
+					 TYPE_ARG_TYPES (type));
+    }
+  else
+    return bottom;
+
+  TREE_READONLY (outer) = TREE_READONLY (type);
+  TREE_THIS_VOLATILE (outer) = TREE_THIS_VOLATILE (type);
+
+  return outer;
+}
+
 /* Returns a vector tree node given a vector mode, the inner type, and
    the signness.  */
 
-static tree
+tree
 make_vector (enum machine_mode mode, tree innertype, int unsignedp)
 {
   tree t;
Index: tree.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/tree.h,v
retrieving revision 1.458.2.4
diff -u -p -r1.458.2.4 tree.h
--- tree.h	8 Feb 2004 01:52:43 -0000	1.458.2.4
+++ tree.h	17 Aug 2004 01:09:50 -0000
@@ -2849,6 +2849,8 @@ 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);
 extern int real_twop (tree);
Index: config/darwin.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/darwin.h,v
retrieving revision 1.65.4.1
diff -u -p -r1.65.4.1 darwin.h
--- config/darwin.h	6 Apr 2004 18:32:59 -0000	1.65.4.1
+++ config/darwin.h	17 Aug 2004 01:09:51 -0000
@@ -99,7 +99,13 @@ Boston, MA 02111-1307, USA.  */
    Note that an option name with a prefix that matches another option
    name, that also takes an argument, needs to be modified so the
    prefix is different, otherwise a '*' after the shorter option will
-   match with the longer one.  */
+   match with the longer one.
+
+   The SUBTARGET_OPTION_TRANSLATE_TABLE macro, which _must_ be defined
+   in gcc/config/{i386,rs6000}/darwin.h, should contain any additional
+   command-line option translations specific to the particular target
+   architecture.  */
+
 #define TARGET_OPTION_TRANSLATE_TABLE \
   { "-all_load", "-Zall_load" },  \
   { "-allowable_client", "-Zallowable_client" },  \
@@ -126,7 +132,8 @@ Boston, MA 02111-1307, USA.  */
   { "-multi_module", "-Zmulti_module" },  \
   { "-static", "-static -Wa,-static" },  \
   { "-single_module", "-Zsingle_module" },  \
-  { "-unexported_symbols_list", "-Zunexported_symbols_list" }
+  { "-unexported_symbols_list", "-Zunexported_symbols_list" },  \
+  SUBTARGET_OPTION_TRANSLATE_TABLE
 
 /* These compiler options take n arguments.  */
 
Index: config/i386/darwin.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/i386/darwin.h,v
retrieving revision 1.9
diff -u -p -r1.9 darwin.h
--- config/i386/darwin.h	27 Sep 2003 04:48:18 -0000	1.9
+++ config/i386/darwin.h	17 Aug 2004 01:09:51 -0000
@@ -41,6 +41,10 @@ Boston, MA 02111-1307, USA.  */
 #undef CC1_SPEC
 #define CC1_SPEC "%{!static:-fPIC}"
 
+/* Use the following macro for any Darwin/x86-specific command-line option
+   translation.  */
+#define SUBTARGET_OPTION_TRANSLATE_TABLE
+
 #define ASM_SPEC "-arch i386 \
   %{Zforce_cpusubtype_ALL:-force_cpusubtype_ALL} \
   %{!Zforce_cpusubtype_ALL:%{mmmx:-force_cpusubtype_ALL}\
Index: config/rs6000/darwin.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/rs6000/darwin.h,v
retrieving revision 1.45.4.2
diff -u -p -r1.45.4.2 darwin.h
--- config/rs6000/darwin.h	31 Jan 2004 06:18:34 -0000	1.45.4.2
+++ config/rs6000/darwin.h	17 Aug 2004 01:09:52 -0000
@@ -111,6 +111,13 @@ do {									\
 #define SUBTARGET_EXTRA_SPECS			\
   { "darwin_arch", "ppc" },
 
+/* The "-faltivec" option should have been called "-maltivec" all along.  */
+#define SUBTARGET_OPTION_TRANSLATE_TABLE                               \
+  { "-faltivec", "-maltivec -include altivec.h" },     \
+  { "-fno-altivec", "-mno-altivec" },  \
+  { "-Waltivec-long-deprecated",       "-mwarn-altivec-long" }, \
+  { "-Wno-altivec-long-deprecated", "-mno-warn-altivec-long" }
+
 /* Make both r2 and r3 available for allocation.  */
 #define FIXED_R2 0
 #define FIXED_R13 0
Index: config/rs6000/rs6000-c.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/rs6000/rs6000-c.c,v
retrieving revision 1.10
diff -u -p -r1.10 rs6000-c.c
--- config/rs6000/rs6000-c.c	12 Sep 2003 19:00:45 -0000	1.10
+++ config/rs6000/rs6000-c.c	17 Aug 2004 01:09:52 -0000
@@ -92,7 +92,15 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
   if (! TARGET_POWER && ! TARGET_POWER2 && ! TARGET_POWERPC)
     builtin_define ("_ARCH_COM");
   if (TARGET_ALTIVEC)
-    builtin_define ("__ALTIVEC__");
+    {
+      builtin_define ("__ALTIVEC__");
+      builtin_define ("__VEC__=10206");
+
+      /* Define the AltiVec syntactic elements.  */
+      builtin_define ("__vector=__attribute__((altivec(vector__)))");
+      builtin_define ("__pixel=__attribute__((altivec(pixel__))) unsigned short");
+      builtin_define ("__bool=__attribute__((altivec(bool__))) unsigned");
+    }
   if (TARGET_SPE)
     builtin_define ("__SPE__");
   if (TARGET_SOFT_FLOAT)
Index: config/rs6000/rs6000.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.576.2.29
diff -u -p -r1.576.2.29 rs6000.c
--- config/rs6000/rs6000.c	11 Aug 2004 23:51:04 -0000	1.576.2.29
+++ config/rs6000/rs6000.c	17 Aug 2004 01:09:53 -0000
@@ -220,6 +220,20 @@ static GTY(()) tree opaque_V2SI_type_nod
 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 bool_char_type_node;	/* __bool char */
+static GTY(()) tree bool_short_type_node;	/* __bool short */
+static GTY(()) tree bool_int_type_node;		/* __bool int */
+static GTY(()) tree pixel_type_node;		/* __pixel */
+static GTY(()) tree bool_V16QI_type_node;	/* __vector __bool char */
+static GTY(()) tree bool_V8HI_type_node;	/* __vector __bool short */
+static GTY(()) tree bool_V4SI_type_node;	/* __vector __bool int */
+static GTY(()) tree pixel_V8HI_type_node;	/* __vector __pixel */
+
+int rs6000_warn_altivec_long = 1;		/* On by default. */
+const char *rs6000_warn_altivec_long_switch;
+
 const char *rs6000_traceback_name;
 static enum {
   traceback_default = 0,
@@ -290,6 +304,8 @@ static void rs6000_assemble_visibility (
 #endif
 static int rs6000_ra_ever_killed (void);
 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
+static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
+static const char *rs6000_mangle_fundamental_type (tree);
 extern const struct attribute_spec rs6000_attribute_table[];
 static void rs6000_set_default_type_attributes (tree);
 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
@@ -564,6 +580,9 @@ static const char alt_reg_names[][8] =
 #undef TARGET_EXPAND_BUILTIN
 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
 
+#undef TARGET_MANGLE_FUNDAMENTAL_TYPE
+#define TARGET_MANGLE_FUNDAMENTAL_TYPE rs6000_mangle_fundamental_type
+
 #undef TARGET_INIT_LIBFUNCS
 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
 
@@ -922,6 +941,17 @@ rs6000_override_options (const char *def
       rs6000_default_long_calls = (base[0] != 'n');
     }
 
+  /* Handle -m(no-)warn-altivec-long similarly.  */
+  if (rs6000_warn_altivec_long_switch)
+    {
+      const char *base = rs6000_warn_altivec_long_switch;
+      while (base[-1] != 'm') base--;
+
+      if (*rs6000_warn_altivec_long_switch != '\0')
+       error ("invalid option `%s'", base);
+      rs6000_warn_altivec_long = (base[0] != 'n');
+    }
+
   /* Handle -mprioritize-restricted-insns option.  */
   rs6000_sched_restricted_insns_priority
     = (rs6000_sched_groups ? 1 : 0);
@@ -5669,6 +5699,7 @@ rs6000_expand_binop_builtin (enum insn_c
       || icode == CODE_FOR_spe_evsrwiu)
     {
       /* Only allow 5-bit unsigned literals.  */
+      STRIP_NOPS (arg1);
       if (TREE_CODE (arg1) != INTEGER_CST
 	  || TREE_INT_CST_LOW (arg1) & ~0x1f)
 	{
@@ -6094,6 +6125,8 @@ altivec_expand_dst_builtin (tree exp, rt
 	    || arg2 == error_mark_node)
 	  return const0_rtx;
 
+	*expandedp = true;
+	STRIP_NOPS (arg2);
 	if (TREE_CODE (arg2) != INTEGER_CST
 	    || TREE_INT_CST_LOW (arg2) & ~0x3)
 	  {
@@ -6110,7 +6143,6 @@ altivec_expand_dst_builtin (tree exp, rt
 	if (pat != 0)
 	  emit_insn (pat);
 
-	*expandedp = true;
 	return NULL_RTX;
       }
 
@@ -6200,6 +6232,7 @@ altivec_expand_builtin (tree exp, rtx ta
     case ALTIVEC_BUILTIN_DSS:
       icode = CODE_FOR_altivec_dss;
       arg0 = TREE_VALUE (arglist);
+      STRIP_NOPS (arg0);
       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
       mode0 = insn_data[icode].operand[0].mode;
 
@@ -6219,6 +6252,15 @@ altivec_expand_builtin (tree exp, rtx ta
 
       emit_insn (gen_altivec_dss (op0));
       return NULL_RTX;
+
+    case ALTIVEC_BUILTIN_COMPILETIME_ERROR:
+      arg0 = TREE_VALUE (arglist);
+      while (TREE_CODE (arg0) == NOP_EXPR || TREE_CODE (arg0) == ADDR_EXPR)
+	arg0 = TREE_OPERAND (arg0, 0);
+      error ("invalid parameter combination for `%s' AltiVec intrinsic",
+	     TREE_STRING_POINTER (arg0));
+
+      return const0_rtx;
     }
 
   /* Expand abs* operations.  */
@@ -6658,6 +6700,73 @@ rs6000_init_builtins (void)
   opaque_V2SF_type_node = copy_node (V2SF_type_node);
   opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
 
+  /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
+     types, especially in C++ land.  Similarly, 'vector pixel' is distinct from+     'vector unsigned short'.  */
+
+  bool_char_type_node = copy_node (unsigned_intQI_type_node);
+  TYPE_MAIN_VARIANT (bool_char_type_node) = bool_char_type_node;
+  bool_short_type_node = copy_node (unsigned_intHI_type_node);
+  TYPE_MAIN_VARIANT (bool_short_type_node) = bool_short_type_node;
+  bool_int_type_node = copy_node (unsigned_intSI_type_node);
+  TYPE_MAIN_VARIANT (bool_int_type_node) = bool_int_type_node;
+  pixel_type_node = copy_node (unsigned_intHI_type_node);
+  TYPE_MAIN_VARIANT (pixel_type_node) = pixel_type_node;
+
+  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+					    get_identifier ("__bool char"),
+					    bool_char_type_node));
+  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+					    get_identifier ("__bool short"),
+					    bool_short_type_node));
+  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+					    get_identifier ("__bool int"),
+					    bool_int_type_node));
+  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+					    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);
+
+  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+					    get_identifier ("__vector unsigned char"),
+					    unsigned_V16QI_type_node));
+  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+					    get_identifier ("__vector signed char"),
+					    V16QI_type_node));
+  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+					    get_identifier ("__vector __bool char"),
+					    bool_V16QI_type_node));
+
+  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+					    get_identifier ("__vector unsigned short"),
+					    unsigned_V8HI_type_node));
+  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+					    get_identifier ("__vector signed short"),
+					    V8HI_type_node));
+  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+					    get_identifier ("__vector __bool short"),
+					    bool_V8HI_type_node));
+
+  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+					    get_identifier ("__vector unsigned int"),
+					    unsigned_V4SI_type_node));
+  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+					    get_identifier ("__vector signed int"),
+					    V4SI_type_node));
+  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+					    get_identifier ("__vector __bool int"),
+					    bool_V4SI_type_node));
+
+  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+					    get_identifier ("__vector float"),
+					    V4SF_type_node));
+  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+					    get_identifier ("__vector __pixel"),
+					    pixel_V8HI_type_node));
+
   if (TARGET_SPE)
     spe_init_builtins ();
   if (TARGET_ALTIVEC)
@@ -6963,8 +7072,8 @@ altivec_init_builtins (void)
     = build_function_type (V8HI_type_node, void_list_node);
   tree void_ftype_void
     = build_function_type (void_type_node, void_list_node);
-  tree void_ftype_qi
-    = build_function_type_list (void_type_node, char_type_node, NULL_TREE);
+  tree void_ftype_int
+    = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
 
   tree v16qi_ftype_long_pcvoid
     = build_function_type_list (V16QI_type_node,
@@ -7008,10 +7117,13 @@ altivec_init_builtins (void)
     = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
   tree v4sf_ftype_v4sf
     = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
-  tree void_ftype_pcvoid_int_char
+  tree void_ftype_pcvoid_int_int
     = build_function_type_list (void_type_node,
 				pcvoid_type_node, integer_type_node,
-				char_type_node, NULL_TREE);
+				integer_type_node, NULL_TREE);
+  tree int_ftype_pcchar
+    = build_function_type_list (integer_type_node,
+				pcchar_type_node, NULL_TREE);
   
   def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
 	       ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
@@ -7032,7 +7144,7 @@ altivec_init_builtins (void)
   def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
   def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
   def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
-  def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_qi, ALTIVEC_BUILTIN_DSS);
+  def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
   def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
   def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
   def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
@@ -7046,10 +7158,14 @@ altivec_init_builtins (void)
   def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
   def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
 
+  /* See altivec.h for usage of "__builtin_altivec_compiletime_error".  */
+  def_builtin (MASK_ALTIVEC, "__builtin_altivec_compiletime_error", int_ftype_pcchar,
+	       ALTIVEC_BUILTIN_COMPILETIME_ERROR);
+
   /* Add the DST variants.  */
   d = (struct builtin_description *) bdesc_dst;
   for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
-    def_builtin (d->mask, d->name, void_ftype_pcvoid_int_char, d->code);
+    def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
 
   /* Initialize the predicates.  */
   dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
@@ -7134,12 +7250,12 @@ rs6000_common_init_builtins (void)
     = build_function_type_list (V16QI_type_node,
 				V16QI_type_node, V16QI_type_node,
 				V16QI_type_node, NULL_TREE);
-  tree v4si_ftype_char
-    = build_function_type_list (V4SI_type_node, char_type_node, NULL_TREE);
-  tree v8hi_ftype_char
-    = build_function_type_list (V8HI_type_node, char_type_node, NULL_TREE);
-  tree v16qi_ftype_char
-    = build_function_type_list (V16QI_type_node, char_type_node, NULL_TREE);
+  tree v4si_ftype_int
+    = build_function_type_list (V4SI_type_node, integer_type_node, NULL_TREE);
+  tree v8hi_ftype_int
+    = build_function_type_list (V8HI_type_node, integer_type_node, NULL_TREE);
+  tree v16qi_ftype_int
+    = build_function_type_list (V16QI_type_node, integer_type_node, NULL_TREE);
   tree v8hi_ftype_v16qi
     = build_function_type_list (V8HI_type_node, V16QI_type_node, NULL_TREE);
   tree v4sf_ftype_v4sf
@@ -7197,37 +7313,37 @@ rs6000_common_init_builtins (void)
   tree v4si_ftype_v4si_v4si
     = build_function_type_list (V4SI_type_node,
 				V4SI_type_node, V4SI_type_node, NULL_TREE);
-  tree v4sf_ftype_v4si_char
+  tree v4sf_ftype_v4si_int
     = build_function_type_list (V4SF_type_node,
-				V4SI_type_node, char_type_node, NULL_TREE);
-  tree v4si_ftype_v4sf_char
+				V4SI_type_node, integer_type_node, NULL_TREE);
+  tree v4si_ftype_v4sf_int
     = build_function_type_list (V4SI_type_node,
-				V4SF_type_node, char_type_node, NULL_TREE);
-  tree v4si_ftype_v4si_char
+				V4SF_type_node, integer_type_node, NULL_TREE);
+  tree v4si_ftype_v4si_int
     = build_function_type_list (V4SI_type_node,
-				V4SI_type_node, char_type_node, NULL_TREE);
-  tree v8hi_ftype_v8hi_char
+				V4SI_type_node, integer_type_node, NULL_TREE);
+  tree v8hi_ftype_v8hi_int
     = build_function_type_list (V8HI_type_node,
-				V8HI_type_node, char_type_node, NULL_TREE);
-  tree v16qi_ftype_v16qi_char
+				V8HI_type_node, integer_type_node, NULL_TREE);
+  tree v16qi_ftype_v16qi_int
     = build_function_type_list (V16QI_type_node,
-				V16QI_type_node, char_type_node, NULL_TREE);
-  tree v16qi_ftype_v16qi_v16qi_char
+				V16QI_type_node, integer_type_node, NULL_TREE);
+  tree v16qi_ftype_v16qi_v16qi_int
     = build_function_type_list (V16QI_type_node,
 				V16QI_type_node, V16QI_type_node,
-				char_type_node, NULL_TREE);
-  tree v8hi_ftype_v8hi_v8hi_char
+				integer_type_node, NULL_TREE);
+  tree v8hi_ftype_v8hi_v8hi_int
     = build_function_type_list (V8HI_type_node,
 				V8HI_type_node, V8HI_type_node,
-				char_type_node, NULL_TREE);
-  tree v4si_ftype_v4si_v4si_char
+				integer_type_node, NULL_TREE);
+  tree v4si_ftype_v4si_v4si_int
     = build_function_type_list (V4SI_type_node,
 				V4SI_type_node, V4SI_type_node,
-				char_type_node, NULL_TREE);
-  tree v4sf_ftype_v4sf_v4sf_char
+				integer_type_node, NULL_TREE);
+  tree v4sf_ftype_v4sf_v4sf_int
     = build_function_type_list (V4SF_type_node,
 				V4SF_type_node, V4SF_type_node,
-				char_type_node, NULL_TREE);
+				integer_type_node, NULL_TREE);
   tree v4sf_ftype_v4sf_v4sf
     = build_function_type_list (V4SF_type_node,
 				V4SF_type_node, V4SF_type_node, NULL_TREE);
@@ -7370,22 +7486,22 @@ rs6000_common_init_builtins (void)
       /* vchar, vchar, vchar, 4 bit literal.  */
       else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
 	       && mode3 == QImode)
-	type = v16qi_ftype_v16qi_v16qi_char;
+	type = v16qi_ftype_v16qi_v16qi_int;
 
       /* vshort, vshort, vshort, 4 bit literal.  */
       else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
 	       && mode3 == QImode)
-	type = v8hi_ftype_v8hi_v8hi_char;
+	type = v8hi_ftype_v8hi_v8hi_int;
 
       /* vint, vint, vint, 4 bit literal.  */
       else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
 	       && mode3 == QImode)
-	type = v4si_ftype_v4si_v4si_char;
+	type = v4si_ftype_v4si_v4si_int;
 
       /* vfloat, vfloat, vfloat, 4 bit literal.  */
       else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
 	       && mode3 == QImode)
-	type = v4sf_ftype_v4sf_v4sf_char;
+	type = v4sf_ftype_v4sf_v4sf_int;
 
       else
 	abort ();
@@ -7474,23 +7590,23 @@ rs6000_common_init_builtins (void)
       
       /* vint, vint, 5 bit literal.  */
       else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
-	type = v4si_ftype_v4si_char;
+	type = v4si_ftype_v4si_int;
       
       /* vshort, vshort, 5 bit literal.  */
       else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
-	type = v8hi_ftype_v8hi_char;
+	type = v8hi_ftype_v8hi_int;
       
       /* vchar, vchar, 5 bit literal.  */
       else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
-	type = v16qi_ftype_v16qi_char;
+	type = v16qi_ftype_v16qi_int;
 
       /* vfloat, vint, 5 bit literal.  */
       else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
-	type = v4sf_ftype_v4si_char;
+	type = v4sf_ftype_v4si_int;
       
       /* vint, vfloat, 5 bit literal.  */
       else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
-	type = v4si_ftype_v4sf_char;
+	type = v4si_ftype_v4sf_int;
 
       else if (mode0 == V2SImode && mode1 == SImode && mode2 == SImode)
 	type = v2si_ftype_int_int;
@@ -7543,11 +7659,11 @@ rs6000_common_init_builtins (void)
       mode1 = insn_data[d->icode].operand[1].mode;
 
       if (mode0 == V4SImode && mode1 == QImode)
-        type = v4si_ftype_char;
+        type = v4si_ftype_int;
       else if (mode0 == V8HImode && mode1 == QImode)
-        type = v8hi_ftype_char;
+        type = v8hi_ftype_int;
       else if (mode0 == V16QImode && mode1 == QImode)
-        type = v16qi_ftype_char;
+        type = v16qi_ftype_int;
       else if (mode0 == V4SFmode && mode1 == V4SFmode)
 	type = v4sf_ftype_v4sf;
       else if (mode0 == V8HImode && mode1 == V16QImode)
@@ -9156,12 +9272,12 @@ print_operand (FILE *file, rtx x, int co
 
     case 'P':
       /* The operand must be an indirect memory reference.  The result
-	 is the register number.  */
+	 is the register name.  */
       if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
 	  || REGNO (XEXP (x, 0)) >= 32)
 	output_operand_lossage ("invalid %%P value");
       else
-	fprintf (file, "%d", REGNO (XEXP (x, 0)));
+	fprintf (file, "%s", reg_names[REGNO (XEXP (x, 0))]);
       return;
 
     case 'q':
@@ -14819,11 +14935,117 @@ rs6000_initialize_trampoline (rtx addr, 
 const struct attribute_spec rs6000_attribute_table[] =
 {
   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
+  { "altivec",   1, 1, false, true,  false, rs6000_handle_altivec_attribute },
   { "longcall",  0, 0, false, true,  true,  rs6000_handle_longcall_attribute },
   { "shortcall", 0, 0, false, true,  true,  rs6000_handle_longcall_attribute },
   { NULL,        0, 0, false, false, false, NULL }
 };
 
+/* Handle the "altivec" attribute.  The attribute may have
+   arguments as follows:
+
+       __attribute__((altivec(vector__)))
+       __attribute__((altivec(pixel__)))       (always followed by 'unsigned short')
+       __attribute__((altivec(bool__)))        (always followed by 'unsigned')
+
+  and may appear more than once (e.g., 'vector bool char') in a
+  given declaration.  */
+
+static tree
+rs6000_handle_altivec_attribute (tree *node, tree name, tree args,
+				 int flags ATTRIBUTE_UNUSED,
+				 bool *no_add_attrs)
+{
+  tree type = *node, result = NULL_TREE;
+  enum machine_mode mode;
+  int unsigned_p;
+  char altivec_type
+    = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
+       && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
+       ? *IDENTIFIER_POINTER (TREE_VALUE (args))
+       : '?');
+
+  while (POINTER_TYPE_P (type)
+	 || TREE_CODE (type) == FUNCTION_TYPE
+	 || TREE_CODE (type) == METHOD_TYPE
+	 || TREE_CODE (type) == ARRAY_TYPE)
+    type = TREE_TYPE (type);
+
+  mode = TYPE_MODE (type);
+
+  if (rs6000_warn_altivec_long
+      && (type == long_unsigned_type_node || type == long_integer_type_node))
+    warning ("use of 'long' in AltiVec types is deprecated; use 'int'");
+
+  switch (altivec_type)
+    {
+    case 'v':
+      unsigned_p = TREE_UNSIGNED (type);
+      switch (mode)
+	{
+	  case SImode:
+	    result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
+	    break;
+	  case HImode:
+	    result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
+	    break;
+	  case QImode:
+	    result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
+	    break;
+	  case SFmode: result = V4SF_type_node; break;
+	    /* If the user says 'vector int bool', we may be handed the 'bool'
+	       attribute _before_ the 'vector' attribute, and so select the proper
+	       type in the 'b' case below.  */
+	  case V4SImode: case V8HImode: case V16QImode: result = type;
+	  default: break;
+	}
+      break;
+    case 'b':
+      switch (mode)
+	{
+	  case SImode: case V4SImode: result = bool_V4SI_type_node; break;
+	  case HImode: case V8HImode: result = bool_V8HI_type_node; break;
+	  case QImode: case V16QImode: result = bool_V16QI_type_node;
+	  default: break;
+	}
+      break;
+    case 'p':
+      switch (mode)
+	{
+	  case V8HImode: result = pixel_V8HI_type_node;
+	  default: break;
+	}
+    default: break;
+    }
+
+  if (result && result != type && TYPE_READONLY (type))
+    result = build_qualified_type (result, TYPE_QUAL_CONST);
+
+  *no_add_attrs = true;  /* No need to hang on to the attribute.  */
+
+  if (!result)
+    warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+  else
+    *node = reconstruct_complex_type (*node, result);
+
+  return NULL_TREE;
+}
+
+/* AltiVec defines four built-in scalar types that serve as vector
+   elements; we must teach the compiler how to mangle them.  */
+
+static const char *
+rs6000_mangle_fundamental_type (tree type)
+{
+  if (type == bool_char_type_node) return "U6__boolc";
+  if (type == bool_short_type_node) return "U6__bools";
+  if (type == pixel_type_node) return "u7__pixel";
+  if (type == bool_int_type_node) return "U6__booli";
+
+  /* For all other types, use normal C++ mangling.  */
+  return NULL;
+}
+
 /* Handle a "longcall" or "shortcall" attribute; arguments as in
    struct attribute_spec.handler.  */
 
Index: config/rs6000/rs6000.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.306.4.10
diff -u -p -r1.306.4.10 rs6000.h
--- config/rs6000/rs6000.h	14 Jun 2004 10:11:42 -0000	1.306.4.10
+++ config/rs6000/rs6000.h	17 Aug 2004 01:09:53 -0000
@@ -464,6 +464,9 @@ enum group_termination
    {"longcall", &rs6000_longcall_switch,				\
     N_("Avoid all range limits on call instructions"), 0},		\
    {"no-longcall", &rs6000_longcall_switch, "", 0},			\
+   {"warn-altivec-long", &rs6000_warn_altivec_long_switch, \
+    N_("Warn about deprecated 'vector long ...' AltiVec type usage"), 0}, \
+   {"no-warn-altivec-long", &rs6000_warn_altivec_long_switch, "", 0}, \
    {"sched-costly-dep=", &rs6000_sched_costly_dep_str,                  \
     N_("Determine which dependences between insns are considered costly"), 0}, \
    {"insert-sched-nops=", &rs6000_sched_insert_nops_str,                \
@@ -532,6 +535,9 @@ extern enum rs6000_dependence_cost rs600
 extern const char *rs6000_sched_insert_nops_str;
 extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
 
+extern int rs6000_warn_altivec_long;
+extern const char *rs6000_warn_altivec_long_switch;
+
 /* Alignment options for fields in structures for sub-targets following
    AIX-like ABI.
    ALIGN_POWER word-aligns FP doubles (default AIX ABI).
@@ -2918,9 +2924,10 @@ enum rs6000_builtins
   ALTIVEC_BUILTIN_ABS_V4SI,
   ALTIVEC_BUILTIN_ABS_V4SF,
   ALTIVEC_BUILTIN_ABS_V8HI,
-  ALTIVEC_BUILTIN_ABS_V16QI
+  ALTIVEC_BUILTIN_ABS_V16QI,
+  ALTIVEC_BUILTIN_COMPILETIME_ERROR,
   /* SPE builtins.  */
-  , SPE_BUILTIN_EVADDW,
+  SPE_BUILTIN_EVADDW,
   SPE_BUILTIN_EVAND,
   SPE_BUILTIN_EVANDC,
   SPE_BUILTIN_EVDIVWS,
Index: cp/Make-lang.in
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/Make-lang.in,v
retrieving revision 1.174.2.3
diff -u -p -r1.174.2.3 Make-lang.in
--- cp/Make-lang.in	6 Feb 2004 00:55:51 -0000	1.174.2.3
+++ cp/Make-lang.in	17 Aug 2004 01:09:53 -0000
@@ -258,7 +258,8 @@ cp/semantics.o: cp/semantics.c $(CXX_TRE
 cp/dump.o: cp/dump.c $(CXX_TREE_H) $(TM_H) tree-dump.h
 cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) rtl.h integrate.h insn-config.h \
   input.h $(PARAMS_H) debug.h tree-inline.h
-cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h real.h gt-cp-mangle.h $(TM_P_H)
+cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h real.h gt-cp-mangle.h \
+  $(TARGET_H) $(TM_P_H)
 
 cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) diagnostic.h gt-cp-parser.h output.h
 
Index: cp/mangle.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/mangle.c,v
retrieving revision 1.95.2.4
diff -u -p -r1.95.2.4 mangle.c
--- cp/mangle.c	26 Feb 2004 02:43:59 -0000	1.95.2.4
+++ cp/mangle.c	17 Aug 2004 01:09:53 -0000
@@ -59,6 +59,7 @@
 #include "toplev.h"
 #include "varray.h"
 #include "flags.h"
+#include "target.h"
 
 /* Debugging support.  */
 
@@ -1497,12 +1498,24 @@ write_type (tree type)
 	case BOOLEAN_TYPE:
 	case INTEGER_TYPE:  /* Includes wchar_t.  */
 	case REAL_TYPE:
+	{
+	  /* Handle any target-specific fundamental types.  */
+	  const char *target_mangling
+	    = targetm.mangle_fundamental_type (type);
+
+	  if (target_mangling)
+	    {
+	      write_string (target_mangling);
+	      return;
+	    }
+
 	  /* If this is a typedef, TYPE may not be one of
 	     the standard builtin type nodes, but an alias of one.  Use
 	     TYPE_MAIN_VARIANT to get to the underlying builtin type.  */
 	  write_builtin_type (TYPE_MAIN_VARIANT (type));
 	  ++is_builtin_type;
 	  break;
+	}
 
 	case COMPLEX_TYPE:
 	  write_char ('C');
Index: cp/tree.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.360.4.7
diff -u -p -r1.360.4.7 tree.c
--- cp/tree.c	21 Jun 2004 12:46:22 -0000	1.360.4.7
+++ cp/tree.c	17 Aug 2004 01:09:54 -0000
@@ -1764,6 +1764,8 @@ pod_type_p (tree t)
     return 1; /* pointer to non-member */
   if (TYPE_PTR_TO_MEMBER_P (t))
     return 1; /* pointer to member */
+  if (TREE_CODE (t) == VECTOR_TYPE)
+    return 1; /* vectors are (small) arrays of scalars */
   
   if (! CLASS_TYPE_P (t))
     return 0; /* other non-class type (reference or function) */
Index: doc/tm.texi
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.281.2.15
diff -u -p -r1.281.2.15 tm.texi
--- doc/tm.texi	17 Jul 2004 21:18:58 -0000	1.281.2.15
+++ doc/tm.texi	17 Aug 2004 01:09:55 -0000
@@ -1502,6 +1502,34 @@ precedence for that field, but the align
 may affect its placement.
 @end deftypefn
 
+@deftypefn {Target Hook} {const char *} TARGET_MANGLE_FUNDAMENTAL_TYPE (tree @var{type})
+If your target defines any fundamental types, define this hook to
+return the appropriate encoding for these types as part of a C++
+mangled name.  The @var{type} argument is the tree structure
+representing the type to be mangled.  The hook may be applied to trees
+which are not target-specific fundamental types; it should return
+@code{NULL} for all such types, as well as arguments it does not
+recognize.  If the return value is not @code{NULL}, it must point to
+a statically-allocated string constant.
+
+Target-specific fundamental types might be new fundamental types or
+qualified versions of ordinary fundamental types.  Encode new
+fundamental types as @samp{@w{u @var{n} @var{name}}}, where @var{name}
+is the name used for the type in source code, and @var{n} is the
+length of @var{name} in decimal.  Encode qualified versions of
+ordinary types as @samp{@w{U @var{n} @var{name} @var{code}}}, where
+@var{name} is the name used for the type qualifier in source code,
+@var{n} is the length of @var{name} as above, and @var{code} is the
+code used to represent the unqualified version of this type.  (See
+@code{write_builtin_type} in @file{cp/mangle.c} for the list of
+codes.)  In both cases the spaces are for clarity; do not include any
+spaces in your string.
+
+The default version of this hook always returns @code{NULL}, which is
+appropriate for a target that does not define any new fundamental
+types.
+@end deftypefn
+
 @node Type Layout
 @section Layout of Source Language Data Types
 
Index: testsuite/g++.dg/ext/altivec-1.C
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/g++.dg/ext/altivec-1.C,v
retrieving revision 1.1
diff -u -p -r1.1 altivec-1.C
--- testsuite/g++.dg/ext/altivec-1.C	25 Aug 2003 15:47:29 -0000	1.1
+++ testsuite/g++.dg/ext/altivec-1.C	17 Aug 2004 01:09:56 -0000
@@ -1,4 +1,5 @@
-// { dg-do compile { target powerpc-*-* } } */
+/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-xfail-if "" { "powerpc-ibm-aix*" } { "-maltivec" } { "" } } */
 /* { dg-options "-maltivec" } */
 
 #include <altivec.h>
Index: testsuite/gcc.dg/altivec-1.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/gcc.dg/altivec-1.c,v
retrieving revision 1.4
diff -u -p -r1.4 altivec-1.c
--- testsuite/gcc.dg/altivec-1.c	12 Mar 2002 01:24:42 -0000	1.4
+++ testsuite/gcc.dg/altivec-1.c	17 Aug 2004 01:09:57 -0000
@@ -1,9 +1,11 @@
-/* { dg-do run { target powerpc-*-*altivec powerpc-*-*-*altivec } } */
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-xfail-if "" { "powerpc-*-eabispe*" "powerpc-ibm-aix*" } { "-maltivec" } { "" } } */
 /* { dg-options "-maltivec" } */
 
 /* Program to test PowerPC AltiVec instructions.  */
 
 #include <altivec.h>
+#include "altivec_check.h"
 
 extern void abort (void);
 
@@ -22,6 +24,8 @@ vector float f, g, h;
 
 int main ()
 {
+  altivec_check();  /* Exits if AltiVec not supported */
+
   k = vec_add (a1, a2);
   if (!vec_all_eq (addi, k))
     abort ();
Index: testsuite/gcc.dg/altivec-10.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/gcc.dg/altivec-10.c,v
retrieving revision 1.1
diff -u -p -r1.1 altivec-10.c
--- testsuite/gcc.dg/altivec-10.c	16 Dec 2003 07:42:08 -0000	1.1
+++ testsuite/gcc.dg/altivec-10.c	17 Aug 2004 01:09:57 -0000
@@ -1,14 +1,11 @@
 /* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-xfail-if "" { "powerpc-ibm-aix*" } { "-maltivec" } { "" } } */
 /* { dg-options "-maltivec -mabi=altivec -fno-inline" } */
 
 #include <altivec.h>
 #include <signal.h>
 
-void 
-sig_ill_handler (int sig)
-{
-    exit(0);
-}
+#include "altivec_check.h"
 
 typedef union
 {
@@ -62,7 +59,7 @@ check_cmple()
 {
   vector float a = {1.0, 2.0, 3.0, 4.0};
   vector float b = {1.0, 3.0, 2.0, 5.0};
-  vector signed int aux;
+  vector bool int aux;
   vector signed int le = {-1, -1, 0, -1};
 
   aux = vec_cmple (a, b);
@@ -75,10 +72,7 @@ check_cmple()
 int 
 main()
 {
-  /* Exit on systems without altivec.  */
-  signal (SIGILL, sig_ill_handler);
-  asm volatile ("vor 0,0,0");
-  signal (SIGILL, SIG_DFL);
+  altivec_check ();
 
   check_cmple ();
   check_vec_all_num ();
Index: testsuite/gcc.dg/altivec-11.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/gcc.dg/altivec-11.c,v
retrieving revision 1.1.4.1
diff -u -p -r1.1.4.1 altivec-11.c
--- testsuite/gcc.dg/altivec-11.c	11 Jun 2004 09:54:16 -0000	1.1.4.1
+++ testsuite/gcc.dg/altivec-11.c	17 Aug 2004 01:09:57 -0000
@@ -1,4 +1,5 @@
 /* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-xfail-if "" { "powerpc-ibm-aix*" } { "-maltivec" } { "" } } */
 /* { dg-options "-O2 -maltivec -mabi=altivec" } */
 /* { dg-final { scan-assembler-not "lvx" } } */
 #include <altivec.h>
Index: testsuite/gcc.dg/altivec-2.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/gcc.dg/altivec-2.c,v
retrieving revision 1.3
diff -u -p -r1.3 altivec-2.c
--- testsuite/gcc.dg/altivec-2.c	4 Jun 2002 06:01:17 -0000	1.3
+++ testsuite/gcc.dg/altivec-2.c	17 Aug 2004 01:09:57 -0000
@@ -1,4 +1,4 @@
-/* { dg-do compile { target powerpc-*-* } } */
+/* { dg-do compile { target powerpc*-*-* } } */
 /* { dg-options "-maltivec" } */
 
 /* Program to test the vector_size attribute.  This needs to run on a
Index: testsuite/gcc.dg/altivec-3.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/gcc.dg/altivec-3.c,v
retrieving revision 1.1
diff -u -p -r1.1 altivec-3.c
--- testsuite/gcc.dg/altivec-3.c	12 Feb 2002 22:26:12 -0000	1.1
+++ testsuite/gcc.dg/altivec-3.c	17 Aug 2004 01:09:57 -0000
@@ -1,8 +1,11 @@
-/* { dg-do run { target powerpc-*-*altivec powerpc-*-*-*altivec } } */
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-xfail-if "" { "powerpc-*-eabispe*" "powerpc-ibm-aix*" } { "-maltivec" } { "" } } */
 /* { dg-options "-maltivec" } */
 
-typedef int int4 __attribute__ ((mode(V4SI)));
-typedef float float4 __attribute__ ((mode(V4SF)));
+#include "altivec_check.h"
+
+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 };
@@ -46,7 +49,8 @@ compare_float4 (float *a, float *b)
       abort ();
 }
 
-main ()
+void
+main1 ()
 {
   int loc1 = 600, loc2 = 800;
   int4 a3 = (int4) { loc1, loc2, 1000, 1200 };
@@ -64,6 +68,12 @@ main ()
   ftmp = vec_add_float4 (f1, f2);
   vec_store (h3, ftmp);
   compare_float4 (g3, h3);
+}
 
+int
+main ()
+{
+  altivec_check ();
+  main1 ();
   exit (0);
 }
Index: testsuite/gcc.dg/altivec-4.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/gcc.dg/altivec-4.c,v
retrieving revision 1.6
diff -u -p -r1.6 altivec-4.c
--- testsuite/gcc.dg/altivec-4.c	5 Feb 2002 08:12:31 -0000	1.6
+++ testsuite/gcc.dg/altivec-4.c	17 Aug 2004 01:09:57 -0000
@@ -1,9 +1,10 @@
-/* { dg-do compile { target powerpc-*-* } } */
+/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-xfail-if "" { "powerpc-ibm-aix*" } { "-maltivec" } { "" } } */
 /* { dg-options "-maltivec -O0 -Wall" } */
 
 #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;
Index: testsuite/gcc.dg/altivec-5.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/gcc.dg/altivec-5.c,v
retrieving revision 1.1
diff -u -p -r1.1 altivec-5.c
--- testsuite/gcc.dg/altivec-5.c	15 Apr 2002 22:39:10 -0000	1.1
+++ testsuite/gcc.dg/altivec-5.c	17 Aug 2004 01:09:57 -0000
@@ -1,4 +1,4 @@
-/* { dg-do compile { target powerpc-*-* } } */
+/* { dg-do compile { target powerpc*-*-* } } */
 /* { dg-options "-maltivec -O2" } */
 
 #define vector __attribute__((vector_size(16)))
Index: testsuite/gcc.dg/altivec-7.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/gcc.dg/altivec-7.c,v
retrieving revision 1.1
diff -u -p -r1.1 altivec-7.c
--- testsuite/gcc.dg/altivec-7.c	1 May 2002 06:52:30 -0000	1.1
+++ testsuite/gcc.dg/altivec-7.c	17 Aug 2004 01:09:57 -0000
@@ -1,45 +1,46 @@
 /* Origin: Aldy Hernandez  <aldyh@redhat.com>  */
 
-/* { dg-do compile { target powerpc-*-* } } */
+/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-xfail-if "" { "powerpc-ibm-aix*" } { "-maltivec" } { "" } } */
 /* { dg-options "-maltivec" } */
 
 #include <altivec.h>
 
-long **longp;
+int **intp;
 int *var_int;
-unsigned long **ulongp;
+unsigned int **uintp;
 vector pixel *varpixel;
 vector signed char *vecchar;
-vector signed long *vecint;
+vector signed int *vecint;
 vector signed short *vecshort;
 vector unsigned char *vecuchar;
-vector unsigned long *vecuint;
+vector unsigned int *vecuint;
 vector unsigned short *vecushort;
 vector float *vecfloat;
 
 int main ()
 {
-  *vecfloat++ = vec_andc(vecint[0], vecfloat[1]);
-  *vecfloat++ = vec_andc(vecfloat[0], vecint[1]);
-  *vecfloat++ = vec_vxor(vecint[0], vecfloat[1]);
-  *vecfloat++ = vec_vxor(vecfloat[0], vecint[1]);
+  *vecfloat++ = vec_andc((vector bool int)vecint[0], vecfloat[1]);
+  *vecfloat++ = vec_andc(vecfloat[0], (vector bool int)vecint[1]);
+  *vecfloat++ = vec_vxor((vector bool int)vecint[0], vecfloat[1]);
+  *vecfloat++ = vec_vxor(vecfloat[0], (vector bool int)vecint[1]);
   *varpixel++ = vec_packpx(vecuint[0], vecuint[1]);
   *varpixel++ = vec_vpkpx(vecuint[0], vecuint[1]);
   *vecshort++ = vec_vmulosb(vecchar[0], vecchar[1]);
-  *vecint++ = vec_ld(var_int[0], longp[1]);
-  *vecint++ = vec_lde(var_int[0], longp[1]);
-  *vecint++ = vec_ldl(var_int[0], longp[1]);
-  *vecint++ = vec_lvewx(var_int[0], longp[1]);
+  *vecint++ = vec_ld(var_int[0], intp[1]);
+  *vecint++ = vec_lde(var_int[0], intp[1]);
+  *vecint++ = vec_ldl(var_int[0], intp[1]);
+  *vecint++ = vec_lvewx(var_int[0], intp[1]);
   *vecint++ = vec_unpackh(vecshort[0]);
   *vecint++ = vec_unpackl(vecshort[0]);
-  *vecushort++ = vec_andc(vecshort[0], vecushort[1]);
-  *vecushort++ = vec_andc(vecushort[0], vecshort[1]);
-  *vecushort++ = vec_vxor(vecshort[0], vecushort[1]);
-  *vecushort++ = vec_vxor(vecushort[0], vecshort[1]);
-  *vecuint++ = vec_ld(var_int[0], ulongp[1]);
-  *vecuint++ = vec_lvx(var_int[0], ulongp[1]);
+  *vecushort++ = vec_andc((vector bool short)vecshort[0], vecushort[1]);
+  *vecushort++ = vec_andc(vecushort[0], (vector bool short)vecshort[1]);
+  *vecushort++ = vec_vxor((vector bool short)vecshort[0], vecushort[1]);
+  *vecushort++ = vec_vxor(vecushort[0], (vector bool short)vecshort[1]);
+  *vecuint++ = vec_ld(var_int[0], uintp[1]);
+  *vecuint++ = vec_lvx(var_int[0], uintp[1]);
   *vecuint++ = vec_vmsumubm(vecuchar[0], vecuchar[1], vecuint[2]);
-  *vecuchar++ = vec_xor(vecuchar[0], vecchar[1]);
+  *vecuchar++ = vec_xor(vecuchar[0], (vector unsigned char)vecchar[1]);
 
   return 0;
 }
Index: testsuite/gcc.dg/altivec-8.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/gcc.dg/altivec-8.c,v
retrieving revision 1.1
diff -u -p -r1.1 altivec-8.c
--- testsuite/gcc.dg/altivec-8.c	2 May 2002 02:03:14 -0000	1.1
+++ testsuite/gcc.dg/altivec-8.c	17 Aug 2004 01:09:57 -0000
@@ -1,7 +1,8 @@
 /* Origin: Aldy Hernandez  <aldyh@redhat.com>  */
 /* Test rs6000_legitimate_address.  PRE_INC should be invalid.  */
 
-/* { dg-do compile { target powerpc-*-* } } */
+/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-xfail-if "" { "powerpc-ibm-aix*" } { "-maltivec" } { "" } } */
 /* { dg-options "-maltivec" } */
 
 #include <altivec.h>
Index: testsuite/gcc.dg/altivec-9.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/gcc.dg/altivec-9.c,v
retrieving revision 1.1
diff -u -p -r1.1 altivec-9.c
--- testsuite/gcc.dg/altivec-9.c	10 Mar 2003 20:52:31 -0000	1.1
+++ testsuite/gcc.dg/altivec-9.c	17 Aug 2004 01:09:57 -0000
@@ -1,4 +1,4 @@
-/* { dg-do compile { target powerpc-*-* } } */
+/* { dg-do compile { target powerpc*-*-* } } */
 /* { dg-options "-maltivec -mabi=altivec -g" } */
 
 /* PR9564 */
Index: testsuite/gcc.dg/altivec-varargs-1.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/gcc.dg/altivec-varargs-1.c,v
retrieving revision 1.2
diff -u -p -r1.2 altivec-varargs-1.c
--- testsuite/gcc.dg/altivec-varargs-1.c	19 Dec 2003 07:52:00 -0000	1.2
+++ testsuite/gcc.dg/altivec-varargs-1.c	17 Aug 2004 01:09:57 -0000
@@ -1,10 +1,13 @@
-/* { dg-do run { target powerpc*-*-darwin* powerpc*-*-*altivec* powerpc*-*-linux*} } */
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-xfail-if "" { "powerpc-*-eabispe*" "powerpc-ibm-aix*" } { "-maltivec" } { "" } } */
 /* { dg-options "-maltivec -mabi=altivec -fno-inline" } */
 
 #include <stdarg.h>
 #include <signal.h>
 
-#define vector __attribute__((mode(V4SI)))
+#include "altivec_check.h"
+
+#define vector __attribute__((vector_size (16)))
 
 const vector unsigned int v1 = {10,11,12,13};
 const vector unsigned int v2 = {20,21,22,23};
@@ -72,19 +75,10 @@ int main1(void)
   return 0;
 }
 
-void 
-sig_ill_handler (int sig)
-{
-    exit(0);
-}
-
 int main (void)
 {
-  /* Exit on systems without altivec.  */
-  signal (SIGILL, sig_ill_handler);
-  /* Altivec instruction, 'vor %v0,%v0,%v0'.  */
-  asm volatile (".long 0x10000484");
-  signal (SIGILL, SIG_DFL);
+  /* Exit on systems without AltiVec.  */
+  altivec_check ();
 
   return main1 ();
 }
Index: testsuite/lib/target-supports.exp
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/lib/target-supports.exp,v
retrieving revision 1.9.4.4
diff -u -p -r1.9.4.4 target-supports.exp
--- testsuite/lib/target-supports.exp	9 Apr 2004 22:23:00 -0000	1.9.4.4
+++ testsuite/lib/target-supports.exp	17 Aug 2004 01:09:57 -0000
@@ -232,3 +232,60 @@ proc check_named_sections_available { } 
     verbose "check_named_sections_available  returning $answer" 2
     return $answer
 }
+
+# Return 1 if the target supports executing AltiVec instructions, 0
+# otherwise.  Cache the result.
+
+proc check_vmx_hw_available { } {
+    global vmx_hw_available_saved
+    global tool
+
+    if [info exists vmx_hw_available_saved] {
+	verbose "check_hw_available  returning saved $vmx_hw_available_saved" 2
+    } else {
+	set vmx_hw_available_saved 0
+
+	# Some simulators are known to not support VMX instructions.
+	if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] } {
+	    verbose "check_hw_available  returning 0" 2
+	    return $vmx_hw_available_saved
+	}
+
+	# Set up, compile, and execute a test program containing VMX
+	# instructions.  Include the current process ID in the file
+	# names to prevent conflicts with invocations for multiple
+	# testsuites.
+	set src vmx[pid].c
+	set exe vmx[pid].x
+
+	set f [open $src "w"]
+	puts $f "int main() {"
+	puts $f "#ifdef __MACH__"
+	puts $f "  asm volatile (\"vor v0,v0,v0\");"
+	puts $f "#else"
+	puts $f "  asm volatile (\"vor 0,0,0\");"
+	puts $f "#endif"
+	puts $f "  return 0; }"
+	close $f
+
+	verbose "check_vmx_hw_available  compiling testfile $src" 2
+	set lines [${tool}_target_compile $src $exe executable ""]
+	file delete $src
+
+	if [string match "" $lines] then {
+	    # No error message, compilation succeeded.
+	    set result [${tool}_load "./$exe" "" ""]
+	    set status [lindex $result 0]
+	    remote_file build delete $exe
+	    verbose "check_vmx_hw_available testfile status is <$status>" 2
+
+	    if { $status == "pass" } then {
+		set vmx_hw_available_saved 1
+	    }
+	} else {
+	    verbose "check_vmx_hw_availalble testfile compilation failed" 2
+	}
+    }
+
+    return $vmx_hw_available_saved
+}

Attachment: 20040816.diffs.altivec.h.bz2
Description: BZip2 compressed data

Attachment: 20040816.diffs.extend.texi.bz2
Description: BZip2 compressed data


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