public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: Include facility for .md files - altivec patches
  2001-11-05 18:41         ` Include facility for .md files - " Alan Matsuoka
@ 2001-11-03 20:37           ` Geoff Keating
  2001-11-13  4:26             ` Geoff Keating
                               ` (3 more replies)
  2001-11-05 18:49           ` Joseph S. Myers
                             ` (4 subsequent siblings)
  5 siblings, 4 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-03 20:37 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: gcc-patches

Alan Matsuoka <alanm@cygnus.com> writes:

> 2001-11-05  Alan Matsuoka  <alanm@redhat.com>
> 
>         * rtl.def (INCLUDE) : Define.
> 	* gensupport.c (init_include_reader, process_include, save_string) :  New functions to
> 	  implement an include facility in .md files.
> 	* gensupport.h : Add prototype for init_md_reader_args.
> 	* genattr.c genattrtab.c gencodes.c genconfig.c genemit.c
> 	  genextract.c genflags.c genopinit.c genoutput.c genpeep.c
> 	  genrecog.c: Change call to init_md_reader to init_md_reader_args.
> 	* md.texi: Document (include "path") and -I directives for RTL generation tools.

The patch is OK.

When you commit, please fix the whitespace and line-wrap the ChangeLog
entry to 80 columns.

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* altivec patches
@ 2001-11-05 12:52 Aldy Hernandez
  2001-11-05 12:58 ` Aldy Hernandez
                   ` (6 more replies)
  0 siblings, 7 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-05 12:52 UTC (permalink / raw)
  To: gcc patches; +Cc: Geoff Keating

finally...

i have fixed everything that was commented on.
alignment macros are in place, a new abi extension (TARGET_ALTIVEC_ABI),
documentation, etc. 

i have not documented the builtins because i'm going to write a script
to generate those automagially later.  besides, there's pretty much a
1:1 correspondence between the altivec insns and the builtin names 

i have added an option "-mabi=altivec" that enhances the current abi
with altivec ABI extensions.  this flag does NOT replace the current
abi, but extends the current abi to handle altivec extensions as
documented by the motorola manuals. 

i have promised geoff i will rewrite the -mcall-foo hackery and
implement "-mabi=sysv,eabi,altivec" style abi flags.  i will do this
after i'm done with the altivec stuff.  i don't want to diverge the
purpose of this patch into unrelated abi functionality.  right now
-mabi= only supports -mabi=altivec. 
what is left?
    - the rest of the gazillion builtins
    
    - varargs
    
    - frame stuff: epilogue, prologue, vrsave
    - <altivec.h> for the user.  this .h will implement the overloaded
    altivec functions described in the "altivec programming interface
    model".  Stuff like generic (overloaded) "vec_add(veca, vecb)". 
    
    - test cases.  i will commit a few simple tests, but serious tests
    will come after i'm done playing with the G3 box. 
    
and then there's the front end changes, but that's a different story. 

i have tested this on powerpc-unknown-linux-gnu.  it bootstraps.  no
regressions on testsuite. 

the patch below has the boring builtin stuff deleted (as requested). 
there's just 1 or 2 builtins for proof of concept. 

ok to install? 
2001-11-05  Aldy Hernandez  <aldyh@redhat.com>

	* doc/invoke.texi: Add -maltivec, -mno-altivec, and -mabi=altivec
	for rs6000.

	* config/rs6000/rs6000.h (MASK_ALTIVEC): New.
	(TARGET_ALTIVEC): New.
	(TARGET_SWITCHES): Add altivec.
	(FIRST_PSEUDO_REGISTER): Change to 109.
	(CALL_USED_REGISTERS): Same.
	(FIRST_ALTIVEC_REGNO): New.
	(LAST_ALTIVEC_REGNO): New.
	(ALTIVEC_REGNO_P): New.
	(UNITS_PER_ALTIVEC_WORD): New.
	(ALTIVEC_VECTOR_MODE): New.
	(FIXED_REGISTERS): Add altivec registers.
	(REG_ALLOC_ORDER): Same.
	(HARD_REGNO_NREGS): Adjust for altivec registers.
	(HARD_REGNO_MODE_OK): Same.
	(MODES_TIEABLE_P): Same.
	(REGISTER_MOVE_COST): Same.
	(REGNO_REG_CLASS): Same.
	(reg_class): Add ALTIVEC_REGS.
	(REG_CLASS_NAMES): Same.
	(REG_CLASS_CONTENTS): Same.
	(REG_CLASS_FROM_LETTER): Add 'v' constraint for ALTIVEC_REGS.
	(ALTIVEC_ARG_RETURN): New.
	(FUNCTION_VALUE): Handle VECTOR_TYPE.
	(LIBCALL_VALUE): Handle altivec vector modes.
	(VECTOR_MODE_SUPPORTED_P): New.
	(ALTIVEC_ARG_MIN_REG): New.
	(ALTIVEC_ARG_MAX_REG): New.
	(ALTIVEC_ARG_NUM_REG): New.
	(FUNCTION_VALUE_REGNO_P): Return true for altivec return register.
	(FUNCTION_ARG_REGNO_P): Support passing args in altivec registers.
	(REGISTER_NAMES): Add altivec regs.
	(DEBUG_REGISTER_NAMES): Same.
	(ADDITIONAL_REGISTER_NAMES): Same.
	(rs6000_builtins): New.
	(MD_EXPAND_BUILTIN): New.
	(MD_INIT_BUILTINS): New.
	(LEGITIMATE_OFFSET_ADDRESS_P): This addressing mode is not valid
	for AltiVec instructions.
	(LEGITIMATE_LO_SUM_ADDRESS_P): Same.
	(HARD_REGNO_MODE_OK): Altivec modes can only go in altivec
	registers.
	(SECONDARY_MEMORY_NEEDED): We need memory to copy vector modes.
	(PREDICATE_CODES): Add altivec_register.
	(TARGET_SWITCHES): Add no-altivec.
	(DATA_ALIGNMENT): Align vectors to 128 bits.
	(TARGET_OPTIONS): Add abi= option.
	Add rs6000_abi_string extern.
	(LOCAL_ALIGNMENT): New.
	(CPP_CPU_SPEC): Define __ALTIVEC__ when -maltivec.
	(MASK_ALTIVEC_ABI): New.
	(TARGET_ALTIVEC_ABI): New.
	(CONDITIONAL_REGISTER_USAGE): Set first 20 AltiVec registers to
	call-saved.
	(STACK_BOUNDARY): Adjust for altivec.
	(BIGGEST_ALIGNMENT): Same.
	(rs6000_args): Add vregno.
	(USE_ALTIVEC_FOR_ARG_P): New.
	
	* config/rs6000/sysv4.h (STACK_BOUNDARY): Adjust for altivec.
	(ABI_STACK_BOUNDARY): Same.
	(BIGGEST_ALIGNMENT): Same.
	(ADJUST_FIELD_ALIGN): Remove undef.  Define anew.
	(ROUND_TYPE_ALIGN): Same.
	
	* config/rs6000/rs6000.c (rs6000_expand_builtin): New.
	(altivec_expand_builtin): New.
	(altivec_init_builtins): New.
	(TARGET_EXPAND_BUILTIN): New.
	(TARGET_INIT_BUILTINS): New.
	(rs6000_init_builtins): New.
	(struct builtin_description): New.
	(bdesc_2arg): New.
	(rs6000_reg_names): Add altivec registers.
	(alt_reg_names): Same.
	(altivec_register): New.
	(secondary_reload_class): Altivec regs can hold altivec regs and
	memory.
	(rs6000_emit_move): Force constants into memory for AltiVec moves.
	(print_operand): Add 'y' case for printing altivec memory
	operands.
	(rs6000_legitimize_address): Legitimize vector addresses into
	[REG+REG] or [REG].
	(altivec_expand_binop_builtin): New.
	New string rs6000_current_abi.
	(rs6000_override_options): Call rs6000_parse_abi_options.
	(rs6000_parse_abi_options): New.
	(function_arg_boundary): Vector arguments must be 16
	byte aligned.
	(function_arg_advance): Handle vector arguments.
	(function_arg_partial_nregs): Same.
	(init_cumulative_args): Same.
	(function_arg): Same.

	* config/rs6000/rs6000.md (altivec_lvx): New.
	(type): Add altivec attribute.
	(*altivec_vec_move): New.
	(movv4si): New.
	(*movv4si_internal): New.
	(movv16qi): New.
	(*movv16qi_internal): New.
	(movv8hi): New.
	(*movv8hi_internal1): New.
	(movv4sf): New.
	(*movv4sf_internal1): New.
	(altivec_stvx): New.
	(vaddubm): New.

--builtins changelog removed--
	
	Index: doc/invoke.texi
===================================================================
RCS file: /cvs/uberbaum/gcc/doc/invoke.texi,v
retrieving revision 1.69
diff -c -p -r1.69 invoke.texi
*** invoke.texi	2001/10/28 19:12:12	1.69
--- invoke.texi	2001/11/05 19:49:18
*************** in the following sections.
*** 424,429 ****
--- 424,430 ----
  -mtune=@var{cpu-type} @gol
  -mpower  -mno-power  -mpower2  -mno-power2 @gol
  -mpowerpc  -mpowerpc64  -mno-powerpc @gol
+ -maltivec -mno-altivec @gol
  -mpowerpc-gpopt  -mno-powerpc-gpopt @gol
  -mpowerpc-gfxopt  -mno-powerpc-gfxopt @gol
  -mnew-mnemonics  -mold-mnemonics @gol
*************** in the following sections.
*** 436,441 ****
--- 437,443 ----
  -mno-relocatable  -mrelocatable-lib  -mno-relocatable-lib @gol
  -mtoc  -mno-toc -mlittle  -mlittle-endian  -mbig  -mbig-endian @gol
  -mcall-aix -mcall-sysv -mcall-netbsd @gol
+ -mabi=altivec @gol
  -mprototype  -mno-prototype @gol
  -msim  -mmvme  -mads  -myellowknife  -memb -msdata @gol
  -msdata=@var{opt}  -mvxworks -G @var{num}}
*************** values for @var{cpu_type} are used for @
*** 6677,6682 ****
--- 6679,6693 ----
  architecture, registers, and mnemonics set by @option{-mcpu}, but the
  scheduling parameters set by @option{-mtune}.
  
+ @item -maltivec
+ @itemx -mno-altivec
+ @opindex maltivec
+ @opindex mno-altivec
+ These switches enable or disable the use of built-in functions that
+ allow access to the AltiVec instruction set.  You may also need to set
+ @option{-mabi=altivec} to adjust the current ABI with AltiVec ABI
+ enhancements.
+ 
  @item -mfull-toc
  @itemx -mno-fp-in-toc
  @itemx -mno-sum-in-toc
*************** Linux-based GNU system.
*** 6904,6909 ****
--- 6915,6926 ----
  @opindex mcall-netbsd
  On System V.4 and embedded PowerPC systems compile code for the
  NetBSD operating system.
+ 
+ @item -mabi=altivec
+ @opindex mabi=altivec
+ Extend the current ABI with AltiVec ABI extensions.  This does not
+ change the default ABI, instead it adds the AltiVec ABI extensions to
+ the current ABI.
  
  @item -mprototype
  @itemx -mno-prototype
Index: rs6000.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.130
diff -c -p -r1.130 rs6000.h
*** rs6000.h	2001/10/02 03:36:44	1.130
--- rs6000.h	2001/11/05 19:49:23
*************** Boston, MA 02111-1307, USA.  */
*** 83,89 ****
  %{mcpu=801: -D_ARCH_PPC} \
  %{mcpu=821: -D_ARCH_PPC} \
  %{mcpu=823: -D_ARCH_PPC} \
! %{mcpu=860: -D_ARCH_PPC}"
  
  /* Common ASM definitions used by ASM_SPEC among the various targets
     for handling -mcpu=xxx switches.  */
--- 83,90 ----
  %{mcpu=801: -D_ARCH_PPC} \
  %{mcpu=821: -D_ARCH_PPC} \
  %{mcpu=823: -D_ARCH_PPC} \
! %{mcpu=860: -D_ARCH_PPC} \
! %{maltivec: -D__ALTIVEC__}"
  
  /* Common ASM definitions used by ASM_SPEC among the various targets
     for handling -mcpu=xxx switches.  */
*************** extern int target_flags;
*** 209,214 ****
--- 210,221 ----
  /* Nonzero if we need to schedule the prolog and epilog.  */
  #define MASK_SCHED_PROLOG	0x00040000
  
+ /* Use AltiVec instructions.  */
+ #define MASK_ALTIVEC		0x00080000
+ 
+ /* Enhance the current ABI with AltiVec extensions.  */
+ #define MASK_ALTIVEC_ABI	0x00100000
+ 
  #define TARGET_POWER		(target_flags & MASK_POWER)
  #define TARGET_POWER2		(target_flags & MASK_POWER2)
  #define TARGET_POWERPC		(target_flags & MASK_POWERPC)
*************** extern int target_flags;
*** 227,232 ****
--- 234,241 ----
  #define TARGET_NO_UPDATE	(target_flags & MASK_NO_UPDATE)
  #define TARGET_NO_FUSED_MADD	(target_flags & MASK_NO_FUSED_MADD)
  #define TARGET_SCHED_PROLOG	(target_flags & MASK_SCHED_PROLOG)
+ #define TARGET_ALTIVEC		(target_flags & MASK_ALTIVEC)
+ #define TARGET_ALTIVEC_ABI	(target_flags & MASK_ALTIVEC_ABI)
  
  #define TARGET_32BIT		(! TARGET_64BIT)
  #define TARGET_HARD_FLOAT	(! TARGET_SOFT_FLOAT)
*************** extern int target_flags;
*** 282,287 ****
--- 291,300 ----
  			N_("Use PowerPC-64 instruction set")},		\
    {"no-powerpc64",	- MASK_POWERPC64,				\
  			N_("Don't use PowerPC-64 instruction set")},	\
+   {"altivec",		MASK_ALTIVEC,					\
+ 			N_("Use AltiVec instructions.")},		\
+   {"no-altivec",	- MASK_ALTIVEC,					\
+ 			N_("Don't use AltiVec instructions.")},	\
    {"new-mnemonics",	MASK_NEW_MNEMONICS,				\
  			N_("Use new mnemonics for PowerPC architecture")},\
    {"old-mnemonics",	-MASK_NEW_MNEMONICS,				\
*************** extern enum processor_type rs6000_cpu;
*** 409,414 ****
--- 422,428 ----
     {"tune=", &rs6000_select[2].string,					\
      N_("Schedule code for given CPU") },				\
     {"debug=", &rs6000_debug_name, N_("Enable debug output") },		\
+    {"abi=", &rs6000_abi_string, N_("Specify ABI to use") },		\
     SUBTARGET_OPTIONS							\
  }
  
*************** struct rs6000_cpu_select
*** 424,430 ****
  extern struct rs6000_cpu_select rs6000_select[];
  
  /* Debug support */
! extern const char *rs6000_debug_name;		/* Name for -mdebug-xxxx option */
  extern int rs6000_debug_stack;		/* debug stack applications */
  extern int rs6000_debug_arg;		/* debug argument handling */
  
--- 438,445 ----
  extern struct rs6000_cpu_select rs6000_select[];
  
  /* Debug support */
! extern const char *rs6000_debug_name;	/* Name for -mdebug-xxxx option */
! extern const char *rs6000_abi_string;	/* for -mabi={sysv,darwin,solaris,eabi,aix,altivec} */
  extern int rs6000_debug_stack;		/* debug stack applications */
  extern int rs6000_debug_arg;		/* debug argument handling */
  
*************** extern int rs6000_debug_arg;		/* debug a
*** 505,510 ****
--- 520,526 ----
  #define UNITS_PER_WORD (! TARGET_POWERPC64 ? 4 : 8)
  #define MIN_UNITS_PER_WORD 4
  #define UNITS_PER_FP_WORD 8
+ #define UNITS_PER_ALTIVEC_WORD 16
  
  /* Type used for ptrdiff_t, as a string used in a declaration.  */
  #define PTRDIFF_TYPE "int"
*************** extern int rs6000_debug_arg;		/* debug a
*** 569,581 ****
  #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
  
  /* Boundary (in *bits*) on which stack pointer should be aligned.  */
! #define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
  
  /* Allocation boundary (in *bits*) for the code of a function.  */
  #define FUNCTION_BOUNDARY 32
  
  /* No data type wants to be aligned rounder than this.  */
! #define BIGGEST_ALIGNMENT 64
  
  /* Handle #pragma pack.  */
  #define HANDLE_PRAGMA_PACK 1
--- 585,604 ----
  #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
  
  /* Boundary (in *bits*) on which stack pointer should be aligned.  */
! #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
  
  /* Allocation boundary (in *bits*) for the code of a function.  */
  #define FUNCTION_BOUNDARY 32
  
  /* No data type wants to be aligned rounder than this.  */
! #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)
! 
! /* A C expression to compute the alignment for a variables in the
!    local store.  TYPE is the data type, and ALIGN is the alignment
!    that the object would ordinarily have.  */
! #define LOCAL_ALIGNMENT(TYPE, ALIGN)				\
! 	((TARGET_ALTIVEC_ABI		    			\
! 	  && TREE_CODE (TYPE)) == VECTOR_TYPE ? 128 : ALIGN)
  
  /* Handle #pragma pack.  */
  #define HANDLE_PRAGMA_PACK 1
*************** extern int rs6000_debug_arg;		/* debug a
*** 594,602 ****
    (TREE_CODE (EXP) == STRING_CST	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
! /* Make arrays of chars word-aligned for the same reasons.  */
  #define DATA_ALIGNMENT(TYPE, ALIGN)		\
!   (TREE_CODE (TYPE) == ARRAY_TYPE		\
     && TYPE_MODE (TREE_TYPE (TYPE)) == QImode	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
--- 617,627 ----
    (TREE_CODE (EXP) == STRING_CST	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
! /* Make arrays of chars word-aligned for the same reasons.
!    Align vectors to 128 bits.  */
  #define DATA_ALIGNMENT(TYPE, ALIGN)		\
!   (TREE_CODE (TYPE) == VECTOR_TYPE ? 128	\
!    : TREE_CODE (TYPE) == ARRAY_TYPE		\
     && TYPE_MODE (TREE_TYPE (TYPE)) == QImode	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
*************** extern int rs6000_debug_arg;		/* debug a
*** 634,640 ****
     a register, in order to work around problems in allocating stack storage
     in inline functions.  */
  
! #define FIRST_PSEUDO_REGISTER 77
  
  /* This must not decrease, for backwards compatibility.  If
     FIRST_PSEUDO_REGISTER increases, this should as well.  */
--- 659,665 ----
     a register, in order to work around problems in allocating stack storage
     in inline functions.  */
  
! #define FIRST_PSEUDO_REGISTER 109
  
  /* This must not decrease, for backwards compatibility.  If
     FIRST_PSEUDO_REGISTER increases, this should as well.  */
*************** extern int rs6000_debug_arg;		/* debug a
*** 655,661 ****
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1}
  
  /* 1 for registers not available across function calls.
     These must include the FIXED_REGISTERS and also any
--- 680,690 ----
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1,	   \
!    /* AltiVec registers.  */			   \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  \
! }
  
  /* 1 for registers not available across function calls.
     These must include the FIXED_REGISTERS and also any
*************** extern int rs6000_debug_arg;		/* debug a
*** 669,675 ****
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1}
  
  #define MQ_REGNO     64
  #define CR0_REGNO    68
--- 698,709 ----
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1,	   \
!    /* AltiVec registers.  */			   \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  \
! }
! 
  
  #define MQ_REGNO     64
  #define CR0_REGNO    68
*************** extern int rs6000_debug_arg;		/* debug a
*** 679,684 ****
--- 713,720 ----
  #define CR4_REGNO    72
  #define MAX_CR_REGNO 75
  #define XER_REGNO    76
+ #define FIRST_ALTIVEC_REGNO	77
+ #define LAST_ALTIVEC_REGNO	108
  
  /* List the order in which to allocate registers.  Each register must be
     listed once, even those in FIXED_REGISTERS.
*************** extern int rs6000_debug_arg;		/* debug a
*** 701,708 ****
  	mq		(not saved; best to use it if we can)
  	ctr		(not saved; when we have the choice ctr is better)
  	lr		(saved)
!         cr5, r1, r2, ap, xer (fixed)  */
  
  #define REG_ALLOC_ORDER					\
    {32, 							\
     45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34,	\
--- 737,753 ----
  	mq		(not saved; best to use it if we can)
  	ctr		(not saved; when we have the choice ctr is better)
  	lr		(saved)
!         cr5, r1, r2, ap, xer (fixed)
  
+ 	AltiVec registers:
+ 	v0 - v1         (not saved or used for anything)
+ 	v13 - v3        (not saved; incoming vector arg registers)
+ 	v2              (not saved; incoming vector arg reg; return value)
+ 	v19 - v14       (not saved or used for anything)
+ 	v31 - v20       (saved; order given to save least number)
+ */
+ 						
+ 
  #define REG_ALLOC_ORDER					\
    {32, 							\
     45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34,	\
*************** extern int rs6000_debug_arg;		/* debug a
*** 716,722 ****
     31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19,	\
     18, 17, 16, 15, 14, 13, 12,				\
     64, 66, 65, 						\
!    73, 1, 2, 67, 76}
  
  /* True if register is floating-point.  */
  #define FP_REGNO_P(N) ((N) >= 32 && (N) <= 63)
--- 761,774 ----
     31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19,	\
     18, 17, 16, 15, 14, 13, 12,				\
     64, 66, 65, 						\
!    73, 1, 2, 67, 76,					\
!    /* AltiVec registers.  */				\
!    77, 78,						\
!    90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80,		\
!    79,							\
!    96, 95, 94, 93, 92, 91,				\
!    108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97 \
! }
  
  /* True if register is floating-point.  */
  #define FP_REGNO_P(N) ((N) >= 32 && (N) <= 63)
*************** extern int rs6000_debug_arg;		/* debug a
*** 733,738 ****
--- 785,793 ----
  /* True if register is the XER register.  */
  #define XER_REGNO_P(N) ((N) == XER_REGNO)
  
+ /* True if register is an AltiVec register.  */
+ #define ALTIVEC_REGNO_P(N) ((N) >= FIRST_ALTIVEC_REGNO && (N) <= LAST_ALTIVEC_REGNO)
+ 
  /* Return number of consecutive hard regs needed starting at reg REGNO
     to hold something of mode MODE.
     This is ordinarily the length in words of a value of mode MODE
*************** extern int rs6000_debug_arg;		/* debug a
*** 744,751 ****
--- 799,821 ----
  #define HARD_REGNO_NREGS(REGNO, MODE)					\
    (FP_REGNO_P (REGNO)							\
     ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
+    : ALTIVEC_REGNO_P (REGNO)						\
+    ? ((GET_MODE_SIZE (MODE) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD) \
     : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
  
+ #define ALTIVEC_VECTOR_MODE(MODE)	\
+ 	((MODE) == V16QImode		\
+ 	 || (MODE) == V8HImode		\
+ 	 || (MODE) == V4SFmode		\
+ 	 || (MODE) == V4SImode)
+ 
+ /* Define this macro to be nonzero if the port is prepared to handle
+    insns involving vector mode MODE.  At the very least, it must have
+    move patterns for this mode.  */
+ 
+ #define VECTOR_MODE_SUPPORTED_P(MODE)	\
+ 	(TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE))
+ 
  /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
     For POWER and PowerPC, the GPRs can hold any mode, but the float
     registers only can hold floating modes and DImode, and CR register only
*************** extern int rs6000_debug_arg;		/* debug a
*** 757,762 ****
--- 827,834 ----
     (GET_MODE_CLASS (MODE) == MODE_FLOAT					\
      || (GET_MODE_CLASS (MODE) == MODE_INT				\
  	&& GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD))			\
+    : ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_REGNO_P (REGNO)		\
+    : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE)		\
     : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC		\
     : XER_REGNO_P (REGNO) ? (MODE) == PSImode				\
     : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT		\
*************** extern int rs6000_debug_arg;		/* debug a
*** 776,781 ****
--- 848,857 ----
     ? GET_MODE_CLASS (MODE2) == MODE_CC		\
     : GET_MODE_CLASS (MODE2) == MODE_CC		\
     ? GET_MODE_CLASS (MODE1) == MODE_CC		\
+    : ALTIVEC_VECTOR_MODE (MODE1)		\
+    ? ALTIVEC_VECTOR_MODE (MODE2)		\
+    : ALTIVEC_VECTOR_MODE (MODE2)		\
+    ? ALTIVEC_VECTOR_MODE (MODE1)		\
     : 1)
  
  /* A C expression returning the cost of moving data from a register of class
*************** extern int rs6000_debug_arg;		/* debug a
*** 788,793 ****
--- 864,870 ----
     ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2		\
     : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10	\
     : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10	\
+    : (CLASS1) == ALTIVEC_REGS && (CLASS2) != ALTIVEC_REGS ? 20	\
     : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS		\
         || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS		\
         || (CLASS1) == LINK_OR_CTR_REGS)				\
*************** extern int rs6000_debug_arg;		/* debug a
*** 839,844 ****
--- 916,924 ----
      global_regs[PIC_OFFSET_TABLE_REGNUM]				\
        = fixed_regs[PIC_OFFSET_TABLE_REGNUM]				\
          = call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;			\
+   if (TARGET_ALTIVEC_ABI)						\
+     for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)	\
+       call_used_regs[i] = 1;						\
  }
  
  /* Specify the registers used for certain standard purposes.
*************** enum reg_class
*** 912,917 ****
--- 992,998 ----
    BASE_REGS,
    GENERAL_REGS,
    FLOAT_REGS,
+   ALTIVEC_REGS,
    NON_SPECIAL_REGS,
    MQ_REGS,
    LINK_REGS,
*************** enum reg_class
*** 937,942 ****
--- 1018,1024 ----
    "BASE_REGS",								\
    "GENERAL_REGS",							\
    "FLOAT_REGS",								\
+   "ALTIVEC_REGS",							\
    "NON_SPECIAL_REGS",							\
    "MQ_REGS",								\
    "LINK_REGS",								\
*************** enum reg_class
*** 955,978 ****
     This is an initializer for a vector of HARD_REG_SET
     of length N_REG_CLASSES.  */
  
! #define REG_CLASS_CONTENTS						\
! {									\
!   { 0x00000000, 0x00000000, 0x00000000 },	/* NO_REGS */		\
!   { 0xfffffffe, 0x00000000, 0x00000008 },	/* BASE_REGS */		\
!   { 0xffffffff, 0x00000000, 0x00000008 },	/* GENERAL_REGS */	\
!   { 0x00000000, 0xffffffff, 0x00000000 },	/* FLOAT_REGS */	\
!   { 0xffffffff, 0xffffffff, 0x00000008 },	/* NON_SPECIAL_REGS */	\
!   { 0x00000000, 0x00000000, 0x00000001 },	/* MQ_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000002 },	/* LINK_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000004 },	/* CTR_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000006 },	/* LINK_OR_CTR_REGS */	\
!   { 0x00000000, 0x00000000, 0x00000007 },	/* SPECIAL_REGS */	\
!   { 0xffffffff, 0x00000000, 0x0000000f },	/* SPEC_OR_GEN_REGS */	\
!   { 0x00000000, 0x00000000, 0x00000010 },	/* CR0_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000ff0 },	/* CR_REGS */		\
!   { 0xffffffff, 0x00000000, 0x0000ffff },	/* NON_FLOAT_REGS */	\
!   { 0x00000000, 0x00000000, 0x00010000 },	/* XER_REGS */		\
!   { 0xffffffff, 0xffffffff, 0x0001ffff }	/* ALL_REGS */		\
  }
  
  /* The same information, inverted:
--- 1037,1061 ----
     This is an initializer for a vector of HARD_REG_SET
     of length N_REG_CLASSES.  */
  
! #define REG_CLASS_CONTENTS						     \
! {									     \
!   { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */	     \
!   { 0xfffffffe, 0x00000000, 0x00000008, 0x00000000 }, /* BASE_REGS */	     \
!   { 0xffffffff, 0x00000000, 0x00000008, 0x00000000 }, /* GENERAL_REGS */     \
!   { 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FLOAT_REGS */       \
!   { 0x00000000, 0x00000000, 0xffffe000, 0x0001ffff }, /* ALTIVEC_REGS */     \
!   { 0xffffffff, 0xffffffff, 0x00000008, 0x00000000 }, /* NON_SPECIAL_REGS */ \
!   { 0x00000000, 0x00000000, 0x00000001, 0x00000000 }, /* MQ_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000002, 0x00000000 }, /* LINK_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000004, 0x00000000 }, /* CTR_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000006, 0x00000000 }, /* LINK_OR_CTR_REGS */ \
!   { 0x00000000, 0x00000000, 0x00000007, 0x00000000 }, /* SPECIAL_REGS */     \
!   { 0xffffffff, 0x00000000, 0x0000000f, 0x00000000 }, /* SPEC_OR_GEN_REGS */ \
!   { 0x00000000, 0x00000000, 0x00000010, 0x00000000 }, /* CR0_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */	     \
!   { 0xffffffff, 0x00000000, 0x0000ffff, 0x00000000 }, /* NON_FLOAT_REGS */   \
!   { 0x00000000, 0x00000000, 0x00010000, 0x00000000 }, /* XER_REGS */	     \
!   { 0xffffffff, 0xffffffff, 0xffffffff, 0x0001ffff }  /* ALL_REGS */	     \
  }
  
  /* The same information, inverted:
*************** enum reg_class
*** 984,989 ****
--- 1067,1073 ----
   ((REGNO) == 0 ? GENERAL_REGS			\
    : (REGNO) < 32 ? BASE_REGS			\
    : FP_REGNO_P (REGNO) ? FLOAT_REGS		\
+   : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_REGS	\
    : (REGNO) == CR0_REGNO ? CR0_REGS		\
    : CR_REGNO_P (REGNO) ? CR_REGS		\
    : (REGNO) == MQ_REGNO ? MQ_REGS		\
*************** enum reg_class
*** 1006,1011 ****
--- 1090,1096 ----
     : (C) == 'q' ? MQ_REGS	\
     : (C) == 'c' ? CTR_REGS	\
     : (C) == 'l' ? LINK_REGS	\
+    : (C) == 'v' ? ALTIVEC_REGS	\
     : (C) == 'x' ? CR0_REGS	\
     : (C) == 'y' ? CR_REGS	\
     : (C) == 'z' ? XER_REGS	\
*************** enum reg_class
*** 1103,1113 ****
  #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
    secondary_reload_class (CLASS, MODE, IN)
  
! /* If we are copying between FP registers and anything else, we need a memory
!    location.  */
  
! #define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
!  ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS || (CLASS2) == FLOAT_REGS))
  
  /* Return the maximum number of consecutive registers
     needed to represent mode MODE in a register of class CLASS.
--- 1188,1201 ----
  #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
    secondary_reload_class (CLASS, MODE, IN)
  
! /* If we are copying between FP or AltiVec registers and anything
!    else, we need a memory location.  */
  
! #define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) 		\
!  ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS		\
! 			   || (CLASS2) == FLOAT_REGS		\
! 			   || (CLASS1) == ALTIVEC_REGS		\
! 			   || (CLASS2) == ALTIVEC_REGS))
  
  /* Return the maximum number of consecutive registers
     needed to represent mode MODE in a register of class CLASS.
*************** typedef struct rs6000_stack {
*** 1294,1309 ****
  		&& TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)	\
  	       || POINTER_TYPE_P (VALTYPE)			\
  	       ? word_mode : TYPE_MODE (VALTYPE),		\
! 	       TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT \
                 ? FP_ARG_RETURN : GP_ARG_RETURN)
  
  /* Define how to find the value returned by a library function
     assuming the value has mode MODE.  */
  
! #define LIBCALL_VALUE(MODE)					\
!   gen_rtx_REG (MODE, (GET_MODE_CLASS (MODE) == MODE_FLOAT	\
! 		      && TARGET_HARD_FLOAT			\
! 		      ? FP_ARG_RETURN : GP_ARG_RETURN))
  
  /* The definition of this macro implies that there are cases where
     a scalar value cannot be returned in registers.
--- 1382,1399 ----
  		&& TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)	\
  	       || POINTER_TYPE_P (VALTYPE)			\
  	       ? word_mode : TYPE_MODE (VALTYPE),		\
! 	       TREE_CODE (VALTYPE) == VECTOR_TYPE ? ALTIVEC_ARG_RETURN \
! 	       : TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT \
                 ? FP_ARG_RETURN : GP_ARG_RETURN)
  
  /* Define how to find the value returned by a library function
     assuming the value has mode MODE.  */
  
! #define LIBCALL_VALUE(MODE)						\
!   gen_rtx_REG (MODE, ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_ARG_RETURN	\
! 		     : GET_MODE_CLASS (MODE) == MODE_FLOAT		\
! 		     && TARGET_HARD_FLOAT				\
! 		     ? FP_ARG_RETURN : GP_ARG_RETURN)
  
  /* The definition of this macro implies that there are cases where
     a scalar value cannot be returned in registers.
*************** typedef struct rs6000_stack {
*** 1338,1346 ****
--- 1428,1442 ----
  			? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG)
  #define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1)
  
+ /* Minimum and maximum AltiVec registers used to hold arguments.  */
+ #define ALTIVEC_ARG_MIN_REG 77
+ #define ALTIVEC_ARG_MAX_REG 88
+ #define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG - ALTIVEC_ARG_MIN_REG + 1)
+ 
  /* Return registers */
  #define GP_ARG_RETURN GP_ARG_MIN_REG
  #define FP_ARG_RETURN FP_ARG_MIN_REG
+ #define ALTIVEC_ARG_RETURN 79
  
  /* Flags for the call/call_value rtl operations set up by function_arg */
  #define CALL_NORMAL		0x00000000	/* no special processing */
*************** typedef struct rs6000_stack {
*** 1352,1364 ****
  /* 1 if N is a possible register number for a function value
     as seen by the caller.
  
!    On RS/6000, this is r3 and fp1.  */
! #define FUNCTION_VALUE_REGNO_P(N)  ((N) == GP_ARG_RETURN || ((N) == FP_ARG_RETURN))
  
  /* 1 if N is a possible register number for function argument passing.
     On RS/6000, these are r3-r10 and fp1-fp13.  */
  #define FUNCTION_ARG_REGNO_P(N)						\
    ((unsigned)(((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG))	\
     || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))
  
  \f
--- 1448,1465 ----
  /* 1 if N is a possible register number for a function value
     as seen by the caller.
  
!    On RS/6000, this is r3, fp1, and v2 (for AltiVec).  */
! #define FUNCTION_VALUE_REGNO_P(N)  ((N) == GP_ARG_RETURN	\
! 				    || ((N) == FP_ARG_RETURN)	\
! 				    || (TARGET_ALTIVEC &&	\
! 					(N) == ALTIVEC_ARG_RETURN))
  
  /* 1 if N is a possible register number for function argument passing.
     On RS/6000, these are r3-r10 and fp1-fp13.  */
  #define FUNCTION_ARG_REGNO_P(N)						\
    ((unsigned)(((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG))	\
+    || (TARGET_ALTIVEC &&						\
+        (unsigned)((N) - ALTIVEC_ARG_MIN_REG) < (unsigned)(ALTIVEC_ARG_MAX_REG)) \
     || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))
  
  \f
*************** typedef struct rs6000_args
*** 1394,1399 ****
--- 1495,1501 ----
  {
    int words;			/* # words used for passing GP registers */
    int fregno;			/* next available FP register */
+   int vregno;			/* next available AltiVec register */
    int nargs_prototype;		/* # args left in the current prototype */
    int orig_nargs;		/* Original value of nargs_prototype */
    int prototype;		/* Whether a prototype was defined */
*************** typedef struct rs6000_args
*** 1436,1441 ****
--- 1538,1549 ----
     && (CUM).fregno <= FP_ARG_MAX_REG    \
     && TARGET_HARD_FLOAT)
  
+ /* Non-zero if we can use an AltiVec register to pass this arg.  */
+ #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE)	\
+   (ALTIVEC_VECTOR_MODE (MODE)			\
+    && (CUM).vregno <= ALTIVEC_ARG_MAX_REG	\
+    && TARGET_ALTIVEC_ABI)
+ 
  /* Determine where to put an argument to a function.
     Value is zero to push the argument on the stack,
     or a hard register in which to store the argument.
*************** typedef struct rs6000_args
*** 1778,1783 ****
--- 1886,1892 ----
    && GET_CODE (XEXP (X, 0)) == REG				\
    && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT))		\
    && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0)		\
+   && ! ALTIVEC_VECTOR_MODE (MODE)				\
    && (((MODE) != DFmode && (MODE) != DImode)			\
        || (TARGET_32BIT						\
  	  ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) 	\
*************** typedef struct rs6000_args
*** 1805,1810 ****
--- 1914,1920 ----
     && ! flag_pic && ! TARGET_TOC				\
     && (MODE) != DImode						\
     && (MODE) != TImode						\
+    && ! ALTIVEC_VECTOR_MODE (MODE)				\
     && (TARGET_HARD_FLOAT || (MODE) != DFmode)			\
     && GET_CODE (X) == LO_SUM					\
     && GET_CODE (XEXP (X, 0)) == REG				\
*************** extern char rs6000_reg_names[][8];	/* re
*** 2389,2394 ****
--- 2499,2537 ----
    &rs6000_reg_names[75][0],	/* cr7  */				\
  									\
    &rs6000_reg_names[76][0],	/* xer  */				\
+ 									\
+   &rs6000_reg_names[77][0],	/* v0  */				\
+   &rs6000_reg_names[78][0],	/* v1  */				\
+   &rs6000_reg_names[79][0],	/* v2  */				\
+   &rs6000_reg_names[80][0],	/* v3  */				\
+   &rs6000_reg_names[81][0],	/* v4  */				\
+   &rs6000_reg_names[82][0],	/* v5  */				\
+   &rs6000_reg_names[83][0],	/* v6  */				\
+   &rs6000_reg_names[84][0],	/* v7  */				\
+   &rs6000_reg_names[85][0],	/* v8  */				\
+   &rs6000_reg_names[86][0],	/* v9  */				\
+   &rs6000_reg_names[87][0],	/* v10  */				\
+   &rs6000_reg_names[88][0],	/* v11  */				\
+   &rs6000_reg_names[89][0],	/* v12  */				\
+   &rs6000_reg_names[90][0],	/* v13  */				\
+   &rs6000_reg_names[91][0],	/* v14  */				\
+   &rs6000_reg_names[92][0],	/* v15  */				\
+   &rs6000_reg_names[93][0],	/* v16  */				\
+   &rs6000_reg_names[94][0],	/* v17  */				\
+   &rs6000_reg_names[95][0],	/* v18  */				\
+   &rs6000_reg_names[96][0],	/* v19  */				\
+   &rs6000_reg_names[97][0],	/* v20  */				\
+   &rs6000_reg_names[98][0],	/* v21  */				\
+   &rs6000_reg_names[99][0],	/* v22  */				\
+   &rs6000_reg_names[100][0],	/* v23  */				\
+   &rs6000_reg_names[101][0],	/* v24  */				\
+   &rs6000_reg_names[102][0],	/* v25  */				\
+   &rs6000_reg_names[103][0],	/* v26  */				\
+   &rs6000_reg_names[104][0],	/* v27  */				\
+   &rs6000_reg_names[105][0],	/* v28  */				\
+   &rs6000_reg_names[106][0],	/* v29  */				\
+   &rs6000_reg_names[107][0],	/* v30  */				\
+   &rs6000_reg_names[108][0],	/* v31  */				\
  }
  
  /* print-rtl can't handle the above REGISTER_NAMES, so define the
*************** extern char rs6000_reg_names[][8];	/* re
*** 2407,2413 ****
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",		\
       "mq",  "lr", "ctr",  "ap",						\
      "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",		\
!   "xer"									\
  }
  
  /* Table of additional register names to use in user input.  */
--- 2550,2560 ----
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",		\
       "mq",  "lr", "ctr",  "ap",						\
      "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",		\
!   "xer",								\
!      "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",             \
!      "v8",  "v9", "v10", "v11", "v12", "v13", "v14", "v15",             \
!     "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",             \
!     "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"              \
  }
  
  /* Table of additional register names to use in user input.  */
*************** extern char rs6000_reg_names[][8];	/* re
*** 2429,2434 ****
--- 2576,2589 ----
    {"fr20", 52}, {"fr21", 53}, {"fr22", 54}, {"fr23", 55},	\
    {"fr24", 56}, {"fr25", 57}, {"fr26", 58}, {"fr27", 59},	\
    {"fr28", 60}, {"fr29", 61}, {"fr30", 62}, {"fr31", 63},	\
+   {"v0",   77}, {"v1",   78}, {"v2",   79}, {"v3",   80},       \
+   {"v4",   81}, {"v5",   82}, {"v6",   83}, {"v7",   84},       \
+   {"v8",   85}, {"v9",   86}, {"v10",  87}, {"v11",  88},       \
+   {"v12",  89}, {"v13",  90}, {"v14",  91}, {"v15",  92},       \
+   {"v16",  93}, {"v17",  94}, {"v18",  95}, {"v19",  96},       \
+   {"v20",  97}, {"v21",  98}, {"v22",  99}, {"v23",  100},	\
+   {"v24",  101},{"v25",  102},{"v26",  103},{"v27",  104},      \
+   {"v28",  105},{"v29",  106},{"v30",  107},{"v31",  108},      \
    /* no additional names for: mq, lr, ctr, ap */		\
    {"cr0",  68}, {"cr1",  69}, {"cr2",  70}, {"cr3",  71},	\
    {"cr4",  72}, {"cr5",  73}, {"cr6",  74}, {"cr7",  75},	\
*************** do {									\
*** 2617,2622 ****
--- 2772,2778 ----
  				GT, LEU, LTU, GEU, GTU}},		   \
    {"boolean_operator", {AND, IOR, XOR}},				   \
    {"boolean_or_operator", {IOR, XOR}},					   \
+   {"altivec_register", {REG, SUBREG}},					   \
    {"min_max_operator", {SMIN, SMAX, UMIN, UMAX}},
  
  /* uncomment for disabling the corresponding default options */
*************** extern int flag_pic;
*** 2629,2631 ****
--- 2785,2900 ----
  extern int optimize;
  extern int flag_expensive_optimizations;
  extern int frame_pointer_needed;
+ 
+ enum rs6000_builtins
+ {
+   /* AltiVec builtins.  */
+   ALTIVEC_BUILTIN_ST_INTERNAL,
+   ALTIVEC_BUILTIN_LD_INTERNAL,
+   ALTIVEC_BUILTIN_VADDUBM,

--more boring builtins deleted--

+ };
Index: sysv4.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/sysv4.h,v
retrieving revision 1.67
diff -c -p -r1.67 sysv4.h
*** sysv4.h	2001/10/29 23:09:43	1.67
--- sysv4.h	2001/11/05 19:49:24
*************** do {									\
*** 400,417 ****
     one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
     versions, just use 64 as the stack boundary.  */
  #undef	STACK_BOUNDARY
! #define	STACK_BOUNDARY	64
  
  /* Real stack boundary as mandated by the appropriate ABI.  */
! #define ABI_STACK_BOUNDARY ((TARGET_EABI) ? 64 : 128)
  
  /* No data type wants to be aligned rounder than this.  */
  #undef	BIGGEST_ALIGNMENT
! #define BIGGEST_ALIGNMENT ((TARGET_EABI) ? 64 : 128)
  
  #undef  BIGGEST_FIELD_ALIGNMENT
  #undef  ADJUST_FIELD_ALIGN
- #undef  ROUND_TYPE_ALIGN
  
  /* Use ELF style section commands.  */
  
--- 400,430 ----
     one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
     versions, just use 64 as the stack boundary.  */
  #undef	STACK_BOUNDARY
! #define	STACK_BOUNDARY	(TARGET_ALTIVEC_ABI ? 128 : 64)
  
  /* Real stack boundary as mandated by the appropriate ABI.  */
! #define ABI_STACK_BOUNDARY ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
  
  /* No data type wants to be aligned rounder than this.  */
  #undef	BIGGEST_ALIGNMENT
! #define BIGGEST_ALIGNMENT ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
  
+ /* An expression for the alignment of a structure field FIELD if the
+    alignment computed in the usual way is COMPUTED.  */
+ #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)				      \
+ 	((TARGET_ALTIVEC_ABI && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
+ 	 ? 128 : COMPUTED)
+ 
+ /* Define this macro as an expression for the alignment of a type
+    (given by TYPE as a tree node) if the alignment computed in the
+    usual way is COMPUTED and the alignment explicitly specified was
+    SPECIFIED.  */
+ #define ROUND_TYPE_ALIGN(TYPE, COMPUTED, SPECIFIED)			\
+ 	((TARGET_ALTIVEC_ABI && TREE_CODE (TYPE) == VECTOR_TYPE)	\
+ 	 ? 128 : MAX (COMPUTED, SPECIFIED))
+ 
  #undef  BIGGEST_FIELD_ALIGNMENT
  #undef  ADJUST_FIELD_ALIGN
  
  /* Use ELF style section commands.  */
  
Index: rs6000.c
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.224
diff -c -p -r1.224 rs6000.c
*** rs6000.c	2001/10/31 14:08:09	1.224
--- rs6000.c	2001/11/05 19:49:27
*************** int fixuplabelno = 0;
*** 96,101 ****
--- 96,104 ----
  /* ABI enumeration available for subtarget to use.  */
  enum rs6000_abi rs6000_current_abi;
  
+ /* ABI string from -mabi= option.  */
+ const char *rs6000_abi_string;
+ 
  /* Debug flags */
  const char *rs6000_debug_name;
  int rs6000_debug_stack;		/* debug stack applications */
*************** static int rs6000_adjust_cost PARAMS ((r
*** 146,151 ****
--- 149,161 ----
  static int rs6000_adjust_priority PARAMS ((rtx, int));
  static int rs6000_issue_rate PARAMS ((void));
  
+ static void rs6000_init_builtins PARAMS ((tree));
+ static void altivec_init_builtins PARAMS ((void));
+ static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
+ static rtx altivec_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
+ static rtx altivec_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
+ 
+ static void rs6000_parse_abi_options PARAMS ((void));
  \f
  /* Default register names.  */
  char rs6000_reg_names[][8] =
*************** char rs6000_reg_names[][8] =
*** 160,166 ****
       "24", "25", "26", "27", "28", "29", "30", "31",
       "mq", "lr", "ctr","ap",
        "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
!       "xer"
  };
  
  #ifdef TARGET_REGNAMES
--- 170,181 ----
       "24", "25", "26", "27", "28", "29", "30", "31",
       "mq", "lr", "ctr","ap",
        "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
!       "xer",
!       /* AltiVec registers.  */
!       "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6", "v7",
!       "v8",  "v9",  "v10", "v11", "v12", "v13", "v14", "v15",
!       "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
!       "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
  };
  
  #ifdef TARGET_REGNAMES
*************** static const char alt_reg_names[][8] =
*** 176,182 ****
    "%f24",  "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
      "mq",    "lr",  "ctr",   "ap",
    "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
!   "xer"
  };
  #endif
  \f
--- 191,202 ----
    "%f24",  "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
      "mq",    "lr",  "ctr",   "ap",
    "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
!    "xer",
!    /* AltiVec registers.  */
!    "%v0",  "%v1",  "%v2",  "%v3",  "%v4",  "%v5",  "%v6", "%v7",
!    "%v8",  "%v9",  "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
!    "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
!    "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31"
  };
  #endif
  \f
*************** static const char alt_reg_names[][8] =
*** 205,210 ****
--- 225,236 ----
  #undef TARGET_SCHED_ADJUST_PRIORITY
  #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
  
+ #undef TARGET_INIT_BUILTINS
+ #define TARGET_INIT_BUILTINS rs6000_init_builtins
+ 
+ #undef TARGET_EXPAND_BUILTIN
+ #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
+ 
  struct gcc_target targetm = TARGET_INITIALIZER;
  \f
  /* Override command line options.  Mostly we process the processor
*************** rs6000_override_options (default_cpu)
*** 438,443 ****
--- 464,472 ----
  	error ("Unknown -mdebug-%s switch", rs6000_debug_name);
      }
  
+   /* Handle -mabi= options.  */
+   rs6000_parse_abi_options ();
+ 
  #ifdef TARGET_REGNAMES
    /* If the user desires alternate register names, copy in the
       alternate names now.  */
*************** rs6000_override_options (default_cpu)
*** 463,468 ****
--- 492,508 ----
    free_machine_status = rs6000_free_machine_status;
  }
  
+ /* Handle -mabi= options.  */
+ void rs6000_parse_abi_options ()
+ {
+   if (rs6000_abi_string == 0)
+     return;
+   else if (! strcmp (rs6000_abi_string, "altivec"))
+     target_flags |= MASK_ALTIVEC_ABI;
+   else
+     error ("Unknown ABI specified: '%s'", rs6000_abi_string);
+ }
+ 
  void
  optimization_options (level, size)
       int level ATTRIBUTE_UNUSED;
*************** input_operand (op, mode)
*** 1411,1416 ****
--- 1451,1475 ----
    return 0;
  }
  
+ /* Return 1 if this is an AltiVec vector register.
+ 
+    Actually, what we really want to know is if this is a vector mode,
+    since vectors can only go in AltiVec registers.
+ 
+    This is used in *altivec_vec_move so we can seamlessly convert
+    between vector types.  */
+ int
+ altivec_register (x, mode)
+      rtx x;
+      enum machine_mode mode;
+ {
+   if (register_operand (x, mode)
+       && ALTIVEC_VECTOR_MODE (GET_MODE (x)))
+     return 1;
+ 
+   return 0;
+ }
+ 
  /* Return 1 for an operand in small memory on V.4/eabi.  */
  
  int
*************** rs6000_legitimize_address (x, oldx, mode
*** 1544,1550 ****
       rtx x;
       rtx oldx ATTRIBUTE_UNUSED;
       enum machine_mode mode;
! { 
    if (GET_CODE (x) == PLUS 
        && GET_CODE (XEXP (x, 0)) == REG
        && GET_CODE (XEXP (x, 1)) == CONST_INT
--- 1603,1609 ----
       rtx x;
       rtx oldx ATTRIBUTE_UNUSED;
       enum machine_mode mode;
! {
    if (GET_CODE (x) == PLUS 
        && GET_CODE (XEXP (x, 0)) == REG
        && GET_CODE (XEXP (x, 1)) == CONST_INT
*************** rs6000_legitimize_address (x, oldx, mode
*** 1570,1575 ****
--- 1629,1646 ----
        return gen_rtx_PLUS (Pmode, XEXP (x, 0),
  			   force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
      }
+   else if (ALTIVEC_VECTOR_MODE (mode))
+     {
+       rtx reg;
+ 
+       /* Make sure both operands are registers.  */
+       if (GET_CODE (x) == PLUS)
+ 	return gen_rtx_PLUS (Pmode, XEXP (x, 0),
+ 			     force_reg (Pmode, XEXP (x, 1)));
+ 
+       reg = force_reg (Pmode, x);
+       return reg;
+     }
    else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic
  	   && GET_CODE (x) != CONST_INT
  	   && GET_CODE (x) != CONST_DOUBLE 
*************** rs6000_emit_move (dest, source, mode)
*** 1862,1867 ****
--- 1933,1947 ----
  	operands[1] = force_const_mem (mode, operands[1]);
        break;
        
+     case V16QImode:
+     case V8HImode:
+     case V4SFmode:
+     case V4SImode:
+       /* fixme: aldyh -- allow vector constants when they are implemented.  */
+       if (CONSTANT_P (operands[1]))
+ 	operands[1] = force_const_mem (mode, operands[1]);
+       break;
+       
      case SImode:
      case DImode:
        /* Use default pattern for address of ELF small data */
*************** init_cumulative_args (cum, fntype, libna
*** 2062,2067 ****
--- 2142,2148 ----
    *cum = zero_cumulative;
    cum->words = 0;
    cum->fregno = FP_ARG_MIN_REG;
+   cum->vregno = ALTIVEC_ARG_MIN_REG;
    cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
    cum->call_cookie = CALL_NORMAL;
    cum->sysv_gregno = GP_ARG_MIN_REG;
*************** function_arg_boundary (mode, type)
*** 2142,2147 ****
--- 2223,2230 ----
    if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
        && (mode == DImode || mode == DFmode))
      return 64;
+   else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
+     return 128;
    else
      return PARM_BOUNDARY;
  }
*************** function_arg_advance (cum, mode, type, n
*** 2159,2165 ****
  {
    cum->nargs_prototype--;
  
!   if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
--- 2242,2255 ----
  {
    cum->nargs_prototype--;
  
!   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
!     {
!       if (cum->vregno <= ALTIVEC_ARG_MAX_REG)
! 	cum->vregno++;
!       else
! 	cum->words += RS6000_ARG_SIZE (mode, type);
!     }
!   else if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
*************** function_arg (cum, mode, type, named)
*** 2287,2294 ****
        return GEN_INT (cum->call_cookie);
      }
  
!   if (abi == ABI_V4 || abi == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
  	{
--- 2377,2391 ----
        return GEN_INT (cum->call_cookie);
      }
  
!   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
      {
+       if (cum->vregno <= ALTIVEC_ARG_MAX_REG)
+ 	return gen_rtx_REG (mode, cum->vregno);
+       else
+ 	return NULL;
+     }
+   else if (abi == ABI_V4 || abi == ABI_SOLARIS)
+     {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
  	{
*************** function_arg_partial_nregs (cum, mode, t
*** 2382,2388 ****
    if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      return 0;
  
!   if (USE_FP_FOR_ARG_P (*cum, mode, type))
      {
        if (cum->nargs_prototype >= 0)
  	return 0;
--- 2479,2486 ----
    if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      return 0;
  
!   if (USE_FP_FOR_ARG_P (*cum, mode, type)
!       || USE_ALTIVEC_FOR_ARG_P (*cum, mode, type))
      {
        if (cum->nargs_prototype >= 0)
  	return 0;
*************** rs6000_va_arg (valist, type)
*** 2838,2843 ****
--- 2936,3411 ----
  
    return addr_rtx;
  }
+ 
+ /* Builtins.  */
+ 
+ #define def_builtin(MASK, NAME, TYPE, CODE)				\
+ do {									\
+   if ((MASK) & target_flags)						\
+     builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL);	\
+ } while (0)
+ 
+ struct builtin_description
+ {
+   const unsigned int mask;
+   const enum insn_code icode;
+   const char *const name;
+   const enum rs6000_builtins code;
+ };
+ 
+ /* Simple binary operatiors: VECc = foo (VECa, VECb).  */
+ static const struct builtin_description bdesc_2arg[] =
+ {
+   { MASK_ALTIVEC, CODE_FOR_altivec_vaddubm, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
+   { MASK_ALTIVEC, CODE_FOR_altivec_vadduhm, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },

--more boring builtins deleted--

+ };
+ 
+ static rtx
+ altivec_expand_binop_builtin (icode, arglist, target)
+      enum insn_code icode;
+      tree arglist;
+      rtx target;
+ {
+   rtx pat;
+   tree arg0 = TREE_VALUE (arglist);
+   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+   rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+   rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+   enum machine_mode tmode = insn_data[icode].operand[0].mode;
+   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
+   enum machine_mode mode1 = insn_data[icode].operand[2].mode;
+ 
+   if (! target
+       || GET_MODE (target) != tmode
+       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+     target = gen_reg_rtx (tmode);
+ 
+   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+     op0 = copy_to_mode_reg (mode0, op0);
+   if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
+     op1 = copy_to_mode_reg (mode1, op1);
+ 
+   pat = GEN_FCN (icode) (target, op0, op1);
+   if (! pat)
+     return 0;
+   emit_insn (pat);
+ 
+   return target;
+ }
+ 
+ static rtx
+ altivec_expand_builtin (exp, target, subtarget, mode, ignore)
+      tree exp;
+      rtx target;
+      rtx subtarget;
+      enum machine_mode mode;
+      int ignore;
+ {
+   struct builtin_description *d;
+   size_t i;
+   enum insn_code icode;
+   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
+   tree arglist = TREE_OPERAND (exp, 1);
+   tree arg0, arg1, arg2, arg3;
+   rtx op0, op1, op2, pat;
+   enum machine_mode tmode, mode0, mode1, mode2;
+   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+   
+   switch (fcode)
+     {
+     case ALTIVEC_BUILTIN_LD_INTERNAL:
+       icode = CODE_FOR_altivec_lvx;
+       arg0 = TREE_VALUE (arglist);
+       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+       tmode = insn_data[icode].operand[0].mode;
+       mode0 = insn_data[icode].operand[1].mode;
+ 
+       if (! target
+ 	  || GET_MODE (target) != tmode
+ 	  || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ 	target = gen_reg_rtx (tmode);
+ 
+       if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+ 	op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
+ 
+       pat = GEN_FCN (icode) (target, op0);
+       if (! pat)
+ 	return 0;
+       emit_insn (pat);
+       return target;
+ 
+     case ALTIVEC_BUILTIN_ST_INTERNAL:
+       icode = CODE_FOR_altivec_stvx;
+       arg0 = TREE_VALUE (arglist);
+       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+       op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+       mode0 = insn_data[icode].operand[0].mode;
+       mode1 = insn_data[icode].operand[1].mode;
+ 
+       if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
+ 	op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
+       if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
+ 	op1 = copy_to_mode_reg (mode1, op1);
+ 
+       pat = GEN_FCN (icode) (op0, op1);
+       if (! pat)
+ 	return 0;
+       emit_insn (pat);
+       return NULL_RTX;
+     }
+ 
+   /* Handle simple binary operations.  */
+   for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
+     if (d->code == fcode)
+       return altivec_expand_binop_builtin (d->icode, arglist, target);
+ 
+   abort ();
+   return NULL_RTX;
+ }
+ 
+ /* Expand an expression EXP that calls a built-in function,
+    with result going to TARGET if that's convenient
+    (and in mode MODE if that's convenient).
+    SUBTARGET may be used as the target for computing one of EXP's operands.
+    IGNORE is nonzero if the value is to be ignored.  */
+ 
+ static rtx
+ rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
+      tree exp;
+      rtx target;
+      rtx subtarget;
+      enum machine_mode mode;
+      int ignore;
+ {
+   if (TARGET_ALTIVEC)
+     return altivec_expand_builtin (exp, target, subtarget, mode, ignore);
+ 
+   abort ();
+ }
+ 
+ static void
+ rs6000_init_builtins (list_node)
+      tree list_node ATTRIBUTE_UNUSED;
+ {
+   if (TARGET_ALTIVEC)
+     altivec_init_builtins ();
+ }
+ 
+ static void
+ altivec_init_builtins (void)
+ {
+   struct builtin_description * d;
+   size_t i;
+ 
+   tree endlink = void_list_node;
+ 
+   tree pint_type_node = build_pointer_type (integer_type_node);
+ 
+   /* V4SI foo (int *).  */
+   tree v4si_ftype_pint
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, pint_type_node, endlink));
+ 
+   /* void foo (int *, V4SI).  */
+   tree void_ftype_pint_v4si
+     = build_function_type (void_type_node,
+ 			   tree_cons (NULL_TREE, pint_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 

--more boring types deleted--

+ 
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal", v4si_ftype_pint, ALTIVEC_BUILTIN_LD_INTERNAL);
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal", void_ftype_pint_v4si, ALTIVEC_BUILTIN_ST_INTERNAL);
+ 
+   /* Add the simple binary operators.  */
+   for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
+     {
+       enum machine_mode mode0, mode1, mode2;
+       tree type;
+ 
+       if (d->name == 0)
+ 	continue;
+       
+       mode0 = insn_data[d->icode].operand[0].mode;
+       mode1 = insn_data[d->icode].operand[1].mode;
+       mode2 = insn_data[d->icode].operand[2].mode;
+ 
+       /* When all three operands are of the same mode.  */
+       if (mode0 == mode1 && mode1 == mode2)
+ 	{
+ 	  switch (mode0)
+ 	    {
+ 	    case V4SFmode:
+ 	      type = v4sf_ftype_v4sf_v4sf;
+ 	      break;
+ 	    case V4SImode:
+ 	      type = v4si_ftype_v4si_v4si;
+ 	      break;
+ 	    case V16QImode:
+ 	      type = v16qi_ftype_v16qi_v16qi;
+ 	      break;
+ 	    case V8HImode:
+ 	      type = v8hi_ftype_v8hi_v8hi;
+ 	      break;
+ 	    default:
+ 	      abort ();
+ 	    }
+ 	}
+ 
+       /* A few other combos we really don't want to do manually.  */
+ 
+       /* vint, vfloat, vfloat.  */
+       else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
+ 	type = v4si_ftype_v4sf_v4sf;
+ 
+       /* vshort, vchar, vchar.  */
+       else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
+ 	type = v8hi_ftype_v16qi_v16qi;
+ 
+       /* vint, vshort, vshort.  */
+       else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
+ 	type = v4si_ftype_v8hi_v8hi;
+ 
+       /* vshort, vint, vint.  */
+       else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
+ 	type = v8hi_ftype_v4si_v4si;
+ 
+       /* vchar, vshort, vshort.  */
+       else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
+ 	type = v16qi_ftype_v8hi_v8hi;
+ 
+       /* vint, vchar, vint.  */
+       else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
+ 	type = v4si_ftype_v16qi_v4si;
+ 
+       /* vint, vshort, vint.  */
+       else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
+ 	type = v4si_ftype_v8hi_v4si;
+ 
+       /* fixme: aldyh */
+       /* int, x, x.  */
+       else if (mode0 == SImode)
+ 	{
+ 	  switch (mode1)
+ 	    {
+ 	    case V4SImode:
+ 	      type = int_ftype_v4si_v4si;
+ 	      break;
+ 	    case V4SFmode:
+ 	      type = int_ftype_v4sf_v4sf;
+ 	      break;
+ 	    case V16QImode:
+ 	      type = int_ftype_v16qi_v16qi;
+ 	      break;
+ 	    case V8HImode:
+ 	      type = int_ftype_v8hi_v8hi;
+ 	      break;
+ 	    default:
+ 	      abort ();
+ 	    }
+ 	}
+ 
+       else
+ 	abort ();
+ 
+       def_builtin (d->mask, d->name, type, d->code);
+     }
+ }
+ 
  \f
  /* Generate a memory reference for expand_block_move, copying volatile,
     and other bits from an original memory reference.  */
*************** secondary_reload_class (class, mode, in)
*** 3941,3946 ****
--- 4509,4519 ----
        && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
      return NO_REGS;
  
+   /* Memory, and AltiVec registers can go into AltiVec registers.  */
+   if ((regno == -1 || ALTIVEC_REGNO_P (regno))
+       && class == ALTIVEC_REGS)
+     return NO_REGS;
+ 
    /* We can copy among the CR registers.  */
    if ((class == CR_REGS || class == CR0_REGS)
        && regno >= 0 && CR_REGNO_P (regno))
*************** print_operand (file, x, code)
*** 4714,4719 ****
--- 5287,5318 ----
  		     reg_names[SMALL_DATA_REG]);
  	}
        return;
+ 
+       /* Print AltiVec memory operand.  */
+     case 'y':
+       {
+ 	rtx tmp;
+ 
+ 	if (GET_CODE (x) != MEM)
+ 	  abort ();
+ 
+ 	tmp = XEXP (x, 0);
+ 
+ 	if (GET_CODE (tmp) == REG)
+ 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
+ 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
+ 	  {
+ 	    if (REGNO (XEXP (tmp, 0)) == 0)
+ 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
+ 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
+ 	    else
+ 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
+ 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
+ 	  }
+ 	else
+ 	  abort ();
+ 	break;
+       }
  			    
      case 0:
        if (GET_CODE (x) == REG)
Index: rs6000.md
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.128
diff -c -p -r1.128 rs6000.md
*** rs6000.md	2001/10/16 00:43:21	1.128
--- rs6000.md	2001/11/05 19:49:32
***************
*** 37,43 ****
  \f
  ;; Define an insn type attribute.  This is used in function unit delay
  ;; computations.
! (define_attr "type" "integer,load,store,fpload,fpstore,imul,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg"
    (const_string "integer"))
  
  ;; Length (in bytes).
--- 37,43 ----
  \f
  ;; Define an insn type attribute.  This is used in function unit delay
  ;; computations.
! (define_attr "type" "integer,load,store,fpload,fpstore,imul,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,altivec"
    (const_string "integer"))
  
  ;; Length (in bytes).
***************
*** 13359,13361 ****
--- 13359,14298 ----
      emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
    DONE;
  }")
+ 
+ ;; AltiVec patterns
+ 
+ ;; Generic LVX load instruction.
+ (define_insn "altivec_lvx"
+   [(set (match_operand:V4SI 0 "register_operand" "=v")
+ 	(match_operand:V4SI 1 "memory_operand" "m"))]
+   "TARGET_ALTIVEC"
+   "lvx\t%0,%y1"
+   [(set_attr "type" "altivec")])
+ 
+ ;; Generic STVX store instruction.
+ (define_insn "altivec_stvx"
+   [(set (match_operand:V4SI 0 "memory_operand" "=m")
+ 	(match_operand:V4SI 1 "register_operand" "v"))]
+   "TARGET_ALTIVEC"
+   "stvx\t%1,%y0"
+   [(set_attr "type" "altivec")])
+ 
+ ;; No code is needed to copy between vector registers.
+ (define_insn "*altivec_vec_move"
+   [(set (match_operand 0 "altivec_register" "=v")
+ 	(match_operand 1 "altivec_register" "v"))]
+   "TARGET_ALTIVEC"
+   ""
+   [(set_attr "type" "altivec")])
+ 
+ ;; Vector move instructions.
+ (define_expand "movv4si"
+   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
+ 	(match_operand:V4SI 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V4SImode); DONE; }")
+ 
+ (define_insn "*movv4si_internal"
+   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v")
+ 	(match_operand:V4SI 1 "input_operand" "v,m"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1"
+   [(set_attr "type" "altivec")])
+ 
+ (define_expand "movv8hi"
+   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
+ 	(match_operand:V8HI 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V8HImode); DONE; }")
+ 
+ (define_insn "*movv8hi_internal1"
+   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=m,v")
+ 	(match_operand:V8HI 1 "input_operand" "v,m"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1"
+   [(set_attr "type" "altivec")])
+ 
+ (define_expand "movv16qi"
+   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
+ 	(match_operand:V16QI 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V16QImode); DONE; }")
+ 
+ (define_insn "*movv16qi_internal1"
+   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=m,v")
+ 	(match_operand:V16QI 1 "input_operand" "v,m"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1"
+   [(set_attr "type" "altivec")])
+ 
+ (define_expand "movv4sf"
+   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
+ 	(match_operand:V4SF 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V4SFmode); DONE; }")
+ 
+ (define_insn "*movv4sf_internal1"
+   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=m,v")
+ 	(match_operand:V4SF 1 "input_operand" "v,m"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1"
+   [(set_attr "type" "altivec")])
+ 
+ ;; Simple binary operations.
+ 

-- boring builtins deleted-- 

+ (define_insn "altivec_vxor"
+   [(set (match_operand:V4SI 0 "register_operand" "=v")
+         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
+                       (match_operand:V4SI 2 "register_operand" "v")] 136))]
+   "TARGET_ALTIVEC"
+   "vxor\t%0,%1,%2"
+   [(set_attr "type" "altivec")])

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 12:52 altivec patches Aldy Hernandez
@ 2001-11-05 12:58 ` Aldy Hernandez
  2001-11-13  4:32   ` Aldy Hernandez
  2001-11-13 15:03   ` Aldy Hernandez
  2001-11-05 12:59 ` Joseph S. Myers
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-05 12:58 UTC (permalink / raw)
  To: gcc patches; +Cc: Geoff Keating

>>>>> "Aldy" == Aldy Hernandez <aldyh@redhat.com> writes:

 > what is left?

Oh yeah, and I also need to fill in pipeline info (altivec function
units, etc).

Aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 12:52 altivec patches Aldy Hernandez
  2001-11-05 12:58 ` Aldy Hernandez
@ 2001-11-05 12:59 ` Joseph S. Myers
  2001-11-05 13:04   ` Aldy Hernandez
                     ` (2 more replies)
  2001-11-05 13:59 ` Geoff Keating
                   ` (4 subsequent siblings)
  6 siblings, 3 replies; 152+ messages in thread
From: Joseph S. Myers @ 2001-11-05 12:59 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: gcc patches

On 5 Nov 2001, Aldy Hernandez wrote:

> + @item -mabi=altivec
> + @opindex mabi=altivec
> + Extend the current ABI with AltiVec ABI extensions.  This does not
> + change the default ABI, instead it adds the AltiVec ABI extensions to
> + the current ABI.

That should end "ABI@." so that spacing after the sentence is correct if
more text gets added to that paragraph later.

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 12:59 ` Joseph S. Myers
@ 2001-11-05 13:04   ` Aldy Hernandez
  2001-11-05 13:17     ` Joseph S. Myers
                       ` (2 more replies)
  2001-11-13  4:32   ` Joseph S. Myers
  2001-11-13 15:03   ` Joseph S. Myers
  2 siblings, 3 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-05 13:04 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc patches

On Mon, 2001-11-05 at 15:59, Joseph S. Myers wrote:
> On 5 Nov 2001, Aldy Hernandez wrote:
> 
> > + @item -mabi=altivec
> > + @opindex mabi=altivec
> > + Extend the current ABI with AltiVec ABI extensions.  This does not
> > + change the default ABI, instead it adds the AltiVec ABI extensions to
> > + the current ABI.
> 
> That should end "ABI@." so that spacing after the sentence is correct if
> more text gets added to that paragraph later.

huh?  i've never heard that.

where are the .texi docs?  i'm bound to make more mistakes if i don't
read the texi docs :)
> 
> -- 
> Joseph S. Myers
> jsm28@cam.ac.uk
-- 
Aldy Hernandez			E-mail: aldyh@redhat.com
Professional Gypsy
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 13:04   ` Aldy Hernandez
@ 2001-11-05 13:17     ` Joseph S. Myers
  2001-11-13  4:32       ` Joseph S. Myers
  2001-11-13 15:03       ` Joseph S. Myers
  2001-11-13  4:32     ` Aldy Hernandez
  2001-11-13 15:03     ` Aldy Hernandez
  2 siblings, 2 replies; 152+ messages in thread
From: Joseph S. Myers @ 2001-11-05 13:17 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: gcc patches

On 5 Nov 2001, Aldy Hernandez wrote:

> > That should end "ABI@." so that spacing after the sentence is correct if
> > more text gets added to that paragraph later.
> 
> huh?  i've never heard that.
> 
> where are the .texi docs?  i'm bound to make more mistakes if i don't
> read the texi docs :)

Included with texinfo, or online at

http://www.gnu.org/manual/texinfo/

in particular

http://www.gnu.org/manual/texinfo/html_chapter/texinfo_14.html#SEC151

which describes this particular issue.

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 12:52 altivec patches Aldy Hernandez
  2001-11-05 12:58 ` Aldy Hernandez
  2001-11-05 12:59 ` Joseph S. Myers
@ 2001-11-05 13:59 ` Geoff Keating
  2001-11-05 14:05   ` Alan Matsuoka
                     ` (6 more replies)
  2001-11-05 14:05 ` Dale Johannesen
                   ` (3 subsequent siblings)
  6 siblings, 7 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-05 13:59 UTC (permalink / raw)
  To: aldyh; +Cc: gcc-patches

> From: Aldy Hernandez <aldyh@redhat.com>
> Cc: Geoff Keating <geoffk@cygnus.com>
> Date: 05 Nov 2001 15:54:20 -0500

Hi Aldy,

> *************** extern int rs6000_debug_arg;		/* debug a
> *** 569,581 ****
>   #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
>   
>   /* Boundary (in *bits*) on which stack pointer should be aligned.  */
> ! #define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
>   
>   /* Allocation boundary (in *bits*) for the code of a function.  */
>   #define FUNCTION_BOUNDARY 32
>   
>   /* No data type wants to be aligned rounder than this.  */
> ! #define BIGGEST_ALIGNMENT 64
>   
>   /* Handle #pragma pack.  */
>   #define HANDLE_PRAGMA_PACK 1
> --- 585,604 ----
>   #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
>   
>   /* Boundary (in *bits*) on which stack pointer should be aligned.  */
> ! #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
>   
>   /* Allocation boundary (in *bits*) for the code of a function.  */
>   #define FUNCTION_BOUNDARY 32
>   
>   /* No data type wants to be aligned rounder than this.  */
> ! #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)

I think you _don't_ want this to be dependent on the ABI.  Changing
this isn't an ABI change (I hope!), which is good because...

> ! 
> ! /* A C expression to compute the alignment for a variables in the
> !    local store.  TYPE is the data type, and ALIGN is the alignment
> !    that the object would ordinarily have.  */
> ! #define LOCAL_ALIGNMENT(TYPE, ALIGN)				\
> ! 	((TARGET_ALTIVEC_ABI		    			\
> ! 	  && TREE_CODE (TYPE)) == VECTOR_TYPE ? 128 : ALIGN)

...as altivec values have to be 128-bit aligned because of the
hardware, you don't want this ABI-dependent either.

> *************** extern int rs6000_debug_arg;		/* debug a
> *** 634,640 ****
>      a register, in order to work around problems in allocating stack storage
>      in inline functions.  */
>   
> ! #define FIRST_PSEUDO_REGISTER 77
>   
>   /* This must not decrease, for backwards compatibility.  If
>      FIRST_PSEUDO_REGISTER increases, this should as well.  */
> --- 659,665 ----
>      a register, in order to work around problems in allocating stack storage
>      in inline functions.  */
>   
> ! #define FIRST_PSEUDO_REGISTER 109
>   
>   /* This must not decrease, for backwards compatibility.  If
>      FIRST_PSEUDO_REGISTER increases, this should as well.  */

The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
quite right:  it has to happen _only when the ABI is 'altivec'_.

This will be a bit tricky because DWARF_FRAME_REGISTERS is also used
in libgcc, so you have to #define something when the Altivec ABI is
chosen, and then key off that if IN_LIBGCC2.

I wonder if you could assume that the integrated cpplib will always be
used when compiling libgcc?  That would make things easier, because
then you wouldn't have muck with specs so much.

> *************** extern int rs6000_debug_arg;		/* debug a
> *** 655,661 ****
>      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
>      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
>      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
> !    0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1}
>   
>   /* 1 for registers not available across function calls.
>      These must include the FIXED_REGISTERS and also any
> --- 680,690 ----
>      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
>      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
>      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
> !    0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1,	   \
> !    /* AltiVec registers.  */			   \
> !    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
> !    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  \
> ! }

This is correct, but doesn't there need to be a change to them in
CONDITIONAL_REGISTER_USAGE when the altivec ABI is chosen (in which
some altivec registers are call-saved)?

> *************** typedef struct rs6000_stack {
> *** 1338,1346 ****
> --- 1428,1442 ----
>   			? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG)
>   #define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1)
>   
> + /* Minimum and maximum AltiVec registers used to hold arguments.  */
> + #define ALTIVEC_ARG_MIN_REG 77
> + #define ALTIVEC_ARG_MAX_REG 88
> + #define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG - ALTIVEC_ARG_MIN_REG + 1)

These should be based off FIRST_ALTIVEC_REGISTER rather than being
magic numbers...

>   /* Return registers */
>   #define GP_ARG_RETURN GP_ARG_MIN_REG
>   #define FP_ARG_RETURN FP_ARG_MIN_REG
> + #define ALTIVEC_ARG_RETURN 79

... this too.


> Index: sysv4.h
> ===================================================================
> RCS file: /cvs/uberbaum/gcc/config/rs6000/sysv4.h,v
> retrieving revision 1.67
> diff -c -p -r1.67 sysv4.h
> *** sysv4.h	2001/10/29 23:09:43	1.67
> --- sysv4.h	2001/11/05 19:49:24
> *************** do {									\
> *** 400,417 ****
>      one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
>      versions, just use 64 as the stack boundary.  */
>   #undef	STACK_BOUNDARY
> ! #define	STACK_BOUNDARY	64
>   
>   /* Real stack boundary as mandated by the appropriate ABI.  */
> ! #define ABI_STACK_BOUNDARY ((TARGET_EABI) ? 64 : 128)
>   
>   /* No data type wants to be aligned rounder than this.  */
>   #undef	BIGGEST_ALIGNMENT
> ! #define BIGGEST_ALIGNMENT ((TARGET_EABI) ? 64 : 128)
>   
>   #undef  BIGGEST_FIELD_ALIGNMENT
>   #undef  ADJUST_FIELD_ALIGN
> - #undef  ROUND_TYPE_ALIGN
>   
>   /* Use ELF style section commands.  */
>   
> --- 400,430 ----
>      one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
>      versions, just use 64 as the stack boundary.  */
>   #undef	STACK_BOUNDARY
> ! #define	STACK_BOUNDARY	(TARGET_ALTIVEC_ABI ? 128 : 64)
>   
>   /* Real stack boundary as mandated by the appropriate ABI.  */
> ! #define ABI_STACK_BOUNDARY ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
>   
>   /* No data type wants to be aligned rounder than this.  */
>   #undef	BIGGEST_ALIGNMENT
> ! #define BIGGEST_ALIGNMENT ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
>   
> + /* An expression for the alignment of a structure field FIELD if the
> +    alignment computed in the usual way is COMPUTED.  */
> + #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)				      \
> + 	((TARGET_ALTIVEC_ABI && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
> + 	 ? 128 : COMPUTED)
> + 
> + /* Define this macro as an expression for the alignment of a type
> +    (given by TYPE as a tree node) if the alignment computed in the
> +    usual way is COMPUTED and the alignment explicitly specified was
> +    SPECIFIED.  */
> + #define ROUND_TYPE_ALIGN(TYPE, COMPUTED, SPECIFIED)			\
> + 	((TARGET_ALTIVEC_ABI && TREE_CODE (TYPE) == VECTOR_TYPE)	\
> + 	 ? 128 : MAX (COMPUTED, SPECIFIED))
> + 
>   #undef  BIGGEST_FIELD_ALIGNMENT
>   #undef  ADJUST_FIELD_ALIGN
>   
>   /* Use ELF style section commands.  */

This has the same comment as the equivalent stuff in rs6000.h.


> *************** function_arg_advance (cum, mode, type, n
> *** 2159,2165 ****
>   {
>     cum->nargs_prototype--;
>   
> !   if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
>       {
>         if (TARGET_HARD_FLOAT
>   	  && (mode == SFmode || mode == DFmode))
> --- 2242,2255 ----
>   {
>     cum->nargs_prototype--;
>   
> !   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
> !     {
> !       if (cum->vregno <= ALTIVEC_ARG_MAX_REG)
> ! 	cum->vregno++;
> !       else
> ! 	cum->words += RS6000_ARG_SIZE (mode, type);
> !     }

Something you might not have seen in the ABI documentation: unnamed
vector arguments (passed to varargs functions after the '...') get
passed in memory, not in registers.  (I don't remember if this is just
the unnamed arguments or all the arguments to varargs functions, you
should check.)

> *************** print_operand (file, x, code)
> *** 4714,4719 ****
> --- 5287,5318 ----
>   		     reg_names[SMALL_DATA_REG]);
>   	}
>         return;
> + 
> +       /* Print AltiVec memory operand.  */
> +     case 'y':
> +       {
> + 	rtx tmp;
> + 
> + 	if (GET_CODE (x) != MEM)
> + 	  abort ();
> + 
> + 	tmp = XEXP (x, 0);
> + 
> + 	if (GET_CODE (tmp) == REG)
> + 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
> + 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
> + 	  {
> + 	    if (REGNO (XEXP (tmp, 0)) == 0)
> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
> + 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
> + 	    else
> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
> + 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
> + 	  }
> + 	else
> + 	  abort ();
> + 	break;
> +       }

Do you really need this?  It looks just like the way a normal memory
operand is printed (for the cases that are allowed for altivec).

> Index: rs6000.md

Can you put the altivec insns in their own .md file and use the include
mechanism?  I believe this is what it was intended for.

> + ;; No code is needed to copy between vector registers.
> + (define_insn "*altivec_vec_move"
> +   [(set (match_operand 0 "altivec_register" "=v")
> + 	(match_operand 1 "altivec_register" "v"))]
> +   "TARGET_ALTIVEC"
> +   ""
> +   [(set_attr "type" "altivec")])

Um, that can't possibly be right.  Also, it should be part of
movv4si_internal, because reload needs all the move insns to be the
same pattern.

> + ;; Vector move instructions.
> + (define_expand "movv4si"
> +   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
> + 	(match_operand:V4SI 1 "any_operand" ""))]
> +   "TARGET_ALTIVEC"
> +   "{ rs6000_emit_move (operands[0], operands[1], V4SImode); DONE; }")
> + 
> + (define_insn "*movv4si_internal"
> +   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v")
> + 	(match_operand:V4SI 1 "input_operand" "v,m"))]
> +   "TARGET_ALTIVEC"
> +   "@
> +    stvx\t%1,%y0
> +    ldvx\t%0,%y1"
> +   [(set_attr "type" "altivec")])

Yes---this needs an alternative to copy a 'v' into a 'v'.  All the
ones below probably need it too.

> + (define_expand "movv8hi"
> +   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
> + 	(match_operand:V8HI 1 "any_operand" ""))]
> +   "TARGET_ALTIVEC"
> +   "{ rs6000_emit_move (operands[0], operands[1], V8HImode); DONE; }")
> + 
> + (define_insn "*movv8hi_internal1"
> +   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=m,v")
> + 	(match_operand:V8HI 1 "input_operand" "v,m"))]
> +   "TARGET_ALTIVEC"
> +   "@
> +    stvx\t%1,%y0
> +    ldvx\t%0,%y1"
> +   [(set_attr "type" "altivec")])
> + 
> + (define_expand "movv16qi"
> +   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
> + 	(match_operand:V16QI 1 "any_operand" ""))]
> +   "TARGET_ALTIVEC"
> +   "{ rs6000_emit_move (operands[0], operands[1], V16QImode); DONE; }")
> + 
> + (define_insn "*movv16qi_internal1"
> +   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=m,v")
> + 	(match_operand:V16QI 1 "input_operand" "v,m"))]
> +   "TARGET_ALTIVEC"
> +   "@
> +    stvx\t%1,%y0
> +    ldvx\t%0,%y1"
> +   [(set_attr "type" "altivec")])
> + 
> + (define_expand "movv4sf"
> +   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
> + 	(match_operand:V4SF 1 "any_operand" ""))]
> +   "TARGET_ALTIVEC"
> +   "{ rs6000_emit_move (operands[0], operands[1], V4SFmode); DONE; }")
> + 
> + (define_insn "*movv4sf_internal1"
> +   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=m,v")
> + 	(match_operand:V4SF 1 "input_operand" "v,m"))]
> +   "TARGET_ALTIVEC"
> +   "@
> +    stvx\t%1,%y0
> +    ldvx\t%0,%y1"
> +   [(set_attr "type" "altivec")])
> + 
> + ;; Simple binary operations.
> + 
> 
> -- boring builtins deleted-- 
> 
> + (define_insn "altivec_vxor"
> +   [(set (match_operand:V4SI 0 "register_operand" "=v")
> +         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
> +                       (match_operand:V4SI 2 "register_operand" "v")] 136))]
> +   "TARGET_ALTIVEC"
> +   "vxor\t%0,%1,%2"
> +   [(set_attr "type" "altivec")])

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 12:52 altivec patches Aldy Hernandez
                   ` (2 preceding siblings ...)
  2001-11-05 13:59 ` Geoff Keating
@ 2001-11-05 14:05 ` Dale Johannesen
  2001-11-05 14:38   ` Geoff Keating
                     ` (4 more replies)
  2001-11-05 14:39 ` Dale Johannesen
                   ` (2 subsequent siblings)
  6 siblings, 5 replies; 152+ messages in thread
From: Dale Johannesen @ 2001-11-05 14:05 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Dale Johannesen, gcc patches, Geoff Keating

This is getting better.

On Monday, November 5, 2001, at 12:54 PM, Aldy Hernandez wrote:

> finally...
> what is left?
>     - the rest of the gazillion builtins
>
>     - varargs
>
>     - frame stuff: epilogue, prologue, vrsave
>     - <altivec.h> for the user.  this .h will implement the overloaded
>     altivec functions described in the "altivec programming interface
>     model".  Stuff like generic (overloaded) "vec_add(veca, vecb)".
>
>     - test cases.  i will commit a few simple tests, but serious tests
>     will come after i'm done playing with the G3 box.

I'd really like to see vrsave in the enums and register macros
(not necessarily the code).  I dislike making a major change to
an area if we know it's going to change again shortly.

>   /* Boundary (in *bits*) on which stack pointer should be aligned.  */
> ! #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 
> 128)

If you plan to support linking files compiled with and without 
-fabi=altivec,
shouldn't this be 128 unconditionally?  Otherwise the stack might not be
128-bit aligned when you enter an Altivec function.  Also in sysv4.h.

> *************** extern int rs6000_debug_arg;		/* debug a
> *** 757,762 ****
> --- 827,834 ----
>      (GET_MODE_CLASS (MODE) == MODE_FLOAT					\
>       || (GET_MODE_CLASS (MODE) == MODE_INT				\
>   	&& GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD))			\
> +    : ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_REGNO_P (REGNO)		\
> +    : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE)		\
>      : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC		\
>      : XER_REGNO_P (REGNO) ? (MODE) == PSImode				\
>      : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT		\

I don't think you want the first changed line here.

> *************** extern int rs6000_debug_arg;		/* debug a
> *** 788,793 ****
> --- 864,870 ----
>      ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2		\
>      : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10	\
>      : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10	\
> +    : (CLASS1) == ALTIVEC_REGS && (CLASS2) != ALTIVEC_REGS ? 20	\
>      : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS		\
>          || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS		\
>          || (CLASS1) == LINK_OR_CTR_REGS)				\

And here you need
	: (CLASS1) != ALTIVEC_REGS && (CLASS2) == ALTIVEC_REGS ? 20
analogous to the FLOAT case.

> *************** typedef struct rs6000_args
> *** 1778,1783 ****
> --- 1886,1892 ----
>     && GET_CODE (XEXP (X, 0)) == REG				\
>     && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT))		\
>     && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0)		\
> +   && ! ALTIVEC_VECTOR_MODE (MODE)				\
>     && (((MODE) != DFmode && (MODE) != DImode)			\
>         || (TARGET_32BIT						\
>   	  ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) 	\

That could be
	  && ( ! ALTIVEC_VECTOR_MODE (MODE) || INTVAL (X) == 0)
for better codegen.  It's not wrong as is, though.

> +
> +       /* Print AltiVec memory operand.  */
> +     case 'y':
> +       {
> + 	rtx tmp;
> +
> + 	if (GET_CODE (x) != MEM)
> + 	  abort ();
> +
> + 	tmp = XEXP (x, 0);
> +
> + 	if (GET_CODE (tmp) == REG)
> + 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
> + 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
> + 	  {
> + 	    if (REGNO (XEXP (tmp, 0)) == 0)
> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
> + 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
> + 	    else
> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
> + 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
> + 	  }
> + 	else
> + 	  abort ();
> + 	break;
> +       }

I guess this is OK.  Apple/Moto version doesn't have any analogous change
here; the patterns in rs6000.md match more elaborate MEM subpatterns,
to do the checking that you do here.  Isn't it generally considered 
preferable
to use the existing pattern mechanism whenever possible?

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 13:59 ` Geoff Keating
@ 2001-11-05 14:05   ` Alan Matsuoka
  2001-11-05 18:22     ` Aldy Hernandez
                       ` (2 more replies)
  2001-11-05 14:31   ` Stan Shebs
                     ` (5 subsequent siblings)
  6 siblings, 3 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-05 14:05 UTC (permalink / raw)
  To: Geoff Keating; +Cc: aldyh, gcc-patches

> Do you really need this?  It looks just like the way a normal memory
> operand is printed (for the cases that are allowed for altivec).
> 
> > Index: rs6000.md
> 
> Can you put the altivec insns in their own .md file and use the include
> mechanism?  I believe this is what it was intended for.

Who does the approvals for my patches? I sent them out ages ago. I
guess I'd better do it again ....



> 
> > + ;; No code is needed to copy between vector registers.
> > + (define_insn "*altivec_vec_move"
> > +   [(set (match_operand 0 "altivec_register" "=v")
> > + 	(match_operand 1 "altivec_register" "v"))]
> > +   "TARGET_ALTIVEC"
> > +   ""
> > +   [(set_attr "type" "altivec")])
> 
> Um, that can't possibly be right.  Also, it should be part of
> movv4si_internal, because reload needs all the move insns to be the
> same pattern.
> 
> > + ;; Vector move instructions.
> > + (define_expand "movv4si"
> > +   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
> > + 	(match_operand:V4SI 1 "any_operand" ""))]
> > +   "TARGET_ALTIVEC"
> > +   "{ rs6000_emit_move (operands[0], operands[1], V4SImode); DONE; }")
> > + 
> > + (define_insn "*movv4si_internal"
> > +   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v")
> > + 	(match_operand:V4SI 1 "input_operand" "v,m"))]
> > +   "TARGET_ALTIVEC"
> > +   "@
> > +    stvx\t%1,%y0
> > +    ldvx\t%0,%y1"
> > +   [(set_attr "type" "altivec")])
> 
> Yes---this needs an alternative to copy a 'v' into a 'v'.  All the
> ones below probably need it too.
> 
> > + (define_expand "movv8hi"
> > +   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
> > + 	(match_operand:V8HI 1 "any_operand" ""))]
> > +   "TARGET_ALTIVEC"
> > +   "{ rs6000_emit_move (operands[0], operands[1], V8HImode); DONE; }")
> > + 
> > + (define_insn "*movv8hi_internal1"
> > +   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=m,v")
> > + 	(match_operand:V8HI 1 "input_operand" "v,m"))]
> > +   "TARGET_ALTIVEC"
> > +   "@
> > +    stvx\t%1,%y0
> > +    ldvx\t%0,%y1"
> > +   [(set_attr "type" "altivec")])
> > + 
> > + (define_expand "movv16qi"
> > +   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
> > + 	(match_operand:V16QI 1 "any_operand" ""))]
> > +   "TARGET_ALTIVEC"
> > +   "{ rs6000_emit_move (operands[0], operands[1], V16QImode); DONE; }")
> > + 
> > + (define_insn "*movv16qi_internal1"
> > +   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=m,v")
> > + 	(match_operand:V16QI 1 "input_operand" "v,m"))]
> > +   "TARGET_ALTIVEC"
> > +   "@
> > +    stvx\t%1,%y0
> > +    ldvx\t%0,%y1"
> > +   [(set_attr "type" "altivec")])
> > + 
> > + (define_expand "movv4sf"
> > +   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
> > + 	(match_operand:V4SF 1 "any_operand" ""))]
> > +   "TARGET_ALTIVEC"
> > +   "{ rs6000_emit_move (operands[0], operands[1], V4SFmode); DONE; }")
> > + 
> > + (define_insn "*movv4sf_internal1"
> > +   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=m,v")
> > + 	(match_operand:V4SF 1 "input_operand" "v,m"))]
> > +   "TARGET_ALTIVEC"
> > +   "@
> > +    stvx\t%1,%y0
> > +    ldvx\t%0,%y1"
> > +   [(set_attr "type" "altivec")])
> > + 
> > + ;; Simple binary operations.
> > + 
> > 
> > -- boring builtins deleted-- 
> > 
> > + (define_insn "altivec_vxor"
> > +   [(set (match_operand:V4SI 0 "register_operand" "=v")
> > +         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
> > +                       (match_operand:V4SI 2 "register_operand" "v")] 136))]
> > +   "TARGET_ALTIVEC"
> > +   "vxor\t%0,%1,%2"
> > +   [(set_attr "type" "altivec")])
> 
> -- 
> - Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>


Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 13:59 ` Geoff Keating
  2001-11-05 14:05   ` Alan Matsuoka
@ 2001-11-05 14:31   ` Stan Shebs
  2001-11-05 14:49     ` Geoff Keating
                       ` (2 more replies)
  2001-11-05 19:27   ` Aldy Hernandez
                     ` (4 subsequent siblings)
  6 siblings, 3 replies; 152+ messages in thread
From: Stan Shebs @ 2001-11-05 14:31 UTC (permalink / raw)
  To: Geoff Keating; +Cc: aldyh, gcc-patches

Geoff Keating wrote:
> 
> The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
> quite right:  it has to happen _only when the ABI is 'altivec'_.
> 
> This will be a bit tricky because DWARF_FRAME_REGISTERS is also used
> in libgcc, so you have to #define something when the Altivec ABI is
> chosen, and then key off that if IN_LIBGCC2.

Thus we slide down the slippery slope... Solving this completely
eventually entails having a method to detect whether the CPU
supports AltiVec instructions - in the case of a C++ throw
in code using AltiVec registers, you need to detect dynamically
(Apple's GCC uses a bit set by the kernel) whether you're on a
G4 or a not-G4.  So you may have to generate a frame descriptor
that mentions registers you won't actually manipulate on a not-G4.

Our GCC just sets DWARF_FRAME_REGISTERS to FIRST_PSEUDO_REGISTERS
unconditionally, seems to work well enough for non-AltiVec code.

Stan

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 14:05 ` Dale Johannesen
@ 2001-11-05 14:38   ` Geoff Keating
  2001-11-13  4:32     ` Geoff Keating
  2001-11-13 15:03     ` Geoff Keating
  2001-11-05 18:30   ` Aldy Hernandez
                     ` (3 subsequent siblings)
  4 siblings, 2 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-05 14:38 UTC (permalink / raw)
  To: Dale Johannesen; +Cc: gcc-patches, aldyh

Dale Johannesen <dalej@apple.com> writes:

> >   /* Boundary (in *bits*) on which stack pointer should be aligned.  */
> > ! #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 
> > 128)
> 
> If you plan to support linking files compiled with and without 
> -fabi=altivec,
> shouldn't this be 128 unconditionally?  Otherwise the stack might not be
> 128-bit aligned when you enter an Altivec function.  Also in sysv4.h.

By definition, you can't expect to link together files compiled with
different ABIs.  This is one example of the problem; another is the
varargs changes that Aldy hasn't done yet.

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 12:52 altivec patches Aldy Hernandez
                   ` (3 preceding siblings ...)
  2001-11-05 14:05 ` Dale Johannesen
@ 2001-11-05 14:39 ` Dale Johannesen
  2001-11-05 18:35   ` Aldy Hernandez
                     ` (2 more replies)
  2001-11-13  4:32 ` Aldy Hernandez
  2001-11-13 15:03 ` Aldy Hernandez
  6 siblings, 3 replies; 152+ messages in thread
From: Dale Johannesen @ 2001-11-05 14:39 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Dale Johannesen, gcc patches, Geoff Keating

On Monday, November 5, 2001, at 12:54 PM, Aldy Hernandez wrote:
> + /* Minimum and maximum AltiVec registers used to hold arguments.  */
> + #define ALTIVEC_ARG_MIN_REG 77
> + #define ALTIVEC_ARG_MAX_REG 88
> + #define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG - ALTIVEC_ARG_MIN_REG 
> + 1)

Incidentally, on Darwin and I think some others, the vector param
regs are V2..V13, not V0..V11.  I guess this is ABI-dependent too.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 14:31   ` Stan Shebs
@ 2001-11-05 14:49     ` Geoff Keating
  2001-11-05 15:29       ` Stan Shebs
                         ` (3 more replies)
  2001-11-13  4:32     ` Stan Shebs
  2001-11-13 15:03     ` Stan Shebs
  2 siblings, 4 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-05 14:49 UTC (permalink / raw)
  To: Stan Shebs; +Cc: gcc-patches

Stan Shebs <shebs@apple.com> writes:

> Geoff Keating wrote:
> > 
> > The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
> > quite right:  it has to happen _only when the ABI is 'altivec'_.
> > 
> > This will be a bit tricky because DWARF_FRAME_REGISTERS is also used
> > in libgcc, so you have to #define something when the Altivec ABI is
> > chosen, and then key off that if IN_LIBGCC2.
> 
> Thus we slide down the slippery slope... Solving this completely
> eventually entails having a method to detect whether the CPU
> supports AltiVec instructions - in the case of a C++ throw
> in code using AltiVec registers, you need to detect dynamically
> (Apple's GCC uses a bit set by the kernel) whether you're on a
> G4 or a not-G4.  So you may have to generate a frame descriptor
> that mentions registers you won't actually manipulate on a not-G4.

Unfortunately, such a method doesn't exist in many environments.  (In
particular, it's not in the powerpc UISA, which is all you can really
rely on in GCC.)

> Our GCC just sets DWARF_FRAME_REGISTERS to FIRST_PSEUDO_REGISTERS
> unconditionally, seems to work well enough for non-AltiVec code.

Can't do that; breaks backwards binary compatibility.  That's why
DWARF_FRAME_REGISTERS was invented, so people could add registers
without breaking binary compatibility.

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 14:49     ` Geoff Keating
@ 2001-11-05 15:29       ` Stan Shebs
  2001-11-13  4:32         ` Stan Shebs
  2001-11-13 15:03         ` Stan Shebs
  2001-11-05 19:30       ` Aldy Hernandez
                         ` (2 subsequent siblings)
  3 siblings, 2 replies; 152+ messages in thread
From: Stan Shebs @ 2001-11-05 15:29 UTC (permalink / raw)
  To: Geoff Keating; +Cc: gcc-patches

Geoff Keating wrote:
> 
> > Our GCC just sets DWARF_FRAME_REGISTERS to FIRST_PSEUDO_REGISTERS
> > unconditionally, seems to work well enough for non-AltiVec code.
> 
> Can't do that; breaks backwards binary compatibility.  That's why
> DWARF_FRAME_REGISTERS was invented, so people could add registers
> without breaking binary compatibility.

Ah, I see what you're getting at.  So we'll move our definition
to darwin.h.

Stan

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 14:05   ` Alan Matsuoka
@ 2001-11-05 18:22     ` Aldy Hernandez
  2001-11-05 18:28       ` Alan Matsuoka
                         ` (2 more replies)
  2001-11-13  4:32     ` Alan Matsuoka
  2001-11-13 15:03     ` Alan Matsuoka
  2 siblings, 3 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-05 18:22 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: Geoff Keating, gcc-patches

>>>>> "Alan" == Alan Matsuoka <alanm@cygnus.com> writes:

 >> Do you really need this?  It looks just like the way a normal memory
 >> operand is printed (for the cases that are allowed for altivec).
 >> 
 >> > Index: rs6000.md
 >> 
 >> Can you put the altivec insns in their own .md file and use the include
 >> mechanism?  I believe this is what it was intended for.

Last i heard, alan matsuoka's include mechanism hadn't been approved.
Alan, perhaps you should send them again.  We definitely need them
now.

Aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 18:22     ` Aldy Hernandez
@ 2001-11-05 18:28       ` Alan Matsuoka
  2001-11-05 18:41         ` Include facility for .md files - " Alan Matsuoka
                           ` (2 more replies)
  2001-11-13  4:32       ` Aldy Hernandez
  2001-11-13 15:03       ` Aldy Hernandez
  2 siblings, 3 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-05 18:28 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Geoff Keating, gcc-patches

On Mon, 05 Nov 2001, Aldy Hernandez wrote:

> >>>>> "Alan" == Alan Matsuoka <alanm@cygnus.com> writes:
> 
>  >> Do you really need this?  It looks just like the way a normal memory
>  >> operand is printed (for the cases that are allowed for altivec).
>  >> 
>  >> > Index: rs6000.md
>  >> 
>  >> Can you put the altivec insns in their own .md file and use the include
>  >> mechanism?  I believe this is what it was intended for.
> 
> Last i heard, alan matsuoka's include mechanism hadn't been approved.
> Alan, perhaps you should send them again.  We definitely need them
> now.

OK.

Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 14:05 ` Dale Johannesen
  2001-11-05 14:38   ` Geoff Keating
@ 2001-11-05 18:30   ` Aldy Hernandez
  2001-11-06 16:12     ` Daniel Jacobowitz
                       ` (2 more replies)
  2001-11-05 19:47   ` Aldy Hernandez
                     ` (2 subsequent siblings)
  4 siblings, 3 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-05 18:30 UTC (permalink / raw)
  To: Dale Johannesen; +Cc: gcc patches, Geoff Keating

>>>>> "Dale" == Dale Johannesen <dalej@apple.com> writes:

 > This is getting better.

Thanks ;-)

 > I'd really like to see vrsave in the enums and register macros
 > (not necessarily the code).  I dislike making a major change to
 > an area if we know it's going to change again shortly.

That was supposed to be tommorrow's work.... :)

 > If you plan to support linking files compiled with and without
 > -fabi=altivec,

nope we don't.  You can't just link too different abi's.

 >> +       /* Print AltiVec memory operand.  */
 >> +     case 'y':
 >> +       {
 >> + 	rtx tmp;
 >> +
 >> + 	if (GET_CODE (x) != MEM)
 >> + 	  abort ();
 >> +
 >> + 	tmp = XEXP (x, 0);
 >> +
 >> + 	if (GET_CODE (tmp) == REG)
 >> + 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
 >> + 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
 >> + 	  {
 >> + 	    if (REGNO (XEXP (tmp, 0)) == 0)
 >> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
 >> + 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
 >> + 	    else
 >> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
 >> + 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
 >> + 	  }
 >> + 	else
 >> + 	  abort ();
 >> + 	break;
 >> +       }

 > I guess this is OK.  Apple/Moto version doesn't have any analogous change
 > here; the patterns in rs6000.md match more elaborate MEM subpatterns,
 > to do the checking that you do here.  Isn't it generally considered
 > preferable
 > to use the existing pattern mechanism whenever possible?

What I do is have some legitimize_address hackery that will transform
incorrect memory addresses into something altivec memory addressing
can handle (mem (plus reg reg)), and then handle [reg+reg] and [reg]
as the %y print operand.

I dislike the idea of having lots of variants of memory addressing in
the MD file.  It seems cleaner to have just memory_operand() and then
have %operands print them out pretty :).

Aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 14:39 ` Dale Johannesen
@ 2001-11-05 18:35   ` Aldy Hernandez
  2001-11-13  4:32     ` Aldy Hernandez
  2001-11-13 15:03     ` Aldy Hernandez
  2001-11-13  4:32   ` Dale Johannesen
  2001-11-13 15:03   ` Dale Johannesen
  2 siblings, 2 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-05 18:35 UTC (permalink / raw)
  To: Dale Johannesen; +Cc: gcc patches, Geoff Keating

>>>>> "Dale" == Dale Johannesen <dalej@apple.com> writes:

 > On Monday, November 5, 2001, at 12:54 PM, Aldy Hernandez wrote:
 >> + /* Minimum and maximum AltiVec registers used to hold arguments.  */
 >> + #define ALTIVEC_ARG_MIN_REG 77
 >> + #define ALTIVEC_ARG_MAX_REG 88
 >> + #define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG -
 >> ALTIVEC_ARG_MIN_REG + 1)

 > Incidentally, on Darwin and I think some others, the vector param
 > regs are V2..V13, not V0..V11.  I guess this is ABI-dependent too.

Whoops.  You are right.  Fixed.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Include facility for .md files - altivec patches
  2001-11-05 18:28       ` Alan Matsuoka
@ 2001-11-05 18:41         ` Alan Matsuoka
  2001-11-03 20:37           ` Geoff Keating
                             ` (5 more replies)
  2001-11-13  4:32         ` Alan Matsuoka
  2001-11-13 15:03         ` Alan Matsuoka
  2 siblings, 6 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-05 18:41 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Geoff Keating, gcc-patches

On Mon, 05 Nov 2001, Alan Matsuoka wrote:

> On Mon, 05 Nov 2001, Aldy Hernandez wrote:
> 
> > >>>>> "Alan" == Alan Matsuoka <alanm@cygnus.com> writes:
> > 
> >  >> Do you really need this?  It looks just like the way a normal memory
> >  >> operand is printed (for the cases that are allowed for altivec).
> >  >> 
> >  >> > Index: rs6000.md
> >  >> 
> >  >> Can you put the altivec insns in their own .md file and use the include
> >  >> mechanism?  I believe this is what it was intended for.
> > 
> > Last i heard, alan matsuoka's include mechanism hadn't been approved.
> > Alan, perhaps you should send them again.  We definitely need them
> > now.
> 
> OK.
> 

The following patch is for the an internal project. This is 
implements a (include "filestuff") mechanism for splitting up 
.md files.

(include "filestuff") expects the include file to be in gcc/config/{target}/filestuff
(include "BOGUS/filestuff") expects the include file to be in gcc/config/{target}/BOGUS/filestuff
(include "/u2/BOGUS/filestuff") expects the include file to be in /u2/BOGUS/filestuff

You can also run things like genrecog -I/p1/abc/proc1 -I/p2/abcd/pro2 target.md

This is used only at build time.

This has been tested for i686-pc-linux-gnu by bootstrapping and testing without 
any regressions.

The DOS pathname style stuff may still be required.


2001-11-05  Alan Matsuoka  <alanm@redhat.com>

        * rtl.def (INCLUDE) : Define.
	* gensupport.c (init_include_reader, process_include, save_string) :  New functions to
	  implement an include facility in .md files.
	* gensupport.h : Add prototype for init_md_reader_args.
	* genattr.c genattrtab.c gencodes.c genconfig.c genemit.c
	  genextract.c genflags.c genopinit.c genoutput.c genpeep.c
	  genrecog.c: Change call to init_md_reader to init_md_reader_args.
	* md.texi: Document (include "path") and -I directives for RTL generation tools.

Index: genattr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genattr.c,v
retrieving revision 1.45
diff -3 -c -p -r1.45 genattr.c
*** genattr.c	2001/10/07 16:50:51	1.45
--- genattr.c	2001/11/06 02:32:32
*************** main (argc, argv)
*** 210,216 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genattr'");
--- 210,216 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genattr'");
Index: genattrtab.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genattrtab.c,v
retrieving revision 1.103
diff -3 -c -p -r1.103 genattrtab.c
*** genattrtab.c	2001/10/21 21:32:00	1.103
--- genattrtab.c	2001/11/06 02:32:58
*************** main (argc, argv)
*** 6075,6081 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    obstack_init (hash_obstack);
--- 6075,6081 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    obstack_init (hash_obstack);
Index: gencodes.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gencodes.c,v
retrieving revision 1.42
diff -3 -c -p -r1.42 gencodes.c
*** gencodes.c	2001/08/22 14:35:16	1.42
--- gencodes.c	2001/11/06 02:32:58
*************** main (argc, argv)
*** 56,62 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("\
--- 56,62 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("\
Index: genconfig.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genconfig.c,v
retrieving revision 1.43
diff -3 -c -p -r1.43 genconfig.c
*** genconfig.c	2001/10/11 07:07:26	1.43
--- genconfig.c	2001/11/06 02:33:00
*************** main (argc, argv)
*** 277,283 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genconfig'");
--- 277,283 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genconfig'");
Index: genemit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genemit.c,v
retrieving revision 1.67
diff -3 -c -p -r1.67 genemit.c
*** genemit.c	2001/10/19 19:37:08	1.67
--- genemit.c	2001/11/06 02:33:05
*************** main (argc, argv)
*** 789,795 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
--- 789,795 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
Index: genextract.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genextract.c,v
retrieving revision 1.46
diff -3 -c -p -r1.46 genextract.c
*** genextract.c	2001/10/11 03:15:42	1.46
--- genextract.c	2001/11/06 02:33:07
*************** main (argc, argv)
*** 362,368 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
--- 362,368 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
Index: genflags.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genflags.c,v
retrieving revision 1.39
diff -3 -c -p -r1.39 genflags.c
*** genflags.c	2001/10/11 03:15:42	1.39
--- genflags.c	2001/11/06 02:33:07
*************** main (argc, argv)
*** 230,236 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
    
    puts ("/* Generated automatically by the program `genflags'");
--- 230,236 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
    
    puts ("/* Generated automatically by the program `genflags'");
Index: genopinit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genopinit.c,v
retrieving revision 1.48
diff -3 -c -p -r1.48 genopinit.c
*** genopinit.c	2001/09/13 14:37:11	1.48
--- genopinit.c	2001/11/06 02:33:07
*************** main (argc, argv)
*** 316,322 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genopinit'\n\
--- 316,322 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genopinit'\n\
Index: genoutput.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genoutput.c,v
retrieving revision 1.65
diff -3 -c -p -r1.65 genoutput.c
*** genoutput.c	2001/10/11 03:15:42	1.65
--- genoutput.c	2001/11/06 02:33:10
*************** main (argc, argv)
*** 953,959 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    output_prologue ();
--- 953,959 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    output_prologue ();
Index: genpeep.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genpeep.c,v
retrieving revision 1.49
diff -3 -c -p -r1.49 genpeep.c
*** genpeep.c	2001/10/11 03:15:43	1.49
--- genpeep.c	2001/11/06 02:33:14
*************** main (argc, argv)
*** 385,391 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genpeep'\n\
--- 385,391 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genpeep'\n\
Index: genrecog.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genrecog.c,v
retrieving revision 1.111
diff -3 -c -p -r1.111 genrecog.c
*** genrecog.c	2001/10/28 20:09:14	1.111
--- genrecog.c	2001/11/06 02:33:19
*************** main (argc, argv)
*** 2689,2695 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    next_insn_code = 0;
--- 2689,2695 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    next_insn_code = 0;
Index: gensupport.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gensupport.c,v
retrieving revision 1.23
diff -3 -c -p -r1.23 gensupport.c
*** gensupport.c	2001/10/25 12:55:16	1.23
--- gensupport.c	2001/11/06 02:33:20
*************** static int predicable_default;
*** 42,47 ****
--- 42,49 ----
  static const char *predicable_true;
  static const char *predicable_false;
  
+ static char *base_dir = NULL;
+ 
  /* We initially queue all patterns, process the define_insn and
     define_cond_exec patterns, then return them one at a time.  */
  
*************** static struct queue_elem *other_queue;
*** 62,67 ****
--- 64,86 ----
  static struct queue_elem **other_tail = &other_queue;
  
  static void queue_pattern PARAMS ((rtx, struct queue_elem ***, int));
+ 
+ /* Current maximum length of directory names in the search path
+    for include files.  (Altered as we get more of them.)  */
+ 
+ size_t max_include_len;
+ 
+ struct file_name_list
+   {
+     struct file_name_list *next;
+     const char *fname;
+   };
+ 
+ struct file_name_list *include = 0;     /* First dir to search */
+         /* First dir to search for <file> */
+ struct file_name_list *first_bracket_include = 0;
+ struct file_name_list *last_include = 0;        /* Last in chain */
+ 
  static void remove_constraints PARAMS ((rtx));
  static void process_rtx PARAMS ((rtx, int));
  
*************** static const char *alter_output_for_insn
*** 78,83 ****
--- 97,105 ----
  						  int, int));
  static void process_one_cond_exec PARAMS ((struct queue_elem *));
  static void process_define_cond_exec PARAMS ((void));
+ static int process_include PARAMS ((rtx, int));
+ static char *save_string PARAMS ((const char *, int));
+ static int init_include_reader PARAMS ((FILE  *));
  \f
  void
  message_with_line VPARAMS ((int lineno, const char *msg, ...))
*************** remove_constraints (part)
*** 157,162 ****
--- 179,320 ----
        }
  }
  
+ /* The entry point for initializing the reader.  */
+ 
+ static int
+ init_include_reader (inf)
+      FILE *inf;
+ {
+   int c;
+ 
+   errors = 0;
+ 
+   /* Read the entire file.  */
+   while (1)
+     {
+       rtx desc;
+       int lineno;
+ 
+       c = read_skip_spaces (inf);
+       if (c == EOF)
+ 	break;
+ 
+       ungetc (c, inf);
+       lineno = read_rtx_lineno;
+       desc = read_rtx (inf);
+       process_rtx (desc, lineno);
+     }
+   fclose (inf);
+ 
+   /* Process define_cond_exec patterns.  */
+   if (define_cond_exec_queue != NULL)
+     process_define_cond_exec ();
+ 
+   return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
+ }
+ 
+ /* Process an include file assuming that it lives in gcc/config/{target}/ 
+    if the include looks line (include "file" )  */
+ static int
+ process_include (desc, lineno)
+      rtx desc;
+      int lineno;
+ {
+   const char *filename = XSTR (desc, 0);
+   char *pathname = NULL;
+   FILE *input_file;
+   char *fname;
+   struct file_name_list *stackp;
+   int flen;
+ 
+   stackp = include;
+ 
+   /* If specified file name is absolute, just open it.  */
+   if (IS_ABSOLUTE_PATHNAME (filename) || !stackp)
+     {
+       if (base_dir)
+         {
+           pathname = xmalloc (strlen (base_dir) + strlen (filename) + 1);
+           pathname = strcpy (pathname, base_dir);
+           strcat (pathname, filename);
+           strcat (pathname, "\0");
+ 	}
+       else
+         {
+ 	  pathname = xstrdup (filename);
+         }
+       read_rtx_filename = pathname;
+       input_file = fopen (pathname, "r");
+ 
+       if (input_file == 0)
+ 	{
+ 	  perror (pathname);
+ 	  return FATAL_EXIT_CODE;
+ 	}
+     }
+   else if (stackp)
+     {
+ 
+       flen = strlen (filename);
+ 
+       fname = (char *) alloca (max_include_len + flen + 2);
+ 
+       /* + 2 above for slash and terminating null.  */
+ 
+       /* Search directory path, trying to open the file.
+          Copy each filename tried into FNAME.  */
+ 
+       for (; stackp; stackp = stackp->next)
+ 	{
+ 	  if (stackp->fname)
+ 	    {
+ 	      strcpy (fname, stackp->fname);
+ 	      strcat (fname, "/");
+ 	      fname[strlen (fname) + flen] = 0;
+ 	    }
+ 	  else
+ 	    {
+ 	      fname[0] = 0;
+ 	    }
+ 	  strncat (fname, (const char *) filename, flen);
+ 	  read_rtx_filename = fname;
+ 	  input_file = fopen (fname, "r");
+ 	  if (input_file != NULL) 
+ 	    break;
+ 	}
+       if (stackp == NULL)
+ 	{
+ 	  if (strchr (fname, '/') == NULL || strchr (fname, '\\' ) || base_dir)
+ 	    {
+ 	      if (base_dir)
+ 		{
+ 		  pathname =
+ 		    xmalloc (strlen (base_dir) + strlen (filename) + 1);
+ 		  pathname = strcpy (pathname, base_dir);
+ 		  strcat (pathname, filename);
+ 		  strcat (pathname, "\0");
+ 		}
+ 	      else
+ 		pathname = xstrdup (filename);
+ 	    }
+ 	  read_rtx_filename = pathname;
+ 	  input_file = fopen (pathname, "r");
+ 
+ 	  if (input_file == 0)
+ 	    {
+ 	      perror (filename);
+ 	      return FATAL_EXIT_CODE;
+ 	    }
+ 	}
+ 
+     }
+ 
+   if (init_include_reader (input_file) == FATAL_EXIT_CODE)
+     message_with_line (lineno, "read errors found in include file  %s\n", pathname);
+ 
+   return SUCCESS_EXIT_CODE;
+ }
+ 
  /* Process a top level rtx in some way, queueing as appropriate.  */
  
  static void
*************** process_rtx (desc, lineno)
*** 164,169 ****
--- 322,329 ----
       rtx desc;
       int lineno;
  {
+   const char *filename = XSTR (desc, 0);
+ 
    switch (GET_CODE (desc))
      {
      case DEFINE_INSN:
*************** process_rtx (desc, lineno)
*** 178,183 ****
--- 338,348 ----
        queue_pattern (desc, &define_attr_tail, lineno);
        break;
  
+     case INCLUDE:
+       if (process_include (desc, lineno) == FATAL_EXIT_CODE)
+         message_with_line (lineno, "include file at  %s not found\n", filename);
+       break;
+ 
      case DEFINE_INSN_AND_SPLIT:
        {
  	const char *split_cond;
*************** process_define_cond_exec ()
*** 767,781 ****
--- 932,1022 ----
    for (elem = define_cond_exec_queue; elem ; elem = elem->next)
      process_one_cond_exec (elem);
  }
+ 
+ static char *
+ save_string (s, len)
+      const char *s;
+      int len;
+ {
+   register char *result = xmalloc (len + 1);
+ 
+   memcpy (result, s, len);
+   result[len] = 0;
+   return result;
+ }
+ 
  \f
  /* The entry point for initializing the reader.  */
  
  int
+ init_md_reader_args (argc, argv)
+      int argc;
+      char **argv;
+ {
+   int i;
+   const char *in_fname;
+ 
+   max_include_len = 0;
+   in_fname = NULL;
+   for (i = 1; i < argc; i++)
+     {
+       if (argv[i][0] != '-')
+ 	{
+ 	  if (in_fname == NULL)
+ 	    in_fname = argv[i];
+ 	}
+       else
+ 	{
+ 	  int c = argv[i][1];
+ 	  switch (c)
+ 	    {
+ 	    case 'I':		/* Add directory to path for includes.  */
+ 	      {
+ 		struct file_name_list *dirtmp;
+ 
+ 		dirtmp = (struct file_name_list *)
+ 		  xmalloc (sizeof (struct file_name_list));
+ 		dirtmp->next = 0;	/* New one goes on the end */
+ 		if (include == 0)
+ 		  include = dirtmp;
+ 		else
+ 		  last_include->next = dirtmp;
+ 		last_include = dirtmp;	/* Tail follows the last one */
+ 		if (argv[i][1] == 'I' && argv[i][2] != 0)
+ 		  dirtmp->fname = argv[i] + 2;
+ 		else if (i + 1 == argc)
+ 		  fatal ("Directory name missing after -I option");
+ 		else
+ 		  dirtmp->fname = argv[++i];
+ 		if (strlen (dirtmp->fname) > max_include_len)
+ 		  max_include_len = strlen (dirtmp->fname);
+ 	      }
+ 	      break;
+ 	    default:
+ 	      fatal ("Invalid option `%s'", argv[i]);
+ 
+ 	    }
+ 	}
+     }
+     return init_md_reader (in_fname);
+ }
+ \f
+ /* The entry point for initializing the reader.  */
+ 
+ int
  init_md_reader (filename)
       const char *filename;
  {
    FILE *input_file;
    int c;
+   char *lastsl;
+ 
+   if (!IS_ABSOLUTE_PATHNAME (filename))
+     {
+       lastsl = strrchr (filename, '/');
+       if (lastsl != NULL) 
+ 	base_dir = save_string (filename, lastsl - filename + 1 );
+     }
  
    read_rtx_filename = filename;
    input_file = fopen (filename, "r");
*************** init_md_reader (filename)
*** 797,803 ****
  
        c = read_skip_spaces (input_file);
        if (c == EOF)
! 	break;
  
        ungetc (c, input_file);
        lineno = read_rtx_lineno;
--- 1038,1044 ----
  
        c = read_skip_spaces (input_file);
        if (c == EOF)
!         break;
  
        ungetc (c, input_file);
        lineno = read_rtx_lineno;
Index: gensupport.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gensupport.h,v
retrieving revision 1.3
diff -3 -c -p -r1.3 gensupport.h
*** gensupport.h	2001/08/22 14:35:17	1.3
--- gensupport.h	2001/11/06 02:33:20
*************** Software Foundation, 59 Temple Place - S
*** 21,26 ****
--- 21,27 ----
  struct obstack;
  extern struct obstack *rtl_obstack;
  
+ extern int init_md_reader_args	PARAMS ((int, char **));
  extern int init_md_reader	PARAMS ((const char *));
  extern rtx read_md_rtx		PARAMS ((int *, int *));
  
Index: rtl.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.def,v
retrieving revision 1.50
diff -3 -c -p -r1.50 rtl.def
*** rtl.def	2001/11/03 16:28:33	1.50
--- rtl.def	2001/11/06 02:33:22
*************** DEF_RTL_EXPR(UNKNOWN, "UnKnown", "*", 'x
*** 73,78 ****
--- 73,83 ----
  
  DEF_RTL_EXPR(NIL, "nil", "*", 'x')
  
+ 
+ /* include a file */
+ 
+ DEF_RTL_EXPR(INCLUDE, "include", "s", 'x')
+ 
  /* ---------------------------------------------------------------------
     Expressions used in constructing lists.
     --------------------------------------------------------------------- */
Index: gcc/gcc/doc/md.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/md.texi,v
retrieving revision 1.23
diff -c -3 -p -r1.23 md.texi
*** md.texi	2001/08/30 20:44:51	1.23
--- md.texi	2001/09/28 20:02:04
*************** See the next chapter for information on 
*** 38,43 ****
--- 38,44 ----
  * Expander Definitions::Generating a sequence of several RTL insns
                            for a standard operation.
  * Insn Splitting::      Splitting Instructions into Multiple Instructions.
+ * Including Patterns::      Including Patterns in Machine Descriptions.
  * Peephole Definitions::Defining machine-specific peephole optimizations.
  * Insn Attributes::     Specifying the value of attributes for generated insns.
  * Conditional Execution::Generating @code{define_insn} patterns for
*************** The @code{define_insn_and_split} constru
*** 3900,3905 ****
--- 3901,3986 ----
  functionality as two separate @code{define_insn} and @code{define_split}
  patterns.  It exists for compactness, and as a maintenance tool to prevent
  having to ensure the two patterns' templates match.
+ 
+ @node Including Patterns
+ @section Including Patterns in Machine Descriptions.
+ @cindex insn includes
+ 
+ @findex include
+ The @code{include} pattern tells the compiler tools where to
+ look for patterns that are in files other than in the file
+ @file{.md}. This is used only at build time and there is no preprocessing allowed.
+ 
+ It looks like:
+ 
+ @smallexample
+ 
+ (include
+   @var{pathname})
+ @end smallexample
+ 
+ For example:
+ 
+ @smallexample
+ 
+ (include "filestuff") 
+ 
+ @end smallexample
+ 
+ Where @var{pathname} is a string that specifies the the location of the file,
+ specifies the include file to be in gcc/config/{target}/filestuff. The
+ directory @file{ gcc/config/{target}} is regarded as the default directory.
+ 
+ 
+ Machine descriptions may be split up into smaller more manageable subsections 
+ and placed into subdirectories. 
+ 
+ By specifying:
+ 
+ @smallexample
+ 
+ (include "BOGUS/filestuff") 
+ 
+ @end smallexample
+ 
+ the include file is specified to be in @file{gcc/config/{target}/BOGUS/filestuff}.
+ 
+ Specifying an absolute path for the include file such as;
+ @smallexample
+ 
+ (include "/u2/BOGUS/filestuff") 
+ 
+ @end smallexample
+ is permitted but is not encouraged. 
+ 
+ @node .md Directory Options
+ @subsection RTL Generation Tool Options for Directory Search
+ @cindex directory options .md
+ @cindex options, directory search
+ @cindex search path
+ 
+ The -I@var{dir} option specifies directories to search for machine descriptions.
+ For example:
+ 
+ @smallexample
+ 
+ genrecog -I/p1/abc/proc1 -I/p2/abcd/pro2 target.md
+ 
+ @end smallexample
+ 
+ 
+ @table @gcctabopt
+ @item -I@var{dir}
+ @opindex I
+ Add the directory @var{dir} to the head of the list of directories to be
+ searched for header files.  This can be used to override a system machine definition
+ file, substituting your own version, since these directories are
+ searched before the default machine description file directories.  If you use more than
+ one @option{-I} option, the directories are scanned in left-to-right
+ order; the standard default directory come after.
+ 
+ @end table
+ 
  
  @node Peephole Definitions
  @section Machine-Specific Peephole Optimizers

Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-05 18:41         ` Include facility for .md files - " Alan Matsuoka
  2001-11-03 20:37           ` Geoff Keating
@ 2001-11-05 18:49           ` Joseph S. Myers
  2001-11-05 19:03             ` Alan Matsuoka
                               ` (2 more replies)
  2001-11-05 18:58           ` Aldy Hernandez
                             ` (3 subsequent siblings)
  5 siblings, 3 replies; 152+ messages in thread
From: Joseph S. Myers @ 2001-11-05 18:49 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: gcc-patches

On Mon, 5 Nov 2001, Alan Matsuoka wrote:

> + Where @var{pathname} is a string that specifies the the location of the file,
> + specifies the include file to be in gcc/config/{target}/filestuff. The

@file{gcc/config/@var{target}/filestuff}.

> + directory @file{ gcc/config/{target}} is regarded as the default directory.

No space after the open brace.  @var{target}.

> + the include file is specified to be in @file{gcc/config/{target}/BOGUS/filestuff}.

@var{target}.

> + The -I@var{dir} option specifies directories to search for machine descriptions.

@option{-I@var{dir}}.

> + @table @gcctabopt
> + @item -I@var{dir}
> + @opindex I

The option index is an index of GCC options, options for support tools
should not have @opindex index entries.

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-05 18:41         ` Include facility for .md files - " Alan Matsuoka
  2001-11-03 20:37           ` Geoff Keating
  2001-11-05 18:49           ` Joseph S. Myers
@ 2001-11-05 18:58           ` Aldy Hernandez
  2001-11-05 19:01             ` Alan Matsuoka
                               ` (3 more replies)
  2001-11-06  0:23           ` Gerald Pfeifer
                             ` (2 subsequent siblings)
  5 siblings, 4 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-05 18:58 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: Geoff Keating, gcc patches

is it recursive?  i mean, can you include files from within include
files?

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-05 18:58           ` Aldy Hernandez
@ 2001-11-05 19:01             ` Alan Matsuoka
  2001-11-13  4:32               ` Alan Matsuoka
  2001-11-13 15:03               ` Alan Matsuoka
  2001-11-05 21:37             ` Alan Matsuoka
                               ` (2 subsequent siblings)
  3 siblings, 2 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-05 19:01 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Geoff Keating, gcc patches

On Mon, 05 Nov 2001, Aldy Hernandez wrote:

> is it recursive?  i mean, can you include files from within include
> files?

Yes it is. 


Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-05 18:49           ` Joseph S. Myers
@ 2001-11-05 19:03             ` Alan Matsuoka
  2001-11-06  1:03               ` Joseph S. Myers
                                 ` (2 more replies)
  2001-11-13  4:32             ` Joseph S. Myers
  2001-11-13 15:03             ` Joseph S. Myers
  2 siblings, 3 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-05 19:03 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc-patches

On Tue, 06 Nov 2001, Joseph S. Myers wrote:

> On Mon, 5 Nov 2001, Alan Matsuoka wrote:
> 
> > + Where @var{pathname} is a string that specifies the the location of the file,
> > + specifies the include file to be in gcc/config/{target}/filestuff. The
> 
> @file{gcc/config/@var{target}/filestuff}.
> 
> > + directory @file{ gcc/config/{target}} is regarded as the default directory.
> 
> No space after the open brace.  @var{target}.

Fixed.
> 
> > + the include file is specified to be in @file{gcc/config/{target}/BOGUS/filestuff}.
> 
> @var{target}.
> 
> > + The -I@var{dir} option specifies directories to search for machine descriptions.

Fixed.
> 
> @option{-I@var{dir}}.
> 
> > + @table @gcctabopt
> > + @item -I@var{dir}
> > + @opindex I

deleted.
> 
> The option index is an index of GCC options, options for support tools
> should not have @opindex index entries.
> 
> -- 
> 

Thank you.

Index: md.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/md.texi,v
retrieving revision 1.26
diff -3 -c -p -r1.26 md.texi
*** md.texi	2001/10/25 18:25:08	1.26
--- md.texi	2001/11/06 02:58:26
*************** See the next chapter for information on 
*** 38,43 ****
--- 38,44 ----
  * Expander Definitions::Generating a sequence of several RTL insns
                            for a standard operation.
  * Insn Splitting::      Splitting Instructions into Multiple Instructions.
+ * Including Patterns::      Including Patterns in Machine Descriptions.
  * Peephole Definitions::Defining machine-specific peephole optimizations.
  * Insn Attributes::     Specifying the value of attributes for generated insns.
  * Conditional Execution::Generating @code{define_insn} patterns for
*************** The @code{define_insn_and_split} constru
*** 3909,3914 ****
--- 3910,3992 ----
  functionality as two separate @code{define_insn} and @code{define_split}
  patterns.  It exists for compactness, and as a maintenance tool to prevent
  having to ensure the two patterns' templates match.
+ 
+ @node Including Patterns
+ @section Including Patterns in Machine Descriptions.
+ @cindex insn includes
+ 
+ @findex include
+ The @code{include} pattern tells the compiler tools where to
+ look for patterns that are in files other than in the file
+ @file{.md}. This is used only at build time and there is no preprocessing allowed.
+ 
+ It looks like:
+ 
+ @smallexample
+ 
+ (include
+   @var{pathname})
+ @end smallexample
+ 
+ For example:
+ 
+ @smallexample
+ 
+ (include "filestuff") 
+ 
+ @end smallexample
+ 
+ Where @var{pathname} is a string that specifies the the location of the file,
+ specifies the include file to be in gcc/config/{target}/filestuff. The
+ directory @file{gcc/config/{target}} is regarded as the default directory.
+ 
+ 
+ Machine descriptions may be split up into smaller more manageable subsections 
+ and placed into subdirectories. 
+ 
+ By specifying:
+ 
+ @smallexample
+ 
+ (include "BOGUS/filestuff") 
+ 
+ @end smallexample
+ 
+ the include file is specified to be in @file{gcc/config/@var{target}/BOGUS/filestuff}.
+ 
+ Specifying an absolute path for the include file such as;
+ @smallexample
+ 
+ (include "/u2/BOGUS/filestuff") 
+ 
+ @end smallexample
+ is permitted but is not encouraged. 
+ 
+ @node .md Directory Options
+ @subsection RTL Generation Tool Options for Directory Search
+ @cindex directory options .md
+ @cindex options, directory search
+ @cindex search path
+ 
+ The @option{-I@var{dir}} option specifies directories to search for machine descriptions.
+ For example:
+ 
+ @smallexample
+ 
+ genrecog -I/p1/abc/proc1 -I/p2/abcd/pro2 target.md
+ 
+ @end smallexample
+ 
+ 
+ Add the directory @var{dir} to the head of the list of directories to be
+ searched for header files.  This can be used to override a system machine definition
+ file, substituting your own version, since these directories are
+ searched before the default machine description file directories.  If you use more than
+ one @option{-I} option, the directories are scanned in left-to-right
+ order; the standard default directory come after.
+ 
+ @end table
+ 
  
  @node Peephole Definitions
  @section Machine-Specific Peephole Optimizers


Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 13:59 ` Geoff Keating
  2001-11-05 14:05   ` Alan Matsuoka
  2001-11-05 14:31   ` Stan Shebs
@ 2001-11-05 19:27   ` Aldy Hernandez
  2001-11-05 20:10     ` Geoff Keating
                       ` (2 more replies)
  2001-11-06 15:02   ` Aldy Hernandez
                     ` (3 subsequent siblings)
  6 siblings, 3 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-05 19:27 UTC (permalink / raw)
  To: Geoff Keating; +Cc: gcc-patches

>>>>> "Geoff" == Geoff Keating <geoffk@geoffk.org> writes:

 >> ! #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)

 > I think you _don't_ want this to be dependent on the ABI.  Changing
 > this isn't an ABI change (I hope!), which is good because...

Fixed.  Set to 128 unconditionally.

 >> ! 
 >> ! /* A C expression to compute the alignment for a variables in the
 >> !    local store.  TYPE is the data type, and ALIGN is the alignment
 >> !    that the object would ordinarily have.  */
 >> ! #define LOCAL_ALIGNMENT(TYPE, ALIGN)				\
 >> ! 	((TARGET_ALTIVEC_ABI		    			\
 >> ! 	  && TREE_CODE (TYPE)) == VECTOR_TYPE ? 128 : ALIGN)

 > ..as altivec values have to be 128-bit aligned because of the
 > hardware, you don't want this ABI-dependent either.

Fixed.  Set to TARGET_ALTIVEC.  Actually, that's ambiguous because you
shouldn't have vector types unless you are in altivec mode, but it
won't hurt.

 > The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
 > quite right:  it has to happen _only when the ABI is 'altivec'_.

I took it out because it needs rethinking.  DWARF_FRAME_REGISTERS is
used as an array size in a few places, particulary unwind-dw2.c.  So I
need to change all these places to dynamically allocate their space.

 > This will be a bit tricky because DWARF_FRAME_REGISTERS is also used
 > in libgcc, so you have to #define something when the Altivec ABI is
 > chosen, and then key off that if IN_LIBGCC2.

 > I wonder if you could assume that the integrated cpplib will always be
 > used when compiling libgcc?  That would make things easier, because
 > then you wouldn't have muck with specs so much.

Please explain.  I only see DWARF_FRAME_REGISTERS being used in
dwarf2out.c and unwind-dw2.c.  There is nothing in libgcc*.

 >> !    /* AltiVec registers.  */			   \
 >> !    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
 >> !    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  \
 >> ! }

 > This is correct, but doesn't there need to be a change to them in
 > CONDITIONAL_REGISTER_USAGE when the altivec ABI is chosen (in which
 > some altivec registers are call-saved)?

And there already is: :)

  if (TARGET_ALTIVEC_ABI)
    for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
      call_used_regs[i] = 1;

 > These should be based off FIRST_ALTIVEC_REGISTER rather than being
 > magic numbers...

Fixed.

 >> /* Return registers */
 >> #define GP_ARG_RETURN GP_ARG_MIN_REG
 >> #define FP_ARG_RETURN FP_ARG_MIN_REG
 >> + #define ALTIVEC_ARG_RETURN 79

 > .. this too.

Fixed.

 >> #undef	STACK_BOUNDARY
 >> ! #define	STACK_BOUNDARY	64
 >> 
 >> /* Real stack boundary as mandated by the appropriate ABI.  */
 >> ! #define ABI_STACK_BOUNDARY ((TARGET_EABI) ? 64 : 128)
 >> 
 >> /* No data type wants to be aligned rounder than this.  */
 >> #undef	BIGGEST_ALIGNMENT
 >> ! #define BIGGEST_ALIGNMENT ((TARGET_EABI) ? 64 : 128)
 >> 
 >> #undef  BIGGEST_FIELD_ALIGNMENT
 >> #undef  ADJUST_FIELD_ALIGN
 >> - #undef  ROUND_TYPE_ALIGN
 >> 
 >> /* Use ELF style section commands.  */
 >> 
 >> --- 400,430 ----
 >> one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
 >> versions, just use 64 as the stack boundary.  */
 >> #undef	STACK_BOUNDARY
 >> ! #define	STACK_BOUNDARY	(TARGET_ALTIVEC_ABI ? 128 : 64)
 >> 
 >> /* Real stack boundary as mandated by the appropriate ABI.  */
 >> ! #define ABI_STACK_BOUNDARY ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
 >> 
 >> /* No data type wants to be aligned rounder than this.  */
 >> #undef	BIGGEST_ALIGNMENT
 >> ! #define BIGGEST_ALIGNMENT ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
 >> 
 >> + /* An expression for the alignment of a structure field FIELD if the
 >> +    alignment computed in the usual way is COMPUTED.  */
 >> + #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)				      \
 >> + 	((TARGET_ALTIVEC_ABI && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
 >> + 	 ? 128 : COMPUTED)
 >> + 
 >> + /* Define this macro as an expression for the alignment of a type
 >> +    (given by TYPE as a tree node) if the alignment computed in the
 >> +    usual way is COMPUTED and the alignment explicitly specified was
 >> +    SPECIFIED.  */
 >> + #define ROUND_TYPE_ALIGN(TYPE, COMPUTED, SPECIFIED)			\
 >> + 	((TARGET_ALTIVEC_ABI && TREE_CODE (TYPE) == VECTOR_TYPE)	\
 >> + 	 ? 128 : MAX (COMPUTED, SPECIFIED))
 >> + 
 >> #undef  BIGGEST_FIELD_ALIGNMENT
 >> #undef  ADJUST_FIELD_ALIGN
 >> 
 >> /* Use ELF style section commands.  */

 > This has the same comment as the equivalent stuff in rs6000.h.

Huh?  What do you mean?

 >> *************** function_arg_advance (cum, mode, type, n
 >> *** 2159,2165 ****
 >> {
 cum-> nargs_prototype--;
 >> 
 >> !   if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
 >> {
 >> if (TARGET_HARD_FLOAT
 >> && (mode == SFmode || mode == DFmode))
 >> --- 2242,2255 ----
 >> {
 cum-> nargs_prototype--;
 >> 
 >> !   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
 >> !     {
 >> !       if (cum->vregno <= ALTIVEC_ARG_MAX_REG)
 >> ! 	cum->vregno++;
 >> !       else
 >> ! 	cum->words += RS6000_ARG_SIZE (mode, type);
 >> !     }

 > Something you might not have seen in the ABI documentation: unnamed
 > vector arguments (passed to varargs functions after the '...') get
 > passed in memory, not in registers.  (I don't remember if this is just
 > the unnamed arguments or all the arguments to varargs functions, you
 > should check.)

This is just for unnamed arguments in varargs.  So I'll have to add:

        if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
done. (?)

 >> +       /* Print AltiVec memory operand.  */
 >> +     case 'y':
 >> +       {
 >> + 	rtx tmp;
 >> + 
 >> + 	if (GET_CODE (x) != MEM)
 >> + 	  abort ();
 >> + 
 >> + 	tmp = XEXP (x, 0);
 >> + 
 >> + 	if (GET_CODE (tmp) == REG)
 >> + 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
 >> + 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
 >> + 	  {
 >> + 	    if (REGNO (XEXP (tmp, 0)) == 0)
 >> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
 >> + 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
 >> + 	    else
 >> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
 >> + 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
 >> + 	  }
 >> + 	else
 >> + 	  abort ();
 >> + 	break;
 >> +       }

 > Do you really need this?  It looks just like the way a normal memory
 > operand is printed (for the cases that are allowed for altivec).

Yes I do.  I want "[reg+reg]" to be outputed as "reg,reg" and [reg] to
be outputed as "reg,0".

Consider "lvx d,a,b".  I want to match:

        (set (reg) (mem))

and have (mem) be dumped as "a,b" (the two registers in the memory
address: (plus (reg) (reg))).  And I make sure that addresses get
canonicalized into (mem (reg)) and (mem (plus (reg) (reg))) with
LEGITIM* code.

 > Can you put the altivec insns in their own .md file and use the include
 > mechanism?  I believe this is what it was intended for.

As soon as you approve Alan's patch, yes :).

 >> + ;; No code is needed to copy between vector registers.
 >> + (define_insn "*altivec_vec_move"
 >> +   [(set (match_operand 0 "altivec_register" "=v")
 >> + 	(match_operand 1 "altivec_register" "v"))]
 >> +   "TARGET_ALTIVEC"
 >> +   ""
 >> +   [(set_attr "type" "altivec")])

 > Um, that can't possibly be right.  Also, it should be part of
 > movv4si_internal, because reload needs all the move insns to be the
 > same pattern.

What the hell was that all about?  I should get my cvs access revoked
for that one.  I dunno how that make it there.  M-x doctor

 >> + ;; Vector move instructions.
 >> + (define_expand "movv4si"
 >> +   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
 >> + 	(match_operand:V4SI 1 "any_operand" ""))]
 >> +   "TARGET_ALTIVEC"
 >> +   "{ rs6000_emit_move (operands[0], operands[1], V4SImode); DONE; }")
 >> + 
 >> + (define_insn "*movv4si_internal"
 >> +   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v")
 >> + 	(match_operand:V4SI 1 "input_operand" "v,m"))]
 >> +   "TARGET_ALTIVEC"
 >> +   "@
 >> +    stvx\t%1,%y0
 >> +    ldvx\t%0,%y1"
 >> +   [(set_attr "type" "altivec")])

 > Yes---this needs an alternative to copy a 'v' into a 'v'.  All the
 > ones below probably need it too.

Will do.

Aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 14:49     ` Geoff Keating
  2001-11-05 15:29       ` Stan Shebs
@ 2001-11-05 19:30       ` Aldy Hernandez
  2001-11-13  4:32         ` Aldy Hernandez
  2001-11-13 15:03         ` Aldy Hernandez
  2001-11-13  4:32       ` Geoff Keating
  2001-11-13 15:03       ` Geoff Keating
  3 siblings, 2 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-05 19:30 UTC (permalink / raw)
  To: Geoff Keating; +Cc: Stan Shebs, gcc-patches

>>>>> "Geoff" == Geoff Keating <geoffk@geoffk.org> writes:

 > DWARF_FRAME_REGISTERS was invented, so people could add registers
 > without breaking binary compatibility.

But as it stands now it's value can't be dynamic-- say, with an abi
flag-- because it's value is used in places where it is expected to be
a constant (array sizes un unwind-dw2.c).

I will remedy this situation in another patch.

Aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 14:05 ` Dale Johannesen
  2001-11-05 14:38   ` Geoff Keating
  2001-11-05 18:30   ` Aldy Hernandez
@ 2001-11-05 19:47   ` Aldy Hernandez
  2001-11-13  4:32     ` Aldy Hernandez
  2001-11-13 15:03     ` Aldy Hernandez
  2001-11-13  4:32   ` Dale Johannesen
  2001-11-13 15:03   ` Dale Johannesen
  4 siblings, 2 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-05 19:47 UTC (permalink / raw)
  To: Dale Johannesen; +Cc: gcc patches, Geoff Keating

> I'd really like to see vrsave in the enums and register macros
> (not necessarily the code).  I dislike making a major change to
> an area if we know it's going to change again shortly.

done

> > +    : ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_REGNO_P (REGNO)		\
> > +    : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE)		\
> >      : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC		\
> >      : XER_REGNO_P (REGNO) ? (MODE) == PSImode				\
> >      : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT		\
> 
> I don't think you want the first changed line here.

fixed

> >      : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10	\
> >      : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10	\
> > +    : (CLASS1) == ALTIVEC_REGS && (CLASS2) != ALTIVEC_REGS ? 20	\
> >      : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS		\
> >          || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS		\
> >          || (CLASS1) == LINK_OR_CTR_REGS)				\
> 
> And here you need
> 	: (CLASS1) != ALTIVEC_REGS && (CLASS2) == ALTIVEC_REGS ? 20
> analogous to the FLOAT case.

whoops.  done.

> > +   && ! ALTIVEC_VECTOR_MODE (MODE)				\
> >     && (((MODE) != DFmode && (MODE) != DImode)			\
> >         || (TARGET_32BIT						\
> >   	  ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) 	\
> 
> That could be
> 	  && ( ! ALTIVEC_VECTOR_MODE (MODE) || INTVAL (X) == 0)
> for better codegen.  It's not wrong as is, though.

done

thanks for your corrections.  hopefully we'll only need one more
iteration through this.

aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 19:27   ` Aldy Hernandez
@ 2001-11-05 20:10     ` Geoff Keating
  2001-11-13  4:32       ` Geoff Keating
  2001-11-13 15:03       ` Geoff Keating
  2001-11-13  4:32     ` Aldy Hernandez
  2001-11-13 15:03     ` Aldy Hernandez
  2 siblings, 2 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-05 20:10 UTC (permalink / raw)
  To: aldyh; +Cc: gcc-patches

> Cc: gcc-patches@gcc.gnu.org
> From: Aldy Hernandez <aldyh@redhat.com>
> Date: 05 Nov 2001 22:29:51 -0500

>  > The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
>  > quite right:  it has to happen _only when the ABI is 'altivec'_.
> 
> I took it out because it needs rethinking.  DWARF_FRAME_REGISTERS is
> used as an array size in a few places, particulary unwind-dw2.c.  So I
> need to change all these places to dynamically allocate their space.

Before changing anything in the unwinder code, you must first make
sure that you're not changing an ABI.  I don't know what the new rules
are on this, with shared libgcc and all, so I will leave you to figure
them out (and please tell me when you do!).  You'll probably want to
ask on the glibc lists.

>  > This will be a bit tricky because DWARF_FRAME_REGISTERS is also used
>  > in libgcc, so you have to #define something when the Altivec ABI is
>  > chosen, and then key off that if IN_LIBGCC2.
> 
>  > I wonder if you could assume that the integrated cpplib will always be
>  > used when compiling libgcc?  That would make things easier, because
>  > then you wouldn't have muck with specs so much.
> 
> Please explain.  I only see DWARF_FRAME_REGISTERS being used in
> dwarf2out.c and unwind-dw2.c.  There is nothing in libgcc*.

unwind-dw2.c is part of libgcc, see LIB2ADDEH in Makefile.in.  I don't
knew about the new arrangement, but it used to be that 'struct
_Unwind_Context' (or equivalent) was passed between a bit of libgcc
that was compiled into glibc, and another bit of libgcc that was
compiled into applications.  Thus, you couldn't change
DWARF_FRAME_REGISTERS because that would change a glibc ABI.

For EABI (as opposed to SVR4/Linux), you can probably change this even
for non-altivec EABI, since libgcc doesn't get split up like that for
embedded systems and libgcc isn't part of the EABI and there hasn't
been any real C++ binary compatibility anyway.

>  >> /* No data type wants to be aligned rounder than this.  */
>  >> #undef	BIGGEST_ALIGNMENT
>  >> ! #define BIGGEST_ALIGNMENT ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
>  >> 
>  >> + /* An expression for the alignment of a structure field FIELD if the
>  >> +    alignment computed in the usual way is COMPUTED.  */
>  >> + #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)				      \
>  >> + 	((TARGET_ALTIVEC_ABI && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
>  >> + 	 ? 128 : COMPUTED)
>  >> + 
>  >> + /* Define this macro as an expression for the alignment of a type
>  >> +    (given by TYPE as a tree node) if the alignment computed in the
>  >> +    usual way is COMPUTED and the alignment explicitly specified was
>  >> +    SPECIFIED.  */
>  >> + #define ROUND_TYPE_ALIGN(TYPE, COMPUTED, SPECIFIED)			\
>  >> + 	((TARGET_ALTIVEC_ABI && TREE_CODE (TYPE) == VECTOR_TYPE)	\
>  >> + 	 ? 128 : MAX (COMPUTED, SPECIFIED))
>  >> + 
>  >> #undef  BIGGEST_FIELD_ALIGNMENT
>  >> #undef  ADJUST_FIELD_ALIGN
>  >> 
>  >> /* Use ELF style section commands.  */
> 
>  > This has the same comment as the equivalent stuff in rs6000.h.
> 
> Huh?  What do you mean?

I had some comments about the changes in rs6000.h to BIGGEST_ALIGNMENT
etc.; these are the sysv4.h changes to BIGGEST_ALIGNMENT, and the same
comments apply.

> This is just for unnamed arguments in varargs.  So I'll have to add:
> 
>         if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
>                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> done. (?)

OK, whatever works.  I just wanted to be sure you knew about the
weirdness.

>  >> +       /* Print AltiVec memory operand.  */
>  >> +     case 'y':
>  >> +       {
>  >> + 	rtx tmp;
>  >> + 
>  >> + 	if (GET_CODE (x) != MEM)
>  >> + 	  abort ();
>  >> + 
>  >> + 	tmp = XEXP (x, 0);
>  >> + 
>  >> + 	if (GET_CODE (tmp) == REG)
>  >> + 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
>  >> + 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
>  >> + 	  {
>  >> + 	    if (REGNO (XEXP (tmp, 0)) == 0)
>  >> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
>  >> + 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
>  >> + 	    else
>  >> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
>  >> + 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
>  >> + 	  }
>  >> + 	else
>  >> + 	  abort ();
>  >> + 	break;
>  >> +       }
> 
>  > Do you really need this?  It looks just like the way a normal memory
>  > operand is printed (for the cases that are allowed for altivec).
> 
> Yes I do.  I want "[reg+reg]" to be outputed as "reg,reg" and [reg] to
> be outputed as "reg,0".
> 
> Consider "lvx d,a,b".  I want to match:
> 
>         (set (reg) (mem))
> 
> and have (mem) be dumped as "a,b" (the two registers in the memory
> address: (plus (reg) (reg))).  

I guess it's not quite the same as the behaviour for 'lwz', because of
the behaviour on just (reg).  This bit is OK, then.

>  > Can you put the altivec insns in their own .md file and use the include
>  > mechanism?  I believe this is what it was intended for.
> 
> As soon as you approve Alan's patch, yes :).

I'll look at it :-).

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-05 18:58           ` Aldy Hernandez
  2001-11-05 19:01             ` Alan Matsuoka
@ 2001-11-05 21:37             ` Alan Matsuoka
  2001-11-13  4:32               ` Alan Matsuoka
  2001-11-13 15:03               ` Alan Matsuoka
  2001-11-13  4:32             ` Aldy Hernandez
  2001-11-13 15:03             ` Aldy Hernandez
  3 siblings, 2 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-05 21:37 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Geoff Keating, gcc patches

On Mon, 05 Nov 2001, Aldy Hernandez wrote:

> is it recursive?  i mean, can you include files from within include
> files?

If you mean nested includes yes. If you mean mutually recursive or self 
recursive references, no.


Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-05 18:41         ` Include facility for .md files - " Alan Matsuoka
                             ` (2 preceding siblings ...)
  2001-11-05 18:58           ` Aldy Hernandez
@ 2001-11-06  0:23           ` Gerald Pfeifer
  2001-11-13  4:32             ` Gerald Pfeifer
  2001-11-13 15:03             ` Gerald Pfeifer
  2001-11-13  4:32           ` Alan Matsuoka
  2001-11-13 15:03           ` Alan Matsuoka
  5 siblings, 2 replies; 152+ messages in thread
From: Gerald Pfeifer @ 2001-11-06  0:23 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: gcc-patches

On Mon, 5 Nov 2001, Alan Matsuoka wrote:
> 2001-11-05  Alan Matsuoka  <alanm@redhat.com>
>
>         * rtl.def (INCLUDE) : Define.
> 	* gensupport.c (init_include_reader, process_include, save_string) :  New functions to

This...

> 	  implement an include facility in .md files.
> 	* gensupport.h : Add prototype for init_md_reader_args.
> 	* genattr.c genattrtab.c gencodes.c genconfig.c genemit.c
> 	  genextract.c genflags.c genopinit.c genoutput.c genpeep.c
> 	  genrecog.c: Change call to init_md_reader to init_md_reader_args.
> 	* md.texi: Document (include "path") and -I directives for RTL generation tools.

...and this lines are to long.  (Lines in ChangeLogs and code should not
exceed, say, 77 characters, and definitely must not exceed 80 characters.)

There are a couple of similiar issues in the patch itself.

Gerald
-- 
Gerald "Jerry" pfeifer@dbai.tuwien.ac.at http://www.dbai.tuwien.ac.at/~pfeifer/


^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-05 19:03             ` Alan Matsuoka
@ 2001-11-06  1:03               ` Joseph S. Myers
  2001-11-06  4:56                 ` Alan Matsuoka
                                   ` (2 more replies)
  2001-11-13  4:32               ` Alan Matsuoka
  2001-11-13 15:03               ` Alan Matsuoka
  2 siblings, 3 replies; 152+ messages in thread
From: Joseph S. Myers @ 2001-11-06  1:03 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: gcc-patches

On Mon, 5 Nov 2001, Alan Matsuoka wrote:

> + Where @var{pathname} is a string that specifies the the location of the file,
> + specifies the include file to be in gcc/config/{target}/filestuff. The

@file{gcc/config/@var{target}/filestuff}.

> + directory @file{gcc/config/{target}} is regarded as the default directory.

@var{target}.

Has this patch passed "make info" and "make dvi"?

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-06  1:03               ` Joseph S. Myers
@ 2001-11-06  4:56                 ` Alan Matsuoka
  2001-11-06  7:58                   ` Alan Matsuoka
                                     ` (2 more replies)
  2001-11-13  4:32                 ` Joseph S. Myers
  2001-11-13 15:03                 ` Joseph S. Myers
  2 siblings, 3 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-06  4:56 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc-patches

On Tue, 06 Nov 2001, Joseph S. Myers wrote:

> On Mon, 5 Nov 2001, Alan Matsuoka wrote:
> 
> > + Where @var{pathname} is a string that specifies the the location of the file,
> > + specifies the include file to be in gcc/config/{target}/filestuff. The
> 
> @file{gcc/config/@var{target}/filestuff}.
> 
> > + directory @file{gcc/config/{target}} is regarded as the default directory.
> 
> @var{target}.
> 
> Has this patch passed "make info" and "make dvi"?


I'll sumbit a revised patch as soon as the cvs server lets me
generate a patch.


Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-06  4:56                 ` Alan Matsuoka
@ 2001-11-06  7:58                   ` Alan Matsuoka
  2001-11-13  4:32                     ` Alan Matsuoka
                                       ` (2 more replies)
  2001-11-13  4:32                   ` Alan Matsuoka
  2001-11-13 15:03                   ` Alan Matsuoka
  2 siblings, 3 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-06  7:58 UTC (permalink / raw)
  To: gcc-patches

Alan Matsuoka wrote:
> 
> On Tue, 06 Nov 2001, Joseph S. Myers wrote:
> 
> > On Mon, 5 Nov 2001, Alan Matsuoka wrote:
> >
> > > + Where @var{pathname} is a string that specifies the the location of the file,
> > > + specifies the include file to be in gcc/config/{target}/filestuff. The
> >
> > @file{gcc/config/@var{target}/filestuff}.
> >
> > > + directory @file{gcc/config/{target}} is regarded as the default directory.
> >
> > @var{target}.
> >
> > Has this patch passed "make info" and "make dvi"?
> 
> I'll sumbit a revised patch as soon as the cvs server lets me
> generate a patch.
This is a revised patch. It now works with "make info" and "make dvi"
-- 
Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299
The following patch is for the an internal project. This is 
implements a (include "filestuff") mechanism for splitting up 
.md files.

(include "filestuff") expects the include file to be in gcc/config/{target}/filestuff
(include "BOGUS/filestuff") expects the include file to be in gcc/config/{target}/BOGUS/filestuff
(include "/u2/BOGUS/filestuff") expects the include file to be in /u2/BOGUS/filestuff

You can also run things like genrecog -I/p1/abc/proc1 -I/p2/abcd/pro2 target.md

This is used only at build time.

This has been tested for i686-pc-linux-gnu by bootstrapping and testing without 
any regressions.

The DOS pathname style stuff may still be required.


2001-11-05  Alan Matsuoka  <alanm@redhat.com>

        * rtl.def (INCLUDE) : Define.
	* gensupport.c (init_include_reader, process_include, 
	  save_string) :  New functions to
	  implement an include facility in .md files.
	* gensupport.h : Add prototype for init_md_reader_args.
	* genattr.c genattrtab.c gencodes.c genconfig.c genemit.c
	  genextract.c genflags.c genopinit.c genoutput.c genpeep.c
	  genrecog.c: Change call to init_md_reader to init_md_reader_args.
	* md.texi: Document (include "path") and -I directives for RTL 
	  generation tools.

Index: genattr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genattr.c,v
retrieving revision 1.45
diff -c -3 -p -r1.45 genattr.c
*** genattr.c	2001/10/07 16:50:51	1.45
--- genattr.c	2001/11/06 15:51:39
*************** main (argc, argv)
*** 210,216 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genattr'");
--- 210,216 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genattr'");
Index: genattrtab.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genattrtab.c,v
retrieving revision 1.103
diff -c -3 -p -r1.103 genattrtab.c
*** genattrtab.c	2001/10/21 21:32:00	1.103
--- genattrtab.c	2001/11/06 15:51:41
*************** main (argc, argv)
*** 6075,6081 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    obstack_init (hash_obstack);
--- 6075,6081 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    obstack_init (hash_obstack);
Index: gencodes.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gencodes.c,v
retrieving revision 1.42
diff -c -3 -p -r1.42 gencodes.c
*** gencodes.c	2001/08/22 14:35:16	1.42
--- gencodes.c	2001/11/06 15:51:41
*************** main (argc, argv)
*** 56,62 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("\
--- 56,62 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("\
Index: genconfig.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genconfig.c,v
retrieving revision 1.43
diff -c -3 -p -r1.43 genconfig.c
*** genconfig.c	2001/10/11 07:07:26	1.43
--- genconfig.c	2001/11/06 15:51:41
*************** main (argc, argv)
*** 277,283 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genconfig'");
--- 277,283 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genconfig'");
Index: genemit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genemit.c,v
retrieving revision 1.67
diff -c -3 -p -r1.67 genemit.c
*** genemit.c	2001/10/19 19:37:08	1.67
--- genemit.c	2001/11/06 15:51:41
*************** main (argc, argv)
*** 789,795 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
--- 789,795 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
Index: genextract.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genextract.c,v
retrieving revision 1.46
diff -c -3 -p -r1.46 genextract.c
*** genextract.c	2001/10/11 03:15:42	1.46
--- genextract.c	2001/11/06 15:51:41
*************** main (argc, argv)
*** 362,368 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
--- 362,368 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
Index: genflags.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genflags.c,v
retrieving revision 1.39
diff -c -3 -p -r1.39 genflags.c
*** genflags.c	2001/10/11 03:15:42	1.39
--- genflags.c	2001/11/06 15:51:42
*************** main (argc, argv)
*** 230,236 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
    
    puts ("/* Generated automatically by the program `genflags'");
--- 230,236 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
    
    puts ("/* Generated automatically by the program `genflags'");
Index: genopinit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genopinit.c,v
retrieving revision 1.48
diff -c -3 -p -r1.48 genopinit.c
*** genopinit.c	2001/09/13 14:37:11	1.48
--- genopinit.c	2001/11/06 15:51:42
*************** main (argc, argv)
*** 316,322 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genopinit'\n\
--- 316,322 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genopinit'\n\
Index: genoutput.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genoutput.c,v
retrieving revision 1.65
diff -c -3 -p -r1.65 genoutput.c
*** genoutput.c	2001/10/11 03:15:42	1.65
--- genoutput.c	2001/11/06 15:51:42
*************** main (argc, argv)
*** 953,959 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    output_prologue ();
--- 953,959 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    output_prologue ();
Index: genpeep.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genpeep.c,v
retrieving revision 1.49
diff -c -3 -p -r1.49 genpeep.c
*** genpeep.c	2001/10/11 03:15:43	1.49
--- genpeep.c	2001/11/06 15:51:42
*************** main (argc, argv)
*** 385,391 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genpeep'\n\
--- 385,391 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genpeep'\n\
Index: genrecog.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genrecog.c,v
retrieving revision 1.111
diff -c -3 -p -r1.111 genrecog.c
*** genrecog.c	2001/10/28 20:09:14	1.111
--- genrecog.c	2001/11/06 15:51:44
*************** main (argc, argv)
*** 2689,2695 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    next_insn_code = 0;
--- 2689,2695 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    next_insn_code = 0;
Index: gensupport.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gensupport.c,v
retrieving revision 1.23
diff -c -3 -p -r1.23 gensupport.c
*** gensupport.c	2001/10/25 12:55:16	1.23
--- gensupport.c	2001/11/06 15:51:44
*************** static int predicable_default;
*** 42,47 ****
--- 42,49 ----
  static const char *predicable_true;
  static const char *predicable_false;
  
+ static char *base_dir = NULL;
+ 
  /* We initially queue all patterns, process the define_insn and
     define_cond_exec patterns, then return them one at a time.  */
  
*************** static struct queue_elem *other_queue;
*** 62,67 ****
--- 64,86 ----
  static struct queue_elem **other_tail = &other_queue;
  
  static void queue_pattern PARAMS ((rtx, struct queue_elem ***, int));
+ 
+ /* Current maximum length of directory names in the search path
+    for include files.  (Altered as we get more of them.)  */
+ 
+ size_t max_include_len;
+ 
+ struct file_name_list
+   {
+     struct file_name_list *next;
+     const char *fname;
+   };
+ 
+ struct file_name_list *include = 0;     /* First dir to search */
+         /* First dir to search for <file> */
+ struct file_name_list *first_bracket_include = 0;
+ struct file_name_list *last_include = 0;        /* Last in chain */
+ 
  static void remove_constraints PARAMS ((rtx));
  static void process_rtx PARAMS ((rtx, int));
  
*************** static const char *alter_output_for_insn
*** 78,83 ****
--- 97,105 ----
  						  int, int));
  static void process_one_cond_exec PARAMS ((struct queue_elem *));
  static void process_define_cond_exec PARAMS ((void));
+ static int process_include PARAMS ((rtx, int));
+ static char *save_string PARAMS ((const char *, int));
+ static int init_include_reader PARAMS ((FILE  *));
  \f
  void
  message_with_line VPARAMS ((int lineno, const char *msg, ...))
*************** remove_constraints (part)
*** 157,162 ****
--- 179,320 ----
        }
  }
  
+ /* The entry point for initializing the reader.  */
+ 
+ static int
+ init_include_reader (inf)
+      FILE *inf;
+ {
+   int c;
+ 
+   errors = 0;
+ 
+   /* Read the entire file.  */
+   while (1)
+     {
+       rtx desc;
+       int lineno;
+ 
+       c = read_skip_spaces (inf);
+       if (c == EOF)
+ 	break;
+ 
+       ungetc (c, inf);
+       lineno = read_rtx_lineno;
+       desc = read_rtx (inf);
+       process_rtx (desc, lineno);
+     }
+   fclose (inf);
+ 
+   /* Process define_cond_exec patterns.  */
+   if (define_cond_exec_queue != NULL)
+     process_define_cond_exec ();
+ 
+   return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
+ }
+ 
+ /* Process an include file assuming that it lives in gcc/config/{target}/ 
+    if the include looks line (include "file" )  */
+ static int
+ process_include (desc, lineno)
+      rtx desc;
+      int lineno;
+ {
+   const char *filename = XSTR (desc, 0);
+   char *pathname = NULL;
+   FILE *input_file;
+   char *fname;
+   struct file_name_list *stackp;
+   int flen;
+ 
+   stackp = include;
+ 
+   /* If specified file name is absolute, just open it.  */
+   if (IS_ABSOLUTE_PATHNAME (filename) || !stackp)
+     {
+       if (base_dir)
+         {
+           pathname = xmalloc (strlen (base_dir) + strlen (filename) + 1);
+           pathname = strcpy (pathname, base_dir);
+           strcat (pathname, filename);
+           strcat (pathname, "\0");
+ 	}
+       else
+         {
+ 	  pathname = xstrdup (filename);
+         }
+       read_rtx_filename = pathname;
+       input_file = fopen (pathname, "r");
+ 
+       if (input_file == 0)
+ 	{
+ 	  perror (pathname);
+ 	  return FATAL_EXIT_CODE;
+ 	}
+     }
+   else if (stackp)
+     {
+ 
+       flen = strlen (filename);
+ 
+       fname = (char *) alloca (max_include_len + flen + 2);
+ 
+       /* + 2 above for slash and terminating null.  */
+ 
+       /* Search directory path, trying to open the file.
+          Copy each filename tried into FNAME.  */
+ 
+       for (; stackp; stackp = stackp->next)
+ 	{
+ 	  if (stackp->fname)
+ 	    {
+ 	      strcpy (fname, stackp->fname);
+ 	      strcat (fname, "/");
+ 	      fname[strlen (fname) + flen] = 0;
+ 	    }
+ 	  else
+ 	    {
+ 	      fname[0] = 0;
+ 	    }
+ 	  strncat (fname, (const char *) filename, flen);
+ 	  read_rtx_filename = fname;
+ 	  input_file = fopen (fname, "r");
+ 	  if (input_file != NULL) 
+ 	    break;
+ 	}
+       if (stackp == NULL)
+ 	{
+ 	  if (strchr (fname, '/') == NULL || strchr (fname, '\\' ) || base_dir)
+ 	    {
+ 	      if (base_dir)
+ 		{
+ 		  pathname =
+ 		    xmalloc (strlen (base_dir) + strlen (filename) + 1);
+ 		  pathname = strcpy (pathname, base_dir);
+ 		  strcat (pathname, filename);
+ 		  strcat (pathname, "\0");
+ 		}
+ 	      else
+ 		pathname = xstrdup (filename);
+ 	    }
+ 	  read_rtx_filename = pathname;
+ 	  input_file = fopen (pathname, "r");
+ 
+ 	  if (input_file == 0)
+ 	    {
+ 	      perror (filename);
+ 	      return FATAL_EXIT_CODE;
+ 	    }
+ 	}
+ 
+     }
+ 
+   if (init_include_reader (input_file) == FATAL_EXIT_CODE)
+     message_with_line (lineno, "read errors found in include file  %s\n", pathname);
+ 
+   return SUCCESS_EXIT_CODE;
+ }
+ 
  /* Process a top level rtx in some way, queueing as appropriate.  */
  
  static void
*************** process_rtx (desc, lineno)
*** 164,169 ****
--- 322,329 ----
       rtx desc;
       int lineno;
  {
+   const char *filename = XSTR (desc, 0);
+ 
    switch (GET_CODE (desc))
      {
      case DEFINE_INSN:
*************** process_rtx (desc, lineno)
*** 178,183 ****
--- 338,348 ----
        queue_pattern (desc, &define_attr_tail, lineno);
        break;
  
+     case INCLUDE:
+       if (process_include (desc, lineno) == FATAL_EXIT_CODE)
+         message_with_line (lineno, "include file at  %s not found\n", filename);
+       break;
+ 
      case DEFINE_INSN_AND_SPLIT:
        {
  	const char *split_cond;
*************** process_define_cond_exec ()
*** 767,781 ****
--- 932,1022 ----
    for (elem = define_cond_exec_queue; elem ; elem = elem->next)
      process_one_cond_exec (elem);
  }
+ 
+ static char *
+ save_string (s, len)
+      const char *s;
+      int len;
+ {
+   register char *result = xmalloc (len + 1);
+ 
+   memcpy (result, s, len);
+   result[len] = 0;
+   return result;
+ }
+ 
  \f
  /* The entry point for initializing the reader.  */
  
  int
+ init_md_reader_args (argc, argv)
+      int argc;
+      char **argv;
+ {
+   int i;
+   const char *in_fname;
+ 
+   max_include_len = 0;
+   in_fname = NULL;
+   for (i = 1; i < argc; i++)
+     {
+       if (argv[i][0] != '-')
+ 	{
+ 	  if (in_fname == NULL)
+ 	    in_fname = argv[i];
+ 	}
+       else
+ 	{
+ 	  int c = argv[i][1];
+ 	  switch (c)
+ 	    {
+ 	    case 'I':		/* Add directory to path for includes.  */
+ 	      {
+ 		struct file_name_list *dirtmp;
+ 
+ 		dirtmp = (struct file_name_list *)
+ 		  xmalloc (sizeof (struct file_name_list));
+ 		dirtmp->next = 0;	/* New one goes on the end */
+ 		if (include == 0)
+ 		  include = dirtmp;
+ 		else
+ 		  last_include->next = dirtmp;
+ 		last_include = dirtmp;	/* Tail follows the last one */
+ 		if (argv[i][1] == 'I' && argv[i][2] != 0)
+ 		  dirtmp->fname = argv[i] + 2;
+ 		else if (i + 1 == argc)
+ 		  fatal ("Directory name missing after -I option");
+ 		else
+ 		  dirtmp->fname = argv[++i];
+ 		if (strlen (dirtmp->fname) > max_include_len)
+ 		  max_include_len = strlen (dirtmp->fname);
+ 	      }
+ 	      break;
+ 	    default:
+ 	      fatal ("Invalid option `%s'", argv[i]);
+ 
+ 	    }
+ 	}
+     }
+     return init_md_reader (in_fname);
+ }
+ \f
+ /* The entry point for initializing the reader.  */
+ 
+ int
  init_md_reader (filename)
       const char *filename;
  {
    FILE *input_file;
    int c;
+   char *lastsl;
+ 
+   if (!IS_ABSOLUTE_PATHNAME (filename))
+     {
+       lastsl = strrchr (filename, '/');
+       if (lastsl != NULL) 
+ 	base_dir = save_string (filename, lastsl - filename + 1 );
+     }
  
    read_rtx_filename = filename;
    input_file = fopen (filename, "r");
*************** init_md_reader (filename)
*** 797,803 ****
  
        c = read_skip_spaces (input_file);
        if (c == EOF)
! 	break;
  
        ungetc (c, input_file);
        lineno = read_rtx_lineno;
--- 1038,1044 ----
  
        c = read_skip_spaces (input_file);
        if (c == EOF)
!         break;
  
        ungetc (c, input_file);
        lineno = read_rtx_lineno;
Index: gensupport.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gensupport.h,v
retrieving revision 1.3
diff -c -3 -p -r1.3 gensupport.h
*** gensupport.h	2001/08/22 14:35:17	1.3
--- gensupport.h	2001/11/06 15:51:44
*************** Software Foundation, 59 Temple Place - S
*** 21,26 ****
--- 21,27 ----
  struct obstack;
  extern struct obstack *rtl_obstack;
  
+ extern int init_md_reader_args	PARAMS ((int, char **));
  extern int init_md_reader	PARAMS ((const char *));
  extern rtx read_md_rtx		PARAMS ((int *, int *));
  
Index: rtl.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.def,v
retrieving revision 1.50
diff -c -3 -p -r1.50 rtl.def
*** rtl.def	2001/11/03 16:28:33	1.50
--- rtl.def	2001/11/06 15:51:46
*************** DEF_RTL_EXPR(UNKNOWN, "UnKnown", "*", 'x
*** 73,78 ****
--- 73,83 ----
  
  DEF_RTL_EXPR(NIL, "nil", "*", 'x')
  
+ 
+ /* include a file */
+ 
+ DEF_RTL_EXPR(INCLUDE, "include", "s", 'x')
+ 
  /* ---------------------------------------------------------------------
     Expressions used in constructing lists.
     --------------------------------------------------------------------- */
Index: doc/md.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/md.texi,v
retrieving revision 1.26
diff -c -3 -p -r1.26 md.texi
*** md.texi	2001/10/25 18:25:08	1.26
--- md.texi	2001/11/06 15:52:02
*************** See the next chapter for information on 
*** 38,43 ****
--- 38,44 ----
  * Expander Definitions::Generating a sequence of several RTL insns
                            for a standard operation.
  * Insn Splitting::      Splitting Instructions into Multiple Instructions.
+ * Including Patterns::      Including Patterns in Machine Descriptions.
  * Peephole Definitions::Defining machine-specific peephole optimizations.
  * Insn Attributes::     Specifying the value of attributes for generated insns.
  * Conditional Execution::Generating @code{define_insn} patterns for
*************** The @code{define_insn_and_split} constru
*** 3909,3914 ****
--- 3910,3989 ----
  functionality as two separate @code{define_insn} and @code{define_split}
  patterns.  It exists for compactness, and as a maintenance tool to prevent
  having to ensure the two patterns' templates match.
+ 
+ @node Including Patterns
+ @section Including Patterns in Machine Descriptions.
+ @cindex insn includes
+ 
+ @findex include
+ The @code{include} pattern tells the compiler tools where to
+ look for patterns that are in files other than in the file
+ @file{.md}. This is used only at build time and there is no preprocessing allowed.
+ 
+ It looks like:
+ 
+ @smallexample
+ 
+ (include
+   @var{pathname})
+ @end smallexample
+ 
+ For example:
+ 
+ @smallexample
+ 
+ (include "filestuff") 
+ 
+ @end smallexample
+ 
+ Where @var{pathname} is a string that specifies the the location of the file,
+ specifies the include file to be in @file{gcc/config/target/filestuff}. The
+ directory @file{gcc/config/target} is regarded as the default directory.
+ 
+ 
+ Machine descriptions may be split up into smaller more manageable subsections 
+ and placed into subdirectories. 
+ 
+ By specifying:
+ 
+ @smallexample
+ 
+ (include "BOGUS/filestuff") 
+ 
+ @end smallexample
+ 
+ the include file is specified to be in @file{gcc/config/@var{target}/BOGUS/filestuff}.
+ 
+ Specifying an absolute path for the include file such as;
+ @smallexample
+ 
+ (include "/u2/BOGUS/filestuff") 
+ 
+ @end smallexample
+ is permitted but is not encouraged. 
+ 
+ @subsection RTL Generation Tool Options for Directory Search
+ @cindex directory options .md
+ @cindex options, directory search
+ @cindex search options
+ 
+ The @option{-I@var{dir}} option specifies directories to search for machine descriptions.
+ For example:
+ 
+ @smallexample
+ 
+ genrecog -I/p1/abc/proc1 -I/p2/abcd/pro2 target.md
+ 
+ @end smallexample
+ 
+ 
+ Add the directory @var{dir} to the head of the list of directories to be
+ searched for header files.  This can be used to override a system machine definition
+ file, substituting your own version, since these directories are
+ searched before the default machine description file directories.  If you use more than
+ one @option{-I} option, the directories are scanned in left-to-right
+ order; the standard default directory come after.
+ 
  
  @node Peephole Definitions
  @section Machine-Specific Peephole Optimizers

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 13:59 ` Geoff Keating
                     ` (2 preceding siblings ...)
  2001-11-05 19:27   ` Aldy Hernandez
@ 2001-11-06 15:02   ` Aldy Hernandez
  2001-11-06 15:14     ` Joseph S. Myers
                       ` (4 more replies)
  2001-11-06 23:17   ` Richard Henderson
                     ` (2 subsequent siblings)
  6 siblings, 5 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-06 15:02 UTC (permalink / raw)
  To: Geoff Keating; +Cc: gcc-patches

hi guys.

After a few iterations I think this is finally it-- for the first
batch of patches anyhow.

Geoff and I had a couple iterations in private to get the alignment
things sorted out, but everything that was suggested has been
implemented: vrsave in bit patterns, alignment, v=v move, etc etc.

I will be working on stack stuff (epilogue, prologue, stack frame,
vrsave) in the next couple days and I wanted to get these standalone
patches in first.

What is left?

        - stack stuff
        - DWARF_FRAME_REGISTERS (unwind-dw2.c work)
        - varargs
        - rest of builtins
        - function units
        - testcases

ok to install now?  I am bootstraping and checking for regressions
again-- assuming these are ok.

Aldy

2001-11-05  Aldy Hernandez  <aldyh@redhat.com>

	* doc/invoke.texi: Add -maltivec, -mno-altivec, and -mabi=altivec
	for rs6000.

	* config/rs6000/rs6000.h (MASK_ALTIVEC): New.
	(TARGET_ALTIVEC): New.
	(TARGET_SWITCHES): Add altivec.
	(FIRST_PSEUDO_REGISTER): Change to 109.
	(CALL_USED_REGISTERS): Same.
	(FIRST_ALTIVEC_REGNO): New.
	(LAST_ALTIVEC_REGNO): New.
	(ALTIVEC_REGNO_P): New.
	(UNITS_PER_ALTIVEC_WORD): New.
	(ALTIVEC_VECTOR_MODE): New.
	(FIXED_REGISTERS): Add altivec registers.
	(REG_ALLOC_ORDER): Same.
	(HARD_REGNO_NREGS): Adjust for altivec registers.
	(HARD_REGNO_MODE_OK): Same.
	(MODES_TIEABLE_P): Same.
	(REGISTER_MOVE_COST): Same.
	(REGNO_REG_CLASS): Same.
	(reg_class): Add ALTIVEC_REGS.
	(REG_CLASS_NAMES): Same.
	(REG_CLASS_CONTENTS): Same.
	(REG_CLASS_FROM_LETTER): Add 'v' constraint for ALTIVEC_REGS.
	(ALTIVEC_ARG_RETURN): New.
	(FUNCTION_VALUE): Handle VECTOR_TYPE.
	(LIBCALL_VALUE): Handle altivec vector modes.
	(VECTOR_MODE_SUPPORTED_P): New.
	(ALTIVEC_ARG_MIN_REG): New.
	(ALTIVEC_ARG_MAX_REG): New.
	(ALTIVEC_ARG_NUM_REG): New.
	(FUNCTION_VALUE_REGNO_P): Return true for altivec return register.
	(FUNCTION_ARG_REGNO_P): Support passing args in altivec registers.
	(REGISTER_NAMES): Add altivec regs.
	(DEBUG_REGISTER_NAMES): Same.
	(ADDITIONAL_REGISTER_NAMES): Same.
	(rs6000_builtins): New.
	(MD_EXPAND_BUILTIN): New.
	(MD_INIT_BUILTINS): New.
	(LEGITIMATE_OFFSET_ADDRESS_P): This addressing mode is not valid
	for AltiVec instructions.
	(LEGITIMATE_LO_SUM_ADDRESS_P): Same.
	(HARD_REGNO_MODE_OK): Altivec modes can only go in altivec
	registers.
	(SECONDARY_MEMORY_NEEDED): We need memory to copy vector modes.
	(TARGET_SWITCHES): Add no-altivec.
	(DATA_ALIGNMENT): Align vectors to 128 bits.
	(TARGET_OPTIONS): Add abi= option.
	Add rs6000_abi_string extern.
	(LOCAL_ALIGNMENT): New.
	(CPP_CPU_SPEC): Define __ALTIVEC__ when -maltivec.
	(MASK_ALTIVEC_ABI): New.
	(TARGET_ALTIVEC_ABI): New.
	(CONDITIONAL_REGISTER_USAGE): Set first 20 AltiVec registers to
	call-saved.
	(STACK_BOUNDARY): Adjust for altivec.
	(BIGGEST_ALIGNMENT): Same.
	(rs6000_args): Add vregno.
	(USE_ALTIVEC_FOR_ARG_P): New.
	(FIXED_REGISTERS): Add vrsave register.
	(CALL_USED_REGISTERS): Same.
	(CONDITIONAL_REGISTER_USAGE): Set VRSAVE info.
	(VRSAVE_REGNO): New.
	(reg_class): Add VRSAVE_REGS.
	(REG_CLASS_NAMES): Same.
	(REG_CLASS_CONTENTS): Same.
	(REGNO_REG_CLASS): Same.
	
	* config/rs6000/sysv4.h (STACK_BOUNDARY): Adjust for altivec.
	(ABI_STACK_BOUNDARY): Same.
	(BIGGEST_ALIGNMENT): Same.
	(ADJUST_FIELD_ALIGN): Remove undef.  Define anew.
	(ROUND_TYPE_ALIGN): Same.
	
	* config/rs6000/rs6000.c (rs6000_expand_builtin): New.
	(altivec_expand_builtin): New.
	(altivec_init_builtins): New.
	(TARGET_EXPAND_BUILTIN): New.
	(TARGET_INIT_BUILTINS): New.
	(rs6000_init_builtins): New.
	(struct builtin_description): New.
	(bdesc_2arg): New.
	(rs6000_reg_names): Add altivec registers.
	(alt_reg_names): Same.
	(secondary_reload_class): Altivec regs can hold altivec regs and
	memory.
	(rs6000_emit_move): Force constants into memory for AltiVec moves.
	(print_operand): Add 'y' case for printing altivec memory
	operands.
	(rs6000_legitimize_address): Legitimize vector addresses into
	[REG+REG] or [REG].
	(altivec_expand_binop_builtin): New.
	New string rs6000_current_abi.
	(rs6000_override_options): Call rs6000_parse_abi_options.
	(rs6000_parse_abi_options): New.
	(function_arg_boundary): Vector arguments must be 16
	byte aligned.
	(function_arg_advance): Handle vector arguments.
	(function_arg_partial_nregs): Same.
	(init_cumulative_args): Same.
	(function_arg): Same.

	* config/rs6000/rs6000.md (altivec_lvx): New.
	(type): Add altivec attribute.
	(movv4si): New.
	(*movv4si_internal): New.
	(movv16qi): New.
	(*movv16qi_internal): New.
	(movv8hi): New.
	(*movv8hi_internal1): New.
	(movv4sf): New.
	(*movv4sf_internal1): New.
	(altivec_stvx): New.
*builtins deleted*

	Index: doc/invoke.texi
===================================================================
RCS file: /cvs/uberbaum/gcc/doc/invoke.texi,v
retrieving revision 1.69
diff -c -p -r1.69 invoke.texi
*** invoke.texi	2001/10/28 19:12:12	1.69
--- invoke.texi	2001/11/06 22:24:35
*************** in the following sections.
*** 424,429 ****
--- 424,430 ----
  -mtune=@var{cpu-type} @gol
  -mpower  -mno-power  -mpower2  -mno-power2 @gol
  -mpowerpc  -mpowerpc64  -mno-powerpc @gol
+ -maltivec -mno-altivec @gol
  -mpowerpc-gpopt  -mno-powerpc-gpopt @gol
  -mpowerpc-gfxopt  -mno-powerpc-gfxopt @gol
  -mnew-mnemonics  -mold-mnemonics @gol
*************** in the following sections.
*** 436,441 ****
--- 437,443 ----
  -mno-relocatable  -mrelocatable-lib  -mno-relocatable-lib @gol
  -mtoc  -mno-toc -mlittle  -mlittle-endian  -mbig  -mbig-endian @gol
  -mcall-aix -mcall-sysv -mcall-netbsd @gol
+ -mabi=altivec @gol
  -mprototype  -mno-prototype @gol
  -msim  -mmvme  -mads  -myellowknife  -memb -msdata @gol
  -msdata=@var{opt}  -mvxworks -G @var{num}}
*************** values for @var{cpu_type} are used for @
*** 6677,6682 ****
--- 6679,6693 ----
  architecture, registers, and mnemonics set by @option{-mcpu}, but the
  scheduling parameters set by @option{-mtune}.
  
+ @item -maltivec
+ @itemx -mno-altivec
+ @opindex maltivec
+ @opindex mno-altivec
+ These switches enable or disable the use of built-in functions that
+ allow access to the AltiVec instruction set.  You may also need to set
+ @option{-mabi=altivec} to adjust the current ABI with AltiVec ABI
+ enhancements.
+ 
  @item -mfull-toc
  @itemx -mno-fp-in-toc
  @itemx -mno-sum-in-toc
*************** Linux-based GNU system.
*** 6904,6909 ****
--- 6915,6926 ----
  @opindex mcall-netbsd
  On System V.4 and embedded PowerPC systems compile code for the
  NetBSD operating system.
+ 
+ @item -mabi=altivec
+ @opindex mabi=altivec
+ Extend the current ABI with AltiVec ABI extensions.  This does not
+ change the default ABI, instead it adds the AltiVec ABI extensions to
+ the current ABI@
  
  @item -mprototype
  @itemx -mno-prototype
Index: rs6000.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.130
diff -c -p -r1.130 rs6000.h
*** rs6000.h	2001/10/02 03:36:44	1.130
--- rs6000.h	2001/11/06 22:24:41
*************** Boston, MA 02111-1307, USA.  */
*** 83,89 ****
  %{mcpu=801: -D_ARCH_PPC} \
  %{mcpu=821: -D_ARCH_PPC} \
  %{mcpu=823: -D_ARCH_PPC} \
! %{mcpu=860: -D_ARCH_PPC}"
  
  /* Common ASM definitions used by ASM_SPEC among the various targets
     for handling -mcpu=xxx switches.  */
--- 83,90 ----
  %{mcpu=801: -D_ARCH_PPC} \
  %{mcpu=821: -D_ARCH_PPC} \
  %{mcpu=823: -D_ARCH_PPC} \
! %{mcpu=860: -D_ARCH_PPC} \
! %{maltivec: -D__ALTIVEC__}"
  
  /* Common ASM definitions used by ASM_SPEC among the various targets
     for handling -mcpu=xxx switches.  */
*************** extern int target_flags;
*** 209,214 ****
--- 210,221 ----
  /* Nonzero if we need to schedule the prolog and epilog.  */
  #define MASK_SCHED_PROLOG	0x00040000
  
+ /* Use AltiVec instructions.  */
+ #define MASK_ALTIVEC		0x00080000
+ 
+ /* Enhance the current ABI with AltiVec extensions.  */
+ #define MASK_ALTIVEC_ABI	0x00100000
+ 
  #define TARGET_POWER		(target_flags & MASK_POWER)
  #define TARGET_POWER2		(target_flags & MASK_POWER2)
  #define TARGET_POWERPC		(target_flags & MASK_POWERPC)
*************** extern int target_flags;
*** 227,232 ****
--- 234,241 ----
  #define TARGET_NO_UPDATE	(target_flags & MASK_NO_UPDATE)
  #define TARGET_NO_FUSED_MADD	(target_flags & MASK_NO_FUSED_MADD)
  #define TARGET_SCHED_PROLOG	(target_flags & MASK_SCHED_PROLOG)
+ #define TARGET_ALTIVEC		(target_flags & MASK_ALTIVEC)
+ #define TARGET_ALTIVEC_ABI	(target_flags & MASK_ALTIVEC_ABI)
  
  #define TARGET_32BIT		(! TARGET_64BIT)
  #define TARGET_HARD_FLOAT	(! TARGET_SOFT_FLOAT)
*************** extern int target_flags;
*** 282,287 ****
--- 291,300 ----
  			N_("Use PowerPC-64 instruction set")},		\
    {"no-powerpc64",	- MASK_POWERPC64,				\
  			N_("Don't use PowerPC-64 instruction set")},	\
+   {"altivec",		MASK_ALTIVEC,					\
+ 			N_("Use AltiVec instructions.")},		\
+   {"no-altivec",	- MASK_ALTIVEC,					\
+ 			N_("Don't use AltiVec instructions.")},	\
    {"new-mnemonics",	MASK_NEW_MNEMONICS,				\
  			N_("Use new mnemonics for PowerPC architecture")},\
    {"old-mnemonics",	-MASK_NEW_MNEMONICS,				\
*************** extern enum processor_type rs6000_cpu;
*** 409,414 ****
--- 422,428 ----
     {"tune=", &rs6000_select[2].string,					\
      N_("Schedule code for given CPU") },				\
     {"debug=", &rs6000_debug_name, N_("Enable debug output") },		\
+    {"abi=", &rs6000_abi_string, N_("Specify ABI to use") },		\
     SUBTARGET_OPTIONS							\
  }
  
*************** struct rs6000_cpu_select
*** 424,430 ****
  extern struct rs6000_cpu_select rs6000_select[];
  
  /* Debug support */
! extern const char *rs6000_debug_name;		/* Name for -mdebug-xxxx option */
  extern int rs6000_debug_stack;		/* debug stack applications */
  extern int rs6000_debug_arg;		/* debug argument handling */
  
--- 438,445 ----
  extern struct rs6000_cpu_select rs6000_select[];
  
  /* Debug support */
! extern const char *rs6000_debug_name;	/* Name for -mdebug-xxxx option */
! extern const char *rs6000_abi_string;	/* for -mabi={sysv,darwin,solaris,eabi,aix,altivec} */
  extern int rs6000_debug_stack;		/* debug stack applications */
  extern int rs6000_debug_arg;		/* debug argument handling */
  
*************** extern int rs6000_debug_arg;		/* debug a
*** 505,510 ****
--- 520,526 ----
  #define UNITS_PER_WORD (! TARGET_POWERPC64 ? 4 : 8)
  #define MIN_UNITS_PER_WORD 4
  #define UNITS_PER_FP_WORD 8
+ #define UNITS_PER_ALTIVEC_WORD 16
  
  /* Type used for ptrdiff_t, as a string used in a declaration.  */
  #define PTRDIFF_TYPE "int"
*************** extern int rs6000_debug_arg;		/* debug a
*** 569,581 ****
  #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
  
  /* Boundary (in *bits*) on which stack pointer should be aligned.  */
! #define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
  
  /* Allocation boundary (in *bits*) for the code of a function.  */
  #define FUNCTION_BOUNDARY 32
  
  /* No data type wants to be aligned rounder than this.  */
! #define BIGGEST_ALIGNMENT 64
  
  /* Handle #pragma pack.  */
  #define HANDLE_PRAGMA_PACK 1
--- 585,604 ----
  #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
  
  /* Boundary (in *bits*) on which stack pointer should be aligned.  */
! #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
  
  /* Allocation boundary (in *bits*) for the code of a function.  */
  #define FUNCTION_BOUNDARY 32
  
  /* No data type wants to be aligned rounder than this.  */
! #define BIGGEST_ALIGNMENT 128
! 
! /* A C expression to compute the alignment for a variables in the
!    local store.  TYPE is the data type, and ALIGN is the alignment
!    that the object would ordinarily have.  */
! #define LOCAL_ALIGNMENT(TYPE, ALIGN)				\
! 	((TARGET_ALTIVEC		    			\
! 	  && TREE_CODE (TYPE)) == VECTOR_TYPE ? 128 : ALIGN)
  
  /* Handle #pragma pack.  */
  #define HANDLE_PRAGMA_PACK 1
*************** extern int rs6000_debug_arg;		/* debug a
*** 594,602 ****
    (TREE_CODE (EXP) == STRING_CST	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
! /* Make arrays of chars word-aligned for the same reasons.  */
  #define DATA_ALIGNMENT(TYPE, ALIGN)		\
!   (TREE_CODE (TYPE) == ARRAY_TYPE		\
     && TYPE_MODE (TREE_TYPE (TYPE)) == QImode	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
--- 617,627 ----
    (TREE_CODE (EXP) == STRING_CST	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
! /* Make arrays of chars word-aligned for the same reasons.
!    Align vectors to 128 bits.  */
  #define DATA_ALIGNMENT(TYPE, ALIGN)		\
!   (TREE_CODE (TYPE) == VECTOR_TYPE ? 128	\
!    : TREE_CODE (TYPE) == ARRAY_TYPE		\
     && TYPE_MODE (TREE_TYPE (TYPE)) == QImode	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
*************** extern int rs6000_debug_arg;		/* debug a
*** 634,643 ****
     a register, in order to work around problems in allocating stack storage
     in inline functions.  */
  
! #define FIRST_PSEUDO_REGISTER 77
  
  /* This must not decrease, for backwards compatibility.  If
     FIRST_PSEUDO_REGISTER increases, this should as well.  */
  #define DWARF_FRAME_REGISTERS 77
  
  /* 1 for registers that have pervasive standard uses
--- 659,670 ----
     a register, in order to work around problems in allocating stack storage
     in inline functions.  */
  
! #define FIRST_PSEUDO_REGISTER 110
  
  /* This must not decrease, for backwards compatibility.  If
     FIRST_PSEUDO_REGISTER increases, this should as well.  */
+ /* fixme: this needs to be defined to "TARGET_ALTIVEC_ABI ? 110 : 77"
+    and then fix usages of DWARF_FRAME_REGISTERS to work.  */
  #define DWARF_FRAME_REGISTERS 77
  
  /* 1 for registers that have pervasive standard uses
*************** extern int rs6000_debug_arg;		/* debug a
*** 655,661 ****
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1}
  
  /* 1 for registers not available across function calls.
     These must include the FIXED_REGISTERS and also any
--- 682,693 ----
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1,	   \
!    /* AltiVec registers.  */			   \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0						   \
! }
  
  /* 1 for registers not available across function calls.
     These must include the FIXED_REGISTERS and also any
*************** extern int rs6000_debug_arg;		/* debug a
*** 669,676 ****
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1}
  
  #define MQ_REGNO     64
  #define CR0_REGNO    68
  #define CR1_REGNO    69
--- 701,714 ----
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1,	   \
!    /* AltiVec registers.  */			   \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0						   \
! }
  
+ 
  #define MQ_REGNO     64
  #define CR0_REGNO    68
  #define CR1_REGNO    69
*************** extern int rs6000_debug_arg;		/* debug a
*** 679,684 ****
--- 717,725 ----
  #define CR4_REGNO    72
  #define MAX_CR_REGNO 75
  #define XER_REGNO    76
+ #define FIRST_ALTIVEC_REGNO	77
+ #define LAST_ALTIVEC_REGNO	108
+ #define VRSAVE_REGNO		109
  
  /* List the order in which to allocate registers.  Each register must be
     listed once, even those in FIXED_REGISTERS.
*************** extern int rs6000_debug_arg;		/* debug a
*** 701,707 ****
  	mq		(not saved; best to use it if we can)
  	ctr		(not saved; when we have the choice ctr is better)
  	lr		(saved)
!         cr5, r1, r2, ap, xer (fixed)  */
  
  #define REG_ALLOC_ORDER					\
    {32, 							\
--- 742,757 ----
  	mq		(not saved; best to use it if we can)
  	ctr		(not saved; when we have the choice ctr is better)
  	lr		(saved)
!         cr5, r1, r2, ap, xer, vrsave (fixed)
! 
! 	AltiVec registers:
! 	v0 - v1         (not saved or used for anything)
! 	v13 - v3        (not saved; incoming vector arg registers)
! 	v2              (not saved; incoming vector arg reg; return value)
! 	v19 - v14       (not saved or used for anything)
! 	v31 - v20       (saved; order given to save least number)
! */
! 						
  
  #define REG_ALLOC_ORDER					\
    {32, 							\
*************** extern int rs6000_debug_arg;		/* debug a
*** 716,722 ****
     31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19,	\
     18, 17, 16, 15, 14, 13, 12,				\
     64, 66, 65, 						\
!    73, 1, 2, 67, 76}
  
  /* True if register is floating-point.  */
  #define FP_REGNO_P(N) ((N) >= 32 && (N) <= 63)
--- 766,779 ----
     31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19,	\
     18, 17, 16, 15, 14, 13, 12,				\
     64, 66, 65, 						\
!    73, 1, 2, 67, 76,					\
!    /* AltiVec registers.  */				\
!    77, 78,						\
!    90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80,		\
!    79,							\
!    96, 95, 94, 93, 92, 91,				\
!    108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97 \
! }
  
  /* True if register is floating-point.  */
  #define FP_REGNO_P(N) ((N) >= 32 && (N) <= 63)
*************** extern int rs6000_debug_arg;		/* debug a
*** 733,738 ****
--- 790,798 ----
  /* True if register is the XER register.  */
  #define XER_REGNO_P(N) ((N) == XER_REGNO)
  
+ /* True if register is an AltiVec register.  */
+ #define ALTIVEC_REGNO_P(N) ((N) >= FIRST_ALTIVEC_REGNO && (N) <= LAST_ALTIVEC_REGNO)
+ 
  /* Return number of consecutive hard regs needed starting at reg REGNO
     to hold something of mode MODE.
     This is ordinarily the length in words of a value of mode MODE
*************** extern int rs6000_debug_arg;		/* debug a
*** 744,751 ****
--- 804,826 ----
  #define HARD_REGNO_NREGS(REGNO, MODE)					\
    (FP_REGNO_P (REGNO)							\
     ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
+    : ALTIVEC_REGNO_P (REGNO)						\
+    ? ((GET_MODE_SIZE (MODE) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD) \
     : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
  
+ #define ALTIVEC_VECTOR_MODE(MODE)	\
+ 	((MODE) == V16QImode		\
+ 	 || (MODE) == V8HImode		\
+ 	 || (MODE) == V4SFmode		\
+ 	 || (MODE) == V4SImode)
+ 
+ /* Define this macro to be nonzero if the port is prepared to handle
+    insns involving vector mode MODE.  At the very least, it must have
+    move patterns for this mode.  */
+ 
+ #define VECTOR_MODE_SUPPORTED_P(MODE)	\
+ 	(TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE))
+ 
  /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
     For POWER and PowerPC, the GPRs can hold any mode, but the float
     registers only can hold floating modes and DImode, and CR register only
*************** extern int rs6000_debug_arg;		/* debug a
*** 757,762 ****
--- 832,838 ----
     (GET_MODE_CLASS (MODE) == MODE_FLOAT					\
      || (GET_MODE_CLASS (MODE) == MODE_INT				\
  	&& GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD))			\
+    : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE)		\
     : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC		\
     : XER_REGNO_P (REGNO) ? (MODE) == PSImode				\
     : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT		\
*************** extern int rs6000_debug_arg;		/* debug a
*** 776,781 ****
--- 852,861 ----
     ? GET_MODE_CLASS (MODE2) == MODE_CC		\
     : GET_MODE_CLASS (MODE2) == MODE_CC		\
     ? GET_MODE_CLASS (MODE1) == MODE_CC		\
+    : ALTIVEC_VECTOR_MODE (MODE1)		\
+    ? ALTIVEC_VECTOR_MODE (MODE2)		\
+    : ALTIVEC_VECTOR_MODE (MODE2)		\
+    ? ALTIVEC_VECTOR_MODE (MODE1)		\
     : 1)
  
  /* A C expression returning the cost of moving data from a register of class
*************** extern int rs6000_debug_arg;		/* debug a
*** 785,793 ****
     registers is expensive.  */
  
  #define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2)		\
!    ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2		\
     : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10	\
     : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10	\
     : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS		\
         || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS		\
         || (CLASS1) == LINK_OR_CTR_REGS)				\
--- 865,875 ----
     registers is expensive.  */
  
  #define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2)		\
!    ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2	\
     : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10	\
     : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10	\
+    : (CLASS1) == ALTIVEC_REGS && (CLASS2) != ALTIVEC_REGS ? 20	\
+    : (CLASS1) != ALTIVEC_REGS && (CLASS2) == ALTIVEC_REGS ? 20	\
     : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS		\
         || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS		\
         || (CLASS1) == LINK_OR_CTR_REGS)				\
*************** extern int rs6000_debug_arg;		/* debug a
*** 839,844 ****
--- 921,932 ----
      global_regs[PIC_OFFSET_TABLE_REGNUM]				\
        = fixed_regs[PIC_OFFSET_TABLE_REGNUM]				\
          = call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;			\
+   if (TARGET_ALTIVEC_ABI)						\
+     {									\
+       fixed_regs[VRSAVE_REGNO] = call_used_regs[VRSAVE_REGNO] = 1;	\
+       for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)	\
+         call_used_regs[i] = 1;						\
+     }									\
  }
  
  /* Specify the registers used for certain standard purposes.
*************** enum reg_class
*** 912,917 ****
--- 1000,1007 ----
    BASE_REGS,
    GENERAL_REGS,
    FLOAT_REGS,
+   ALTIVEC_REGS,
+   VRSAVE_REGS,
    NON_SPECIAL_REGS,
    MQ_REGS,
    LINK_REGS,
*************** enum reg_class
*** 937,942 ****
--- 1027,1034 ----
    "BASE_REGS",								\
    "GENERAL_REGS",							\
    "FLOAT_REGS",								\
+   "ALTIVEC_REGS",							\
+   "VRSAVE_REGS",							\
    "NON_SPECIAL_REGS",							\
    "MQ_REGS",								\
    "LINK_REGS",								\
*************** enum reg_class
*** 955,978 ****
     This is an initializer for a vector of HARD_REG_SET
     of length N_REG_CLASSES.  */
  
! #define REG_CLASS_CONTENTS						\
! {									\
!   { 0x00000000, 0x00000000, 0x00000000 },	/* NO_REGS */		\
!   { 0xfffffffe, 0x00000000, 0x00000008 },	/* BASE_REGS */		\
!   { 0xffffffff, 0x00000000, 0x00000008 },	/* GENERAL_REGS */	\
!   { 0x00000000, 0xffffffff, 0x00000000 },	/* FLOAT_REGS */	\
!   { 0xffffffff, 0xffffffff, 0x00000008 },	/* NON_SPECIAL_REGS */	\
!   { 0x00000000, 0x00000000, 0x00000001 },	/* MQ_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000002 },	/* LINK_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000004 },	/* CTR_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000006 },	/* LINK_OR_CTR_REGS */	\
!   { 0x00000000, 0x00000000, 0x00000007 },	/* SPECIAL_REGS */	\
!   { 0xffffffff, 0x00000000, 0x0000000f },	/* SPEC_OR_GEN_REGS */	\
!   { 0x00000000, 0x00000000, 0x00000010 },	/* CR0_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000ff0 },	/* CR_REGS */		\
!   { 0xffffffff, 0x00000000, 0x0000ffff },	/* NON_FLOAT_REGS */	\
!   { 0x00000000, 0x00000000, 0x00010000 },	/* XER_REGS */		\
!   { 0xffffffff, 0xffffffff, 0x0001ffff }	/* ALL_REGS */		\
  }
  
  /* The same information, inverted:
--- 1047,1072 ----
     This is an initializer for a vector of HARD_REG_SET
     of length N_REG_CLASSES.  */
  
! #define REG_CLASS_CONTENTS						     \
! {									     \
!   { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */	     \
!   { 0xfffffffe, 0x00000000, 0x00000008, 0x00000000 }, /* BASE_REGS */	     \
!   { 0xffffffff, 0x00000000, 0x00000008, 0x00000000 }, /* GENERAL_REGS */     \
!   { 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FLOAT_REGS */       \
!   { 0x00000000, 0x00000000, 0xffffe000, 0x0001ffff }, /* ALTIVEC_REGS */     \
!   { 0x00000000, 0x00000000, 0x00000000, 0x00020000 }, /* VRSAVE_REGS */	     \
!   { 0xffffffff, 0xffffffff, 0x00000008, 0x00000000 }, /* NON_SPECIAL_REGS */ \
!   { 0x00000000, 0x00000000, 0x00000001, 0x00000000 }, /* MQ_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000002, 0x00000000 }, /* LINK_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000004, 0x00000000 }, /* CTR_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000006, 0x00000000 }, /* LINK_OR_CTR_REGS */ \
!   { 0x00000000, 0x00000000, 0x00000007, 0x00000000 }, /* SPECIAL_REGS */     \
!   { 0xffffffff, 0x00000000, 0x0000000f, 0x00000000 }, /* SPEC_OR_GEN_REGS */ \
!   { 0x00000000, 0x00000000, 0x00000010, 0x00000000 }, /* CR0_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */	     \
!   { 0xffffffff, 0x00000000, 0x0000ffff, 0x00000000 }, /* NON_FLOAT_REGS */   \
!   { 0x00000000, 0x00000000, 0x00010000, 0x00000000 }, /* XER_REGS */	     \
!   { 0xffffffff, 0xffffffff, 0xffffffff, 0x0001ffff }  /* ALL_REGS */	     \
  }
  
  /* The same information, inverted:
*************** enum reg_class
*** 984,989 ****
--- 1078,1084 ----
   ((REGNO) == 0 ? GENERAL_REGS			\
    : (REGNO) < 32 ? BASE_REGS			\
    : FP_REGNO_P (REGNO) ? FLOAT_REGS		\
+   : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_REGS	\
    : (REGNO) == CR0_REGNO ? CR0_REGS		\
    : CR_REGNO_P (REGNO) ? CR_REGS		\
    : (REGNO) == MQ_REGNO ? MQ_REGS		\
*************** enum reg_class
*** 991,996 ****
--- 1086,1092 ----
    : (REGNO) == COUNT_REGISTER_REGNUM ? CTR_REGS	\
    : (REGNO) == ARG_POINTER_REGNUM ? BASE_REGS	\
    : (REGNO) == XER_REGNO ? XER_REGS		\
+   : (REGNO) == VRSAVE_REGNO ? VRSAVE_REGS	\
    : NO_REGS)
  
  /* The class value for index registers, and the one for base regs.  */
*************** enum reg_class
*** 1006,1011 ****
--- 1102,1108 ----
     : (C) == 'q' ? MQ_REGS	\
     : (C) == 'c' ? CTR_REGS	\
     : (C) == 'l' ? LINK_REGS	\
+    : (C) == 'v' ? ALTIVEC_REGS	\
     : (C) == 'x' ? CR0_REGS	\
     : (C) == 'y' ? CR_REGS	\
     : (C) == 'z' ? XER_REGS	\
*************** enum reg_class
*** 1103,1113 ****
  #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
    secondary_reload_class (CLASS, MODE, IN)
  
! /* If we are copying between FP registers and anything else, we need a memory
!    location.  */
  
! #define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
!  ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS || (CLASS2) == FLOAT_REGS))
  
  /* Return the maximum number of consecutive registers
     needed to represent mode MODE in a register of class CLASS.
--- 1200,1213 ----
  #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
    secondary_reload_class (CLASS, MODE, IN)
  
! /* If we are copying between FP or AltiVec registers and anything
!    else, we need a memory location.  */
  
! #define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) 		\
!  ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS		\
! 			   || (CLASS2) == FLOAT_REGS		\
! 			   || (CLASS1) == ALTIVEC_REGS		\
! 			   || (CLASS2) == ALTIVEC_REGS))
  
  /* Return the maximum number of consecutive registers
     needed to represent mode MODE in a register of class CLASS.
*************** typedef struct rs6000_stack {
*** 1294,1309 ****
  		&& TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)	\
  	       || POINTER_TYPE_P (VALTYPE)			\
  	       ? word_mode : TYPE_MODE (VALTYPE),		\
! 	       TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT \
                 ? FP_ARG_RETURN : GP_ARG_RETURN)
  
  /* Define how to find the value returned by a library function
     assuming the value has mode MODE.  */
  
! #define LIBCALL_VALUE(MODE)					\
!   gen_rtx_REG (MODE, (GET_MODE_CLASS (MODE) == MODE_FLOAT	\
! 		      && TARGET_HARD_FLOAT			\
! 		      ? FP_ARG_RETURN : GP_ARG_RETURN))
  
  /* The definition of this macro implies that there are cases where
     a scalar value cannot be returned in registers.
--- 1394,1411 ----
  		&& TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)	\
  	       || POINTER_TYPE_P (VALTYPE)			\
  	       ? word_mode : TYPE_MODE (VALTYPE),		\
! 	       TREE_CODE (VALTYPE) == VECTOR_TYPE ? ALTIVEC_ARG_RETURN \
! 	       : TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT \
                 ? FP_ARG_RETURN : GP_ARG_RETURN)
  
  /* Define how to find the value returned by a library function
     assuming the value has mode MODE.  */
  
! #define LIBCALL_VALUE(MODE)						\
!   gen_rtx_REG (MODE, ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_ARG_RETURN	\
! 		     : GET_MODE_CLASS (MODE) == MODE_FLOAT		\
! 		     && TARGET_HARD_FLOAT				\
! 		     ? FP_ARG_RETURN : GP_ARG_RETURN)
  
  /* The definition of this macro implies that there are cases where
     a scalar value cannot be returned in registers.
*************** typedef struct rs6000_stack {
*** 1338,1346 ****
--- 1440,1454 ----
  			? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG)
  #define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1)
  
+ /* Minimum and maximum AltiVec registers used to hold arguments.  */
+ #define ALTIVEC_ARG_MIN_REG (FIRST_ALTIVEC_REGNO + 2)
+ #define ALTIVEC_ARG_MAX_REG (ALTIVEC_ARG_MIN_REG + 11)
+ #define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG - ALTIVEC_ARG_MIN_REG + 1)
+ 
  /* Return registers */
  #define GP_ARG_RETURN GP_ARG_MIN_REG
  #define FP_ARG_RETURN FP_ARG_MIN_REG
+ #define ALTIVEC_ARG_RETURN (FIRST_ALTIVEC_REGNO + 2)
  
  /* Flags for the call/call_value rtl operations set up by function_arg */
  #define CALL_NORMAL		0x00000000	/* no special processing */
*************** typedef struct rs6000_stack {
*** 1352,1364 ****
  /* 1 if N is a possible register number for a function value
     as seen by the caller.
  
!    On RS/6000, this is r3 and fp1.  */
! #define FUNCTION_VALUE_REGNO_P(N)  ((N) == GP_ARG_RETURN || ((N) == FP_ARG_RETURN))
  
  /* 1 if N is a possible register number for function argument passing.
     On RS/6000, these are r3-r10 and fp1-fp13.  */
  #define FUNCTION_ARG_REGNO_P(N)						\
    ((unsigned)(((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG))	\
     || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))
  
  \f
--- 1460,1477 ----
  /* 1 if N is a possible register number for a function value
     as seen by the caller.
  
!    On RS/6000, this is r3, fp1, and v2 (for AltiVec).  */
! #define FUNCTION_VALUE_REGNO_P(N)  ((N) == GP_ARG_RETURN	\
! 				    || ((N) == FP_ARG_RETURN)	\
! 				    || (TARGET_ALTIVEC &&	\
! 					(N) == ALTIVEC_ARG_RETURN))
  
  /* 1 if N is a possible register number for function argument passing.
     On RS/6000, these are r3-r10 and fp1-fp13.  */
  #define FUNCTION_ARG_REGNO_P(N)						\
    ((unsigned)(((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG))	\
+    || (TARGET_ALTIVEC &&						\
+        (unsigned)((N) - ALTIVEC_ARG_MIN_REG) < (unsigned)(ALTIVEC_ARG_MAX_REG)) \
     || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))
  
  \f
*************** typedef struct rs6000_args
*** 1394,1399 ****
--- 1507,1513 ----
  {
    int words;			/* # words used for passing GP registers */
    int fregno;			/* next available FP register */
+   int vregno;			/* next available AltiVec register */
    int nargs_prototype;		/* # args left in the current prototype */
    int orig_nargs;		/* Original value of nargs_prototype */
    int prototype;		/* Whether a prototype was defined */
*************** typedef struct rs6000_args
*** 1436,1441 ****
--- 1550,1561 ----
     && (CUM).fregno <= FP_ARG_MAX_REG    \
     && TARGET_HARD_FLOAT)
  
+ /* Non-zero if we can use an AltiVec register to pass this arg.  */
+ #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE)	\
+   (ALTIVEC_VECTOR_MODE (MODE)			\
+    && (CUM).vregno <= ALTIVEC_ARG_MAX_REG	\
+    && TARGET_ALTIVEC_ABI)
+ 
  /* Determine where to put an argument to a function.
     Value is zero to push the argument on the stack,
     or a hard register in which to store the argument.
*************** typedef struct rs6000_args
*** 1778,1783 ****
--- 1898,1904 ----
    && GET_CODE (XEXP (X, 0)) == REG				\
    && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT))		\
    && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0)		\
+   && (! ALTIVEC_VECTOR_MODE (MODE) || INTVAL (X) == 0)		\
    && (((MODE) != DFmode && (MODE) != DImode)			\
        || (TARGET_32BIT						\
  	  ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) 	\
*************** typedef struct rs6000_args
*** 1805,1810 ****
--- 1926,1932 ----
     && ! flag_pic && ! TARGET_TOC				\
     && (MODE) != DImode						\
     && (MODE) != TImode						\
+    && ! ALTIVEC_VECTOR_MODE (MODE)				\
     && (TARGET_HARD_FLOAT || (MODE) != DFmode)			\
     && GET_CODE (X) == LO_SUM					\
     && GET_CODE (XEXP (X, 0)) == REG				\
*************** extern char rs6000_reg_names[][8];	/* re
*** 2389,2394 ****
--- 2511,2549 ----
    &rs6000_reg_names[75][0],	/* cr7  */				\
  									\
    &rs6000_reg_names[76][0],	/* xer  */				\
+ 									\
+   &rs6000_reg_names[77][0],	/* v0  */				\
+   &rs6000_reg_names[78][0],	/* v1  */				\
+   &rs6000_reg_names[79][0],	/* v2  */				\
+   &rs6000_reg_names[80][0],	/* v3  */				\
+   &rs6000_reg_names[81][0],	/* v4  */				\
+   &rs6000_reg_names[82][0],	/* v5  */				\
+   &rs6000_reg_names[83][0],	/* v6  */				\
+   &rs6000_reg_names[84][0],	/* v7  */				\
+   &rs6000_reg_names[85][0],	/* v8  */				\
+   &rs6000_reg_names[86][0],	/* v9  */				\
+   &rs6000_reg_names[87][0],	/* v10  */				\
+   &rs6000_reg_names[88][0],	/* v11  */				\
+   &rs6000_reg_names[89][0],	/* v12  */				\
+   &rs6000_reg_names[90][0],	/* v13  */				\
+   &rs6000_reg_names[91][0],	/* v14  */				\
+   &rs6000_reg_names[92][0],	/* v15  */				\
+   &rs6000_reg_names[93][0],	/* v16  */				\
+   &rs6000_reg_names[94][0],	/* v17  */				\
+   &rs6000_reg_names[95][0],	/* v18  */				\
+   &rs6000_reg_names[96][0],	/* v19  */				\
+   &rs6000_reg_names[97][0],	/* v20  */				\
+   &rs6000_reg_names[98][0],	/* v21  */				\
+   &rs6000_reg_names[99][0],	/* v22  */				\
+   &rs6000_reg_names[100][0],	/* v23  */				\
+   &rs6000_reg_names[101][0],	/* v24  */				\
+   &rs6000_reg_names[102][0],	/* v25  */				\
+   &rs6000_reg_names[103][0],	/* v26  */				\
+   &rs6000_reg_names[104][0],	/* v27  */				\
+   &rs6000_reg_names[105][0],	/* v28  */				\
+   &rs6000_reg_names[106][0],	/* v29  */				\
+   &rs6000_reg_names[107][0],	/* v30  */				\
+   &rs6000_reg_names[108][0],	/* v31  */				\
  }
  
  /* print-rtl can't handle the above REGISTER_NAMES, so define the
*************** extern char rs6000_reg_names[][8];	/* re
*** 2407,2413 ****
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",		\
       "mq",  "lr", "ctr",  "ap",						\
      "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",		\
!   "xer"									\
  }
  
  /* Table of additional register names to use in user input.  */
--- 2562,2572 ----
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",		\
       "mq",  "lr", "ctr",  "ap",						\
      "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",		\
!   "xer",								\
!      "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",             \
!      "v8",  "v9", "v10", "v11", "v12", "v13", "v14", "v15",             \
!     "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",             \
!     "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"              \
  }
  
  /* Table of additional register names to use in user input.  */
*************** extern char rs6000_reg_names[][8];	/* re
*** 2429,2434 ****
--- 2588,2601 ----
    {"fr20", 52}, {"fr21", 53}, {"fr22", 54}, {"fr23", 55},	\
    {"fr24", 56}, {"fr25", 57}, {"fr26", 58}, {"fr27", 59},	\
    {"fr28", 60}, {"fr29", 61}, {"fr30", 62}, {"fr31", 63},	\
+   {"v0",   77}, {"v1",   78}, {"v2",   79}, {"v3",   80},       \
+   {"v4",   81}, {"v5",   82}, {"v6",   83}, {"v7",   84},       \
+   {"v8",   85}, {"v9",   86}, {"v10",  87}, {"v11",  88},       \
+   {"v12",  89}, {"v13",  90}, {"v14",  91}, {"v15",  92},       \
+   {"v16",  93}, {"v17",  94}, {"v18",  95}, {"v19",  96},       \
+   {"v20",  97}, {"v21",  98}, {"v22",  99}, {"v23",  100},	\
+   {"v24",  101},{"v25",  102},{"v26",  103},{"v27",  104},      \
+   {"v28",  105},{"v29",  106},{"v30",  107},{"v31",  108},      \
    /* no additional names for: mq, lr, ctr, ap */		\
    {"cr0",  68}, {"cr1",  69}, {"cr2",  70}, {"cr3",  71},	\
    {"cr4",  72}, {"cr5",  73}, {"cr6",  74}, {"cr7",  75},	\
*************** extern int flag_pic;
*** 2629,2631 ****
--- 2796,2911 ----
  extern int optimize;
  extern int flag_expensive_optimizations;
  extern int frame_pointer_needed;
+ 
+ enum rs6000_builtins
+ {
+   /* AltiVec builtins.  */
+   ALTIVEC_BUILTIN_ST_INTERNAL,

*builtins deleted*

+ };
Index: sysv4.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/sysv4.h,v
retrieving revision 1.67
diff -c -p -r1.67 sysv4.h
*** sysv4.h	2001/10/29 23:09:43	1.67
--- sysv4.h	2001/11/06 22:24:42
*************** do {									\
*** 400,417 ****
     one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
     versions, just use 64 as the stack boundary.  */
  #undef	STACK_BOUNDARY
! #define	STACK_BOUNDARY	64
  
  /* Real stack boundary as mandated by the appropriate ABI.  */
! #define ABI_STACK_BOUNDARY ((TARGET_EABI) ? 64 : 128)
  
  /* No data type wants to be aligned rounder than this.  */
  #undef	BIGGEST_ALIGNMENT
! #define BIGGEST_ALIGNMENT ((TARGET_EABI) ? 64 : 128)
  
  #undef  BIGGEST_FIELD_ALIGNMENT
  #undef  ADJUST_FIELD_ALIGN
- #undef  ROUND_TYPE_ALIGN
  
  /* Use ELF style section commands.  */
  
--- 400,430 ----
     one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
     versions, just use 64 as the stack boundary.  */
  #undef	STACK_BOUNDARY
! #define	STACK_BOUNDARY	(TARGET_ALTIVEC_ABI ? 128 : 64)
  
  /* Real stack boundary as mandated by the appropriate ABI.  */
! #define ABI_STACK_BOUNDARY ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
  
  /* No data type wants to be aligned rounder than this.  */
  #undef	BIGGEST_ALIGNMENT
! #define BIGGEST_ALIGNMENT (TARGET_EABI ? 64 : 128)
  
+ /* An expression for the alignment of a structure field FIELD if the
+    alignment computed in the usual way is COMPUTED.  */
+ #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)				      \
+ 	((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE)     \
+ 	 ? 128 : COMPUTED)
+ 
+ /* Define this macro as an expression for the alignment of a type
+    (given by TYPE as a tree node) if the alignment computed in the
+    usual way is COMPUTED and the alignment explicitly specified was
+    SPECIFIED.  */
+ #define ROUND_TYPE_ALIGN(TYPE, COMPUTED, SPECIFIED)			\
+ 	((TARGET_ALTIVEC  && TREE_CODE (TYPE) == VECTOR_TYPE)	        \
+ 	 ? 128 : MAX (COMPUTED, SPECIFIED))
+ 
  #undef  BIGGEST_FIELD_ALIGNMENT
  #undef  ADJUST_FIELD_ALIGN
  
  /* Use ELF style section commands.  */
  
Index: rs6000.c
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.224
diff -c -p -r1.224 rs6000.c
*** rs6000.c	2001/10/31 14:08:09	1.224
--- rs6000.c	2001/11/06 22:24:45
*************** int fixuplabelno = 0;
*** 96,101 ****
--- 96,104 ----
  /* ABI enumeration available for subtarget to use.  */
  enum rs6000_abi rs6000_current_abi;
  
+ /* ABI string from -mabi= option.  */
+ const char *rs6000_abi_string;
+ 
  /* Debug flags */
  const char *rs6000_debug_name;
  int rs6000_debug_stack;		/* debug stack applications */
*************** static int rs6000_adjust_cost PARAMS ((r
*** 146,151 ****
--- 149,161 ----
  static int rs6000_adjust_priority PARAMS ((rtx, int));
  static int rs6000_issue_rate PARAMS ((void));
  
+ static void rs6000_init_builtins PARAMS ((tree));
+ static void altivec_init_builtins PARAMS ((void));
+ static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
+ static rtx altivec_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
+ static rtx altivec_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
+ 
+ static void rs6000_parse_abi_options PARAMS ((void));
  \f
  /* Default register names.  */
  char rs6000_reg_names[][8] =
*************** char rs6000_reg_names[][8] =
*** 160,166 ****
       "24", "25", "26", "27", "28", "29", "30", "31",
       "mq", "lr", "ctr","ap",
        "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
!       "xer"
  };
  
  #ifdef TARGET_REGNAMES
--- 170,181 ----
       "24", "25", "26", "27", "28", "29", "30", "31",
       "mq", "lr", "ctr","ap",
        "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
!       "xer",
!       /* AltiVec registers.  */
!       "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6", "v7",
!       "v8",  "v9",  "v10", "v11", "v12", "v13", "v14", "v15",
!       "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
!       "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
  };
  
  #ifdef TARGET_REGNAMES
*************** static const char alt_reg_names[][8] =
*** 176,182 ****
    "%f24",  "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
      "mq",    "lr",  "ctr",   "ap",
    "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
!   "xer"
  };
  #endif
  \f
--- 191,202 ----
    "%f24",  "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
      "mq",    "lr",  "ctr",   "ap",
    "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
!    "xer",
!    /* AltiVec registers.  */
!    "%v0",  "%v1",  "%v2",  "%v3",  "%v4",  "%v5",  "%v6", "%v7",
!    "%v8",  "%v9",  "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
!    "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
!    "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31"
  };
  #endif
  \f
*************** static const char alt_reg_names[][8] =
*** 205,210 ****
--- 225,236 ----
  #undef TARGET_SCHED_ADJUST_PRIORITY
  #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
  
+ #undef TARGET_INIT_BUILTINS
+ #define TARGET_INIT_BUILTINS rs6000_init_builtins
+ 
+ #undef TARGET_EXPAND_BUILTIN
+ #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
+ 
  struct gcc_target targetm = TARGET_INITIALIZER;
  \f
  /* Override command line options.  Mostly we process the processor
*************** rs6000_override_options (default_cpu)
*** 438,443 ****
--- 464,472 ----
  	error ("Unknown -mdebug-%s switch", rs6000_debug_name);
      }
  
+   /* Handle -mabi= options.  */
+   rs6000_parse_abi_options ();
+ 
  #ifdef TARGET_REGNAMES
    /* If the user desires alternate register names, copy in the
       alternate names now.  */
*************** rs6000_override_options (default_cpu)
*** 463,468 ****
--- 492,508 ----
    free_machine_status = rs6000_free_machine_status;
  }
  
+ /* Handle -mabi= options.  */
+ void rs6000_parse_abi_options ()
+ {
+   if (rs6000_abi_string == 0)
+     return;
+   else if (! strcmp (rs6000_abi_string, "altivec"))
+     target_flags |= MASK_ALTIVEC_ABI;
+   else
+     error ("Unknown ABI specified: '%s'", rs6000_abi_string);
+ }
+ 
  void
  optimization_options (level, size)
       int level ATTRIBUTE_UNUSED;
*************** rs6000_legitimize_address (x, oldx, mode
*** 1544,1550 ****
       rtx x;
       rtx oldx ATTRIBUTE_UNUSED;
       enum machine_mode mode;
! { 
    if (GET_CODE (x) == PLUS 
        && GET_CODE (XEXP (x, 0)) == REG
        && GET_CODE (XEXP (x, 1)) == CONST_INT
--- 1584,1590 ----
       rtx x;
       rtx oldx ATTRIBUTE_UNUSED;
       enum machine_mode mode;
! {
    if (GET_CODE (x) == PLUS 
        && GET_CODE (XEXP (x, 0)) == REG
        && GET_CODE (XEXP (x, 1)) == CONST_INT
*************** rs6000_legitimize_address (x, oldx, mode
*** 1570,1575 ****
--- 1610,1627 ----
        return gen_rtx_PLUS (Pmode, XEXP (x, 0),
  			   force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
      }
+   else if (ALTIVEC_VECTOR_MODE (mode))
+     {
+       rtx reg;
+ 
+       /* Make sure both operands are registers.  */
+       if (GET_CODE (x) == PLUS)
+ 	return gen_rtx_PLUS (Pmode, XEXP (x, 0),
+ 			     force_reg (Pmode, XEXP (x, 1)));
+ 
+       reg = force_reg (Pmode, x);
+       return reg;
+     }
    else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic
  	   && GET_CODE (x) != CONST_INT
  	   && GET_CODE (x) != CONST_DOUBLE 
*************** rs6000_emit_move (dest, source, mode)
*** 1862,1867 ****
--- 1914,1928 ----
  	operands[1] = force_const_mem (mode, operands[1]);
        break;
        
+     case V16QImode:
+     case V8HImode:
+     case V4SFmode:
+     case V4SImode:
+       /* fixme: aldyh -- allow vector constants when they are implemented.  */
+       if (CONSTANT_P (operands[1]))
+ 	operands[1] = force_const_mem (mode, operands[1]);
+       break;
+       
      case SImode:
      case DImode:
        /* Use default pattern for address of ELF small data */
*************** init_cumulative_args (cum, fntype, libna
*** 2062,2067 ****
--- 2123,2129 ----
    *cum = zero_cumulative;
    cum->words = 0;
    cum->fregno = FP_ARG_MIN_REG;
+   cum->vregno = ALTIVEC_ARG_MIN_REG;
    cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
    cum->call_cookie = CALL_NORMAL;
    cum->sysv_gregno = GP_ARG_MIN_REG;
*************** function_arg_boundary (mode, type)
*** 2142,2147 ****
--- 2204,2211 ----
    if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
        && (mode == DImode || mode == DFmode))
      return 64;
+   else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
+     return 128;
    else
      return PARM_BOUNDARY;
  }
*************** function_arg_advance (cum, mode, type, n
*** 2159,2165 ****
  {
    cum->nargs_prototype--;
  
!   if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
--- 2223,2236 ----
  {
    cum->nargs_prototype--;
  
!   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
!     {
!       if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
! 	cum->vregno++;
!       else
! 	cum->words += RS6000_ARG_SIZE (mode, type);
!     }
!   else if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
*************** function_arg (cum, mode, type, named)
*** 2287,2293 ****
        return GEN_INT (cum->call_cookie);
      }
  
!   if (abi == ABI_V4 || abi == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
--- 2358,2371 ----
        return GEN_INT (cum->call_cookie);
      }
  
!   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
!     {
!       if (cum->vregno <= ALTIVEC_ARG_MAX_REG)
! 	return gen_rtx_REG (mode, cum->vregno);
!       else
! 	return NULL;
!     }
!   else if (abi == ABI_V4 || abi == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
*************** function_arg_partial_nregs (cum, mode, t
*** 2382,2388 ****
    if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      return 0;
  
!   if (USE_FP_FOR_ARG_P (*cum, mode, type))
      {
        if (cum->nargs_prototype >= 0)
  	return 0;
--- 2460,2467 ----
    if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      return 0;
  
!   if (USE_FP_FOR_ARG_P (*cum, mode, type)
!       || USE_ALTIVEC_FOR_ARG_P (*cum, mode, type))
      {
        if (cum->nargs_prototype >= 0)
  	return 0;
*************** rs6000_va_arg (valist, type)
*** 2838,2843 ****
--- 2917,3392 ----
  
    return addr_rtx;
  }
+ 
+ /* Builtins.  */
+ 
+ #define def_builtin(MASK, NAME, TYPE, CODE)				\
+ do {									\
+   if ((MASK) & target_flags)						\
+     builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL);	\
+ } while (0)
+ 
+ struct builtin_description
+ {
+   const unsigned int mask;
+   const enum insn_code icode;
+   const char *const name;
+   const enum rs6000_builtins code;
+ };
+ 
+ /* Simple binary operatiors: VECc = foo (VECa, VECb).  */
+ static const struct builtin_description bdesc_2arg[] =
+ {
+   { MASK_ALTIVEC, CODE_FOR_altivec_vaddubm, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },

*builtins deleted*

+ };
+ 
+ static rtx
+ altivec_expand_binop_builtin (icode, arglist, target)
+      enum insn_code icode;
+      tree arglist;
+      rtx target;
+ {
+   rtx pat;
+   tree arg0 = TREE_VALUE (arglist);
+   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+   rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+   rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+   enum machine_mode tmode = insn_data[icode].operand[0].mode;
+   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
+   enum machine_mode mode1 = insn_data[icode].operand[2].mode;
+ 
+   if (! target
+       || GET_MODE (target) != tmode
+       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+     target = gen_reg_rtx (tmode);
+ 
+   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+     op0 = copy_to_mode_reg (mode0, op0);
+   if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
+     op1 = copy_to_mode_reg (mode1, op1);
+ 
+   pat = GEN_FCN (icode) (target, op0, op1);
+   if (! pat)
+     return 0;
+   emit_insn (pat);
+ 
+   return target;
+ }
+ 
+ static rtx
+ altivec_expand_builtin (exp, target, subtarget, mode, ignore)
+      tree exp;
+      rtx target;
+      rtx subtarget;
+      enum machine_mode mode;
+      int ignore;
+ {
+   struct builtin_description *d;
+   size_t i;
+   enum insn_code icode;
+   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
+   tree arglist = TREE_OPERAND (exp, 1);
+   tree arg0, arg1, arg2, arg3;
+   rtx op0, op1, op2, pat;
+   enum machine_mode tmode, mode0, mode1, mode2;
+   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+   
+   switch (fcode)
+     {
+     case ALTIVEC_BUILTIN_LD_INTERNAL:
+       icode = CODE_FOR_altivec_lvx;
+       arg0 = TREE_VALUE (arglist);
+       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+       tmode = insn_data[icode].operand[0].mode;
+       mode0 = insn_data[icode].operand[1].mode;
+ 
+       if (! target
+ 	  || GET_MODE (target) != tmode
+ 	  || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ 	target = gen_reg_rtx (tmode);
+ 
+       if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+ 	op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
+ 
+       pat = GEN_FCN (icode) (target, op0);
+       if (! pat)
+ 	return 0;
+       emit_insn (pat);
+       return target;
+ 
+     case ALTIVEC_BUILTIN_ST_INTERNAL:
+       icode = CODE_FOR_altivec_stvx;
+       arg0 = TREE_VALUE (arglist);
+       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+       op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+       mode0 = insn_data[icode].operand[0].mode;
+       mode1 = insn_data[icode].operand[1].mode;
+ 
+       if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
+ 	op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
+       if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
+ 	op1 = copy_to_mode_reg (mode1, op1);
+ 
+       pat = GEN_FCN (icode) (op0, op1);
+       if (! pat)
+ 	return 0;
+       emit_insn (pat);
+       return NULL_RTX;
+     }
+ 
+   /* Handle simple binary operations.  */
+   for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
+     if (d->code == fcode)
+       return altivec_expand_binop_builtin (d->icode, arglist, target);
+ 
+   abort ();
+   return NULL_RTX;
+ }
+ 
+ /* Expand an expression EXP that calls a built-in function,
+    with result going to TARGET if that's convenient
+    (and in mode MODE if that's convenient).
+    SUBTARGET may be used as the target for computing one of EXP's operands.
+    IGNORE is nonzero if the value is to be ignored.  */
+ 
+ static rtx
+ rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
+      tree exp;
+      rtx target;
+      rtx subtarget;
+      enum machine_mode mode;
+      int ignore;
+ {
+   if (TARGET_ALTIVEC)
+     return altivec_expand_builtin (exp, target, subtarget, mode, ignore);
+ 
+   abort ();
+ }
+ 
+ static void
+ rs6000_init_builtins (list_node)
+      tree list_node ATTRIBUTE_UNUSED;
+ {
+   if (TARGET_ALTIVEC)
+     altivec_init_builtins ();
+ }
+ 
+ static void
+ altivec_init_builtins (void)
+ {
+   struct builtin_description * d;
+   size_t i;
+ 
+   tree endlink = void_list_node;
+ 
+   tree pint_type_node = build_pointer_type (integer_type_node);
+ 
+   /* V4SI foo (int *).  */
+   tree v4si_ftype_pint
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, pint_type_node, endlink));
+ 
+   /* void foo (int *, V4SI).  */
+   tree void_ftype_pint_v4si
+     = build_function_type (void_type_node,
+ 			   tree_cons (NULL_TREE, pint_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 
+   tree v4si_ftype_v4si_v4si
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, V4SI_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 
+   tree v4sf_ftype_v4sf_v4sf
+     = build_function_type (V4SF_type_node,
+ 			   tree_cons (NULL_TREE, V4SF_type_node,
+ 				      tree_cons (NULL_TREE, V4SF_type_node,
+ 						 endlink)));
+ 
+   tree v8hi_ftype_v8hi_v8hi
+     = build_function_type (V8HI_type_node,
+ 			   tree_cons (NULL_TREE, V8HI_type_node,
+ 				      tree_cons (NULL_TREE, V8HI_type_node,
+ 						 endlink)));
+ 
+   tree v16qi_ftype_v16qi_v16qi
+     = build_function_type (V16QI_type_node,
+ 			   tree_cons (NULL_TREE, V16QI_type_node,
+ 				      tree_cons (NULL_TREE, V16QI_type_node,
+ 						 endlink)));
+ 
+   tree v4si_ftype_v4sf_v4sf
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, V4SF_type_node,
+ 				      tree_cons (NULL_TREE, V4SF_type_node,
+ 						 endlink)));
+ 
+   tree v8hi_ftype_v16qi_v16qi
+     = build_function_type (V8HI_type_node,
+ 			   tree_cons (NULL_TREE, V16QI_type_node,
+ 				      tree_cons (NULL_TREE, V16QI_type_node,
+ 						 endlink)));
+ 
+   tree v4si_ftype_v8hi_v8hi
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, V8HI_type_node,
+ 				      tree_cons (NULL_TREE, V8HI_type_node,
+ 						 endlink)));
+ 
+   tree v8hi_ftype_v4si_v4si
+     = build_function_type (V8HI_type_node,
+ 			   tree_cons (NULL_TREE, V4SI_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 
+   tree v16qi_ftype_v8hi_v8hi
+     = build_function_type (V16QI_type_node,
+ 			   tree_cons (NULL_TREE, V8HI_type_node,
+ 				      tree_cons (NULL_TREE, V8HI_type_node,
+ 						 endlink)));
+ 
+   tree v4si_ftype_v16qi_v4si
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, V16QI_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 
+   tree v4si_ftype_v8hi_v4si
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, V8HI_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 
+   tree int_ftype_v4si_v4si
+     = build_function_type (integer_type_node,
+ 			   tree_cons (NULL_TREE, V4SI_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 
+   tree int_ftype_v4sf_v4sf
+     = build_function_type (integer_type_node,
+ 			   tree_cons (NULL_TREE, V4SF_type_node,
+ 				      tree_cons (NULL_TREE, V4SF_type_node,
+ 						 endlink)));
+ 
+   tree int_ftype_v16qi_v16qi
+     = build_function_type (integer_type_node,
+ 			   tree_cons (NULL_TREE, V16QI_type_node,
+ 				      tree_cons (NULL_TREE, V16QI_type_node,
+ 						 endlink)));
+ 
+   tree int_ftype_v8hi_v8hi
+     = build_function_type (integer_type_node,
+ 			   tree_cons (NULL_TREE, V8HI_type_node,
+ 				      tree_cons (NULL_TREE, V8HI_type_node,
+ 						 endlink)));
+ 
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal", v4si_ftype_pint, ALTIVEC_BUILTIN_LD_INTERNAL);
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal", void_ftype_pint_v4si, ALTIVEC_BUILTIN_ST_INTERNAL);
+ 
+   /* Add the simple binary operators.  */
+   for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
+     {
+       enum machine_mode mode0, mode1, mode2;
+       tree type;
+ 
+       if (d->name == 0)
+ 	continue;
+       
+       mode0 = insn_data[d->icode].operand[0].mode;
+       mode1 = insn_data[d->icode].operand[1].mode;
+       mode2 = insn_data[d->icode].operand[2].mode;
+ 
+       /* When all three operands are of the same mode.  */
+       if (mode0 == mode1 && mode1 == mode2)
+ 	{
+ 	  switch (mode0)
+ 	    {
+ 	    case V4SFmode:
+ 	      type = v4sf_ftype_v4sf_v4sf;
+ 	      break;
+ 	    case V4SImode:
+ 	      type = v4si_ftype_v4si_v4si;
+ 	      break;
+ 	    case V16QImode:
+ 	      type = v16qi_ftype_v16qi_v16qi;
+ 	      break;
+ 	    case V8HImode:
+ 	      type = v8hi_ftype_v8hi_v8hi;
+ 	      break;
+ 	    default:
+ 	      abort ();
+ 	    }
+ 	}
+ 
+       /* A few other combos we really don't want to do manually.  */
+ 
+       /* vint, vfloat, vfloat.  */
+       else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
+ 	type = v4si_ftype_v4sf_v4sf;
+ 
+       /* vshort, vchar, vchar.  */
+       else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
+ 	type = v8hi_ftype_v16qi_v16qi;
+ 
+       /* vint, vshort, vshort.  */
+       else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
+ 	type = v4si_ftype_v8hi_v8hi;
+ 
+       /* vshort, vint, vint.  */
+       else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
+ 	type = v8hi_ftype_v4si_v4si;
+ 
+       /* vchar, vshort, vshort.  */
+       else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
+ 	type = v16qi_ftype_v8hi_v8hi;
+ 
+       /* vint, vchar, vint.  */
+       else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
+ 	type = v4si_ftype_v16qi_v4si;
+ 
+       /* vint, vshort, vint.  */
+       else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
+ 	type = v4si_ftype_v8hi_v4si;
+ 
+       /* fixme: aldyh */
+       /* int, x, x.  */
+       else if (mode0 == SImode)
+ 	{
+ 	  switch (mode1)
+ 	    {
+ 	    case V4SImode:
+ 	      type = int_ftype_v4si_v4si;
+ 	      break;
+ 	    case V4SFmode:
+ 	      type = int_ftype_v4sf_v4sf;
+ 	      break;
+ 	    case V16QImode:
+ 	      type = int_ftype_v16qi_v16qi;
+ 	      break;
+ 	    case V8HImode:
+ 	      type = int_ftype_v8hi_v8hi;
+ 	      break;
+ 	    default:
+ 	      abort ();
+ 	    }
+ 	}
+ 
+       else
+ 	abort ();
+ 
+       def_builtin (d->mask, d->name, type, d->code);
+     }
+ }
+ 
  \f
  /* Generate a memory reference for expand_block_move, copying volatile,
     and other bits from an original memory reference.  */
*************** secondary_reload_class (class, mode, in)
*** 3941,3946 ****
--- 4490,4500 ----
        && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
      return NO_REGS;
  
+   /* Memory, and AltiVec registers can go into AltiVec registers.  */
+   if ((regno == -1 || ALTIVEC_REGNO_P (regno))
+       && class == ALTIVEC_REGS)
+     return NO_REGS;
+ 
    /* We can copy among the CR registers.  */
    if ((class == CR_REGS || class == CR0_REGS)
        && regno >= 0 && CR_REGNO_P (regno))
*************** print_operand (file, x, code)
*** 4714,4719 ****
--- 5268,5299 ----
  		     reg_names[SMALL_DATA_REG]);
  	}
        return;
+ 
+       /* Print AltiVec memory operand.  */
+     case 'y':
+       {
+ 	rtx tmp;
+ 
+ 	if (GET_CODE (x) != MEM)
+ 	  abort ();
+ 
+ 	tmp = XEXP (x, 0);
+ 
+ 	if (GET_CODE (tmp) == REG)
+ 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
+ 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
+ 	  {
+ 	    if (REGNO (XEXP (tmp, 0)) == 0)
+ 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
+ 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
+ 	    else
+ 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
+ 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
+ 	  }
+ 	else
+ 	  abort ();
+ 	break;
+       }
  			    
      case 0:
        if (GET_CODE (x) == REG)
Index: rs6000.md
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.128
diff -c -p -r1.128 rs6000.md
*** rs6000.md	2001/10/16 00:43:21	1.128
--- rs6000.md	2001/11/06 22:24:51
***************
*** 37,43 ****
  \f
  ;; Define an insn type attribute.  This is used in function unit delay
  ;; computations.
! (define_attr "type" "integer,load,store,fpload,fpstore,imul,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg"
    (const_string "integer"))
  
  ;; Length (in bytes).
--- 37,43 ----
  \f
  ;; Define an insn type attribute.  This is used in function unit delay
  ;; computations.
! (define_attr "type" "integer,load,store,fpload,fpstore,imul,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,altivec"
    (const_string "integer"))
  
  ;; Length (in bytes).
***************
*** 13359,13361 ****
--- 13359,14294 ----
      emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
    DONE;
  }")
+ 
+ ;; AltiVec patterns
+ 
+ ;; Generic LVX load instruction.
+ (define_insn "altivec_lvx"
+   [(set (match_operand:V4SI 0 "register_operand" "=v")
+ 	(match_operand:V4SI 1 "memory_operand" "m"))]
+   "TARGET_ALTIVEC"
+   "lvx\t%0,%y1"
+   [(set_attr "type" "altivec")])
+ 
+ ;; Generic STVX store instruction.
+ (define_insn "altivec_stvx"
+   [(set (match_operand:V4SI 0 "memory_operand" "=m")
+ 	(match_operand:V4SI 1 "register_operand" "v"))]
+   "TARGET_ALTIVEC"
+   "stvx\t%1,%y0"
+   [(set_attr "type" "altivec")])
+ 
+ ;; Vector move instructions.
+ (define_expand "movv4si"
+   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
+ 	(match_operand:V4SI 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V4SImode); DONE; }")
+ 
+ (define_insn "*movv4si_internal"
+   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v,v")
+ 	(match_operand:V4SI 1 "input_operand" "v,m,v"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1
+    vor\t%0,%1,%1"
+   [(set_attr "type" "altivec")])
+ 
+ (define_expand "movv8hi"
+   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
+ 	(match_operand:V8HI 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V8HImode); DONE; }")
+ 
+ (define_insn "*movv8hi_internal1"
+   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=m,v,v")
+ 	(match_operand:V8HI 1 "input_operand" "v,m,v"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1
+    vor\t%0,%1,%1"
+   [(set_attr "type" "altivec")])
+ 
+ (define_expand "movv16qi"
+   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
+ 	(match_operand:V16QI 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V16QImode); DONE; }")
+ 
+ (define_insn "*movv16qi_internal1"
+   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=m,v,v")
+ 	(match_operand:V16QI 1 "input_operand" "v,m,v"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1
+    vor\t%0,%1,%1"
+   [(set_attr "type" "altivec")])
+ 
+ (define_expand "movv4sf"
+   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
+ 	(match_operand:V4SF 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V4SFmode); DONE; }")
+ 
+ (define_insn "*movv4sf_internal1"
+   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=m,v,v")
+ 	(match_operand:V4SF 1 "input_operand" "v,m,v"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1
+    vor\t%0,%1,%1"
+   [(set_attr "type" "altivec")])
+ 
+ ;; Simple binary operations.
+ 
+ (define_insn "altivec_vaddubm"
+   [(set (match_operand:V16QI 0 "register_operand" "=v")
+         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
+                        (match_operand:V16QI 2 "register_operand" "v")] 31))]
+   "TARGET_ALTIVEC"
+   "vaddubm\t%0,%1,%2"
+   [(set_attr "type" "altivec")])

*builtins deleted*

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 15:02   ` Aldy Hernandez
@ 2001-11-06 15:14     ` Joseph S. Myers
  2001-11-06 16:28       ` Aldy Hernandez
                         ` (2 more replies)
  2001-11-06 17:00     ` Dale Johannesen
                       ` (3 subsequent siblings)
  4 siblings, 3 replies; 152+ messages in thread
From: Joseph S. Myers @ 2001-11-06 15:14 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: gcc-patches

On 6 Nov 2001, Aldy Hernandez wrote:

> + the current ABI@

This sentence now seems to be missing its trailing ".".

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 18:30   ` Aldy Hernandez
@ 2001-11-06 16:12     ` Daniel Jacobowitz
  2001-11-06 16:46       ` Aldy Hernandez
                         ` (3 more replies)
  2001-11-13  4:32     ` Aldy Hernandez
  2001-11-13 15:03     ` Aldy Hernandez
  2 siblings, 4 replies; 152+ messages in thread
From: Daniel Jacobowitz @ 2001-11-06 16:12 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Dale Johannesen, gcc patches, Geoff Keating

On Mon, Nov 05, 2001 at 09:33:11PM -0500, Aldy Hernandez wrote:
> >>>>> "Dale" == Dale Johannesen <dalej@apple.com> writes:
> 
>  > This is getting better.
> 
> Thanks ;-)
> 
>  > I'd really like to see vrsave in the enums and register macros
>  > (not necessarily the code).  I dislike making a major change to
>  > an area if we know it's going to change again shortly.
> 
> That was supposed to be tommorrow's work.... :)
> 
>  > If you plan to support linking files compiled with and without
>  > -fabi=altivec,
> 
> nope we don't.  You can't just link too different abi's.

Is there any reasonable way to reflect that in the generated objects,
then?  Is there a spare bit in the ELF header for this?

-- 
Daniel Jacobowitz                           Carnegie Mellon University
MontaVista Software                         Debian GNU/Linux Developer

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 15:14     ` Joseph S. Myers
@ 2001-11-06 16:28       ` Aldy Hernandez
  2001-11-13  4:33         ` Aldy Hernandez
  2001-11-13 15:03         ` Aldy Hernandez
  2001-11-13  4:33       ` Joseph S. Myers
  2001-11-13 15:03       ` Joseph S. Myers
  2 siblings, 2 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-06 16:28 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc patches

On Tue, 2001-11-06 at 18:14, Joseph S. Myers wrote:
> On 6 Nov 2001, Aldy Hernandez wrote:
> 
> > + the current ABI@
> 
> This sentence now seems to be missing its trailing ".".
> 

fixed.
> -- 
> Joseph S. Myers
> jsm28@cam.ac.uk
-- 
Aldy Hernandez			E-mail: aldyh@redhat.com
Professional Gypsy
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 16:12     ` Daniel Jacobowitz
@ 2001-11-06 16:46       ` Aldy Hernandez
  2001-11-13  4:33         ` Aldy Hernandez
  2001-11-13 15:03         ` Aldy Hernandez
  2001-11-07  2:36       ` Geoff Keating
                         ` (2 subsequent siblings)
  3 siblings, 2 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-06 16:46 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: Dale Johannesen, gcc patches, Geoff Keating

> Is there any reasonable way to reflect that in the generated objects,
> then?  Is there a spare bit in the ELF header for this?

sure, i guess i can come up with a patch later... but that _is_ the
general idea of an ABI, you can't mix and match them and expect them to
work.

> 
> -- 
> Daniel Jacobowitz                           Carnegie Mellon University
> MontaVista Software                         Debian GNU/Linux Developer
-- 

Aldy Hernandez			E-mail: aldyh@redhat.com
Professional Gypsy
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 15:02   ` Aldy Hernandez
  2001-11-06 15:14     ` Joseph S. Myers
@ 2001-11-06 17:00     ` Dale Johannesen
  2001-11-06 17:06       ` Aldy Hernandez
                         ` (2 more replies)
  2001-11-06 17:07     ` Stan Shebs
                       ` (2 subsequent siblings)
  4 siblings, 3 replies; 152+ messages in thread
From: Dale Johannesen @ 2001-11-06 17:00 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Dale Johannesen, Geoff Keating, gcc-patches

On Tuesday, November 6, 2001, at 03:04 PM, Aldy Hernandez wrote:

> *************** extern int rs6000_debug_arg;	
> --- 766,779 ----
>      31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19,	\
>      18, 17, 16, 15, 14, 13, 12,				\
>      64, 66, 65, 						\
> !    73, 1, 2, 67, 76,					\
> !    /* AltiVec registers.  */				\
> !    77, 78,						\
> !    90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80,		\
> !    79,							\
> !    96, 95, 94, 93, 92, 91,				\
> !    108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97 \
> ! }

This needs an entry for vrsave.  (If you leave it out, you can get
a crash in reload on code that has nothing to do with Altivec; trust
me on this one:)

>   /* 1 if N is a possible register number for function argument passing.
>      On RS/6000, these are r3-r10 and fp1-fp13.  */
>   #define FUNCTION_ARG_REGNO_P(N)						\
>     ((unsigned)(((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG))	\
> +    || (TARGET_ALTIVEC &&						\
> +        (unsigned)((N) - ALTIVEC_ARG_MIN_REG) < 
> (unsigned)(ALTIVEC_ARG_MAX_REG)) \
>      || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))\

It would be nice, though not essential, to update the comment.

> --- 2511,2549 ----
...snipped...
> +   &rs6000_reg_names[107][0],	/* v30  */				\
> +   &rs6000_reg_names[108][0],	/* v31  */				\
>   }

This needs an entry for vrsave.

> --- 2562,2572 ----
>       "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",		\
>        "mq",  "lr", "ctr",  "ap",						\
>       "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",		\
> !   "xer",								\
> !      "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",            
>  \
> !      "v8",  "v9", "v10", "v11", "v12", "v13", "v14", "v15",            
>  \
> !     "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",            
>  \
> !     "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"             
>  \
>   }

So does this.

> +   {"v24",  101},{"v25",  102},{"v26",  103},{"v27",  104},      \
> +   {"v28",  105},{"v29",  106},{"v30",  107},{"v31",  108},      \
>     /* no additional names for: mq, lr, ctr, ap */		\
>     {"cr0",  68}, {"cr1",  69}, {"cr2",  70}, {"cr3",  71},	\
>     {"cr4",  72}, {"cr5",  73}, {"cr6",  74}, {"cr7",  75}

Not sure about here, but either the table or the commment should be 
updated.

> --- 170,181 ----
>        "24", "25", "26", "27", "28", "29", "30", "31",
>        "mq", "lr", "ctr","ap",
>         "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
> !       "xer",
> !       /* AltiVec registers.  */
> !       "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6", "v7",
> !       "v8",  "v9",  "v10", "v11", "v12", "v13", "v14", "v15",
> !       "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
> !       "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
>   };

vrsave again.

> --- 191,202 ----
>     "%f24",  "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
>       "mq",    "lr",  "ctr",   "ap",
>     "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
> !    "xer",
> !    /* AltiVec registers.  */
> !    "%v0",  "%v1",  "%v2",  "%v3",  "%v4",  "%v5",  "%v6", "%v7",
> !    "%v8",  "%v9",  "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
> !    "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
> !    "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31"
>   };

and again.

With these fixes I'll approve everything but the builtins, which I'm not
planning to rule on either way.  You'll have to go through and change all
the 'altivec' functional units later, but I guess you're aware of that.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 17:00     ` Dale Johannesen
@ 2001-11-06 17:06       ` Aldy Hernandez
  2001-11-13  4:33         ` Aldy Hernandez
  2001-11-13 15:03         ` Aldy Hernandez
  2001-11-13  4:33       ` Dale Johannesen
  2001-11-13 15:03       ` Dale Johannesen
  2 siblings, 2 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-06 17:06 UTC (permalink / raw)
  To: Dale Johannesen; +Cc: Geoff Keating, gcc patches

> This needs an entry for vrsave.

yes i know.  i fixed them all.  they showed up during regression testing
and i fixed them all. am retesting bootstrap plus regressions right now.

> With these fixes I'll approve everything but the builtins, which I'm not
> planning to rule on either way.  You'll have to go through and change all
> the 'altivec' functional units later, but I guess you're aware of that.

yup.  i am aware.

feel free to approve then :-)

-- 
Aldy Hernandez			E-mail: aldyh@redhat.com
Professional Gypsy
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 15:02   ` Aldy Hernandez
  2001-11-06 15:14     ` Joseph S. Myers
  2001-11-06 17:00     ` Dale Johannesen
@ 2001-11-06 17:07     ` Stan Shebs
  2001-11-06 17:15       ` Aldy Hernandez
                         ` (2 more replies)
  2001-11-13  4:33     ` Aldy Hernandez
  2001-11-13 15:03     ` Aldy Hernandez
  4 siblings, 3 replies; 152+ messages in thread
From: Stan Shebs @ 2001-11-06 17:07 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Geoff Keating, gcc-patches

Aldy Hernandez wrote:
> 
> After a few iterations I think this is finally it-- for the first
> batch of patches anyhow.

It's all looking good to me, modulo the question below.

It would be ever so slightly more convenient for Apple's next import
if vrsave were to be listed ahead of the general vector registers
instead of after (it then becomes part of the "block" of misc regs),
but we can cope with it either way.

> --- 2562,2572 ----
>       "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",           \
>        "mq",  "lr", "ctr",  "ap",                                               \
>       "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",           \
> !   "xer",                                                              \
> !      "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",             \
> !      "v8",  "v9", "v10", "v11", "v12", "v13", "v14", "v15",             \
> !     "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",             \
> !     "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"              \
>   }

Missing a "vrsave" here?

Stan

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 17:07     ` Stan Shebs
@ 2001-11-06 17:15       ` Aldy Hernandez
  2001-11-13  4:33         ` Aldy Hernandez
  2001-11-13 15:03         ` Aldy Hernandez
  2001-11-13  4:33       ` Stan Shebs
  2001-11-13 15:03       ` Stan Shebs
  2 siblings, 2 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-06 17:15 UTC (permalink / raw)
  To: Stan Shebs; +Cc: Geoff Keating, gcc patches

On Tue, 2001-11-06 at 20:07, Stan Shebs wrote:
> Aldy Hernandez wrote:
> > 
> > After a few iterations I think this is finally it-- for the first
> > batch of patches anyhow.
> 
> It's all looking good to me, modulo the question below.
> 
> It would be ever so slightly more convenient for Apple's next import
> if vrsave were to be listed ahead of the general vector registers
> instead of after (it then becomes part of the "block" of misc regs),
> but we can cope with it either way.
> 

heh.  gcc merges... i bet it's going to be a painful merge.  sorry.

would you mind changing the vrsave order yourself after this gets
committed?  i'm doing my umteenth "make bootstrap; make check" today and
i don't want to do so yet again ;)

> Missing a "vrsave" here?
> 
> Stan

yes typo.  i had already fixed it.


-- 
Aldy Hernandez			E-mail: aldyh@redhat.com
Professional Gypsy
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 13:59 ` Geoff Keating
                     ` (3 preceding siblings ...)
  2001-11-06 15:02   ` Aldy Hernandez
@ 2001-11-06 23:17   ` Richard Henderson
  2001-11-07  2:50     ` Geoff Keating
                       ` (3 more replies)
  2001-11-13  4:32   ` Geoff Keating
  2001-11-13 15:03   ` Geoff Keating
  6 siblings, 4 replies; 152+ messages in thread
From: Richard Henderson @ 2001-11-06 23:17 UTC (permalink / raw)
  To: Geoff Keating; +Cc: aldyh, gcc-patches

On Mon, Nov 05, 2001 at 01:58:06PM -0800, Geoff Keating wrote:
> > - #define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
> > + #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
> > - #define BIGGEST_ALIGNMENT 64
> > + #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)
> 
> I think you _don't_ want this to be dependent on the ABI.  Changing
> this isn't an ABI change (I hope!), which is good because...

Yes it is.  REGNO_POINTER_ALIGN(STACK_POINTER_REGNUM) == STACK_BOUNDARY.

Remember that STACK_BOUNDARY != PREFERRED_STACK_BOUNDARY, and that the
later does not help you unless you also have code to enforce stack
alignment, like we're supposed to have for x86 vector code.

> > ! /* A C expression to compute the alignment for a variables in the
> > !    local store.  TYPE is the data type, and ALIGN is the alignment
> > !    that the object would ordinarily have.  */
> > ! #define LOCAL_ALIGNMENT(TYPE, ALIGN)				\
> > ! 	((TARGET_ALTIVEC_ABI		    			\
> > ! 	  && TREE_CODE (TYPE)) == VECTOR_TYPE ? 128 : ALIGN)
> 
> ...as altivec values have to be 128-bit aligned because of the
> hardware, you don't want this ABI-dependent either.

Well, so long as you don't spill...  ;-)

> The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
> quite right:  it has to happen _only when the ABI is 'altivec'_.

I _think_ you don't have to worry about this any longer.  The ia64
eh library interface does not expose the number of registers
involved.  

We might ought to have checks added to die more gracefully if the
target adds registers, since we do statically allocate this space
and older libgcc would not be able to unwind for newer gcc code.



r~

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 16:12     ` Daniel Jacobowitz
  2001-11-06 16:46       ` Aldy Hernandez
@ 2001-11-07  2:36       ` Geoff Keating
  2001-11-13  4:33         ` Geoff Keating
  2001-11-13 15:03         ` Geoff Keating
  2001-11-13  4:33       ` Daniel Jacobowitz
  2001-11-13 15:03       ` Daniel Jacobowitz
  3 siblings, 2 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-07  2:36 UTC (permalink / raw)
  To: drow; +Cc: aldyh, dalej, gcc-patches

> Date: Tue, 6 Nov 2001 19:12:03 -0500
> From: Daniel Jacobowitz <drow@mvista.com>
> Cc: Dale Johannesen <dalej@apple.com>, gcc patches <gcc-patches@gcc.gnu.org>,
>         Geoff Keating <geoffk@cygnus.com>

> Is there any reasonable way to reflect that in the generated objects,
> then?  Is there a spare bit in the ELF header for this?

You can create a special .note section.  Using bits in the ELF header
for this is not recommended; consider the problems it causes on MIPS for
instance.

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 23:17   ` Richard Henderson
@ 2001-11-07  2:50     ` Geoff Keating
  2001-11-07  8:30       ` Aldy Hernandez
                         ` (3 more replies)
  2001-11-07  8:23     ` Aldy Hernandez
                       ` (2 subsequent siblings)
  3 siblings, 4 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-07  2:50 UTC (permalink / raw)
  To: rth; +Cc: aldyh, gcc-patches

> Date: Tue, 6 Nov 2001 23:16:48 -0800
> From: Richard Henderson <rth@redhat.com>
> Cc: aldyh@redhat.com, gcc-patches@gcc.gnu.org
> Mail-Followup-To: Richard Henderson <rth@redhat.com>,
> 	Geoff Keating <geoffk@redhat.com>, aldyh@redhat.com,
> 	gcc-patches@gcc.gnu.org
> Content-Disposition: inline
> User-Agent: Mutt/1.2.5i
> 
> On Mon, Nov 05, 2001 at 01:58:06PM -0800, Geoff Keating wrote:
> > > - #define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
> > > + #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
> > > - #define BIGGEST_ALIGNMENT 64
> > > + #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)
> > 
> > I think you _don't_ want this to be dependent on the ABI.  Changing
> > this isn't an ABI change (I hope!), which is good because...
> 
> Yes it is.  REGNO_POINTER_ALIGN(STACK_POINTER_REGNUM) == STACK_BOUNDARY.
> 
> Remember that STACK_BOUNDARY != PREFERRED_STACK_BOUNDARY, and that the
> later does not help you unless you also have code to enforce stack
> alignment, like we're supposed to have for x86 vector code.

Here I was talking about BIGGEST_ALIGNMENT only.  Changing
STACK_BOUNDARY is of course an ABI change.

> > The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
> > quite right:  it has to happen _only when the ABI is 'altivec'_.
> 
> I _think_ you don't have to worry about this any longer.  The ia64
> eh library interface does not expose the number of registers
> involved.  
> 
> We might ought to have checks added to die more gracefully if the
> target adds registers, since we do statically allocate this space
> and older libgcc would not be able to unwind for newer gcc code.

The complexities of this boggle my mind.  I think we haven't even
decided on how some of the pieces should work yet.

Can we really change the EH library interface like this?  Even in the
presence of a glibc compatibility layer to support pre-gcc3.0 C++
binaries?

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 23:17   ` Richard Henderson
  2001-11-07  2:50     ` Geoff Keating
@ 2001-11-07  8:23     ` Aldy Hernandez
  2001-11-13  4:33       ` Aldy Hernandez
  2001-11-13 15:03       ` Aldy Hernandez
  2001-11-13  4:33     ` Richard Henderson
  2001-11-13 15:03     ` Richard Henderson
  3 siblings, 2 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-07  8:23 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Geoff Keating, gcc patches

On Wed, 2001-11-07 at 02:16, Richard Henderson wrote:
> On Mon, Nov 05, 2001 at 01:58:06PM -0800, Geoff Keating wrote:
> > > - #define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
> > > + #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
> > > - #define BIGGEST_ALIGNMENT 64
> > > + #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)
> > 
> > I think you _don't_ want this to be dependent on the ABI.  Changing
> > this isn't an ABI change (I hope!), which is good because...
> 
> Yes it is.  REGNO_POINTER_ALIGN(STACK_POINTER_REGNUM) == STACK_BOUNDARY.

ok, i have reverted to my original code then:

#define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)

> > The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
> > quite right:  it has to happen _only when the ABI is 'altivec'_.
> 
> I _think_ you don't have to worry about this any longer.  The ia64
> eh library interface does not expose the number of registers
> involved.  
> 
> We might ought to have checks added to die more gracefully if the
> target adds registers, since we do statically allocate this space
> and older libgcc would not be able to unwind for newer gcc code.

so can i just up the # of DWARF_FRAME_REGISTERS without any bad side
effects?

-- 
Aldy Hernandez			E-mail: aldyh@redhat.com
Professional Gypsy
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-07  2:50     ` Geoff Keating
@ 2001-11-07  8:30       ` Aldy Hernandez
  2001-11-13  4:33         ` Aldy Hernandez
  2001-11-13 15:03         ` Aldy Hernandez
  2001-11-07 11:41       ` Richard Henderson
                         ` (2 subsequent siblings)
  3 siblings, 2 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-07  8:30 UTC (permalink / raw)
  To: Geoff Keating; +Cc: rth, gcc-patches

>>>>> "Geoff" == Geoff Keating <geoffk@geoffk.org> writes:

 >> > > + #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)
 >> > 
 >> > I think you _don't_ want this to be dependent on the ABI.  Changing
 >> > this isn't an ABI change (I hope!), which is good because...
 >> 
 >> Yes it is.  REGNO_POINTER_ALIGN(STACK_POINTER_REGNUM) == STACK_BOUNDARY.
 >> 
 >> Remember that STACK_BOUNDARY != PREFERRED_STACK_BOUNDARY, and that the
 >> later does not help you unless you also have code to enforce stack
 >> alignment, like we're supposed to have for x86 vector code.

 > Here I was talking about BIGGEST_ALIGNMENT only.  Changing
 > STACK_BOUNDARY is of course an ABI change.

Woh, my bad.  Ok, biggest_alignment remains as is.  Nothing changed
from my last post then.

Still waiting approval on patch, and guidance on DWARF_FRAME_REGISTERS.

Aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-07  2:50     ` Geoff Keating
  2001-11-07  8:30       ` Aldy Hernandez
@ 2001-11-07 11:41       ` Richard Henderson
  2001-11-07 12:12         ` Geoff Keating
                           ` (2 more replies)
  2001-11-13  4:33       ` Geoff Keating
  2001-11-13 15:03       ` Geoff Keating
  3 siblings, 3 replies; 152+ messages in thread
From: Richard Henderson @ 2001-11-07 11:41 UTC (permalink / raw)
  To: Geoff Keating; +Cc: aldyh, gcc-patches

On Wed, Nov 07, 2001 at 02:49:15AM -0800, Geoff Keating wrote:
> Here I was talking about BIGGEST_ALIGNMENT only.  Changing
> STACK_BOUNDARY is of course an ABI change.

Well, there is

  struct {
    int x __attribute__((aligned));
    int y;
  };

to name one place that BIGGEST_ALIGNMENT affects the ABI.
I suspect there are other places as well.

> Can we really change the EH library interface like this?  Even in the
> presence of a glibc compatibility layer to support pre-gcc3.0 C++
> binaries?

Pre gcc 3.0, we don't support altivec, so we don't have to worry 
about this.



r~

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-07 11:41       ` Richard Henderson
@ 2001-11-07 12:12         ` Geoff Keating
  2001-11-13  5:05           ` Geoff Keating
  2001-11-13 15:03           ` Geoff Keating
  2001-11-13  5:05         ` Richard Henderson
  2001-11-13 15:03         ` Richard Henderson
  2 siblings, 2 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-07 12:12 UTC (permalink / raw)
  To: rth; +Cc: aldyh, gcc-patches

> Date: Wed, 7 Nov 2001 11:41:11 -0800
> From: Richard Henderson <rth@redhat.com>
> Cc: aldyh@redhat.com, gcc-patches@gcc.gnu.org
> Mail-Followup-To: Richard Henderson <rth@redhat.com>,
> 	Geoff Keating <geoffk@redhat.com>, aldyh@redhat.com,
> 	gcc-patches@gcc.gnu.org
> Content-Disposition: inline
> User-Agent: Mutt/1.2.5i
> 
> On Wed, Nov 07, 2001 at 02:49:15AM -0800, Geoff Keating wrote:
> > Here I was talking about BIGGEST_ALIGNMENT only.  Changing
> > STACK_BOUNDARY is of course an ABI change.
> 
> Well, there is
> 
>   struct {
>     int x __attribute__((aligned));
>     int y;
>   };
> 
> to name one place that BIGGEST_ALIGNMENT affects the ABI.
> I suspect there are other places as well.

Hmmm.  Well, we'll see.

> > Can we really change the EH library interface like this?  Even in the
> > presence of a glibc compatibility layer to support pre-gcc3.0 C++
> > binaries?
> 
> Pre gcc 3.0, we don't support altivec, so we don't have to worry 
> about this.

Yes, but that's the question:  Can this be changed even for
non-altivec compilations?

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-03 20:37           ` Geoff Keating
@ 2001-11-13  4:26             ` Geoff Keating
  2001-11-13 13:21             ` Geoff Keating
                               ` (2 subsequent siblings)
  3 siblings, 0 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-13  4:26 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: gcc-patches

Alan Matsuoka <alanm@cygnus.com> writes:

> 2001-11-05  Alan Matsuoka  <alanm@redhat.com>
> 
>         * rtl.def (INCLUDE) : Define.
> 	* gensupport.c (init_include_reader, process_include, save_string) :  New functions to
> 	  implement an include facility in .md files.
> 	* gensupport.h : Add prototype for init_md_reader_args.
> 	* genattr.c genattrtab.c gencodes.c genconfig.c genemit.c
> 	  genextract.c genflags.c genopinit.c genoutput.c genpeep.c
> 	  genrecog.c: Change call to init_md_reader to init_md_reader_args.
> 	* md.texi: Document (include "path") and -I directives for RTL generation tools.

The patch is OK.

When you commit, please fix the whitespace and line-wrap the ChangeLog
entry to 80 columns.

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-05 21:37             ` Alan Matsuoka
@ 2001-11-13  4:32               ` Alan Matsuoka
  2001-11-13 15:03               ` Alan Matsuoka
  1 sibling, 0 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Geoff Keating, gcc patches

On Mon, 05 Nov 2001, Aldy Hernandez wrote:

> is it recursive?  i mean, can you include files from within include
> files?

If you mean nested includes yes. If you mean mutually recursive or self 
recursive references, no.


Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 18:30   ` Aldy Hernandez
  2001-11-06 16:12     ` Daniel Jacobowitz
@ 2001-11-13  4:32     ` Aldy Hernandez
  2001-11-13 15:03     ` Aldy Hernandez
  2 siblings, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Dale Johannesen; +Cc: gcc patches, Geoff Keating

>>>>> "Dale" == Dale Johannesen <dalej@apple.com> writes:

 > This is getting better.

Thanks ;-)

 > I'd really like to see vrsave in the enums and register macros
 > (not necessarily the code).  I dislike making a major change to
 > an area if we know it's going to change again shortly.

That was supposed to be tommorrow's work.... :)

 > If you plan to support linking files compiled with and without
 > -fabi=altivec,

nope we don't.  You can't just link too different abi's.

 >> +       /* Print AltiVec memory operand.  */
 >> +     case 'y':
 >> +       {
 >> + 	rtx tmp;
 >> +
 >> + 	if (GET_CODE (x) != MEM)
 >> + 	  abort ();
 >> +
 >> + 	tmp = XEXP (x, 0);
 >> +
 >> + 	if (GET_CODE (tmp) == REG)
 >> + 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
 >> + 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
 >> + 	  {
 >> + 	    if (REGNO (XEXP (tmp, 0)) == 0)
 >> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
 >> + 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
 >> + 	    else
 >> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
 >> + 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
 >> + 	  }
 >> + 	else
 >> + 	  abort ();
 >> + 	break;
 >> +       }

 > I guess this is OK.  Apple/Moto version doesn't have any analogous change
 > here; the patterns in rs6000.md match more elaborate MEM subpatterns,
 > to do the checking that you do here.  Isn't it generally considered
 > preferable
 > to use the existing pattern mechanism whenever possible?

What I do is have some legitimize_address hackery that will transform
incorrect memory addresses into something altivec memory addressing
can handle (mem (plus reg reg)), and then handle [reg+reg] and [reg]
as the %y print operand.

I dislike the idea of having lots of variants of memory addressing in
the MD file.  It seems cleaner to have just memory_operand() and then
have %operands print them out pretty :).

Aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 19:27   ` Aldy Hernandez
  2001-11-05 20:10     ` Geoff Keating
@ 2001-11-13  4:32     ` Aldy Hernandez
  2001-11-13 15:03     ` Aldy Hernandez
  2 siblings, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Geoff Keating; +Cc: gcc-patches

>>>>> "Geoff" == Geoff Keating <geoffk@geoffk.org> writes:

 >> ! #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)

 > I think you _don't_ want this to be dependent on the ABI.  Changing
 > this isn't an ABI change (I hope!), which is good because...

Fixed.  Set to 128 unconditionally.

 >> ! 
 >> ! /* A C expression to compute the alignment for a variables in the
 >> !    local store.  TYPE is the data type, and ALIGN is the alignment
 >> !    that the object would ordinarily have.  */
 >> ! #define LOCAL_ALIGNMENT(TYPE, ALIGN)				\
 >> ! 	((TARGET_ALTIVEC_ABI		    			\
 >> ! 	  && TREE_CODE (TYPE)) == VECTOR_TYPE ? 128 : ALIGN)

 > ..as altivec values have to be 128-bit aligned because of the
 > hardware, you don't want this ABI-dependent either.

Fixed.  Set to TARGET_ALTIVEC.  Actually, that's ambiguous because you
shouldn't have vector types unless you are in altivec mode, but it
won't hurt.

 > The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
 > quite right:  it has to happen _only when the ABI is 'altivec'_.

I took it out because it needs rethinking.  DWARF_FRAME_REGISTERS is
used as an array size in a few places, particulary unwind-dw2.c.  So I
need to change all these places to dynamically allocate their space.

 > This will be a bit tricky because DWARF_FRAME_REGISTERS is also used
 > in libgcc, so you have to #define something when the Altivec ABI is
 > chosen, and then key off that if IN_LIBGCC2.

 > I wonder if you could assume that the integrated cpplib will always be
 > used when compiling libgcc?  That would make things easier, because
 > then you wouldn't have muck with specs so much.

Please explain.  I only see DWARF_FRAME_REGISTERS being used in
dwarf2out.c and unwind-dw2.c.  There is nothing in libgcc*.

 >> !    /* AltiVec registers.  */			   \
 >> !    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
 >> !    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  \
 >> ! }

 > This is correct, but doesn't there need to be a change to them in
 > CONDITIONAL_REGISTER_USAGE when the altivec ABI is chosen (in which
 > some altivec registers are call-saved)?

And there already is: :)

  if (TARGET_ALTIVEC_ABI)
    for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
      call_used_regs[i] = 1;

 > These should be based off FIRST_ALTIVEC_REGISTER rather than being
 > magic numbers...

Fixed.

 >> /* Return registers */
 >> #define GP_ARG_RETURN GP_ARG_MIN_REG
 >> #define FP_ARG_RETURN FP_ARG_MIN_REG
 >> + #define ALTIVEC_ARG_RETURN 79

 > .. this too.

Fixed.

 >> #undef	STACK_BOUNDARY
 >> ! #define	STACK_BOUNDARY	64
 >> 
 >> /* Real stack boundary as mandated by the appropriate ABI.  */
 >> ! #define ABI_STACK_BOUNDARY ((TARGET_EABI) ? 64 : 128)
 >> 
 >> /* No data type wants to be aligned rounder than this.  */
 >> #undef	BIGGEST_ALIGNMENT
 >> ! #define BIGGEST_ALIGNMENT ((TARGET_EABI) ? 64 : 128)
 >> 
 >> #undef  BIGGEST_FIELD_ALIGNMENT
 >> #undef  ADJUST_FIELD_ALIGN
 >> - #undef  ROUND_TYPE_ALIGN
 >> 
 >> /* Use ELF style section commands.  */
 >> 
 >> --- 400,430 ----
 >> one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
 >> versions, just use 64 as the stack boundary.  */
 >> #undef	STACK_BOUNDARY
 >> ! #define	STACK_BOUNDARY	(TARGET_ALTIVEC_ABI ? 128 : 64)
 >> 
 >> /* Real stack boundary as mandated by the appropriate ABI.  */
 >> ! #define ABI_STACK_BOUNDARY ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
 >> 
 >> /* No data type wants to be aligned rounder than this.  */
 >> #undef	BIGGEST_ALIGNMENT
 >> ! #define BIGGEST_ALIGNMENT ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
 >> 
 >> + /* An expression for the alignment of a structure field FIELD if the
 >> +    alignment computed in the usual way is COMPUTED.  */
 >> + #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)				      \
 >> + 	((TARGET_ALTIVEC_ABI && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
 >> + 	 ? 128 : COMPUTED)
 >> + 
 >> + /* Define this macro as an expression for the alignment of a type
 >> +    (given by TYPE as a tree node) if the alignment computed in the
 >> +    usual way is COMPUTED and the alignment explicitly specified was
 >> +    SPECIFIED.  */
 >> + #define ROUND_TYPE_ALIGN(TYPE, COMPUTED, SPECIFIED)			\
 >> + 	((TARGET_ALTIVEC_ABI && TREE_CODE (TYPE) == VECTOR_TYPE)	\
 >> + 	 ? 128 : MAX (COMPUTED, SPECIFIED))
 >> + 
 >> #undef  BIGGEST_FIELD_ALIGNMENT
 >> #undef  ADJUST_FIELD_ALIGN
 >> 
 >> /* Use ELF style section commands.  */

 > This has the same comment as the equivalent stuff in rs6000.h.

Huh?  What do you mean?

 >> *************** function_arg_advance (cum, mode, type, n
 >> *** 2159,2165 ****
 >> {
 cum-> nargs_prototype--;
 >> 
 >> !   if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
 >> {
 >> if (TARGET_HARD_FLOAT
 >> && (mode == SFmode || mode == DFmode))
 >> --- 2242,2255 ----
 >> {
 cum-> nargs_prototype--;
 >> 
 >> !   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
 >> !     {
 >> !       if (cum->vregno <= ALTIVEC_ARG_MAX_REG)
 >> ! 	cum->vregno++;
 >> !       else
 >> ! 	cum->words += RS6000_ARG_SIZE (mode, type);
 >> !     }

 > Something you might not have seen in the ABI documentation: unnamed
 > vector arguments (passed to varargs functions after the '...') get
 > passed in memory, not in registers.  (I don't remember if this is just
 > the unnamed arguments or all the arguments to varargs functions, you
 > should check.)

This is just for unnamed arguments in varargs.  So I'll have to add:

        if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
done. (?)

 >> +       /* Print AltiVec memory operand.  */
 >> +     case 'y':
 >> +       {
 >> + 	rtx tmp;
 >> + 
 >> + 	if (GET_CODE (x) != MEM)
 >> + 	  abort ();
 >> + 
 >> + 	tmp = XEXP (x, 0);
 >> + 
 >> + 	if (GET_CODE (tmp) == REG)
 >> + 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
 >> + 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
 >> + 	  {
 >> + 	    if (REGNO (XEXP (tmp, 0)) == 0)
 >> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
 >> + 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
 >> + 	    else
 >> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
 >> + 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
 >> + 	  }
 >> + 	else
 >> + 	  abort ();
 >> + 	break;
 >> +       }

 > Do you really need this?  It looks just like the way a normal memory
 > operand is printed (for the cases that are allowed for altivec).

Yes I do.  I want "[reg+reg]" to be outputed as "reg,reg" and [reg] to
be outputed as "reg,0".

Consider "lvx d,a,b".  I want to match:

        (set (reg) (mem))

and have (mem) be dumped as "a,b" (the two registers in the memory
address: (plus (reg) (reg))).  And I make sure that addresses get
canonicalized into (mem (reg)) and (mem (plus (reg) (reg))) with
LEGITIM* code.

 > Can you put the altivec insns in their own .md file and use the include
 > mechanism?  I believe this is what it was intended for.

As soon as you approve Alan's patch, yes :).

 >> + ;; No code is needed to copy between vector registers.
 >> + (define_insn "*altivec_vec_move"
 >> +   [(set (match_operand 0 "altivec_register" "=v")
 >> + 	(match_operand 1 "altivec_register" "v"))]
 >> +   "TARGET_ALTIVEC"
 >> +   ""
 >> +   [(set_attr "type" "altivec")])

 > Um, that can't possibly be right.  Also, it should be part of
 > movv4si_internal, because reload needs all the move insns to be the
 > same pattern.

What the hell was that all about?  I should get my cvs access revoked
for that one.  I dunno how that make it there.  M-x doctor

 >> + ;; Vector move instructions.
 >> + (define_expand "movv4si"
 >> +   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
 >> + 	(match_operand:V4SI 1 "any_operand" ""))]
 >> +   "TARGET_ALTIVEC"
 >> +   "{ rs6000_emit_move (operands[0], operands[1], V4SImode); DONE; }")
 >> + 
 >> + (define_insn "*movv4si_internal"
 >> +   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v")
 >> + 	(match_operand:V4SI 1 "input_operand" "v,m"))]
 >> +   "TARGET_ALTIVEC"
 >> +   "@
 >> +    stvx\t%1,%y0
 >> +    ldvx\t%0,%y1"
 >> +   [(set_attr "type" "altivec")])

 > Yes---this needs an alternative to copy a 'v' into a 'v'.  All the
 > ones below probably need it too.

Will do.

Aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 14:31   ` Stan Shebs
  2001-11-05 14:49     ` Geoff Keating
@ 2001-11-13  4:32     ` Stan Shebs
  2001-11-13 15:03     ` Stan Shebs
  2 siblings, 0 replies; 152+ messages in thread
From: Stan Shebs @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Geoff Keating; +Cc: aldyh, gcc-patches

Geoff Keating wrote:
> 
> The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
> quite right:  it has to happen _only when the ABI is 'altivec'_.
> 
> This will be a bit tricky because DWARF_FRAME_REGISTERS is also used
> in libgcc, so you have to #define something when the Altivec ABI is
> chosen, and then key off that if IN_LIBGCC2.

Thus we slide down the slippery slope... Solving this completely
eventually entails having a method to detect whether the CPU
supports AltiVec instructions - in the case of a C++ throw
in code using AltiVec registers, you need to detect dynamically
(Apple's GCC uses a bit set by the kernel) whether you're on a
G4 or a not-G4.  So you may have to generate a frame descriptor
that mentions registers you won't actually manipulate on a not-G4.

Our GCC just sets DWARF_FRAME_REGISTERS to FIRST_PSEUDO_REGISTERS
unconditionally, seems to work well enough for non-AltiVec code.

Stan

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-06  0:23           ` Gerald Pfeifer
@ 2001-11-13  4:32             ` Gerald Pfeifer
  2001-11-13 15:03             ` Gerald Pfeifer
  1 sibling, 0 replies; 152+ messages in thread
From: Gerald Pfeifer @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: gcc-patches

On Mon, 5 Nov 2001, Alan Matsuoka wrote:
> 2001-11-05  Alan Matsuoka  <alanm@redhat.com>
>
>         * rtl.def (INCLUDE) : Define.
> 	* gensupport.c (init_include_reader, process_include, save_string) :  New functions to

This...

> 	  implement an include facility in .md files.
> 	* gensupport.h : Add prototype for init_md_reader_args.
> 	* genattr.c genattrtab.c gencodes.c genconfig.c genemit.c
> 	  genextract.c genflags.c genopinit.c genoutput.c genpeep.c
> 	  genrecog.c: Change call to init_md_reader to init_md_reader_args.
> 	* md.texi: Document (include "path") and -I directives for RTL generation tools.

...and this lines are to long.  (Lines in ChangeLogs and code should not
exceed, say, 77 characters, and definitely must not exceed 80 characters.)

There are a couple of similiar issues in the patch itself.

Gerald
-- 
Gerald "Jerry" pfeifer@dbai.tuwien.ac.at http://www.dbai.tuwien.ac.at/~pfeifer/


^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 13:04   ` Aldy Hernandez
  2001-11-05 13:17     ` Joseph S. Myers
@ 2001-11-13  4:32     ` Aldy Hernandez
  2001-11-13 15:03     ` Aldy Hernandez
  2 siblings, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc patches

On Mon, 2001-11-05 at 15:59, Joseph S. Myers wrote:
> On 5 Nov 2001, Aldy Hernandez wrote:
> 
> > + @item -mabi=altivec
> > + @opindex mabi=altivec
> > + Extend the current ABI with AltiVec ABI extensions.  This does not
> > + change the default ABI, instead it adds the AltiVec ABI extensions to
> > + the current ABI.
> 
> That should end "ABI@." so that spacing after the sentence is correct if
> more text gets added to that paragraph later.

huh?  i've never heard that.

where are the .texi docs?  i'm bound to make more mistakes if i don't
read the texi docs :)
> 
> -- 
> Joseph S. Myers
> jsm28@cam.ac.uk
-- 
Aldy Hernandez			E-mail: aldyh@redhat.com
Professional Gypsy
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* altivec patches
  2001-11-05 12:52 altivec patches Aldy Hernandez
                   ` (4 preceding siblings ...)
  2001-11-05 14:39 ` Dale Johannesen
@ 2001-11-13  4:32 ` Aldy Hernandez
  2001-11-13 15:03 ` Aldy Hernandez
  6 siblings, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13  4:32 UTC (permalink / raw)
  To: gcc patches; +Cc: Geoff Keating

finally...

i have fixed everything that was commented on.
alignment macros are in place, a new abi extension (TARGET_ALTIVEC_ABI),
documentation, etc. 

i have not documented the builtins because i'm going to write a script
to generate those automagially later.  besides, there's pretty much a
1:1 correspondence between the altivec insns and the builtin names 

i have added an option "-mabi=altivec" that enhances the current abi
with altivec ABI extensions.  this flag does NOT replace the current
abi, but extends the current abi to handle altivec extensions as
documented by the motorola manuals. 

i have promised geoff i will rewrite the -mcall-foo hackery and
implement "-mabi=sysv,eabi,altivec" style abi flags.  i will do this
after i'm done with the altivec stuff.  i don't want to diverge the
purpose of this patch into unrelated abi functionality.  right now
-mabi= only supports -mabi=altivec. 
what is left?
    - the rest of the gazillion builtins
    
    - varargs
    
    - frame stuff: epilogue, prologue, vrsave
    - <altivec.h> for the user.  this .h will implement the overloaded
    altivec functions described in the "altivec programming interface
    model".  Stuff like generic (overloaded) "vec_add(veca, vecb)". 
    
    - test cases.  i will commit a few simple tests, but serious tests
    will come after i'm done playing with the G3 box. 
    
and then there's the front end changes, but that's a different story. 

i have tested this on powerpc-unknown-linux-gnu.  it bootstraps.  no
regressions on testsuite. 

the patch below has the boring builtin stuff deleted (as requested). 
there's just 1 or 2 builtins for proof of concept. 

ok to install? 
2001-11-05  Aldy Hernandez  <aldyh@redhat.com>

	* doc/invoke.texi: Add -maltivec, -mno-altivec, and -mabi=altivec
	for rs6000.

	* config/rs6000/rs6000.h (MASK_ALTIVEC): New.
	(TARGET_ALTIVEC): New.
	(TARGET_SWITCHES): Add altivec.
	(FIRST_PSEUDO_REGISTER): Change to 109.
	(CALL_USED_REGISTERS): Same.
	(FIRST_ALTIVEC_REGNO): New.
	(LAST_ALTIVEC_REGNO): New.
	(ALTIVEC_REGNO_P): New.
	(UNITS_PER_ALTIVEC_WORD): New.
	(ALTIVEC_VECTOR_MODE): New.
	(FIXED_REGISTERS): Add altivec registers.
	(REG_ALLOC_ORDER): Same.
	(HARD_REGNO_NREGS): Adjust for altivec registers.
	(HARD_REGNO_MODE_OK): Same.
	(MODES_TIEABLE_P): Same.
	(REGISTER_MOVE_COST): Same.
	(REGNO_REG_CLASS): Same.
	(reg_class): Add ALTIVEC_REGS.
	(REG_CLASS_NAMES): Same.
	(REG_CLASS_CONTENTS): Same.
	(REG_CLASS_FROM_LETTER): Add 'v' constraint for ALTIVEC_REGS.
	(ALTIVEC_ARG_RETURN): New.
	(FUNCTION_VALUE): Handle VECTOR_TYPE.
	(LIBCALL_VALUE): Handle altivec vector modes.
	(VECTOR_MODE_SUPPORTED_P): New.
	(ALTIVEC_ARG_MIN_REG): New.
	(ALTIVEC_ARG_MAX_REG): New.
	(ALTIVEC_ARG_NUM_REG): New.
	(FUNCTION_VALUE_REGNO_P): Return true for altivec return register.
	(FUNCTION_ARG_REGNO_P): Support passing args in altivec registers.
	(REGISTER_NAMES): Add altivec regs.
	(DEBUG_REGISTER_NAMES): Same.
	(ADDITIONAL_REGISTER_NAMES): Same.
	(rs6000_builtins): New.
	(MD_EXPAND_BUILTIN): New.
	(MD_INIT_BUILTINS): New.
	(LEGITIMATE_OFFSET_ADDRESS_P): This addressing mode is not valid
	for AltiVec instructions.
	(LEGITIMATE_LO_SUM_ADDRESS_P): Same.
	(HARD_REGNO_MODE_OK): Altivec modes can only go in altivec
	registers.
	(SECONDARY_MEMORY_NEEDED): We need memory to copy vector modes.
	(PREDICATE_CODES): Add altivec_register.
	(TARGET_SWITCHES): Add no-altivec.
	(DATA_ALIGNMENT): Align vectors to 128 bits.
	(TARGET_OPTIONS): Add abi= option.
	Add rs6000_abi_string extern.
	(LOCAL_ALIGNMENT): New.
	(CPP_CPU_SPEC): Define __ALTIVEC__ when -maltivec.
	(MASK_ALTIVEC_ABI): New.
	(TARGET_ALTIVEC_ABI): New.
	(CONDITIONAL_REGISTER_USAGE): Set first 20 AltiVec registers to
	call-saved.
	(STACK_BOUNDARY): Adjust for altivec.
	(BIGGEST_ALIGNMENT): Same.
	(rs6000_args): Add vregno.
	(USE_ALTIVEC_FOR_ARG_P): New.
	
	* config/rs6000/sysv4.h (STACK_BOUNDARY): Adjust for altivec.
	(ABI_STACK_BOUNDARY): Same.
	(BIGGEST_ALIGNMENT): Same.
	(ADJUST_FIELD_ALIGN): Remove undef.  Define anew.
	(ROUND_TYPE_ALIGN): Same.
	
	* config/rs6000/rs6000.c (rs6000_expand_builtin): New.
	(altivec_expand_builtin): New.
	(altivec_init_builtins): New.
	(TARGET_EXPAND_BUILTIN): New.
	(TARGET_INIT_BUILTINS): New.
	(rs6000_init_builtins): New.
	(struct builtin_description): New.
	(bdesc_2arg): New.
	(rs6000_reg_names): Add altivec registers.
	(alt_reg_names): Same.
	(altivec_register): New.
	(secondary_reload_class): Altivec regs can hold altivec regs and
	memory.
	(rs6000_emit_move): Force constants into memory for AltiVec moves.
	(print_operand): Add 'y' case for printing altivec memory
	operands.
	(rs6000_legitimize_address): Legitimize vector addresses into
	[REG+REG] or [REG].
	(altivec_expand_binop_builtin): New.
	New string rs6000_current_abi.
	(rs6000_override_options): Call rs6000_parse_abi_options.
	(rs6000_parse_abi_options): New.
	(function_arg_boundary): Vector arguments must be 16
	byte aligned.
	(function_arg_advance): Handle vector arguments.
	(function_arg_partial_nregs): Same.
	(init_cumulative_args): Same.
	(function_arg): Same.

	* config/rs6000/rs6000.md (altivec_lvx): New.
	(type): Add altivec attribute.
	(*altivec_vec_move): New.
	(movv4si): New.
	(*movv4si_internal): New.
	(movv16qi): New.
	(*movv16qi_internal): New.
	(movv8hi): New.
	(*movv8hi_internal1): New.
	(movv4sf): New.
	(*movv4sf_internal1): New.
	(altivec_stvx): New.
	(vaddubm): New.

--builtins changelog removed--
	
	Index: doc/invoke.texi
===================================================================
RCS file: /cvs/uberbaum/gcc/doc/invoke.texi,v
retrieving revision 1.69
diff -c -p -r1.69 invoke.texi
*** invoke.texi	2001/10/28 19:12:12	1.69
--- invoke.texi	2001/11/05 19:49:18
*************** in the following sections.
*** 424,429 ****
--- 424,430 ----
  -mtune=@var{cpu-type} @gol
  -mpower  -mno-power  -mpower2  -mno-power2 @gol
  -mpowerpc  -mpowerpc64  -mno-powerpc @gol
+ -maltivec -mno-altivec @gol
  -mpowerpc-gpopt  -mno-powerpc-gpopt @gol
  -mpowerpc-gfxopt  -mno-powerpc-gfxopt @gol
  -mnew-mnemonics  -mold-mnemonics @gol
*************** in the following sections.
*** 436,441 ****
--- 437,443 ----
  -mno-relocatable  -mrelocatable-lib  -mno-relocatable-lib @gol
  -mtoc  -mno-toc -mlittle  -mlittle-endian  -mbig  -mbig-endian @gol
  -mcall-aix -mcall-sysv -mcall-netbsd @gol
+ -mabi=altivec @gol
  -mprototype  -mno-prototype @gol
  -msim  -mmvme  -mads  -myellowknife  -memb -msdata @gol
  -msdata=@var{opt}  -mvxworks -G @var{num}}
*************** values for @var{cpu_type} are used for @
*** 6677,6682 ****
--- 6679,6693 ----
  architecture, registers, and mnemonics set by @option{-mcpu}, but the
  scheduling parameters set by @option{-mtune}.
  
+ @item -maltivec
+ @itemx -mno-altivec
+ @opindex maltivec
+ @opindex mno-altivec
+ These switches enable or disable the use of built-in functions that
+ allow access to the AltiVec instruction set.  You may also need to set
+ @option{-mabi=altivec} to adjust the current ABI with AltiVec ABI
+ enhancements.
+ 
  @item -mfull-toc
  @itemx -mno-fp-in-toc
  @itemx -mno-sum-in-toc
*************** Linux-based GNU system.
*** 6904,6909 ****
--- 6915,6926 ----
  @opindex mcall-netbsd
  On System V.4 and embedded PowerPC systems compile code for the
  NetBSD operating system.
+ 
+ @item -mabi=altivec
+ @opindex mabi=altivec
+ Extend the current ABI with AltiVec ABI extensions.  This does not
+ change the default ABI, instead it adds the AltiVec ABI extensions to
+ the current ABI.
  
  @item -mprototype
  @itemx -mno-prototype
Index: rs6000.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.130
diff -c -p -r1.130 rs6000.h
*** rs6000.h	2001/10/02 03:36:44	1.130
--- rs6000.h	2001/11/05 19:49:23
*************** Boston, MA 02111-1307, USA.  */
*** 83,89 ****
  %{mcpu=801: -D_ARCH_PPC} \
  %{mcpu=821: -D_ARCH_PPC} \
  %{mcpu=823: -D_ARCH_PPC} \
! %{mcpu=860: -D_ARCH_PPC}"
  
  /* Common ASM definitions used by ASM_SPEC among the various targets
     for handling -mcpu=xxx switches.  */
--- 83,90 ----
  %{mcpu=801: -D_ARCH_PPC} \
  %{mcpu=821: -D_ARCH_PPC} \
  %{mcpu=823: -D_ARCH_PPC} \
! %{mcpu=860: -D_ARCH_PPC} \
! %{maltivec: -D__ALTIVEC__}"
  
  /* Common ASM definitions used by ASM_SPEC among the various targets
     for handling -mcpu=xxx switches.  */
*************** extern int target_flags;
*** 209,214 ****
--- 210,221 ----
  /* Nonzero if we need to schedule the prolog and epilog.  */
  #define MASK_SCHED_PROLOG	0x00040000
  
+ /* Use AltiVec instructions.  */
+ #define MASK_ALTIVEC		0x00080000
+ 
+ /* Enhance the current ABI with AltiVec extensions.  */
+ #define MASK_ALTIVEC_ABI	0x00100000
+ 
  #define TARGET_POWER		(target_flags & MASK_POWER)
  #define TARGET_POWER2		(target_flags & MASK_POWER2)
  #define TARGET_POWERPC		(target_flags & MASK_POWERPC)
*************** extern int target_flags;
*** 227,232 ****
--- 234,241 ----
  #define TARGET_NO_UPDATE	(target_flags & MASK_NO_UPDATE)
  #define TARGET_NO_FUSED_MADD	(target_flags & MASK_NO_FUSED_MADD)
  #define TARGET_SCHED_PROLOG	(target_flags & MASK_SCHED_PROLOG)
+ #define TARGET_ALTIVEC		(target_flags & MASK_ALTIVEC)
+ #define TARGET_ALTIVEC_ABI	(target_flags & MASK_ALTIVEC_ABI)
  
  #define TARGET_32BIT		(! TARGET_64BIT)
  #define TARGET_HARD_FLOAT	(! TARGET_SOFT_FLOAT)
*************** extern int target_flags;
*** 282,287 ****
--- 291,300 ----
  			N_("Use PowerPC-64 instruction set")},		\
    {"no-powerpc64",	- MASK_POWERPC64,				\
  			N_("Don't use PowerPC-64 instruction set")},	\
+   {"altivec",		MASK_ALTIVEC,					\
+ 			N_("Use AltiVec instructions.")},		\
+   {"no-altivec",	- MASK_ALTIVEC,					\
+ 			N_("Don't use AltiVec instructions.")},	\
    {"new-mnemonics",	MASK_NEW_MNEMONICS,				\
  			N_("Use new mnemonics for PowerPC architecture")},\
    {"old-mnemonics",	-MASK_NEW_MNEMONICS,				\
*************** extern enum processor_type rs6000_cpu;
*** 409,414 ****
--- 422,428 ----
     {"tune=", &rs6000_select[2].string,					\
      N_("Schedule code for given CPU") },				\
     {"debug=", &rs6000_debug_name, N_("Enable debug output") },		\
+    {"abi=", &rs6000_abi_string, N_("Specify ABI to use") },		\
     SUBTARGET_OPTIONS							\
  }
  
*************** struct rs6000_cpu_select
*** 424,430 ****
  extern struct rs6000_cpu_select rs6000_select[];
  
  /* Debug support */
! extern const char *rs6000_debug_name;		/* Name for -mdebug-xxxx option */
  extern int rs6000_debug_stack;		/* debug stack applications */
  extern int rs6000_debug_arg;		/* debug argument handling */
  
--- 438,445 ----
  extern struct rs6000_cpu_select rs6000_select[];
  
  /* Debug support */
! extern const char *rs6000_debug_name;	/* Name for -mdebug-xxxx option */
! extern const char *rs6000_abi_string;	/* for -mabi={sysv,darwin,solaris,eabi,aix,altivec} */
  extern int rs6000_debug_stack;		/* debug stack applications */
  extern int rs6000_debug_arg;		/* debug argument handling */
  
*************** extern int rs6000_debug_arg;		/* debug a
*** 505,510 ****
--- 520,526 ----
  #define UNITS_PER_WORD (! TARGET_POWERPC64 ? 4 : 8)
  #define MIN_UNITS_PER_WORD 4
  #define UNITS_PER_FP_WORD 8
+ #define UNITS_PER_ALTIVEC_WORD 16
  
  /* Type used for ptrdiff_t, as a string used in a declaration.  */
  #define PTRDIFF_TYPE "int"
*************** extern int rs6000_debug_arg;		/* debug a
*** 569,581 ****
  #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
  
  /* Boundary (in *bits*) on which stack pointer should be aligned.  */
! #define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
  
  /* Allocation boundary (in *bits*) for the code of a function.  */
  #define FUNCTION_BOUNDARY 32
  
  /* No data type wants to be aligned rounder than this.  */
! #define BIGGEST_ALIGNMENT 64
  
  /* Handle #pragma pack.  */
  #define HANDLE_PRAGMA_PACK 1
--- 585,604 ----
  #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
  
  /* Boundary (in *bits*) on which stack pointer should be aligned.  */
! #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
  
  /* Allocation boundary (in *bits*) for the code of a function.  */
  #define FUNCTION_BOUNDARY 32
  
  /* No data type wants to be aligned rounder than this.  */
! #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)
! 
! /* A C expression to compute the alignment for a variables in the
!    local store.  TYPE is the data type, and ALIGN is the alignment
!    that the object would ordinarily have.  */
! #define LOCAL_ALIGNMENT(TYPE, ALIGN)				\
! 	((TARGET_ALTIVEC_ABI		    			\
! 	  && TREE_CODE (TYPE)) == VECTOR_TYPE ? 128 : ALIGN)
  
  /* Handle #pragma pack.  */
  #define HANDLE_PRAGMA_PACK 1
*************** extern int rs6000_debug_arg;		/* debug a
*** 594,602 ****
    (TREE_CODE (EXP) == STRING_CST	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
! /* Make arrays of chars word-aligned for the same reasons.  */
  #define DATA_ALIGNMENT(TYPE, ALIGN)		\
!   (TREE_CODE (TYPE) == ARRAY_TYPE		\
     && TYPE_MODE (TREE_TYPE (TYPE)) == QImode	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
--- 617,627 ----
    (TREE_CODE (EXP) == STRING_CST	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
! /* Make arrays of chars word-aligned for the same reasons.
!    Align vectors to 128 bits.  */
  #define DATA_ALIGNMENT(TYPE, ALIGN)		\
!   (TREE_CODE (TYPE) == VECTOR_TYPE ? 128	\
!    : TREE_CODE (TYPE) == ARRAY_TYPE		\
     && TYPE_MODE (TREE_TYPE (TYPE)) == QImode	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
*************** extern int rs6000_debug_arg;		/* debug a
*** 634,640 ****
     a register, in order to work around problems in allocating stack storage
     in inline functions.  */
  
! #define FIRST_PSEUDO_REGISTER 77
  
  /* This must not decrease, for backwards compatibility.  If
     FIRST_PSEUDO_REGISTER increases, this should as well.  */
--- 659,665 ----
     a register, in order to work around problems in allocating stack storage
     in inline functions.  */
  
! #define FIRST_PSEUDO_REGISTER 109
  
  /* This must not decrease, for backwards compatibility.  If
     FIRST_PSEUDO_REGISTER increases, this should as well.  */
*************** extern int rs6000_debug_arg;		/* debug a
*** 655,661 ****
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1}
  
  /* 1 for registers not available across function calls.
     These must include the FIXED_REGISTERS and also any
--- 680,690 ----
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1,	   \
!    /* AltiVec registers.  */			   \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  \
! }
  
  /* 1 for registers not available across function calls.
     These must include the FIXED_REGISTERS and also any
*************** extern int rs6000_debug_arg;		/* debug a
*** 669,675 ****
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1}
  
  #define MQ_REGNO     64
  #define CR0_REGNO    68
--- 698,709 ----
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1,	   \
!    /* AltiVec registers.  */			   \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  \
! }
! 
  
  #define MQ_REGNO     64
  #define CR0_REGNO    68
*************** extern int rs6000_debug_arg;		/* debug a
*** 679,684 ****
--- 713,720 ----
  #define CR4_REGNO    72
  #define MAX_CR_REGNO 75
  #define XER_REGNO    76
+ #define FIRST_ALTIVEC_REGNO	77
+ #define LAST_ALTIVEC_REGNO	108
  
  /* List the order in which to allocate registers.  Each register must be
     listed once, even those in FIXED_REGISTERS.
*************** extern int rs6000_debug_arg;		/* debug a
*** 701,708 ****
  	mq		(not saved; best to use it if we can)
  	ctr		(not saved; when we have the choice ctr is better)
  	lr		(saved)
!         cr5, r1, r2, ap, xer (fixed)  */
  
  #define REG_ALLOC_ORDER					\
    {32, 							\
     45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34,	\
--- 737,753 ----
  	mq		(not saved; best to use it if we can)
  	ctr		(not saved; when we have the choice ctr is better)
  	lr		(saved)
!         cr5, r1, r2, ap, xer (fixed)
  
+ 	AltiVec registers:
+ 	v0 - v1         (not saved or used for anything)
+ 	v13 - v3        (not saved; incoming vector arg registers)
+ 	v2              (not saved; incoming vector arg reg; return value)
+ 	v19 - v14       (not saved or used for anything)
+ 	v31 - v20       (saved; order given to save least number)
+ */
+ 						
+ 
  #define REG_ALLOC_ORDER					\
    {32, 							\
     45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34,	\
*************** extern int rs6000_debug_arg;		/* debug a
*** 716,722 ****
     31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19,	\
     18, 17, 16, 15, 14, 13, 12,				\
     64, 66, 65, 						\
!    73, 1, 2, 67, 76}
  
  /* True if register is floating-point.  */
  #define FP_REGNO_P(N) ((N) >= 32 && (N) <= 63)
--- 761,774 ----
     31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19,	\
     18, 17, 16, 15, 14, 13, 12,				\
     64, 66, 65, 						\
!    73, 1, 2, 67, 76,					\
!    /* AltiVec registers.  */				\
!    77, 78,						\
!    90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80,		\
!    79,							\
!    96, 95, 94, 93, 92, 91,				\
!    108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97 \
! }
  
  /* True if register is floating-point.  */
  #define FP_REGNO_P(N) ((N) >= 32 && (N) <= 63)
*************** extern int rs6000_debug_arg;		/* debug a
*** 733,738 ****
--- 785,793 ----
  /* True if register is the XER register.  */
  #define XER_REGNO_P(N) ((N) == XER_REGNO)
  
+ /* True if register is an AltiVec register.  */
+ #define ALTIVEC_REGNO_P(N) ((N) >= FIRST_ALTIVEC_REGNO && (N) <= LAST_ALTIVEC_REGNO)
+ 
  /* Return number of consecutive hard regs needed starting at reg REGNO
     to hold something of mode MODE.
     This is ordinarily the length in words of a value of mode MODE
*************** extern int rs6000_debug_arg;		/* debug a
*** 744,751 ****
--- 799,821 ----
  #define HARD_REGNO_NREGS(REGNO, MODE)					\
    (FP_REGNO_P (REGNO)							\
     ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
+    : ALTIVEC_REGNO_P (REGNO)						\
+    ? ((GET_MODE_SIZE (MODE) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD) \
     : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
  
+ #define ALTIVEC_VECTOR_MODE(MODE)	\
+ 	((MODE) == V16QImode		\
+ 	 || (MODE) == V8HImode		\
+ 	 || (MODE) == V4SFmode		\
+ 	 || (MODE) == V4SImode)
+ 
+ /* Define this macro to be nonzero if the port is prepared to handle
+    insns involving vector mode MODE.  At the very least, it must have
+    move patterns for this mode.  */
+ 
+ #define VECTOR_MODE_SUPPORTED_P(MODE)	\
+ 	(TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE))
+ 
  /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
     For POWER and PowerPC, the GPRs can hold any mode, but the float
     registers only can hold floating modes and DImode, and CR register only
*************** extern int rs6000_debug_arg;		/* debug a
*** 757,762 ****
--- 827,834 ----
     (GET_MODE_CLASS (MODE) == MODE_FLOAT					\
      || (GET_MODE_CLASS (MODE) == MODE_INT				\
  	&& GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD))			\
+    : ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_REGNO_P (REGNO)		\
+    : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE)		\
     : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC		\
     : XER_REGNO_P (REGNO) ? (MODE) == PSImode				\
     : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT		\
*************** extern int rs6000_debug_arg;		/* debug a
*** 776,781 ****
--- 848,857 ----
     ? GET_MODE_CLASS (MODE2) == MODE_CC		\
     : GET_MODE_CLASS (MODE2) == MODE_CC		\
     ? GET_MODE_CLASS (MODE1) == MODE_CC		\
+    : ALTIVEC_VECTOR_MODE (MODE1)		\
+    ? ALTIVEC_VECTOR_MODE (MODE2)		\
+    : ALTIVEC_VECTOR_MODE (MODE2)		\
+    ? ALTIVEC_VECTOR_MODE (MODE1)		\
     : 1)
  
  /* A C expression returning the cost of moving data from a register of class
*************** extern int rs6000_debug_arg;		/* debug a
*** 788,793 ****
--- 864,870 ----
     ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2		\
     : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10	\
     : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10	\
+    : (CLASS1) == ALTIVEC_REGS && (CLASS2) != ALTIVEC_REGS ? 20	\
     : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS		\
         || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS		\
         || (CLASS1) == LINK_OR_CTR_REGS)				\
*************** extern int rs6000_debug_arg;		/* debug a
*** 839,844 ****
--- 916,924 ----
      global_regs[PIC_OFFSET_TABLE_REGNUM]				\
        = fixed_regs[PIC_OFFSET_TABLE_REGNUM]				\
          = call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;			\
+   if (TARGET_ALTIVEC_ABI)						\
+     for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)	\
+       call_used_regs[i] = 1;						\
  }
  
  /* Specify the registers used for certain standard purposes.
*************** enum reg_class
*** 912,917 ****
--- 992,998 ----
    BASE_REGS,
    GENERAL_REGS,
    FLOAT_REGS,
+   ALTIVEC_REGS,
    NON_SPECIAL_REGS,
    MQ_REGS,
    LINK_REGS,
*************** enum reg_class
*** 937,942 ****
--- 1018,1024 ----
    "BASE_REGS",								\
    "GENERAL_REGS",							\
    "FLOAT_REGS",								\
+   "ALTIVEC_REGS",							\
    "NON_SPECIAL_REGS",							\
    "MQ_REGS",								\
    "LINK_REGS",								\
*************** enum reg_class
*** 955,978 ****
     This is an initializer for a vector of HARD_REG_SET
     of length N_REG_CLASSES.  */
  
! #define REG_CLASS_CONTENTS						\
! {									\
!   { 0x00000000, 0x00000000, 0x00000000 },	/* NO_REGS */		\
!   { 0xfffffffe, 0x00000000, 0x00000008 },	/* BASE_REGS */		\
!   { 0xffffffff, 0x00000000, 0x00000008 },	/* GENERAL_REGS */	\
!   { 0x00000000, 0xffffffff, 0x00000000 },	/* FLOAT_REGS */	\
!   { 0xffffffff, 0xffffffff, 0x00000008 },	/* NON_SPECIAL_REGS */	\
!   { 0x00000000, 0x00000000, 0x00000001 },	/* MQ_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000002 },	/* LINK_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000004 },	/* CTR_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000006 },	/* LINK_OR_CTR_REGS */	\
!   { 0x00000000, 0x00000000, 0x00000007 },	/* SPECIAL_REGS */	\
!   { 0xffffffff, 0x00000000, 0x0000000f },	/* SPEC_OR_GEN_REGS */	\
!   { 0x00000000, 0x00000000, 0x00000010 },	/* CR0_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000ff0 },	/* CR_REGS */		\
!   { 0xffffffff, 0x00000000, 0x0000ffff },	/* NON_FLOAT_REGS */	\
!   { 0x00000000, 0x00000000, 0x00010000 },	/* XER_REGS */		\
!   { 0xffffffff, 0xffffffff, 0x0001ffff }	/* ALL_REGS */		\
  }
  
  /* The same information, inverted:
--- 1037,1061 ----
     This is an initializer for a vector of HARD_REG_SET
     of length N_REG_CLASSES.  */
  
! #define REG_CLASS_CONTENTS						     \
! {									     \
!   { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */	     \
!   { 0xfffffffe, 0x00000000, 0x00000008, 0x00000000 }, /* BASE_REGS */	     \
!   { 0xffffffff, 0x00000000, 0x00000008, 0x00000000 }, /* GENERAL_REGS */     \
!   { 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FLOAT_REGS */       \
!   { 0x00000000, 0x00000000, 0xffffe000, 0x0001ffff }, /* ALTIVEC_REGS */     \
!   { 0xffffffff, 0xffffffff, 0x00000008, 0x00000000 }, /* NON_SPECIAL_REGS */ \
!   { 0x00000000, 0x00000000, 0x00000001, 0x00000000 }, /* MQ_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000002, 0x00000000 }, /* LINK_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000004, 0x00000000 }, /* CTR_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000006, 0x00000000 }, /* LINK_OR_CTR_REGS */ \
!   { 0x00000000, 0x00000000, 0x00000007, 0x00000000 }, /* SPECIAL_REGS */     \
!   { 0xffffffff, 0x00000000, 0x0000000f, 0x00000000 }, /* SPEC_OR_GEN_REGS */ \
!   { 0x00000000, 0x00000000, 0x00000010, 0x00000000 }, /* CR0_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */	     \
!   { 0xffffffff, 0x00000000, 0x0000ffff, 0x00000000 }, /* NON_FLOAT_REGS */   \
!   { 0x00000000, 0x00000000, 0x00010000, 0x00000000 }, /* XER_REGS */	     \
!   { 0xffffffff, 0xffffffff, 0xffffffff, 0x0001ffff }  /* ALL_REGS */	     \
  }
  
  /* The same information, inverted:
*************** enum reg_class
*** 984,989 ****
--- 1067,1073 ----
   ((REGNO) == 0 ? GENERAL_REGS			\
    : (REGNO) < 32 ? BASE_REGS			\
    : FP_REGNO_P (REGNO) ? FLOAT_REGS		\
+   : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_REGS	\
    : (REGNO) == CR0_REGNO ? CR0_REGS		\
    : CR_REGNO_P (REGNO) ? CR_REGS		\
    : (REGNO) == MQ_REGNO ? MQ_REGS		\
*************** enum reg_class
*** 1006,1011 ****
--- 1090,1096 ----
     : (C) == 'q' ? MQ_REGS	\
     : (C) == 'c' ? CTR_REGS	\
     : (C) == 'l' ? LINK_REGS	\
+    : (C) == 'v' ? ALTIVEC_REGS	\
     : (C) == 'x' ? CR0_REGS	\
     : (C) == 'y' ? CR_REGS	\
     : (C) == 'z' ? XER_REGS	\
*************** enum reg_class
*** 1103,1113 ****
  #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
    secondary_reload_class (CLASS, MODE, IN)
  
! /* If we are copying between FP registers and anything else, we need a memory
!    location.  */
  
! #define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
!  ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS || (CLASS2) == FLOAT_REGS))
  
  /* Return the maximum number of consecutive registers
     needed to represent mode MODE in a register of class CLASS.
--- 1188,1201 ----
  #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
    secondary_reload_class (CLASS, MODE, IN)
  
! /* If we are copying between FP or AltiVec registers and anything
!    else, we need a memory location.  */
  
! #define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) 		\
!  ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS		\
! 			   || (CLASS2) == FLOAT_REGS		\
! 			   || (CLASS1) == ALTIVEC_REGS		\
! 			   || (CLASS2) == ALTIVEC_REGS))
  
  /* Return the maximum number of consecutive registers
     needed to represent mode MODE in a register of class CLASS.
*************** typedef struct rs6000_stack {
*** 1294,1309 ****
  		&& TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)	\
  	       || POINTER_TYPE_P (VALTYPE)			\
  	       ? word_mode : TYPE_MODE (VALTYPE),		\
! 	       TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT \
                 ? FP_ARG_RETURN : GP_ARG_RETURN)
  
  /* Define how to find the value returned by a library function
     assuming the value has mode MODE.  */
  
! #define LIBCALL_VALUE(MODE)					\
!   gen_rtx_REG (MODE, (GET_MODE_CLASS (MODE) == MODE_FLOAT	\
! 		      && TARGET_HARD_FLOAT			\
! 		      ? FP_ARG_RETURN : GP_ARG_RETURN))
  
  /* The definition of this macro implies that there are cases where
     a scalar value cannot be returned in registers.
--- 1382,1399 ----
  		&& TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)	\
  	       || POINTER_TYPE_P (VALTYPE)			\
  	       ? word_mode : TYPE_MODE (VALTYPE),		\
! 	       TREE_CODE (VALTYPE) == VECTOR_TYPE ? ALTIVEC_ARG_RETURN \
! 	       : TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT \
                 ? FP_ARG_RETURN : GP_ARG_RETURN)
  
  /* Define how to find the value returned by a library function
     assuming the value has mode MODE.  */
  
! #define LIBCALL_VALUE(MODE)						\
!   gen_rtx_REG (MODE, ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_ARG_RETURN	\
! 		     : GET_MODE_CLASS (MODE) == MODE_FLOAT		\
! 		     && TARGET_HARD_FLOAT				\
! 		     ? FP_ARG_RETURN : GP_ARG_RETURN)
  
  /* The definition of this macro implies that there are cases where
     a scalar value cannot be returned in registers.
*************** typedef struct rs6000_stack {
*** 1338,1346 ****
--- 1428,1442 ----
  			? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG)
  #define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1)
  
+ /* Minimum and maximum AltiVec registers used to hold arguments.  */
+ #define ALTIVEC_ARG_MIN_REG 77
+ #define ALTIVEC_ARG_MAX_REG 88
+ #define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG - ALTIVEC_ARG_MIN_REG + 1)
+ 
  /* Return registers */
  #define GP_ARG_RETURN GP_ARG_MIN_REG
  #define FP_ARG_RETURN FP_ARG_MIN_REG
+ #define ALTIVEC_ARG_RETURN 79
  
  /* Flags for the call/call_value rtl operations set up by function_arg */
  #define CALL_NORMAL		0x00000000	/* no special processing */
*************** typedef struct rs6000_stack {
*** 1352,1364 ****
  /* 1 if N is a possible register number for a function value
     as seen by the caller.
  
!    On RS/6000, this is r3 and fp1.  */
! #define FUNCTION_VALUE_REGNO_P(N)  ((N) == GP_ARG_RETURN || ((N) == FP_ARG_RETURN))
  
  /* 1 if N is a possible register number for function argument passing.
     On RS/6000, these are r3-r10 and fp1-fp13.  */
  #define FUNCTION_ARG_REGNO_P(N)						\
    ((unsigned)(((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG))	\
     || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))
  
  \f
--- 1448,1465 ----
  /* 1 if N is a possible register number for a function value
     as seen by the caller.
  
!    On RS/6000, this is r3, fp1, and v2 (for AltiVec).  */
! #define FUNCTION_VALUE_REGNO_P(N)  ((N) == GP_ARG_RETURN	\
! 				    || ((N) == FP_ARG_RETURN)	\
! 				    || (TARGET_ALTIVEC &&	\
! 					(N) == ALTIVEC_ARG_RETURN))
  
  /* 1 if N is a possible register number for function argument passing.
     On RS/6000, these are r3-r10 and fp1-fp13.  */
  #define FUNCTION_ARG_REGNO_P(N)						\
    ((unsigned)(((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG))	\
+    || (TARGET_ALTIVEC &&						\
+        (unsigned)((N) - ALTIVEC_ARG_MIN_REG) < (unsigned)(ALTIVEC_ARG_MAX_REG)) \
     || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))
  
  \f
*************** typedef struct rs6000_args
*** 1394,1399 ****
--- 1495,1501 ----
  {
    int words;			/* # words used for passing GP registers */
    int fregno;			/* next available FP register */
+   int vregno;			/* next available AltiVec register */
    int nargs_prototype;		/* # args left in the current prototype */
    int orig_nargs;		/* Original value of nargs_prototype */
    int prototype;		/* Whether a prototype was defined */
*************** typedef struct rs6000_args
*** 1436,1441 ****
--- 1538,1549 ----
     && (CUM).fregno <= FP_ARG_MAX_REG    \
     && TARGET_HARD_FLOAT)
  
+ /* Non-zero if we can use an AltiVec register to pass this arg.  */
+ #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE)	\
+   (ALTIVEC_VECTOR_MODE (MODE)			\
+    && (CUM).vregno <= ALTIVEC_ARG_MAX_REG	\
+    && TARGET_ALTIVEC_ABI)
+ 
  /* Determine where to put an argument to a function.
     Value is zero to push the argument on the stack,
     or a hard register in which to store the argument.
*************** typedef struct rs6000_args
*** 1778,1783 ****
--- 1886,1892 ----
    && GET_CODE (XEXP (X, 0)) == REG				\
    && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT))		\
    && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0)		\
+   && ! ALTIVEC_VECTOR_MODE (MODE)				\
    && (((MODE) != DFmode && (MODE) != DImode)			\
        || (TARGET_32BIT						\
  	  ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) 	\
*************** typedef struct rs6000_args
*** 1805,1810 ****
--- 1914,1920 ----
     && ! flag_pic && ! TARGET_TOC				\
     && (MODE) != DImode						\
     && (MODE) != TImode						\
+    && ! ALTIVEC_VECTOR_MODE (MODE)				\
     && (TARGET_HARD_FLOAT || (MODE) != DFmode)			\
     && GET_CODE (X) == LO_SUM					\
     && GET_CODE (XEXP (X, 0)) == REG				\
*************** extern char rs6000_reg_names[][8];	/* re
*** 2389,2394 ****
--- 2499,2537 ----
    &rs6000_reg_names[75][0],	/* cr7  */				\
  									\
    &rs6000_reg_names[76][0],	/* xer  */				\
+ 									\
+   &rs6000_reg_names[77][0],	/* v0  */				\
+   &rs6000_reg_names[78][0],	/* v1  */				\
+   &rs6000_reg_names[79][0],	/* v2  */				\
+   &rs6000_reg_names[80][0],	/* v3  */				\
+   &rs6000_reg_names[81][0],	/* v4  */				\
+   &rs6000_reg_names[82][0],	/* v5  */				\
+   &rs6000_reg_names[83][0],	/* v6  */				\
+   &rs6000_reg_names[84][0],	/* v7  */				\
+   &rs6000_reg_names[85][0],	/* v8  */				\
+   &rs6000_reg_names[86][0],	/* v9  */				\
+   &rs6000_reg_names[87][0],	/* v10  */				\
+   &rs6000_reg_names[88][0],	/* v11  */				\
+   &rs6000_reg_names[89][0],	/* v12  */				\
+   &rs6000_reg_names[90][0],	/* v13  */				\
+   &rs6000_reg_names[91][0],	/* v14  */				\
+   &rs6000_reg_names[92][0],	/* v15  */				\
+   &rs6000_reg_names[93][0],	/* v16  */				\
+   &rs6000_reg_names[94][0],	/* v17  */				\
+   &rs6000_reg_names[95][0],	/* v18  */				\
+   &rs6000_reg_names[96][0],	/* v19  */				\
+   &rs6000_reg_names[97][0],	/* v20  */				\
+   &rs6000_reg_names[98][0],	/* v21  */				\
+   &rs6000_reg_names[99][0],	/* v22  */				\
+   &rs6000_reg_names[100][0],	/* v23  */				\
+   &rs6000_reg_names[101][0],	/* v24  */				\
+   &rs6000_reg_names[102][0],	/* v25  */				\
+   &rs6000_reg_names[103][0],	/* v26  */				\
+   &rs6000_reg_names[104][0],	/* v27  */				\
+   &rs6000_reg_names[105][0],	/* v28  */				\
+   &rs6000_reg_names[106][0],	/* v29  */				\
+   &rs6000_reg_names[107][0],	/* v30  */				\
+   &rs6000_reg_names[108][0],	/* v31  */				\
  }
  
  /* print-rtl can't handle the above REGISTER_NAMES, so define the
*************** extern char rs6000_reg_names[][8];	/* re
*** 2407,2413 ****
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",		\
       "mq",  "lr", "ctr",  "ap",						\
      "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",		\
!   "xer"									\
  }
  
  /* Table of additional register names to use in user input.  */
--- 2550,2560 ----
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",		\
       "mq",  "lr", "ctr",  "ap",						\
      "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",		\
!   "xer",								\
!      "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",             \
!      "v8",  "v9", "v10", "v11", "v12", "v13", "v14", "v15",             \
!     "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",             \
!     "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"              \
  }
  
  /* Table of additional register names to use in user input.  */
*************** extern char rs6000_reg_names[][8];	/* re
*** 2429,2434 ****
--- 2576,2589 ----
    {"fr20", 52}, {"fr21", 53}, {"fr22", 54}, {"fr23", 55},	\
    {"fr24", 56}, {"fr25", 57}, {"fr26", 58}, {"fr27", 59},	\
    {"fr28", 60}, {"fr29", 61}, {"fr30", 62}, {"fr31", 63},	\
+   {"v0",   77}, {"v1",   78}, {"v2",   79}, {"v3",   80},       \
+   {"v4",   81}, {"v5",   82}, {"v6",   83}, {"v7",   84},       \
+   {"v8",   85}, {"v9",   86}, {"v10",  87}, {"v11",  88},       \
+   {"v12",  89}, {"v13",  90}, {"v14",  91}, {"v15",  92},       \
+   {"v16",  93}, {"v17",  94}, {"v18",  95}, {"v19",  96},       \
+   {"v20",  97}, {"v21",  98}, {"v22",  99}, {"v23",  100},	\
+   {"v24",  101},{"v25",  102},{"v26",  103},{"v27",  104},      \
+   {"v28",  105},{"v29",  106},{"v30",  107},{"v31",  108},      \
    /* no additional names for: mq, lr, ctr, ap */		\
    {"cr0",  68}, {"cr1",  69}, {"cr2",  70}, {"cr3",  71},	\
    {"cr4",  72}, {"cr5",  73}, {"cr6",  74}, {"cr7",  75},	\
*************** do {									\
*** 2617,2622 ****
--- 2772,2778 ----
  				GT, LEU, LTU, GEU, GTU}},		   \
    {"boolean_operator", {AND, IOR, XOR}},				   \
    {"boolean_or_operator", {IOR, XOR}},					   \
+   {"altivec_register", {REG, SUBREG}},					   \
    {"min_max_operator", {SMIN, SMAX, UMIN, UMAX}},
  
  /* uncomment for disabling the corresponding default options */
*************** extern int flag_pic;
*** 2629,2631 ****
--- 2785,2900 ----
  extern int optimize;
  extern int flag_expensive_optimizations;
  extern int frame_pointer_needed;
+ 
+ enum rs6000_builtins
+ {
+   /* AltiVec builtins.  */
+   ALTIVEC_BUILTIN_ST_INTERNAL,
+   ALTIVEC_BUILTIN_LD_INTERNAL,
+   ALTIVEC_BUILTIN_VADDUBM,

--more boring builtins deleted--

+ };
Index: sysv4.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/sysv4.h,v
retrieving revision 1.67
diff -c -p -r1.67 sysv4.h
*** sysv4.h	2001/10/29 23:09:43	1.67
--- sysv4.h	2001/11/05 19:49:24
*************** do {									\
*** 400,417 ****
     one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
     versions, just use 64 as the stack boundary.  */
  #undef	STACK_BOUNDARY
! #define	STACK_BOUNDARY	64
  
  /* Real stack boundary as mandated by the appropriate ABI.  */
! #define ABI_STACK_BOUNDARY ((TARGET_EABI) ? 64 : 128)
  
  /* No data type wants to be aligned rounder than this.  */
  #undef	BIGGEST_ALIGNMENT
! #define BIGGEST_ALIGNMENT ((TARGET_EABI) ? 64 : 128)
  
  #undef  BIGGEST_FIELD_ALIGNMENT
  #undef  ADJUST_FIELD_ALIGN
- #undef  ROUND_TYPE_ALIGN
  
  /* Use ELF style section commands.  */
  
--- 400,430 ----
     one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
     versions, just use 64 as the stack boundary.  */
  #undef	STACK_BOUNDARY
! #define	STACK_BOUNDARY	(TARGET_ALTIVEC_ABI ? 128 : 64)
  
  /* Real stack boundary as mandated by the appropriate ABI.  */
! #define ABI_STACK_BOUNDARY ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
  
  /* No data type wants to be aligned rounder than this.  */
  #undef	BIGGEST_ALIGNMENT
! #define BIGGEST_ALIGNMENT ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
  
+ /* An expression for the alignment of a structure field FIELD if the
+    alignment computed in the usual way is COMPUTED.  */
+ #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)				      \
+ 	((TARGET_ALTIVEC_ABI && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
+ 	 ? 128 : COMPUTED)
+ 
+ /* Define this macro as an expression for the alignment of a type
+    (given by TYPE as a tree node) if the alignment computed in the
+    usual way is COMPUTED and the alignment explicitly specified was
+    SPECIFIED.  */
+ #define ROUND_TYPE_ALIGN(TYPE, COMPUTED, SPECIFIED)			\
+ 	((TARGET_ALTIVEC_ABI && TREE_CODE (TYPE) == VECTOR_TYPE)	\
+ 	 ? 128 : MAX (COMPUTED, SPECIFIED))
+ 
  #undef  BIGGEST_FIELD_ALIGNMENT
  #undef  ADJUST_FIELD_ALIGN
  
  /* Use ELF style section commands.  */
  
Index: rs6000.c
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.224
diff -c -p -r1.224 rs6000.c
*** rs6000.c	2001/10/31 14:08:09	1.224
--- rs6000.c	2001/11/05 19:49:27
*************** int fixuplabelno = 0;
*** 96,101 ****
--- 96,104 ----
  /* ABI enumeration available for subtarget to use.  */
  enum rs6000_abi rs6000_current_abi;
  
+ /* ABI string from -mabi= option.  */
+ const char *rs6000_abi_string;
+ 
  /* Debug flags */
  const char *rs6000_debug_name;
  int rs6000_debug_stack;		/* debug stack applications */
*************** static int rs6000_adjust_cost PARAMS ((r
*** 146,151 ****
--- 149,161 ----
  static int rs6000_adjust_priority PARAMS ((rtx, int));
  static int rs6000_issue_rate PARAMS ((void));
  
+ static void rs6000_init_builtins PARAMS ((tree));
+ static void altivec_init_builtins PARAMS ((void));
+ static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
+ static rtx altivec_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
+ static rtx altivec_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
+ 
+ static void rs6000_parse_abi_options PARAMS ((void));
  \f
  /* Default register names.  */
  char rs6000_reg_names[][8] =
*************** char rs6000_reg_names[][8] =
*** 160,166 ****
       "24", "25", "26", "27", "28", "29", "30", "31",
       "mq", "lr", "ctr","ap",
        "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
!       "xer"
  };
  
  #ifdef TARGET_REGNAMES
--- 170,181 ----
       "24", "25", "26", "27", "28", "29", "30", "31",
       "mq", "lr", "ctr","ap",
        "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
!       "xer",
!       /* AltiVec registers.  */
!       "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6", "v7",
!       "v8",  "v9",  "v10", "v11", "v12", "v13", "v14", "v15",
!       "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
!       "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
  };
  
  #ifdef TARGET_REGNAMES
*************** static const char alt_reg_names[][8] =
*** 176,182 ****
    "%f24",  "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
      "mq",    "lr",  "ctr",   "ap",
    "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
!   "xer"
  };
  #endif
  \f
--- 191,202 ----
    "%f24",  "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
      "mq",    "lr",  "ctr",   "ap",
    "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
!    "xer",
!    /* AltiVec registers.  */
!    "%v0",  "%v1",  "%v2",  "%v3",  "%v4",  "%v5",  "%v6", "%v7",
!    "%v8",  "%v9",  "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
!    "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
!    "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31"
  };
  #endif
  \f
*************** static const char alt_reg_names[][8] =
*** 205,210 ****
--- 225,236 ----
  #undef TARGET_SCHED_ADJUST_PRIORITY
  #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
  
+ #undef TARGET_INIT_BUILTINS
+ #define TARGET_INIT_BUILTINS rs6000_init_builtins
+ 
+ #undef TARGET_EXPAND_BUILTIN
+ #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
+ 
  struct gcc_target targetm = TARGET_INITIALIZER;
  \f
  /* Override command line options.  Mostly we process the processor
*************** rs6000_override_options (default_cpu)
*** 438,443 ****
--- 464,472 ----
  	error ("Unknown -mdebug-%s switch", rs6000_debug_name);
      }
  
+   /* Handle -mabi= options.  */
+   rs6000_parse_abi_options ();
+ 
  #ifdef TARGET_REGNAMES
    /* If the user desires alternate register names, copy in the
       alternate names now.  */
*************** rs6000_override_options (default_cpu)
*** 463,468 ****
--- 492,508 ----
    free_machine_status = rs6000_free_machine_status;
  }
  
+ /* Handle -mabi= options.  */
+ void rs6000_parse_abi_options ()
+ {
+   if (rs6000_abi_string == 0)
+     return;
+   else if (! strcmp (rs6000_abi_string, "altivec"))
+     target_flags |= MASK_ALTIVEC_ABI;
+   else
+     error ("Unknown ABI specified: '%s'", rs6000_abi_string);
+ }
+ 
  void
  optimization_options (level, size)
       int level ATTRIBUTE_UNUSED;
*************** input_operand (op, mode)
*** 1411,1416 ****
--- 1451,1475 ----
    return 0;
  }
  
+ /* Return 1 if this is an AltiVec vector register.
+ 
+    Actually, what we really want to know is if this is a vector mode,
+    since vectors can only go in AltiVec registers.
+ 
+    This is used in *altivec_vec_move so we can seamlessly convert
+    between vector types.  */
+ int
+ altivec_register (x, mode)
+      rtx x;
+      enum machine_mode mode;
+ {
+   if (register_operand (x, mode)
+       && ALTIVEC_VECTOR_MODE (GET_MODE (x)))
+     return 1;
+ 
+   return 0;
+ }
+ 
  /* Return 1 for an operand in small memory on V.4/eabi.  */
  
  int
*************** rs6000_legitimize_address (x, oldx, mode
*** 1544,1550 ****
       rtx x;
       rtx oldx ATTRIBUTE_UNUSED;
       enum machine_mode mode;
! { 
    if (GET_CODE (x) == PLUS 
        && GET_CODE (XEXP (x, 0)) == REG
        && GET_CODE (XEXP (x, 1)) == CONST_INT
--- 1603,1609 ----
       rtx x;
       rtx oldx ATTRIBUTE_UNUSED;
       enum machine_mode mode;
! {
    if (GET_CODE (x) == PLUS 
        && GET_CODE (XEXP (x, 0)) == REG
        && GET_CODE (XEXP (x, 1)) == CONST_INT
*************** rs6000_legitimize_address (x, oldx, mode
*** 1570,1575 ****
--- 1629,1646 ----
        return gen_rtx_PLUS (Pmode, XEXP (x, 0),
  			   force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
      }
+   else if (ALTIVEC_VECTOR_MODE (mode))
+     {
+       rtx reg;
+ 
+       /* Make sure both operands are registers.  */
+       if (GET_CODE (x) == PLUS)
+ 	return gen_rtx_PLUS (Pmode, XEXP (x, 0),
+ 			     force_reg (Pmode, XEXP (x, 1)));
+ 
+       reg = force_reg (Pmode, x);
+       return reg;
+     }
    else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic
  	   && GET_CODE (x) != CONST_INT
  	   && GET_CODE (x) != CONST_DOUBLE 
*************** rs6000_emit_move (dest, source, mode)
*** 1862,1867 ****
--- 1933,1947 ----
  	operands[1] = force_const_mem (mode, operands[1]);
        break;
        
+     case V16QImode:
+     case V8HImode:
+     case V4SFmode:
+     case V4SImode:
+       /* fixme: aldyh -- allow vector constants when they are implemented.  */
+       if (CONSTANT_P (operands[1]))
+ 	operands[1] = force_const_mem (mode, operands[1]);
+       break;
+       
      case SImode:
      case DImode:
        /* Use default pattern for address of ELF small data */
*************** init_cumulative_args (cum, fntype, libna
*** 2062,2067 ****
--- 2142,2148 ----
    *cum = zero_cumulative;
    cum->words = 0;
    cum->fregno = FP_ARG_MIN_REG;
+   cum->vregno = ALTIVEC_ARG_MIN_REG;
    cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
    cum->call_cookie = CALL_NORMAL;
    cum->sysv_gregno = GP_ARG_MIN_REG;
*************** function_arg_boundary (mode, type)
*** 2142,2147 ****
--- 2223,2230 ----
    if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
        && (mode == DImode || mode == DFmode))
      return 64;
+   else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
+     return 128;
    else
      return PARM_BOUNDARY;
  }
*************** function_arg_advance (cum, mode, type, n
*** 2159,2165 ****
  {
    cum->nargs_prototype--;
  
!   if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
--- 2242,2255 ----
  {
    cum->nargs_prototype--;
  
!   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
!     {
!       if (cum->vregno <= ALTIVEC_ARG_MAX_REG)
! 	cum->vregno++;
!       else
! 	cum->words += RS6000_ARG_SIZE (mode, type);
!     }
!   else if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
*************** function_arg (cum, mode, type, named)
*** 2287,2294 ****
        return GEN_INT (cum->call_cookie);
      }
  
!   if (abi == ABI_V4 || abi == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
  	{
--- 2377,2391 ----
        return GEN_INT (cum->call_cookie);
      }
  
!   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
      {
+       if (cum->vregno <= ALTIVEC_ARG_MAX_REG)
+ 	return gen_rtx_REG (mode, cum->vregno);
+       else
+ 	return NULL;
+     }
+   else if (abi == ABI_V4 || abi == ABI_SOLARIS)
+     {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
  	{
*************** function_arg_partial_nregs (cum, mode, t
*** 2382,2388 ****
    if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      return 0;
  
!   if (USE_FP_FOR_ARG_P (*cum, mode, type))
      {
        if (cum->nargs_prototype >= 0)
  	return 0;
--- 2479,2486 ----
    if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      return 0;
  
!   if (USE_FP_FOR_ARG_P (*cum, mode, type)
!       || USE_ALTIVEC_FOR_ARG_P (*cum, mode, type))
      {
        if (cum->nargs_prototype >= 0)
  	return 0;
*************** rs6000_va_arg (valist, type)
*** 2838,2843 ****
--- 2936,3411 ----
  
    return addr_rtx;
  }
+ 
+ /* Builtins.  */
+ 
+ #define def_builtin(MASK, NAME, TYPE, CODE)				\
+ do {									\
+   if ((MASK) & target_flags)						\
+     builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL);	\
+ } while (0)
+ 
+ struct builtin_description
+ {
+   const unsigned int mask;
+   const enum insn_code icode;
+   const char *const name;
+   const enum rs6000_builtins code;
+ };
+ 
+ /* Simple binary operatiors: VECc = foo (VECa, VECb).  */
+ static const struct builtin_description bdesc_2arg[] =
+ {
+   { MASK_ALTIVEC, CODE_FOR_altivec_vaddubm, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
+   { MASK_ALTIVEC, CODE_FOR_altivec_vadduhm, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },

--more boring builtins deleted--

+ };
+ 
+ static rtx
+ altivec_expand_binop_builtin (icode, arglist, target)
+      enum insn_code icode;
+      tree arglist;
+      rtx target;
+ {
+   rtx pat;
+   tree arg0 = TREE_VALUE (arglist);
+   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+   rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+   rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+   enum machine_mode tmode = insn_data[icode].operand[0].mode;
+   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
+   enum machine_mode mode1 = insn_data[icode].operand[2].mode;
+ 
+   if (! target
+       || GET_MODE (target) != tmode
+       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+     target = gen_reg_rtx (tmode);
+ 
+   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+     op0 = copy_to_mode_reg (mode0, op0);
+   if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
+     op1 = copy_to_mode_reg (mode1, op1);
+ 
+   pat = GEN_FCN (icode) (target, op0, op1);
+   if (! pat)
+     return 0;
+   emit_insn (pat);
+ 
+   return target;
+ }
+ 
+ static rtx
+ altivec_expand_builtin (exp, target, subtarget, mode, ignore)
+      tree exp;
+      rtx target;
+      rtx subtarget;
+      enum machine_mode mode;
+      int ignore;
+ {
+   struct builtin_description *d;
+   size_t i;
+   enum insn_code icode;
+   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
+   tree arglist = TREE_OPERAND (exp, 1);
+   tree arg0, arg1, arg2, arg3;
+   rtx op0, op1, op2, pat;
+   enum machine_mode tmode, mode0, mode1, mode2;
+   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+   
+   switch (fcode)
+     {
+     case ALTIVEC_BUILTIN_LD_INTERNAL:
+       icode = CODE_FOR_altivec_lvx;
+       arg0 = TREE_VALUE (arglist);
+       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+       tmode = insn_data[icode].operand[0].mode;
+       mode0 = insn_data[icode].operand[1].mode;
+ 
+       if (! target
+ 	  || GET_MODE (target) != tmode
+ 	  || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ 	target = gen_reg_rtx (tmode);
+ 
+       if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+ 	op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
+ 
+       pat = GEN_FCN (icode) (target, op0);
+       if (! pat)
+ 	return 0;
+       emit_insn (pat);
+       return target;
+ 
+     case ALTIVEC_BUILTIN_ST_INTERNAL:
+       icode = CODE_FOR_altivec_stvx;
+       arg0 = TREE_VALUE (arglist);
+       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+       op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+       mode0 = insn_data[icode].operand[0].mode;
+       mode1 = insn_data[icode].operand[1].mode;
+ 
+       if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
+ 	op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
+       if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
+ 	op1 = copy_to_mode_reg (mode1, op1);
+ 
+       pat = GEN_FCN (icode) (op0, op1);
+       if (! pat)
+ 	return 0;
+       emit_insn (pat);
+       return NULL_RTX;
+     }
+ 
+   /* Handle simple binary operations.  */
+   for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
+     if (d->code == fcode)
+       return altivec_expand_binop_builtin (d->icode, arglist, target);
+ 
+   abort ();
+   return NULL_RTX;
+ }
+ 
+ /* Expand an expression EXP that calls a built-in function,
+    with result going to TARGET if that's convenient
+    (and in mode MODE if that's convenient).
+    SUBTARGET may be used as the target for computing one of EXP's operands.
+    IGNORE is nonzero if the value is to be ignored.  */
+ 
+ static rtx
+ rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
+      tree exp;
+      rtx target;
+      rtx subtarget;
+      enum machine_mode mode;
+      int ignore;
+ {
+   if (TARGET_ALTIVEC)
+     return altivec_expand_builtin (exp, target, subtarget, mode, ignore);
+ 
+   abort ();
+ }
+ 
+ static void
+ rs6000_init_builtins (list_node)
+      tree list_node ATTRIBUTE_UNUSED;
+ {
+   if (TARGET_ALTIVEC)
+     altivec_init_builtins ();
+ }
+ 
+ static void
+ altivec_init_builtins (void)
+ {
+   struct builtin_description * d;
+   size_t i;
+ 
+   tree endlink = void_list_node;
+ 
+   tree pint_type_node = build_pointer_type (integer_type_node);
+ 
+   /* V4SI foo (int *).  */
+   tree v4si_ftype_pint
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, pint_type_node, endlink));
+ 
+   /* void foo (int *, V4SI).  */
+   tree void_ftype_pint_v4si
+     = build_function_type (void_type_node,
+ 			   tree_cons (NULL_TREE, pint_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 

--more boring types deleted--

+ 
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal", v4si_ftype_pint, ALTIVEC_BUILTIN_LD_INTERNAL);
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal", void_ftype_pint_v4si, ALTIVEC_BUILTIN_ST_INTERNAL);
+ 
+   /* Add the simple binary operators.  */
+   for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
+     {
+       enum machine_mode mode0, mode1, mode2;
+       tree type;
+ 
+       if (d->name == 0)
+ 	continue;
+       
+       mode0 = insn_data[d->icode].operand[0].mode;
+       mode1 = insn_data[d->icode].operand[1].mode;
+       mode2 = insn_data[d->icode].operand[2].mode;
+ 
+       /* When all three operands are of the same mode.  */
+       if (mode0 == mode1 && mode1 == mode2)
+ 	{
+ 	  switch (mode0)
+ 	    {
+ 	    case V4SFmode:
+ 	      type = v4sf_ftype_v4sf_v4sf;
+ 	      break;
+ 	    case V4SImode:
+ 	      type = v4si_ftype_v4si_v4si;
+ 	      break;
+ 	    case V16QImode:
+ 	      type = v16qi_ftype_v16qi_v16qi;
+ 	      break;
+ 	    case V8HImode:
+ 	      type = v8hi_ftype_v8hi_v8hi;
+ 	      break;
+ 	    default:
+ 	      abort ();
+ 	    }
+ 	}
+ 
+       /* A few other combos we really don't want to do manually.  */
+ 
+       /* vint, vfloat, vfloat.  */
+       else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
+ 	type = v4si_ftype_v4sf_v4sf;
+ 
+       /* vshort, vchar, vchar.  */
+       else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
+ 	type = v8hi_ftype_v16qi_v16qi;
+ 
+       /* vint, vshort, vshort.  */
+       else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
+ 	type = v4si_ftype_v8hi_v8hi;
+ 
+       /* vshort, vint, vint.  */
+       else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
+ 	type = v8hi_ftype_v4si_v4si;
+ 
+       /* vchar, vshort, vshort.  */
+       else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
+ 	type = v16qi_ftype_v8hi_v8hi;
+ 
+       /* vint, vchar, vint.  */
+       else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
+ 	type = v4si_ftype_v16qi_v4si;
+ 
+       /* vint, vshort, vint.  */
+       else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
+ 	type = v4si_ftype_v8hi_v4si;
+ 
+       /* fixme: aldyh */
+       /* int, x, x.  */
+       else if (mode0 == SImode)
+ 	{
+ 	  switch (mode1)
+ 	    {
+ 	    case V4SImode:
+ 	      type = int_ftype_v4si_v4si;
+ 	      break;
+ 	    case V4SFmode:
+ 	      type = int_ftype_v4sf_v4sf;
+ 	      break;
+ 	    case V16QImode:
+ 	      type = int_ftype_v16qi_v16qi;
+ 	      break;
+ 	    case V8HImode:
+ 	      type = int_ftype_v8hi_v8hi;
+ 	      break;
+ 	    default:
+ 	      abort ();
+ 	    }
+ 	}
+ 
+       else
+ 	abort ();
+ 
+       def_builtin (d->mask, d->name, type, d->code);
+     }
+ }
+ 
  \f
  /* Generate a memory reference for expand_block_move, copying volatile,
     and other bits from an original memory reference.  */
*************** secondary_reload_class (class, mode, in)
*** 3941,3946 ****
--- 4509,4519 ----
        && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
      return NO_REGS;
  
+   /* Memory, and AltiVec registers can go into AltiVec registers.  */
+   if ((regno == -1 || ALTIVEC_REGNO_P (regno))
+       && class == ALTIVEC_REGS)
+     return NO_REGS;
+ 
    /* We can copy among the CR registers.  */
    if ((class == CR_REGS || class == CR0_REGS)
        && regno >= 0 && CR_REGNO_P (regno))
*************** print_operand (file, x, code)
*** 4714,4719 ****
--- 5287,5318 ----
  		     reg_names[SMALL_DATA_REG]);
  	}
        return;
+ 
+       /* Print AltiVec memory operand.  */
+     case 'y':
+       {
+ 	rtx tmp;
+ 
+ 	if (GET_CODE (x) != MEM)
+ 	  abort ();
+ 
+ 	tmp = XEXP (x, 0);
+ 
+ 	if (GET_CODE (tmp) == REG)
+ 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
+ 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
+ 	  {
+ 	    if (REGNO (XEXP (tmp, 0)) == 0)
+ 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
+ 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
+ 	    else
+ 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
+ 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
+ 	  }
+ 	else
+ 	  abort ();
+ 	break;
+       }
  			    
      case 0:
        if (GET_CODE (x) == REG)
Index: rs6000.md
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.128
diff -c -p -r1.128 rs6000.md
*** rs6000.md	2001/10/16 00:43:21	1.128
--- rs6000.md	2001/11/05 19:49:32
***************
*** 37,43 ****
  \f
  ;; Define an insn type attribute.  This is used in function unit delay
  ;; computations.
! (define_attr "type" "integer,load,store,fpload,fpstore,imul,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg"
    (const_string "integer"))
  
  ;; Length (in bytes).
--- 37,43 ----
  \f
  ;; Define an insn type attribute.  This is used in function unit delay
  ;; computations.
! (define_attr "type" "integer,load,store,fpload,fpstore,imul,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,altivec"
    (const_string "integer"))
  
  ;; Length (in bytes).
***************
*** 13359,13361 ****
--- 13359,14298 ----
      emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
    DONE;
  }")
+ 
+ ;; AltiVec patterns
+ 
+ ;; Generic LVX load instruction.
+ (define_insn "altivec_lvx"
+   [(set (match_operand:V4SI 0 "register_operand" "=v")
+ 	(match_operand:V4SI 1 "memory_operand" "m"))]
+   "TARGET_ALTIVEC"
+   "lvx\t%0,%y1"
+   [(set_attr "type" "altivec")])
+ 
+ ;; Generic STVX store instruction.
+ (define_insn "altivec_stvx"
+   [(set (match_operand:V4SI 0 "memory_operand" "=m")
+ 	(match_operand:V4SI 1 "register_operand" "v"))]
+   "TARGET_ALTIVEC"
+   "stvx\t%1,%y0"
+   [(set_attr "type" "altivec")])
+ 
+ ;; No code is needed to copy between vector registers.
+ (define_insn "*altivec_vec_move"
+   [(set (match_operand 0 "altivec_register" "=v")
+ 	(match_operand 1 "altivec_register" "v"))]
+   "TARGET_ALTIVEC"
+   ""
+   [(set_attr "type" "altivec")])
+ 
+ ;; Vector move instructions.
+ (define_expand "movv4si"
+   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
+ 	(match_operand:V4SI 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V4SImode); DONE; }")
+ 
+ (define_insn "*movv4si_internal"
+   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v")
+ 	(match_operand:V4SI 1 "input_operand" "v,m"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1"
+   [(set_attr "type" "altivec")])
+ 
+ (define_expand "movv8hi"
+   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
+ 	(match_operand:V8HI 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V8HImode); DONE; }")
+ 
+ (define_insn "*movv8hi_internal1"
+   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=m,v")
+ 	(match_operand:V8HI 1 "input_operand" "v,m"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1"
+   [(set_attr "type" "altivec")])
+ 
+ (define_expand "movv16qi"
+   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
+ 	(match_operand:V16QI 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V16QImode); DONE; }")
+ 
+ (define_insn "*movv16qi_internal1"
+   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=m,v")
+ 	(match_operand:V16QI 1 "input_operand" "v,m"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1"
+   [(set_attr "type" "altivec")])
+ 
+ (define_expand "movv4sf"
+   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
+ 	(match_operand:V4SF 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V4SFmode); DONE; }")
+ 
+ (define_insn "*movv4sf_internal1"
+   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=m,v")
+ 	(match_operand:V4SF 1 "input_operand" "v,m"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1"
+   [(set_attr "type" "altivec")])
+ 
+ ;; Simple binary operations.
+ 

-- boring builtins deleted-- 

+ (define_insn "altivec_vxor"
+   [(set (match_operand:V4SI 0 "register_operand" "=v")
+         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
+                       (match_operand:V4SI 2 "register_operand" "v")] 136))]
+   "TARGET_ALTIVEC"
+   "vxor\t%0,%1,%2"
+   [(set_attr "type" "altivec")])

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-06  7:58                   ` Alan Matsuoka
@ 2001-11-13  4:32                     ` Alan Matsuoka
  2001-11-13 15:03                     ` Alexandre Oliva
  2001-11-13 15:03                     ` Alan Matsuoka
  2 siblings, 0 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-13  4:32 UTC (permalink / raw)
  To: gcc-patches

Alan Matsuoka wrote:
> 
> On Tue, 06 Nov 2001, Joseph S. Myers wrote:
> 
> > On Mon, 5 Nov 2001, Alan Matsuoka wrote:
> >
> > > + Where @var{pathname} is a string that specifies the the location of the file,
> > > + specifies the include file to be in gcc/config/{target}/filestuff. The
> >
> > @file{gcc/config/@var{target}/filestuff}.
> >
> > > + directory @file{gcc/config/{target}} is regarded as the default directory.
> >
> > @var{target}.
> >
> > Has this patch passed "make info" and "make dvi"?
> 
> I'll sumbit a revised patch as soon as the cvs server lets me
> generate a patch.
This is a revised patch. It now works with "make info" and "make dvi"
-- 
Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299
The following patch is for the an internal project. This is 
implements a (include "filestuff") mechanism for splitting up 
.md files.

(include "filestuff") expects the include file to be in gcc/config/{target}/filestuff
(include "BOGUS/filestuff") expects the include file to be in gcc/config/{target}/BOGUS/filestuff
(include "/u2/BOGUS/filestuff") expects the include file to be in /u2/BOGUS/filestuff

You can also run things like genrecog -I/p1/abc/proc1 -I/p2/abcd/pro2 target.md

This is used only at build time.

This has been tested for i686-pc-linux-gnu by bootstrapping and testing without 
any regressions.

The DOS pathname style stuff may still be required.


2001-11-05  Alan Matsuoka  <alanm@redhat.com>

        * rtl.def (INCLUDE) : Define.
	* gensupport.c (init_include_reader, process_include, 
	  save_string) :  New functions to
	  implement an include facility in .md files.
	* gensupport.h : Add prototype for init_md_reader_args.
	* genattr.c genattrtab.c gencodes.c genconfig.c genemit.c
	  genextract.c genflags.c genopinit.c genoutput.c genpeep.c
	  genrecog.c: Change call to init_md_reader to init_md_reader_args.
	* md.texi: Document (include "path") and -I directives for RTL 
	  generation tools.

Index: genattr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genattr.c,v
retrieving revision 1.45
diff -c -3 -p -r1.45 genattr.c
*** genattr.c	2001/10/07 16:50:51	1.45
--- genattr.c	2001/11/06 15:51:39
*************** main (argc, argv)
*** 210,216 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genattr'");
--- 210,216 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genattr'");
Index: genattrtab.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genattrtab.c,v
retrieving revision 1.103
diff -c -3 -p -r1.103 genattrtab.c
*** genattrtab.c	2001/10/21 21:32:00	1.103
--- genattrtab.c	2001/11/06 15:51:41
*************** main (argc, argv)
*** 6075,6081 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    obstack_init (hash_obstack);
--- 6075,6081 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    obstack_init (hash_obstack);
Index: gencodes.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gencodes.c,v
retrieving revision 1.42
diff -c -3 -p -r1.42 gencodes.c
*** gencodes.c	2001/08/22 14:35:16	1.42
--- gencodes.c	2001/11/06 15:51:41
*************** main (argc, argv)
*** 56,62 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("\
--- 56,62 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("\
Index: genconfig.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genconfig.c,v
retrieving revision 1.43
diff -c -3 -p -r1.43 genconfig.c
*** genconfig.c	2001/10/11 07:07:26	1.43
--- genconfig.c	2001/11/06 15:51:41
*************** main (argc, argv)
*** 277,283 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genconfig'");
--- 277,283 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genconfig'");
Index: genemit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genemit.c,v
retrieving revision 1.67
diff -c -3 -p -r1.67 genemit.c
*** genemit.c	2001/10/19 19:37:08	1.67
--- genemit.c	2001/11/06 15:51:41
*************** main (argc, argv)
*** 789,795 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
--- 789,795 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
Index: genextract.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genextract.c,v
retrieving revision 1.46
diff -c -3 -p -r1.46 genextract.c
*** genextract.c	2001/10/11 03:15:42	1.46
--- genextract.c	2001/11/06 15:51:41
*************** main (argc, argv)
*** 362,368 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
--- 362,368 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
Index: genflags.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genflags.c,v
retrieving revision 1.39
diff -c -3 -p -r1.39 genflags.c
*** genflags.c	2001/10/11 03:15:42	1.39
--- genflags.c	2001/11/06 15:51:42
*************** main (argc, argv)
*** 230,236 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
    
    puts ("/* Generated automatically by the program `genflags'");
--- 230,236 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
    
    puts ("/* Generated automatically by the program `genflags'");
Index: genopinit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genopinit.c,v
retrieving revision 1.48
diff -c -3 -p -r1.48 genopinit.c
*** genopinit.c	2001/09/13 14:37:11	1.48
--- genopinit.c	2001/11/06 15:51:42
*************** main (argc, argv)
*** 316,322 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genopinit'\n\
--- 316,322 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genopinit'\n\
Index: genoutput.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genoutput.c,v
retrieving revision 1.65
diff -c -3 -p -r1.65 genoutput.c
*** genoutput.c	2001/10/11 03:15:42	1.65
--- genoutput.c	2001/11/06 15:51:42
*************** main (argc, argv)
*** 953,959 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    output_prologue ();
--- 953,959 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    output_prologue ();
Index: genpeep.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genpeep.c,v
retrieving revision 1.49
diff -c -3 -p -r1.49 genpeep.c
*** genpeep.c	2001/10/11 03:15:43	1.49
--- genpeep.c	2001/11/06 15:51:42
*************** main (argc, argv)
*** 385,391 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genpeep'\n\
--- 385,391 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genpeep'\n\
Index: genrecog.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genrecog.c,v
retrieving revision 1.111
diff -c -3 -p -r1.111 genrecog.c
*** genrecog.c	2001/10/28 20:09:14	1.111
--- genrecog.c	2001/11/06 15:51:44
*************** main (argc, argv)
*** 2689,2695 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    next_insn_code = 0;
--- 2689,2695 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    next_insn_code = 0;
Index: gensupport.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gensupport.c,v
retrieving revision 1.23
diff -c -3 -p -r1.23 gensupport.c
*** gensupport.c	2001/10/25 12:55:16	1.23
--- gensupport.c	2001/11/06 15:51:44
*************** static int predicable_default;
*** 42,47 ****
--- 42,49 ----
  static const char *predicable_true;
  static const char *predicable_false;
  
+ static char *base_dir = NULL;
+ 
  /* We initially queue all patterns, process the define_insn and
     define_cond_exec patterns, then return them one at a time.  */
  
*************** static struct queue_elem *other_queue;
*** 62,67 ****
--- 64,86 ----
  static struct queue_elem **other_tail = &other_queue;
  
  static void queue_pattern PARAMS ((rtx, struct queue_elem ***, int));
+ 
+ /* Current maximum length of directory names in the search path
+    for include files.  (Altered as we get more of them.)  */
+ 
+ size_t max_include_len;
+ 
+ struct file_name_list
+   {
+     struct file_name_list *next;
+     const char *fname;
+   };
+ 
+ struct file_name_list *include = 0;     /* First dir to search */
+         /* First dir to search for <file> */
+ struct file_name_list *first_bracket_include = 0;
+ struct file_name_list *last_include = 0;        /* Last in chain */
+ 
  static void remove_constraints PARAMS ((rtx));
  static void process_rtx PARAMS ((rtx, int));
  
*************** static const char *alter_output_for_insn
*** 78,83 ****
--- 97,105 ----
  						  int, int));
  static void process_one_cond_exec PARAMS ((struct queue_elem *));
  static void process_define_cond_exec PARAMS ((void));
+ static int process_include PARAMS ((rtx, int));
+ static char *save_string PARAMS ((const char *, int));
+ static int init_include_reader PARAMS ((FILE  *));
  \f
  void
  message_with_line VPARAMS ((int lineno, const char *msg, ...))
*************** remove_constraints (part)
*** 157,162 ****
--- 179,320 ----
        }
  }
  
+ /* The entry point for initializing the reader.  */
+ 
+ static int
+ init_include_reader (inf)
+      FILE *inf;
+ {
+   int c;
+ 
+   errors = 0;
+ 
+   /* Read the entire file.  */
+   while (1)
+     {
+       rtx desc;
+       int lineno;
+ 
+       c = read_skip_spaces (inf);
+       if (c == EOF)
+ 	break;
+ 
+       ungetc (c, inf);
+       lineno = read_rtx_lineno;
+       desc = read_rtx (inf);
+       process_rtx (desc, lineno);
+     }
+   fclose (inf);
+ 
+   /* Process define_cond_exec patterns.  */
+   if (define_cond_exec_queue != NULL)
+     process_define_cond_exec ();
+ 
+   return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
+ }
+ 
+ /* Process an include file assuming that it lives in gcc/config/{target}/ 
+    if the include looks line (include "file" )  */
+ static int
+ process_include (desc, lineno)
+      rtx desc;
+      int lineno;
+ {
+   const char *filename = XSTR (desc, 0);
+   char *pathname = NULL;
+   FILE *input_file;
+   char *fname;
+   struct file_name_list *stackp;
+   int flen;
+ 
+   stackp = include;
+ 
+   /* If specified file name is absolute, just open it.  */
+   if (IS_ABSOLUTE_PATHNAME (filename) || !stackp)
+     {
+       if (base_dir)
+         {
+           pathname = xmalloc (strlen (base_dir) + strlen (filename) + 1);
+           pathname = strcpy (pathname, base_dir);
+           strcat (pathname, filename);
+           strcat (pathname, "\0");
+ 	}
+       else
+         {
+ 	  pathname = xstrdup (filename);
+         }
+       read_rtx_filename = pathname;
+       input_file = fopen (pathname, "r");
+ 
+       if (input_file == 0)
+ 	{
+ 	  perror (pathname);
+ 	  return FATAL_EXIT_CODE;
+ 	}
+     }
+   else if (stackp)
+     {
+ 
+       flen = strlen (filename);
+ 
+       fname = (char *) alloca (max_include_len + flen + 2);
+ 
+       /* + 2 above for slash and terminating null.  */
+ 
+       /* Search directory path, trying to open the file.
+          Copy each filename tried into FNAME.  */
+ 
+       for (; stackp; stackp = stackp->next)
+ 	{
+ 	  if (stackp->fname)
+ 	    {
+ 	      strcpy (fname, stackp->fname);
+ 	      strcat (fname, "/");
+ 	      fname[strlen (fname) + flen] = 0;
+ 	    }
+ 	  else
+ 	    {
+ 	      fname[0] = 0;
+ 	    }
+ 	  strncat (fname, (const char *) filename, flen);
+ 	  read_rtx_filename = fname;
+ 	  input_file = fopen (fname, "r");
+ 	  if (input_file != NULL) 
+ 	    break;
+ 	}
+       if (stackp == NULL)
+ 	{
+ 	  if (strchr (fname, '/') == NULL || strchr (fname, '\\' ) || base_dir)
+ 	    {
+ 	      if (base_dir)
+ 		{
+ 		  pathname =
+ 		    xmalloc (strlen (base_dir) + strlen (filename) + 1);
+ 		  pathname = strcpy (pathname, base_dir);
+ 		  strcat (pathname, filename);
+ 		  strcat (pathname, "\0");
+ 		}
+ 	      else
+ 		pathname = xstrdup (filename);
+ 	    }
+ 	  read_rtx_filename = pathname;
+ 	  input_file = fopen (pathname, "r");
+ 
+ 	  if (input_file == 0)
+ 	    {
+ 	      perror (filename);
+ 	      return FATAL_EXIT_CODE;
+ 	    }
+ 	}
+ 
+     }
+ 
+   if (init_include_reader (input_file) == FATAL_EXIT_CODE)
+     message_with_line (lineno, "read errors found in include file  %s\n", pathname);
+ 
+   return SUCCESS_EXIT_CODE;
+ }
+ 
  /* Process a top level rtx in some way, queueing as appropriate.  */
  
  static void
*************** process_rtx (desc, lineno)
*** 164,169 ****
--- 322,329 ----
       rtx desc;
       int lineno;
  {
+   const char *filename = XSTR (desc, 0);
+ 
    switch (GET_CODE (desc))
      {
      case DEFINE_INSN:
*************** process_rtx (desc, lineno)
*** 178,183 ****
--- 338,348 ----
        queue_pattern (desc, &define_attr_tail, lineno);
        break;
  
+     case INCLUDE:
+       if (process_include (desc, lineno) == FATAL_EXIT_CODE)
+         message_with_line (lineno, "include file at  %s not found\n", filename);
+       break;
+ 
      case DEFINE_INSN_AND_SPLIT:
        {
  	const char *split_cond;
*************** process_define_cond_exec ()
*** 767,781 ****
--- 932,1022 ----
    for (elem = define_cond_exec_queue; elem ; elem = elem->next)
      process_one_cond_exec (elem);
  }
+ 
+ static char *
+ save_string (s, len)
+      const char *s;
+      int len;
+ {
+   register char *result = xmalloc (len + 1);
+ 
+   memcpy (result, s, len);
+   result[len] = 0;
+   return result;
+ }
+ 
  \f
  /* The entry point for initializing the reader.  */
  
  int
+ init_md_reader_args (argc, argv)
+      int argc;
+      char **argv;
+ {
+   int i;
+   const char *in_fname;
+ 
+   max_include_len = 0;
+   in_fname = NULL;
+   for (i = 1; i < argc; i++)
+     {
+       if (argv[i][0] != '-')
+ 	{
+ 	  if (in_fname == NULL)
+ 	    in_fname = argv[i];
+ 	}
+       else
+ 	{
+ 	  int c = argv[i][1];
+ 	  switch (c)
+ 	    {
+ 	    case 'I':		/* Add directory to path for includes.  */
+ 	      {
+ 		struct file_name_list *dirtmp;
+ 
+ 		dirtmp = (struct file_name_list *)
+ 		  xmalloc (sizeof (struct file_name_list));
+ 		dirtmp->next = 0;	/* New one goes on the end */
+ 		if (include == 0)
+ 		  include = dirtmp;
+ 		else
+ 		  last_include->next = dirtmp;
+ 		last_include = dirtmp;	/* Tail follows the last one */
+ 		if (argv[i][1] == 'I' && argv[i][2] != 0)
+ 		  dirtmp->fname = argv[i] + 2;
+ 		else if (i + 1 == argc)
+ 		  fatal ("Directory name missing after -I option");
+ 		else
+ 		  dirtmp->fname = argv[++i];
+ 		if (strlen (dirtmp->fname) > max_include_len)
+ 		  max_include_len = strlen (dirtmp->fname);
+ 	      }
+ 	      break;
+ 	    default:
+ 	      fatal ("Invalid option `%s'", argv[i]);
+ 
+ 	    }
+ 	}
+     }
+     return init_md_reader (in_fname);
+ }
+ \f
+ /* The entry point for initializing the reader.  */
+ 
+ int
  init_md_reader (filename)
       const char *filename;
  {
    FILE *input_file;
    int c;
+   char *lastsl;
+ 
+   if (!IS_ABSOLUTE_PATHNAME (filename))
+     {
+       lastsl = strrchr (filename, '/');
+       if (lastsl != NULL) 
+ 	base_dir = save_string (filename, lastsl - filename + 1 );
+     }
  
    read_rtx_filename = filename;
    input_file = fopen (filename, "r");
*************** init_md_reader (filename)
*** 797,803 ****
  
        c = read_skip_spaces (input_file);
        if (c == EOF)
! 	break;
  
        ungetc (c, input_file);
        lineno = read_rtx_lineno;
--- 1038,1044 ----
  
        c = read_skip_spaces (input_file);
        if (c == EOF)
!         break;
  
        ungetc (c, input_file);
        lineno = read_rtx_lineno;
Index: gensupport.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gensupport.h,v
retrieving revision 1.3
diff -c -3 -p -r1.3 gensupport.h
*** gensupport.h	2001/08/22 14:35:17	1.3
--- gensupport.h	2001/11/06 15:51:44
*************** Software Foundation, 59 Temple Place - S
*** 21,26 ****
--- 21,27 ----
  struct obstack;
  extern struct obstack *rtl_obstack;
  
+ extern int init_md_reader_args	PARAMS ((int, char **));
  extern int init_md_reader	PARAMS ((const char *));
  extern rtx read_md_rtx		PARAMS ((int *, int *));
  
Index: rtl.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.def,v
retrieving revision 1.50
diff -c -3 -p -r1.50 rtl.def
*** rtl.def	2001/11/03 16:28:33	1.50
--- rtl.def	2001/11/06 15:51:46
*************** DEF_RTL_EXPR(UNKNOWN, "UnKnown", "*", 'x
*** 73,78 ****
--- 73,83 ----
  
  DEF_RTL_EXPR(NIL, "nil", "*", 'x')
  
+ 
+ /* include a file */
+ 
+ DEF_RTL_EXPR(INCLUDE, "include", "s", 'x')
+ 
  /* ---------------------------------------------------------------------
     Expressions used in constructing lists.
     --------------------------------------------------------------------- */
Index: doc/md.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/md.texi,v
retrieving revision 1.26
diff -c -3 -p -r1.26 md.texi
*** md.texi	2001/10/25 18:25:08	1.26
--- md.texi	2001/11/06 15:52:02
*************** See the next chapter for information on 
*** 38,43 ****
--- 38,44 ----
  * Expander Definitions::Generating a sequence of several RTL insns
                            for a standard operation.
  * Insn Splitting::      Splitting Instructions into Multiple Instructions.
+ * Including Patterns::      Including Patterns in Machine Descriptions.
  * Peephole Definitions::Defining machine-specific peephole optimizations.
  * Insn Attributes::     Specifying the value of attributes for generated insns.
  * Conditional Execution::Generating @code{define_insn} patterns for
*************** The @code{define_insn_and_split} constru
*** 3909,3914 ****
--- 3910,3989 ----
  functionality as two separate @code{define_insn} and @code{define_split}
  patterns.  It exists for compactness, and as a maintenance tool to prevent
  having to ensure the two patterns' templates match.
+ 
+ @node Including Patterns
+ @section Including Patterns in Machine Descriptions.
+ @cindex insn includes
+ 
+ @findex include
+ The @code{include} pattern tells the compiler tools where to
+ look for patterns that are in files other than in the file
+ @file{.md}. This is used only at build time and there is no preprocessing allowed.
+ 
+ It looks like:
+ 
+ @smallexample
+ 
+ (include
+   @var{pathname})
+ @end smallexample
+ 
+ For example:
+ 
+ @smallexample
+ 
+ (include "filestuff") 
+ 
+ @end smallexample
+ 
+ Where @var{pathname} is a string that specifies the the location of the file,
+ specifies the include file to be in @file{gcc/config/target/filestuff}. The
+ directory @file{gcc/config/target} is regarded as the default directory.
+ 
+ 
+ Machine descriptions may be split up into smaller more manageable subsections 
+ and placed into subdirectories. 
+ 
+ By specifying:
+ 
+ @smallexample
+ 
+ (include "BOGUS/filestuff") 
+ 
+ @end smallexample
+ 
+ the include file is specified to be in @file{gcc/config/@var{target}/BOGUS/filestuff}.
+ 
+ Specifying an absolute path for the include file such as;
+ @smallexample
+ 
+ (include "/u2/BOGUS/filestuff") 
+ 
+ @end smallexample
+ is permitted but is not encouraged. 
+ 
+ @subsection RTL Generation Tool Options for Directory Search
+ @cindex directory options .md
+ @cindex options, directory search
+ @cindex search options
+ 
+ The @option{-I@var{dir}} option specifies directories to search for machine descriptions.
+ For example:
+ 
+ @smallexample
+ 
+ genrecog -I/p1/abc/proc1 -I/p2/abcd/pro2 target.md
+ 
+ @end smallexample
+ 
+ 
+ Add the directory @var{dir} to the head of the list of directories to be
+ searched for header files.  This can be used to override a system machine definition
+ file, substituting your own version, since these directories are
+ searched before the default machine description file directories.  If you use more than
+ one @option{-I} option, the directories are scanned in left-to-right
+ order; the standard default directory come after.
+ 
  
  @node Peephole Definitions
  @section Machine-Specific Peephole Optimizers

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 14:05   ` Alan Matsuoka
  2001-11-05 18:22     ` Aldy Hernandez
@ 2001-11-13  4:32     ` Alan Matsuoka
  2001-11-13 15:03     ` Alan Matsuoka
  2 siblings, 0 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Geoff Keating; +Cc: aldyh, gcc-patches

> Do you really need this?  It looks just like the way a normal memory
> operand is printed (for the cases that are allowed for altivec).
> 
> > Index: rs6000.md
> 
> Can you put the altivec insns in their own .md file and use the include
> mechanism?  I believe this is what it was intended for.

Who does the approvals for my patches? I sent them out ages ago. I
guess I'd better do it again ....



> 
> > + ;; No code is needed to copy between vector registers.
> > + (define_insn "*altivec_vec_move"
> > +   [(set (match_operand 0 "altivec_register" "=v")
> > + 	(match_operand 1 "altivec_register" "v"))]
> > +   "TARGET_ALTIVEC"
> > +   ""
> > +   [(set_attr "type" "altivec")])
> 
> Um, that can't possibly be right.  Also, it should be part of
> movv4si_internal, because reload needs all the move insns to be the
> same pattern.
> 
> > + ;; Vector move instructions.
> > + (define_expand "movv4si"
> > +   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
> > + 	(match_operand:V4SI 1 "any_operand" ""))]
> > +   "TARGET_ALTIVEC"
> > +   "{ rs6000_emit_move (operands[0], operands[1], V4SImode); DONE; }")
> > + 
> > + (define_insn "*movv4si_internal"
> > +   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v")
> > + 	(match_operand:V4SI 1 "input_operand" "v,m"))]
> > +   "TARGET_ALTIVEC"
> > +   "@
> > +    stvx\t%1,%y0
> > +    ldvx\t%0,%y1"
> > +   [(set_attr "type" "altivec")])
> 
> Yes---this needs an alternative to copy a 'v' into a 'v'.  All the
> ones below probably need it too.
> 
> > + (define_expand "movv8hi"
> > +   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
> > + 	(match_operand:V8HI 1 "any_operand" ""))]
> > +   "TARGET_ALTIVEC"
> > +   "{ rs6000_emit_move (operands[0], operands[1], V8HImode); DONE; }")
> > + 
> > + (define_insn "*movv8hi_internal1"
> > +   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=m,v")
> > + 	(match_operand:V8HI 1 "input_operand" "v,m"))]
> > +   "TARGET_ALTIVEC"
> > +   "@
> > +    stvx\t%1,%y0
> > +    ldvx\t%0,%y1"
> > +   [(set_attr "type" "altivec")])
> > + 
> > + (define_expand "movv16qi"
> > +   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
> > + 	(match_operand:V16QI 1 "any_operand" ""))]
> > +   "TARGET_ALTIVEC"
> > +   "{ rs6000_emit_move (operands[0], operands[1], V16QImode); DONE; }")
> > + 
> > + (define_insn "*movv16qi_internal1"
> > +   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=m,v")
> > + 	(match_operand:V16QI 1 "input_operand" "v,m"))]
> > +   "TARGET_ALTIVEC"
> > +   "@
> > +    stvx\t%1,%y0
> > +    ldvx\t%0,%y1"
> > +   [(set_attr "type" "altivec")])
> > + 
> > + (define_expand "movv4sf"
> > +   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
> > + 	(match_operand:V4SF 1 "any_operand" ""))]
> > +   "TARGET_ALTIVEC"
> > +   "{ rs6000_emit_move (operands[0], operands[1], V4SFmode); DONE; }")
> > + 
> > + (define_insn "*movv4sf_internal1"
> > +   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=m,v")
> > + 	(match_operand:V4SF 1 "input_operand" "v,m"))]
> > +   "TARGET_ALTIVEC"
> > +   "@
> > +    stvx\t%1,%y0
> > +    ldvx\t%0,%y1"
> > +   [(set_attr "type" "altivec")])
> > + 
> > + ;; Simple binary operations.
> > + 
> > 
> > -- boring builtins deleted-- 
> > 
> > + (define_insn "altivec_vxor"
> > +   [(set (match_operand:V4SI 0 "register_operand" "=v")
> > +         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
> > +                       (match_operand:V4SI 2 "register_operand" "v")] 136))]
> > +   "TARGET_ALTIVEC"
> > +   "vxor\t%0,%1,%2"
> > +   [(set_attr "type" "altivec")])
> 
> -- 
> - Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>


Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-05 18:58           ` Aldy Hernandez
  2001-11-05 19:01             ` Alan Matsuoka
  2001-11-05 21:37             ` Alan Matsuoka
@ 2001-11-13  4:32             ` Aldy Hernandez
  2001-11-13 15:03             ` Aldy Hernandez
  3 siblings, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: Geoff Keating, gcc patches

is it recursive?  i mean, can you include files from within include
files?

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-05 18:49           ` Joseph S. Myers
  2001-11-05 19:03             ` Alan Matsuoka
@ 2001-11-13  4:32             ` Joseph S. Myers
  2001-11-13 15:03             ` Joseph S. Myers
  2 siblings, 0 replies; 152+ messages in thread
From: Joseph S. Myers @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: gcc-patches

On Mon, 5 Nov 2001, Alan Matsuoka wrote:

> + Where @var{pathname} is a string that specifies the the location of the file,
> + specifies the include file to be in gcc/config/{target}/filestuff. The

@file{gcc/config/@var{target}/filestuff}.

> + directory @file{ gcc/config/{target}} is regarded as the default directory.

No space after the open brace.  @var{target}.

> + the include file is specified to be in @file{gcc/config/{target}/BOGUS/filestuff}.

@var{target}.

> + The -I@var{dir} option specifies directories to search for machine descriptions.

@option{-I@var{dir}}.

> + @table @gcctabopt
> + @item -I@var{dir}
> + @opindex I

The option index is an index of GCC options, options for support tools
should not have @opindex index entries.

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 20:10     ` Geoff Keating
@ 2001-11-13  4:32       ` Geoff Keating
  2001-11-13 15:03       ` Geoff Keating
  1 sibling, 0 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-13  4:32 UTC (permalink / raw)
  To: aldyh; +Cc: gcc-patches

> Cc: gcc-patches@gcc.gnu.org
> From: Aldy Hernandez <aldyh@redhat.com>
> Date: 05 Nov 2001 22:29:51 -0500

>  > The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
>  > quite right:  it has to happen _only when the ABI is 'altivec'_.
> 
> I took it out because it needs rethinking.  DWARF_FRAME_REGISTERS is
> used as an array size in a few places, particulary unwind-dw2.c.  So I
> need to change all these places to dynamically allocate their space.

Before changing anything in the unwinder code, you must first make
sure that you're not changing an ABI.  I don't know what the new rules
are on this, with shared libgcc and all, so I will leave you to figure
them out (and please tell me when you do!).  You'll probably want to
ask on the glibc lists.

>  > This will be a bit tricky because DWARF_FRAME_REGISTERS is also used
>  > in libgcc, so you have to #define something when the Altivec ABI is
>  > chosen, and then key off that if IN_LIBGCC2.
> 
>  > I wonder if you could assume that the integrated cpplib will always be
>  > used when compiling libgcc?  That would make things easier, because
>  > then you wouldn't have muck with specs so much.
> 
> Please explain.  I only see DWARF_FRAME_REGISTERS being used in
> dwarf2out.c and unwind-dw2.c.  There is nothing in libgcc*.

unwind-dw2.c is part of libgcc, see LIB2ADDEH in Makefile.in.  I don't
knew about the new arrangement, but it used to be that 'struct
_Unwind_Context' (or equivalent) was passed between a bit of libgcc
that was compiled into glibc, and another bit of libgcc that was
compiled into applications.  Thus, you couldn't change
DWARF_FRAME_REGISTERS because that would change a glibc ABI.

For EABI (as opposed to SVR4/Linux), you can probably change this even
for non-altivec EABI, since libgcc doesn't get split up like that for
embedded systems and libgcc isn't part of the EABI and there hasn't
been any real C++ binary compatibility anyway.

>  >> /* No data type wants to be aligned rounder than this.  */
>  >> #undef	BIGGEST_ALIGNMENT
>  >> ! #define BIGGEST_ALIGNMENT ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
>  >> 
>  >> + /* An expression for the alignment of a structure field FIELD if the
>  >> +    alignment computed in the usual way is COMPUTED.  */
>  >> + #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)				      \
>  >> + 	((TARGET_ALTIVEC_ABI && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
>  >> + 	 ? 128 : COMPUTED)
>  >> + 
>  >> + /* Define this macro as an expression for the alignment of a type
>  >> +    (given by TYPE as a tree node) if the alignment computed in the
>  >> +    usual way is COMPUTED and the alignment explicitly specified was
>  >> +    SPECIFIED.  */
>  >> + #define ROUND_TYPE_ALIGN(TYPE, COMPUTED, SPECIFIED)			\
>  >> + 	((TARGET_ALTIVEC_ABI && TREE_CODE (TYPE) == VECTOR_TYPE)	\
>  >> + 	 ? 128 : MAX (COMPUTED, SPECIFIED))
>  >> + 
>  >> #undef  BIGGEST_FIELD_ALIGNMENT
>  >> #undef  ADJUST_FIELD_ALIGN
>  >> 
>  >> /* Use ELF style section commands.  */
> 
>  > This has the same comment as the equivalent stuff in rs6000.h.
> 
> Huh?  What do you mean?

I had some comments about the changes in rs6000.h to BIGGEST_ALIGNMENT
etc.; these are the sysv4.h changes to BIGGEST_ALIGNMENT, and the same
comments apply.

> This is just for unnamed arguments in varargs.  So I'll have to add:
> 
>         if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
>                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> done. (?)

OK, whatever works.  I just wanted to be sure you knew about the
weirdness.

>  >> +       /* Print AltiVec memory operand.  */
>  >> +     case 'y':
>  >> +       {
>  >> + 	rtx tmp;
>  >> + 
>  >> + 	if (GET_CODE (x) != MEM)
>  >> + 	  abort ();
>  >> + 
>  >> + 	tmp = XEXP (x, 0);
>  >> + 
>  >> + 	if (GET_CODE (tmp) == REG)
>  >> + 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
>  >> + 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
>  >> + 	  {
>  >> + 	    if (REGNO (XEXP (tmp, 0)) == 0)
>  >> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
>  >> + 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
>  >> + 	    else
>  >> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
>  >> + 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
>  >> + 	  }
>  >> + 	else
>  >> + 	  abort ();
>  >> + 	break;
>  >> +       }
> 
>  > Do you really need this?  It looks just like the way a normal memory
>  > operand is printed (for the cases that are allowed for altivec).
> 
> Yes I do.  I want "[reg+reg]" to be outputed as "reg,reg" and [reg] to
> be outputed as "reg,0".
> 
> Consider "lvx d,a,b".  I want to match:
> 
>         (set (reg) (mem))
> 
> and have (mem) be dumped as "a,b" (the two registers in the memory
> address: (plus (reg) (reg))).  

I guess it's not quite the same as the behaviour for 'lwz', because of
the behaviour on just (reg).  This bit is OK, then.

>  > Can you put the altivec insns in their own .md file and use the include
>  > mechanism?  I believe this is what it was intended for.
> 
> As soon as you approve Alan's patch, yes :).

I'll look at it :-).

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-06  4:56                 ` Alan Matsuoka
  2001-11-06  7:58                   ` Alan Matsuoka
@ 2001-11-13  4:32                   ` Alan Matsuoka
  2001-11-13 15:03                   ` Alan Matsuoka
  2 siblings, 0 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc-patches

On Tue, 06 Nov 2001, Joseph S. Myers wrote:

> On Mon, 5 Nov 2001, Alan Matsuoka wrote:
> 
> > + Where @var{pathname} is a string that specifies the the location of the file,
> > + specifies the include file to be in gcc/config/{target}/filestuff. The
> 
> @file{gcc/config/@var{target}/filestuff}.
> 
> > + directory @file{gcc/config/{target}} is regarded as the default directory.
> 
> @var{target}.
> 
> Has this patch passed "make info" and "make dvi"?


I'll sumbit a revised patch as soon as the cvs server lets me
generate a patch.


Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 14:38   ` Geoff Keating
@ 2001-11-13  4:32     ` Geoff Keating
  2001-11-13 15:03     ` Geoff Keating
  1 sibling, 0 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Dale Johannesen; +Cc: gcc-patches, aldyh

Dale Johannesen <dalej@apple.com> writes:

> >   /* Boundary (in *bits*) on which stack pointer should be aligned.  */
> > ! #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 
> > 128)
> 
> If you plan to support linking files compiled with and without 
> -fabi=altivec,
> shouldn't this be 128 unconditionally?  Otherwise the stack might not be
> 128-bit aligned when you enter an Altivec function.  Also in sysv4.h.

By definition, you can't expect to link together files compiled with
different ABIs.  This is one example of the problem; another is the
varargs changes that Aldy hasn't done yet.

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 12:59 ` Joseph S. Myers
  2001-11-05 13:04   ` Aldy Hernandez
@ 2001-11-13  4:32   ` Joseph S. Myers
  2001-11-13 15:03   ` Joseph S. Myers
  2 siblings, 0 replies; 152+ messages in thread
From: Joseph S. Myers @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: gcc patches

On 5 Nov 2001, Aldy Hernandez wrote:

> + @item -mabi=altivec
> + @opindex mabi=altivec
> + Extend the current ABI with AltiVec ABI extensions.  This does not
> + change the default ABI, instead it adds the AltiVec ABI extensions to
> + the current ABI.

That should end "ABI@." so that spacing after the sentence is correct if
more text gets added to that paragraph later.

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 18:28       ` Alan Matsuoka
  2001-11-05 18:41         ` Include facility for .md files - " Alan Matsuoka
@ 2001-11-13  4:32         ` Alan Matsuoka
  2001-11-13 15:03         ` Alan Matsuoka
  2 siblings, 0 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Geoff Keating, gcc-patches

On Mon, 05 Nov 2001, Aldy Hernandez wrote:

> >>>>> "Alan" == Alan Matsuoka <alanm@cygnus.com> writes:
> 
>  >> Do you really need this?  It looks just like the way a normal memory
>  >> operand is printed (for the cases that are allowed for altivec).
>  >> 
>  >> > Index: rs6000.md
>  >> 
>  >> Can you put the altivec insns in their own .md file and use the include
>  >> mechanism?  I believe this is what it was intended for.
> 
> Last i heard, alan matsuoka's include mechanism hadn't been approved.
> Alan, perhaps you should send them again.  We definitely need them
> now.

OK.

Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-05 19:03             ` Alan Matsuoka
  2001-11-06  1:03               ` Joseph S. Myers
@ 2001-11-13  4:32               ` Alan Matsuoka
  2001-11-13 15:03               ` Alan Matsuoka
  2 siblings, 0 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc-patches

On Tue, 06 Nov 2001, Joseph S. Myers wrote:

> On Mon, 5 Nov 2001, Alan Matsuoka wrote:
> 
> > + Where @var{pathname} is a string that specifies the the location of the file,
> > + specifies the include file to be in gcc/config/{target}/filestuff. The
> 
> @file{gcc/config/@var{target}/filestuff}.
> 
> > + directory @file{ gcc/config/{target}} is regarded as the default directory.
> 
> No space after the open brace.  @var{target}.

Fixed.
> 
> > + the include file is specified to be in @file{gcc/config/{target}/BOGUS/filestuff}.
> 
> @var{target}.
> 
> > + The -I@var{dir} option specifies directories to search for machine descriptions.

Fixed.
> 
> @option{-I@var{dir}}.
> 
> > + @table @gcctabopt
> > + @item -I@var{dir}
> > + @opindex I

deleted.
> 
> The option index is an index of GCC options, options for support tools
> should not have @opindex index entries.
> 
> -- 
> 

Thank you.

Index: md.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/md.texi,v
retrieving revision 1.26
diff -3 -c -p -r1.26 md.texi
*** md.texi	2001/10/25 18:25:08	1.26
--- md.texi	2001/11/06 02:58:26
*************** See the next chapter for information on 
*** 38,43 ****
--- 38,44 ----
  * Expander Definitions::Generating a sequence of several RTL insns
                            for a standard operation.
  * Insn Splitting::      Splitting Instructions into Multiple Instructions.
+ * Including Patterns::      Including Patterns in Machine Descriptions.
  * Peephole Definitions::Defining machine-specific peephole optimizations.
  * Insn Attributes::     Specifying the value of attributes for generated insns.
  * Conditional Execution::Generating @code{define_insn} patterns for
*************** The @code{define_insn_and_split} constru
*** 3909,3914 ****
--- 3910,3992 ----
  functionality as two separate @code{define_insn} and @code{define_split}
  patterns.  It exists for compactness, and as a maintenance tool to prevent
  having to ensure the two patterns' templates match.
+ 
+ @node Including Patterns
+ @section Including Patterns in Machine Descriptions.
+ @cindex insn includes
+ 
+ @findex include
+ The @code{include} pattern tells the compiler tools where to
+ look for patterns that are in files other than in the file
+ @file{.md}. This is used only at build time and there is no preprocessing allowed.
+ 
+ It looks like:
+ 
+ @smallexample
+ 
+ (include
+   @var{pathname})
+ @end smallexample
+ 
+ For example:
+ 
+ @smallexample
+ 
+ (include "filestuff") 
+ 
+ @end smallexample
+ 
+ Where @var{pathname} is a string that specifies the the location of the file,
+ specifies the include file to be in gcc/config/{target}/filestuff. The
+ directory @file{gcc/config/{target}} is regarded as the default directory.
+ 
+ 
+ Machine descriptions may be split up into smaller more manageable subsections 
+ and placed into subdirectories. 
+ 
+ By specifying:
+ 
+ @smallexample
+ 
+ (include "BOGUS/filestuff") 
+ 
+ @end smallexample
+ 
+ the include file is specified to be in @file{gcc/config/@var{target}/BOGUS/filestuff}.
+ 
+ Specifying an absolute path for the include file such as;
+ @smallexample
+ 
+ (include "/u2/BOGUS/filestuff") 
+ 
+ @end smallexample
+ is permitted but is not encouraged. 
+ 
+ @node .md Directory Options
+ @subsection RTL Generation Tool Options for Directory Search
+ @cindex directory options .md
+ @cindex options, directory search
+ @cindex search path
+ 
+ The @option{-I@var{dir}} option specifies directories to search for machine descriptions.
+ For example:
+ 
+ @smallexample
+ 
+ genrecog -I/p1/abc/proc1 -I/p2/abcd/pro2 target.md
+ 
+ @end smallexample
+ 
+ 
+ Add the directory @var{dir} to the head of the list of directories to be
+ searched for header files.  This can be used to override a system machine definition
+ file, substituting your own version, since these directories are
+ searched before the default machine description file directories.  If you use more than
+ one @option{-I} option, the directories are scanned in left-to-right
+ order; the standard default directory come after.
+ 
+ @end table
+ 
  
  @node Peephole Definitions
  @section Machine-Specific Peephole Optimizers


Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 19:30       ` Aldy Hernandez
@ 2001-11-13  4:32         ` Aldy Hernandez
  2001-11-13 15:03         ` Aldy Hernandez
  1 sibling, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Geoff Keating; +Cc: Stan Shebs, gcc-patches

>>>>> "Geoff" == Geoff Keating <geoffk@geoffk.org> writes:

 > DWARF_FRAME_REGISTERS was invented, so people could add registers
 > without breaking binary compatibility.

But as it stands now it's value can't be dynamic-- say, with an abi
flag-- because it's value is used in places where it is expected to be
a constant (array sizes un unwind-dw2.c).

I will remedy this situation in another patch.

Aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 12:58 ` Aldy Hernandez
@ 2001-11-13  4:32   ` Aldy Hernandez
  2001-11-13 15:03   ` Aldy Hernandez
  1 sibling, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13  4:32 UTC (permalink / raw)
  To: gcc patches; +Cc: Geoff Keating

>>>>> "Aldy" == Aldy Hernandez <aldyh@redhat.com> writes:

 > what is left?

Oh yeah, and I also need to fill in pipeline info (altivec function
units, etc).

Aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 14:49     ` Geoff Keating
  2001-11-05 15:29       ` Stan Shebs
  2001-11-05 19:30       ` Aldy Hernandez
@ 2001-11-13  4:32       ` Geoff Keating
  2001-11-13 15:03       ` Geoff Keating
  3 siblings, 0 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Stan Shebs; +Cc: gcc-patches

Stan Shebs <shebs@apple.com> writes:

> Geoff Keating wrote:
> > 
> > The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
> > quite right:  it has to happen _only when the ABI is 'altivec'_.
> > 
> > This will be a bit tricky because DWARF_FRAME_REGISTERS is also used
> > in libgcc, so you have to #define something when the Altivec ABI is
> > chosen, and then key off that if IN_LIBGCC2.
> 
> Thus we slide down the slippery slope... Solving this completely
> eventually entails having a method to detect whether the CPU
> supports AltiVec instructions - in the case of a C++ throw
> in code using AltiVec registers, you need to detect dynamically
> (Apple's GCC uses a bit set by the kernel) whether you're on a
> G4 or a not-G4.  So you may have to generate a frame descriptor
> that mentions registers you won't actually manipulate on a not-G4.

Unfortunately, such a method doesn't exist in many environments.  (In
particular, it's not in the powerpc UISA, which is all you can really
rely on in GCC.)

> Our GCC just sets DWARF_FRAME_REGISTERS to FIRST_PSEUDO_REGISTERS
> unconditionally, seems to work well enough for non-AltiVec code.

Can't do that; breaks backwards binary compatibility.  That's why
DWARF_FRAME_REGISTERS was invented, so people could add registers
without breaking binary compatibility.

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 19:47   ` Aldy Hernandez
@ 2001-11-13  4:32     ` Aldy Hernandez
  2001-11-13 15:03     ` Aldy Hernandez
  1 sibling, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Dale Johannesen; +Cc: gcc patches, Geoff Keating

> I'd really like to see vrsave in the enums and register macros
> (not necessarily the code).  I dislike making a major change to
> an area if we know it's going to change again shortly.

done

> > +    : ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_REGNO_P (REGNO)		\
> > +    : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE)		\
> >      : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC		\
> >      : XER_REGNO_P (REGNO) ? (MODE) == PSImode				\
> >      : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT		\
> 
> I don't think you want the first changed line here.

fixed

> >      : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10	\
> >      : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10	\
> > +    : (CLASS1) == ALTIVEC_REGS && (CLASS2) != ALTIVEC_REGS ? 20	\
> >      : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS		\
> >          || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS		\
> >          || (CLASS1) == LINK_OR_CTR_REGS)				\
> 
> And here you need
> 	: (CLASS1) != ALTIVEC_REGS && (CLASS2) == ALTIVEC_REGS ? 20
> analogous to the FLOAT case.

whoops.  done.

> > +   && ! ALTIVEC_VECTOR_MODE (MODE)				\
> >     && (((MODE) != DFmode && (MODE) != DImode)			\
> >         || (TARGET_32BIT						\
> >   	  ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) 	\
> 
> That could be
> 	  && ( ! ALTIVEC_VECTOR_MODE (MODE) || INTVAL (X) == 0)
> for better codegen.  It's not wrong as is, though.

done

thanks for your corrections.  hopefully we'll only need one more
iteration through this.

aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-05 19:01             ` Alan Matsuoka
@ 2001-11-13  4:32               ` Alan Matsuoka
  2001-11-13 15:03               ` Alan Matsuoka
  1 sibling, 0 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Geoff Keating, gcc patches

On Mon, 05 Nov 2001, Aldy Hernandez wrote:

> is it recursive?  i mean, can you include files from within include
> files?

Yes it is. 


Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Include facility for .md files - altivec patches
  2001-11-05 18:41         ` Include facility for .md files - " Alan Matsuoka
                             ` (3 preceding siblings ...)
  2001-11-06  0:23           ` Gerald Pfeifer
@ 2001-11-13  4:32           ` Alan Matsuoka
  2001-11-13 15:03           ` Alan Matsuoka
  5 siblings, 0 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Geoff Keating, gcc-patches

On Mon, 05 Nov 2001, Alan Matsuoka wrote:

> On Mon, 05 Nov 2001, Aldy Hernandez wrote:
> 
> > >>>>> "Alan" == Alan Matsuoka <alanm@cygnus.com> writes:
> > 
> >  >> Do you really need this?  It looks just like the way a normal memory
> >  >> operand is printed (for the cases that are allowed for altivec).
> >  >> 
> >  >> > Index: rs6000.md
> >  >> 
> >  >> Can you put the altivec insns in their own .md file and use the include
> >  >> mechanism?  I believe this is what it was intended for.
> > 
> > Last i heard, alan matsuoka's include mechanism hadn't been approved.
> > Alan, perhaps you should send them again.  We definitely need them
> > now.
> 
> OK.
> 

The following patch is for the an internal project. This is 
implements a (include "filestuff") mechanism for splitting up 
.md files.

(include "filestuff") expects the include file to be in gcc/config/{target}/filestuff
(include "BOGUS/filestuff") expects the include file to be in gcc/config/{target}/BOGUS/filestuff
(include "/u2/BOGUS/filestuff") expects the include file to be in /u2/BOGUS/filestuff

You can also run things like genrecog -I/p1/abc/proc1 -I/p2/abcd/pro2 target.md

This is used only at build time.

This has been tested for i686-pc-linux-gnu by bootstrapping and testing without 
any regressions.

The DOS pathname style stuff may still be required.


2001-11-05  Alan Matsuoka  <alanm@redhat.com>

        * rtl.def (INCLUDE) : Define.
	* gensupport.c (init_include_reader, process_include, save_string) :  New functions to
	  implement an include facility in .md files.
	* gensupport.h : Add prototype for init_md_reader_args.
	* genattr.c genattrtab.c gencodes.c genconfig.c genemit.c
	  genextract.c genflags.c genopinit.c genoutput.c genpeep.c
	  genrecog.c: Change call to init_md_reader to init_md_reader_args.
	* md.texi: Document (include "path") and -I directives for RTL generation tools.

Index: genattr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genattr.c,v
retrieving revision 1.45
diff -3 -c -p -r1.45 genattr.c
*** genattr.c	2001/10/07 16:50:51	1.45
--- genattr.c	2001/11/06 02:32:32
*************** main (argc, argv)
*** 210,216 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genattr'");
--- 210,216 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genattr'");
Index: genattrtab.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genattrtab.c,v
retrieving revision 1.103
diff -3 -c -p -r1.103 genattrtab.c
*** genattrtab.c	2001/10/21 21:32:00	1.103
--- genattrtab.c	2001/11/06 02:32:58
*************** main (argc, argv)
*** 6075,6081 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    obstack_init (hash_obstack);
--- 6075,6081 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    obstack_init (hash_obstack);
Index: gencodes.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gencodes.c,v
retrieving revision 1.42
diff -3 -c -p -r1.42 gencodes.c
*** gencodes.c	2001/08/22 14:35:16	1.42
--- gencodes.c	2001/11/06 02:32:58
*************** main (argc, argv)
*** 56,62 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("\
--- 56,62 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("\
Index: genconfig.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genconfig.c,v
retrieving revision 1.43
diff -3 -c -p -r1.43 genconfig.c
*** genconfig.c	2001/10/11 07:07:26	1.43
--- genconfig.c	2001/11/06 02:33:00
*************** main (argc, argv)
*** 277,283 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genconfig'");
--- 277,283 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genconfig'");
Index: genemit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genemit.c,v
retrieving revision 1.67
diff -3 -c -p -r1.67 genemit.c
*** genemit.c	2001/10/19 19:37:08	1.67
--- genemit.c	2001/11/06 02:33:05
*************** main (argc, argv)
*** 789,795 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
--- 789,795 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
Index: genextract.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genextract.c,v
retrieving revision 1.46
diff -3 -c -p -r1.46 genextract.c
*** genextract.c	2001/10/11 03:15:42	1.46
--- genextract.c	2001/11/06 02:33:07
*************** main (argc, argv)
*** 362,368 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
--- 362,368 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
Index: genflags.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genflags.c,v
retrieving revision 1.39
diff -3 -c -p -r1.39 genflags.c
*** genflags.c	2001/10/11 03:15:42	1.39
--- genflags.c	2001/11/06 02:33:07
*************** main (argc, argv)
*** 230,236 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
    
    puts ("/* Generated automatically by the program `genflags'");
--- 230,236 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
    
    puts ("/* Generated automatically by the program `genflags'");
Index: genopinit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genopinit.c,v
retrieving revision 1.48
diff -3 -c -p -r1.48 genopinit.c
*** genopinit.c	2001/09/13 14:37:11	1.48
--- genopinit.c	2001/11/06 02:33:07
*************** main (argc, argv)
*** 316,322 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genopinit'\n\
--- 316,322 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genopinit'\n\
Index: genoutput.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genoutput.c,v
retrieving revision 1.65
diff -3 -c -p -r1.65 genoutput.c
*** genoutput.c	2001/10/11 03:15:42	1.65
--- genoutput.c	2001/11/06 02:33:10
*************** main (argc, argv)
*** 953,959 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    output_prologue ();
--- 953,959 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    output_prologue ();
Index: genpeep.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genpeep.c,v
retrieving revision 1.49
diff -3 -c -p -r1.49 genpeep.c
*** genpeep.c	2001/10/11 03:15:43	1.49
--- genpeep.c	2001/11/06 02:33:14
*************** main (argc, argv)
*** 385,391 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genpeep'\n\
--- 385,391 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genpeep'\n\
Index: genrecog.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genrecog.c,v
retrieving revision 1.111
diff -3 -c -p -r1.111 genrecog.c
*** genrecog.c	2001/10/28 20:09:14	1.111
--- genrecog.c	2001/11/06 02:33:19
*************** main (argc, argv)
*** 2689,2695 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    next_insn_code = 0;
--- 2689,2695 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    next_insn_code = 0;
Index: gensupport.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gensupport.c,v
retrieving revision 1.23
diff -3 -c -p -r1.23 gensupport.c
*** gensupport.c	2001/10/25 12:55:16	1.23
--- gensupport.c	2001/11/06 02:33:20
*************** static int predicable_default;
*** 42,47 ****
--- 42,49 ----
  static const char *predicable_true;
  static const char *predicable_false;
  
+ static char *base_dir = NULL;
+ 
  /* We initially queue all patterns, process the define_insn and
     define_cond_exec patterns, then return them one at a time.  */
  
*************** static struct queue_elem *other_queue;
*** 62,67 ****
--- 64,86 ----
  static struct queue_elem **other_tail = &other_queue;
  
  static void queue_pattern PARAMS ((rtx, struct queue_elem ***, int));
+ 
+ /* Current maximum length of directory names in the search path
+    for include files.  (Altered as we get more of them.)  */
+ 
+ size_t max_include_len;
+ 
+ struct file_name_list
+   {
+     struct file_name_list *next;
+     const char *fname;
+   };
+ 
+ struct file_name_list *include = 0;     /* First dir to search */
+         /* First dir to search for <file> */
+ struct file_name_list *first_bracket_include = 0;
+ struct file_name_list *last_include = 0;        /* Last in chain */
+ 
  static void remove_constraints PARAMS ((rtx));
  static void process_rtx PARAMS ((rtx, int));
  
*************** static const char *alter_output_for_insn
*** 78,83 ****
--- 97,105 ----
  						  int, int));
  static void process_one_cond_exec PARAMS ((struct queue_elem *));
  static void process_define_cond_exec PARAMS ((void));
+ static int process_include PARAMS ((rtx, int));
+ static char *save_string PARAMS ((const char *, int));
+ static int init_include_reader PARAMS ((FILE  *));
  \f
  void
  message_with_line VPARAMS ((int lineno, const char *msg, ...))
*************** remove_constraints (part)
*** 157,162 ****
--- 179,320 ----
        }
  }
  
+ /* The entry point for initializing the reader.  */
+ 
+ static int
+ init_include_reader (inf)
+      FILE *inf;
+ {
+   int c;
+ 
+   errors = 0;
+ 
+   /* Read the entire file.  */
+   while (1)
+     {
+       rtx desc;
+       int lineno;
+ 
+       c = read_skip_spaces (inf);
+       if (c == EOF)
+ 	break;
+ 
+       ungetc (c, inf);
+       lineno = read_rtx_lineno;
+       desc = read_rtx (inf);
+       process_rtx (desc, lineno);
+     }
+   fclose (inf);
+ 
+   /* Process define_cond_exec patterns.  */
+   if (define_cond_exec_queue != NULL)
+     process_define_cond_exec ();
+ 
+   return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
+ }
+ 
+ /* Process an include file assuming that it lives in gcc/config/{target}/ 
+    if the include looks line (include "file" )  */
+ static int
+ process_include (desc, lineno)
+      rtx desc;
+      int lineno;
+ {
+   const char *filename = XSTR (desc, 0);
+   char *pathname = NULL;
+   FILE *input_file;
+   char *fname;
+   struct file_name_list *stackp;
+   int flen;
+ 
+   stackp = include;
+ 
+   /* If specified file name is absolute, just open it.  */
+   if (IS_ABSOLUTE_PATHNAME (filename) || !stackp)
+     {
+       if (base_dir)
+         {
+           pathname = xmalloc (strlen (base_dir) + strlen (filename) + 1);
+           pathname = strcpy (pathname, base_dir);
+           strcat (pathname, filename);
+           strcat (pathname, "\0");
+ 	}
+       else
+         {
+ 	  pathname = xstrdup (filename);
+         }
+       read_rtx_filename = pathname;
+       input_file = fopen (pathname, "r");
+ 
+       if (input_file == 0)
+ 	{
+ 	  perror (pathname);
+ 	  return FATAL_EXIT_CODE;
+ 	}
+     }
+   else if (stackp)
+     {
+ 
+       flen = strlen (filename);
+ 
+       fname = (char *) alloca (max_include_len + flen + 2);
+ 
+       /* + 2 above for slash and terminating null.  */
+ 
+       /* Search directory path, trying to open the file.
+          Copy each filename tried into FNAME.  */
+ 
+       for (; stackp; stackp = stackp->next)
+ 	{
+ 	  if (stackp->fname)
+ 	    {
+ 	      strcpy (fname, stackp->fname);
+ 	      strcat (fname, "/");
+ 	      fname[strlen (fname) + flen] = 0;
+ 	    }
+ 	  else
+ 	    {
+ 	      fname[0] = 0;
+ 	    }
+ 	  strncat (fname, (const char *) filename, flen);
+ 	  read_rtx_filename = fname;
+ 	  input_file = fopen (fname, "r");
+ 	  if (input_file != NULL) 
+ 	    break;
+ 	}
+       if (stackp == NULL)
+ 	{
+ 	  if (strchr (fname, '/') == NULL || strchr (fname, '\\' ) || base_dir)
+ 	    {
+ 	      if (base_dir)
+ 		{
+ 		  pathname =
+ 		    xmalloc (strlen (base_dir) + strlen (filename) + 1);
+ 		  pathname = strcpy (pathname, base_dir);
+ 		  strcat (pathname, filename);
+ 		  strcat (pathname, "\0");
+ 		}
+ 	      else
+ 		pathname = xstrdup (filename);
+ 	    }
+ 	  read_rtx_filename = pathname;
+ 	  input_file = fopen (pathname, "r");
+ 
+ 	  if (input_file == 0)
+ 	    {
+ 	      perror (filename);
+ 	      return FATAL_EXIT_CODE;
+ 	    }
+ 	}
+ 
+     }
+ 
+   if (init_include_reader (input_file) == FATAL_EXIT_CODE)
+     message_with_line (lineno, "read errors found in include file  %s\n", pathname);
+ 
+   return SUCCESS_EXIT_CODE;
+ }
+ 
  /* Process a top level rtx in some way, queueing as appropriate.  */
  
  static void
*************** process_rtx (desc, lineno)
*** 164,169 ****
--- 322,329 ----
       rtx desc;
       int lineno;
  {
+   const char *filename = XSTR (desc, 0);
+ 
    switch (GET_CODE (desc))
      {
      case DEFINE_INSN:
*************** process_rtx (desc, lineno)
*** 178,183 ****
--- 338,348 ----
        queue_pattern (desc, &define_attr_tail, lineno);
        break;
  
+     case INCLUDE:
+       if (process_include (desc, lineno) == FATAL_EXIT_CODE)
+         message_with_line (lineno, "include file at  %s not found\n", filename);
+       break;
+ 
      case DEFINE_INSN_AND_SPLIT:
        {
  	const char *split_cond;
*************** process_define_cond_exec ()
*** 767,781 ****
--- 932,1022 ----
    for (elem = define_cond_exec_queue; elem ; elem = elem->next)
      process_one_cond_exec (elem);
  }
+ 
+ static char *
+ save_string (s, len)
+      const char *s;
+      int len;
+ {
+   register char *result = xmalloc (len + 1);
+ 
+   memcpy (result, s, len);
+   result[len] = 0;
+   return result;
+ }
+ 
  \f
  /* The entry point for initializing the reader.  */
  
  int
+ init_md_reader_args (argc, argv)
+      int argc;
+      char **argv;
+ {
+   int i;
+   const char *in_fname;
+ 
+   max_include_len = 0;
+   in_fname = NULL;
+   for (i = 1; i < argc; i++)
+     {
+       if (argv[i][0] != '-')
+ 	{
+ 	  if (in_fname == NULL)
+ 	    in_fname = argv[i];
+ 	}
+       else
+ 	{
+ 	  int c = argv[i][1];
+ 	  switch (c)
+ 	    {
+ 	    case 'I':		/* Add directory to path for includes.  */
+ 	      {
+ 		struct file_name_list *dirtmp;
+ 
+ 		dirtmp = (struct file_name_list *)
+ 		  xmalloc (sizeof (struct file_name_list));
+ 		dirtmp->next = 0;	/* New one goes on the end */
+ 		if (include == 0)
+ 		  include = dirtmp;
+ 		else
+ 		  last_include->next = dirtmp;
+ 		last_include = dirtmp;	/* Tail follows the last one */
+ 		if (argv[i][1] == 'I' && argv[i][2] != 0)
+ 		  dirtmp->fname = argv[i] + 2;
+ 		else if (i + 1 == argc)
+ 		  fatal ("Directory name missing after -I option");
+ 		else
+ 		  dirtmp->fname = argv[++i];
+ 		if (strlen (dirtmp->fname) > max_include_len)
+ 		  max_include_len = strlen (dirtmp->fname);
+ 	      }
+ 	      break;
+ 	    default:
+ 	      fatal ("Invalid option `%s'", argv[i]);
+ 
+ 	    }
+ 	}
+     }
+     return init_md_reader (in_fname);
+ }
+ \f
+ /* The entry point for initializing the reader.  */
+ 
+ int
  init_md_reader (filename)
       const char *filename;
  {
    FILE *input_file;
    int c;
+   char *lastsl;
+ 
+   if (!IS_ABSOLUTE_PATHNAME (filename))
+     {
+       lastsl = strrchr (filename, '/');
+       if (lastsl != NULL) 
+ 	base_dir = save_string (filename, lastsl - filename + 1 );
+     }
  
    read_rtx_filename = filename;
    input_file = fopen (filename, "r");
*************** init_md_reader (filename)
*** 797,803 ****
  
        c = read_skip_spaces (input_file);
        if (c == EOF)
! 	break;
  
        ungetc (c, input_file);
        lineno = read_rtx_lineno;
--- 1038,1044 ----
  
        c = read_skip_spaces (input_file);
        if (c == EOF)
!         break;
  
        ungetc (c, input_file);
        lineno = read_rtx_lineno;
Index: gensupport.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gensupport.h,v
retrieving revision 1.3
diff -3 -c -p -r1.3 gensupport.h
*** gensupport.h	2001/08/22 14:35:17	1.3
--- gensupport.h	2001/11/06 02:33:20
*************** Software Foundation, 59 Temple Place - S
*** 21,26 ****
--- 21,27 ----
  struct obstack;
  extern struct obstack *rtl_obstack;
  
+ extern int init_md_reader_args	PARAMS ((int, char **));
  extern int init_md_reader	PARAMS ((const char *));
  extern rtx read_md_rtx		PARAMS ((int *, int *));
  
Index: rtl.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.def,v
retrieving revision 1.50
diff -3 -c -p -r1.50 rtl.def
*** rtl.def	2001/11/03 16:28:33	1.50
--- rtl.def	2001/11/06 02:33:22
*************** DEF_RTL_EXPR(UNKNOWN, "UnKnown", "*", 'x
*** 73,78 ****
--- 73,83 ----
  
  DEF_RTL_EXPR(NIL, "nil", "*", 'x')
  
+ 
+ /* include a file */
+ 
+ DEF_RTL_EXPR(INCLUDE, "include", "s", 'x')
+ 
  /* ---------------------------------------------------------------------
     Expressions used in constructing lists.
     --------------------------------------------------------------------- */
Index: gcc/gcc/doc/md.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/md.texi,v
retrieving revision 1.23
diff -c -3 -p -r1.23 md.texi
*** md.texi	2001/08/30 20:44:51	1.23
--- md.texi	2001/09/28 20:02:04
*************** See the next chapter for information on 
*** 38,43 ****
--- 38,44 ----
  * Expander Definitions::Generating a sequence of several RTL insns
                            for a standard operation.
  * Insn Splitting::      Splitting Instructions into Multiple Instructions.
+ * Including Patterns::      Including Patterns in Machine Descriptions.
  * Peephole Definitions::Defining machine-specific peephole optimizations.
  * Insn Attributes::     Specifying the value of attributes for generated insns.
  * Conditional Execution::Generating @code{define_insn} patterns for
*************** The @code{define_insn_and_split} constru
*** 3900,3905 ****
--- 3901,3986 ----
  functionality as two separate @code{define_insn} and @code{define_split}
  patterns.  It exists for compactness, and as a maintenance tool to prevent
  having to ensure the two patterns' templates match.
+ 
+ @node Including Patterns
+ @section Including Patterns in Machine Descriptions.
+ @cindex insn includes
+ 
+ @findex include
+ The @code{include} pattern tells the compiler tools where to
+ look for patterns that are in files other than in the file
+ @file{.md}. This is used only at build time and there is no preprocessing allowed.
+ 
+ It looks like:
+ 
+ @smallexample
+ 
+ (include
+   @var{pathname})
+ @end smallexample
+ 
+ For example:
+ 
+ @smallexample
+ 
+ (include "filestuff") 
+ 
+ @end smallexample
+ 
+ Where @var{pathname} is a string that specifies the the location of the file,
+ specifies the include file to be in gcc/config/{target}/filestuff. The
+ directory @file{ gcc/config/{target}} is regarded as the default directory.
+ 
+ 
+ Machine descriptions may be split up into smaller more manageable subsections 
+ and placed into subdirectories. 
+ 
+ By specifying:
+ 
+ @smallexample
+ 
+ (include "BOGUS/filestuff") 
+ 
+ @end smallexample
+ 
+ the include file is specified to be in @file{gcc/config/{target}/BOGUS/filestuff}.
+ 
+ Specifying an absolute path for the include file such as;
+ @smallexample
+ 
+ (include "/u2/BOGUS/filestuff") 
+ 
+ @end smallexample
+ is permitted but is not encouraged. 
+ 
+ @node .md Directory Options
+ @subsection RTL Generation Tool Options for Directory Search
+ @cindex directory options .md
+ @cindex options, directory search
+ @cindex search path
+ 
+ The -I@var{dir} option specifies directories to search for machine descriptions.
+ For example:
+ 
+ @smallexample
+ 
+ genrecog -I/p1/abc/proc1 -I/p2/abcd/pro2 target.md
+ 
+ @end smallexample
+ 
+ 
+ @table @gcctabopt
+ @item -I@var{dir}
+ @opindex I
+ Add the directory @var{dir} to the head of the list of directories to be
+ searched for header files.  This can be used to override a system machine definition
+ file, substituting your own version, since these directories are
+ searched before the default machine description file directories.  If you use more than
+ one @option{-I} option, the directories are scanned in left-to-right
+ order; the standard default directory come after.
+ 
+ @end table
+ 
  
  @node Peephole Definitions
  @section Machine-Specific Peephole Optimizers

Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 14:39 ` Dale Johannesen
  2001-11-05 18:35   ` Aldy Hernandez
@ 2001-11-13  4:32   ` Dale Johannesen
  2001-11-13 15:03   ` Dale Johannesen
  2 siblings, 0 replies; 152+ messages in thread
From: Dale Johannesen @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Dale Johannesen, gcc patches, Geoff Keating

On Monday, November 5, 2001, at 12:54 PM, Aldy Hernandez wrote:
> + /* Minimum and maximum AltiVec registers used to hold arguments.  */
> + #define ALTIVEC_ARG_MIN_REG 77
> + #define ALTIVEC_ARG_MAX_REG 88
> + #define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG - ALTIVEC_ARG_MIN_REG 
> + 1)

Incidentally, on Darwin and I think some others, the vector param
regs are V2..V13, not V0..V11.  I guess this is ABI-dependent too.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 13:17     ` Joseph S. Myers
@ 2001-11-13  4:32       ` Joseph S. Myers
  2001-11-13 15:03       ` Joseph S. Myers
  1 sibling, 0 replies; 152+ messages in thread
From: Joseph S. Myers @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: gcc patches

On 5 Nov 2001, Aldy Hernandez wrote:

> > That should end "ABI@." so that spacing after the sentence is correct if
> > more text gets added to that paragraph later.
> 
> huh?  i've never heard that.
> 
> where are the .texi docs?  i'm bound to make more mistakes if i don't
> read the texi docs :)

Included with texinfo, or online at

http://www.gnu.org/manual/texinfo/

in particular

http://www.gnu.org/manual/texinfo/html_chapter/texinfo_14.html#SEC151

which describes this particular issue.

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 18:35   ` Aldy Hernandez
@ 2001-11-13  4:32     ` Aldy Hernandez
  2001-11-13 15:03     ` Aldy Hernandez
  1 sibling, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Dale Johannesen; +Cc: gcc patches, Geoff Keating

>>>>> "Dale" == Dale Johannesen <dalej@apple.com> writes:

 > On Monday, November 5, 2001, at 12:54 PM, Aldy Hernandez wrote:
 >> + /* Minimum and maximum AltiVec registers used to hold arguments.  */
 >> + #define ALTIVEC_ARG_MIN_REG 77
 >> + #define ALTIVEC_ARG_MAX_REG 88
 >> + #define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG -
 >> ALTIVEC_ARG_MIN_REG + 1)

 > Incidentally, on Darwin and I think some others, the vector param
 > regs are V2..V13, not V0..V11.  I guess this is ABI-dependent too.

Whoops.  You are right.  Fixed.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-06  1:03               ` Joseph S. Myers
  2001-11-06  4:56                 ` Alan Matsuoka
@ 2001-11-13  4:32                 ` Joseph S. Myers
  2001-11-13 15:03                 ` Joseph S. Myers
  2 siblings, 0 replies; 152+ messages in thread
From: Joseph S. Myers @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: gcc-patches

On Mon, 5 Nov 2001, Alan Matsuoka wrote:

> + Where @var{pathname} is a string that specifies the the location of the file,
> + specifies the include file to be in gcc/config/{target}/filestuff. The

@file{gcc/config/@var{target}/filestuff}.

> + directory @file{gcc/config/{target}} is regarded as the default directory.

@var{target}.

Has this patch passed "make info" and "make dvi"?

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 18:22     ` Aldy Hernandez
  2001-11-05 18:28       ` Alan Matsuoka
@ 2001-11-13  4:32       ` Aldy Hernandez
  2001-11-13 15:03       ` Aldy Hernandez
  2 siblings, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: Geoff Keating, gcc-patches

>>>>> "Alan" == Alan Matsuoka <alanm@cygnus.com> writes:

 >> Do you really need this?  It looks just like the way a normal memory
 >> operand is printed (for the cases that are allowed for altivec).
 >> 
 >> > Index: rs6000.md
 >> 
 >> Can you put the altivec insns in their own .md file and use the include
 >> mechanism?  I believe this is what it was intended for.

Last i heard, alan matsuoka's include mechanism hadn't been approved.
Alan, perhaps you should send them again.  We definitely need them
now.

Aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 14:05 ` Dale Johannesen
                     ` (2 preceding siblings ...)
  2001-11-05 19:47   ` Aldy Hernandez
@ 2001-11-13  4:32   ` Dale Johannesen
  2001-11-13 15:03   ` Dale Johannesen
  4 siblings, 0 replies; 152+ messages in thread
From: Dale Johannesen @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Dale Johannesen, gcc patches, Geoff Keating

This is getting better.

On Monday, November 5, 2001, at 12:54 PM, Aldy Hernandez wrote:

> finally...
> what is left?
>     - the rest of the gazillion builtins
>
>     - varargs
>
>     - frame stuff: epilogue, prologue, vrsave
>     - <altivec.h> for the user.  this .h will implement the overloaded
>     altivec functions described in the "altivec programming interface
>     model".  Stuff like generic (overloaded) "vec_add(veca, vecb)".
>
>     - test cases.  i will commit a few simple tests, but serious tests
>     will come after i'm done playing with the G3 box.

I'd really like to see vrsave in the enums and register macros
(not necessarily the code).  I dislike making a major change to
an area if we know it's going to change again shortly.

>   /* Boundary (in *bits*) on which stack pointer should be aligned.  */
> ! #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 
> 128)

If you plan to support linking files compiled with and without 
-fabi=altivec,
shouldn't this be 128 unconditionally?  Otherwise the stack might not be
128-bit aligned when you enter an Altivec function.  Also in sysv4.h.

> *************** extern int rs6000_debug_arg;		/* debug a
> *** 757,762 ****
> --- 827,834 ----
>      (GET_MODE_CLASS (MODE) == MODE_FLOAT					\
>       || (GET_MODE_CLASS (MODE) == MODE_INT				\
>   	&& GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD))			\
> +    : ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_REGNO_P (REGNO)		\
> +    : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE)		\
>      : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC		\
>      : XER_REGNO_P (REGNO) ? (MODE) == PSImode				\
>      : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT		\

I don't think you want the first changed line here.

> *************** extern int rs6000_debug_arg;		/* debug a
> *** 788,793 ****
> --- 864,870 ----
>      ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2		\
>      : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10	\
>      : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10	\
> +    : (CLASS1) == ALTIVEC_REGS && (CLASS2) != ALTIVEC_REGS ? 20	\
>      : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS		\
>          || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS		\
>          || (CLASS1) == LINK_OR_CTR_REGS)				\

And here you need
	: (CLASS1) != ALTIVEC_REGS && (CLASS2) == ALTIVEC_REGS ? 20
analogous to the FLOAT case.

> *************** typedef struct rs6000_args
> *** 1778,1783 ****
> --- 1886,1892 ----
>     && GET_CODE (XEXP (X, 0)) == REG				\
>     && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT))		\
>     && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0)		\
> +   && ! ALTIVEC_VECTOR_MODE (MODE)				\
>     && (((MODE) != DFmode && (MODE) != DImode)			\
>         || (TARGET_32BIT						\
>   	  ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) 	\

That could be
	  && ( ! ALTIVEC_VECTOR_MODE (MODE) || INTVAL (X) == 0)
for better codegen.  It's not wrong as is, though.

> +
> +       /* Print AltiVec memory operand.  */
> +     case 'y':
> +       {
> + 	rtx tmp;
> +
> + 	if (GET_CODE (x) != MEM)
> + 	  abort ();
> +
> + 	tmp = XEXP (x, 0);
> +
> + 	if (GET_CODE (tmp) == REG)
> + 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
> + 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
> + 	  {
> + 	    if (REGNO (XEXP (tmp, 0)) == 0)
> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
> + 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
> + 	    else
> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
> + 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
> + 	  }
> + 	else
> + 	  abort ();
> + 	break;
> +       }

I guess this is OK.  Apple/Moto version doesn't have any analogous change
here; the patterns in rs6000.md match more elaborate MEM subpatterns,
to do the checking that you do here.  Isn't it generally considered 
preferable
to use the existing pattern mechanism whenever possible?

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 13:59 ` Geoff Keating
                     ` (4 preceding siblings ...)
  2001-11-06 23:17   ` Richard Henderson
@ 2001-11-13  4:32   ` Geoff Keating
  2001-11-13 15:03   ` Geoff Keating
  6 siblings, 0 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-13  4:32 UTC (permalink / raw)
  To: aldyh; +Cc: gcc-patches

> From: Aldy Hernandez <aldyh@redhat.com>
> Cc: Geoff Keating <geoffk@cygnus.com>
> Date: 05 Nov 2001 15:54:20 -0500

Hi Aldy,

> *************** extern int rs6000_debug_arg;		/* debug a
> *** 569,581 ****
>   #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
>   
>   /* Boundary (in *bits*) on which stack pointer should be aligned.  */
> ! #define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
>   
>   /* Allocation boundary (in *bits*) for the code of a function.  */
>   #define FUNCTION_BOUNDARY 32
>   
>   /* No data type wants to be aligned rounder than this.  */
> ! #define BIGGEST_ALIGNMENT 64
>   
>   /* Handle #pragma pack.  */
>   #define HANDLE_PRAGMA_PACK 1
> --- 585,604 ----
>   #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
>   
>   /* Boundary (in *bits*) on which stack pointer should be aligned.  */
> ! #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
>   
>   /* Allocation boundary (in *bits*) for the code of a function.  */
>   #define FUNCTION_BOUNDARY 32
>   
>   /* No data type wants to be aligned rounder than this.  */
> ! #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)

I think you _don't_ want this to be dependent on the ABI.  Changing
this isn't an ABI change (I hope!), which is good because...

> ! 
> ! /* A C expression to compute the alignment for a variables in the
> !    local store.  TYPE is the data type, and ALIGN is the alignment
> !    that the object would ordinarily have.  */
> ! #define LOCAL_ALIGNMENT(TYPE, ALIGN)				\
> ! 	((TARGET_ALTIVEC_ABI		    			\
> ! 	  && TREE_CODE (TYPE)) == VECTOR_TYPE ? 128 : ALIGN)

...as altivec values have to be 128-bit aligned because of the
hardware, you don't want this ABI-dependent either.

> *************** extern int rs6000_debug_arg;		/* debug a
> *** 634,640 ****
>      a register, in order to work around problems in allocating stack storage
>      in inline functions.  */
>   
> ! #define FIRST_PSEUDO_REGISTER 77
>   
>   /* This must not decrease, for backwards compatibility.  If
>      FIRST_PSEUDO_REGISTER increases, this should as well.  */
> --- 659,665 ----
>      a register, in order to work around problems in allocating stack storage
>      in inline functions.  */
>   
> ! #define FIRST_PSEUDO_REGISTER 109
>   
>   /* This must not decrease, for backwards compatibility.  If
>      FIRST_PSEUDO_REGISTER increases, this should as well.  */

The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
quite right:  it has to happen _only when the ABI is 'altivec'_.

This will be a bit tricky because DWARF_FRAME_REGISTERS is also used
in libgcc, so you have to #define something when the Altivec ABI is
chosen, and then key off that if IN_LIBGCC2.

I wonder if you could assume that the integrated cpplib will always be
used when compiling libgcc?  That would make things easier, because
then you wouldn't have muck with specs so much.

> *************** extern int rs6000_debug_arg;		/* debug a
> *** 655,661 ****
>      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
>      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
>      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
> !    0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1}
>   
>   /* 1 for registers not available across function calls.
>      These must include the FIXED_REGISTERS and also any
> --- 680,690 ----
>      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
>      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
>      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
> !    0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1,	   \
> !    /* AltiVec registers.  */			   \
> !    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
> !    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  \
> ! }

This is correct, but doesn't there need to be a change to them in
CONDITIONAL_REGISTER_USAGE when the altivec ABI is chosen (in which
some altivec registers are call-saved)?

> *************** typedef struct rs6000_stack {
> *** 1338,1346 ****
> --- 1428,1442 ----
>   			? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG)
>   #define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1)
>   
> + /* Minimum and maximum AltiVec registers used to hold arguments.  */
> + #define ALTIVEC_ARG_MIN_REG 77
> + #define ALTIVEC_ARG_MAX_REG 88
> + #define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG - ALTIVEC_ARG_MIN_REG + 1)

These should be based off FIRST_ALTIVEC_REGISTER rather than being
magic numbers...

>   /* Return registers */
>   #define GP_ARG_RETURN GP_ARG_MIN_REG
>   #define FP_ARG_RETURN FP_ARG_MIN_REG
> + #define ALTIVEC_ARG_RETURN 79

... this too.


> Index: sysv4.h
> ===================================================================
> RCS file: /cvs/uberbaum/gcc/config/rs6000/sysv4.h,v
> retrieving revision 1.67
> diff -c -p -r1.67 sysv4.h
> *** sysv4.h	2001/10/29 23:09:43	1.67
> --- sysv4.h	2001/11/05 19:49:24
> *************** do {									\
> *** 400,417 ****
>      one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
>      versions, just use 64 as the stack boundary.  */
>   #undef	STACK_BOUNDARY
> ! #define	STACK_BOUNDARY	64
>   
>   /* Real stack boundary as mandated by the appropriate ABI.  */
> ! #define ABI_STACK_BOUNDARY ((TARGET_EABI) ? 64 : 128)
>   
>   /* No data type wants to be aligned rounder than this.  */
>   #undef	BIGGEST_ALIGNMENT
> ! #define BIGGEST_ALIGNMENT ((TARGET_EABI) ? 64 : 128)
>   
>   #undef  BIGGEST_FIELD_ALIGNMENT
>   #undef  ADJUST_FIELD_ALIGN
> - #undef  ROUND_TYPE_ALIGN
>   
>   /* Use ELF style section commands.  */
>   
> --- 400,430 ----
>      one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
>      versions, just use 64 as the stack boundary.  */
>   #undef	STACK_BOUNDARY
> ! #define	STACK_BOUNDARY	(TARGET_ALTIVEC_ABI ? 128 : 64)
>   
>   /* Real stack boundary as mandated by the appropriate ABI.  */
> ! #define ABI_STACK_BOUNDARY ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
>   
>   /* No data type wants to be aligned rounder than this.  */
>   #undef	BIGGEST_ALIGNMENT
> ! #define BIGGEST_ALIGNMENT ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
>   
> + /* An expression for the alignment of a structure field FIELD if the
> +    alignment computed in the usual way is COMPUTED.  */
> + #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)				      \
> + 	((TARGET_ALTIVEC_ABI && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
> + 	 ? 128 : COMPUTED)
> + 
> + /* Define this macro as an expression for the alignment of a type
> +    (given by TYPE as a tree node) if the alignment computed in the
> +    usual way is COMPUTED and the alignment explicitly specified was
> +    SPECIFIED.  */
> + #define ROUND_TYPE_ALIGN(TYPE, COMPUTED, SPECIFIED)			\
> + 	((TARGET_ALTIVEC_ABI && TREE_CODE (TYPE) == VECTOR_TYPE)	\
> + 	 ? 128 : MAX (COMPUTED, SPECIFIED))
> + 
>   #undef  BIGGEST_FIELD_ALIGNMENT
>   #undef  ADJUST_FIELD_ALIGN
>   
>   /* Use ELF style section commands.  */

This has the same comment as the equivalent stuff in rs6000.h.


> *************** function_arg_advance (cum, mode, type, n
> *** 2159,2165 ****
>   {
>     cum->nargs_prototype--;
>   
> !   if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
>       {
>         if (TARGET_HARD_FLOAT
>   	  && (mode == SFmode || mode == DFmode))
> --- 2242,2255 ----
>   {
>     cum->nargs_prototype--;
>   
> !   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
> !     {
> !       if (cum->vregno <= ALTIVEC_ARG_MAX_REG)
> ! 	cum->vregno++;
> !       else
> ! 	cum->words += RS6000_ARG_SIZE (mode, type);
> !     }

Something you might not have seen in the ABI documentation: unnamed
vector arguments (passed to varargs functions after the '...') get
passed in memory, not in registers.  (I don't remember if this is just
the unnamed arguments or all the arguments to varargs functions, you
should check.)

> *************** print_operand (file, x, code)
> *** 4714,4719 ****
> --- 5287,5318 ----
>   		     reg_names[SMALL_DATA_REG]);
>   	}
>         return;
> + 
> +       /* Print AltiVec memory operand.  */
> +     case 'y':
> +       {
> + 	rtx tmp;
> + 
> + 	if (GET_CODE (x) != MEM)
> + 	  abort ();
> + 
> + 	tmp = XEXP (x, 0);
> + 
> + 	if (GET_CODE (tmp) == REG)
> + 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
> + 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
> + 	  {
> + 	    if (REGNO (XEXP (tmp, 0)) == 0)
> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
> + 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
> + 	    else
> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
> + 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
> + 	  }
> + 	else
> + 	  abort ();
> + 	break;
> +       }

Do you really need this?  It looks just like the way a normal memory
operand is printed (for the cases that are allowed for altivec).

> Index: rs6000.md

Can you put the altivec insns in their own .md file and use the include
mechanism?  I believe this is what it was intended for.

> + ;; No code is needed to copy between vector registers.
> + (define_insn "*altivec_vec_move"
> +   [(set (match_operand 0 "altivec_register" "=v")
> + 	(match_operand 1 "altivec_register" "v"))]
> +   "TARGET_ALTIVEC"
> +   ""
> +   [(set_attr "type" "altivec")])

Um, that can't possibly be right.  Also, it should be part of
movv4si_internal, because reload needs all the move insns to be the
same pattern.

> + ;; Vector move instructions.
> + (define_expand "movv4si"
> +   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
> + 	(match_operand:V4SI 1 "any_operand" ""))]
> +   "TARGET_ALTIVEC"
> +   "{ rs6000_emit_move (operands[0], operands[1], V4SImode); DONE; }")
> + 
> + (define_insn "*movv4si_internal"
> +   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v")
> + 	(match_operand:V4SI 1 "input_operand" "v,m"))]
> +   "TARGET_ALTIVEC"
> +   "@
> +    stvx\t%1,%y0
> +    ldvx\t%0,%y1"
> +   [(set_attr "type" "altivec")])

Yes---this needs an alternative to copy a 'v' into a 'v'.  All the
ones below probably need it too.

> + (define_expand "movv8hi"
> +   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
> + 	(match_operand:V8HI 1 "any_operand" ""))]
> +   "TARGET_ALTIVEC"
> +   "{ rs6000_emit_move (operands[0], operands[1], V8HImode); DONE; }")
> + 
> + (define_insn "*movv8hi_internal1"
> +   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=m,v")
> + 	(match_operand:V8HI 1 "input_operand" "v,m"))]
> +   "TARGET_ALTIVEC"
> +   "@
> +    stvx\t%1,%y0
> +    ldvx\t%0,%y1"
> +   [(set_attr "type" "altivec")])
> + 
> + (define_expand "movv16qi"
> +   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
> + 	(match_operand:V16QI 1 "any_operand" ""))]
> +   "TARGET_ALTIVEC"
> +   "{ rs6000_emit_move (operands[0], operands[1], V16QImode); DONE; }")
> + 
> + (define_insn "*movv16qi_internal1"
> +   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=m,v")
> + 	(match_operand:V16QI 1 "input_operand" "v,m"))]
> +   "TARGET_ALTIVEC"
> +   "@
> +    stvx\t%1,%y0
> +    ldvx\t%0,%y1"
> +   [(set_attr "type" "altivec")])
> + 
> + (define_expand "movv4sf"
> +   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
> + 	(match_operand:V4SF 1 "any_operand" ""))]
> +   "TARGET_ALTIVEC"
> +   "{ rs6000_emit_move (operands[0], operands[1], V4SFmode); DONE; }")
> + 
> + (define_insn "*movv4sf_internal1"
> +   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=m,v")
> + 	(match_operand:V4SF 1 "input_operand" "v,m"))]
> +   "TARGET_ALTIVEC"
> +   "@
> +    stvx\t%1,%y0
> +    ldvx\t%0,%y1"
> +   [(set_attr "type" "altivec")])
> + 
> + ;; Simple binary operations.
> + 
> 
> -- boring builtins deleted-- 
> 
> + (define_insn "altivec_vxor"
> +   [(set (match_operand:V4SI 0 "register_operand" "=v")
> +         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
> +                       (match_operand:V4SI 2 "register_operand" "v")] 136))]
> +   "TARGET_ALTIVEC"
> +   "vxor\t%0,%1,%2"
> +   [(set_attr "type" "altivec")])

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 15:29       ` Stan Shebs
@ 2001-11-13  4:32         ` Stan Shebs
  2001-11-13 15:03         ` Stan Shebs
  1 sibling, 0 replies; 152+ messages in thread
From: Stan Shebs @ 2001-11-13  4:32 UTC (permalink / raw)
  To: Geoff Keating; +Cc: gcc-patches

Geoff Keating wrote:
> 
> > Our GCC just sets DWARF_FRAME_REGISTERS to FIRST_PSEUDO_REGISTERS
> > unconditionally, seems to work well enough for non-AltiVec code.
> 
> Can't do that; breaks backwards binary compatibility.  That's why
> DWARF_FRAME_REGISTERS was invented, so people could add registers
> without breaking binary compatibility.

Ah, I see what you're getting at.  So we'll move our definition
to darwin.h.

Stan

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 16:28       ` Aldy Hernandez
@ 2001-11-13  4:33         ` Aldy Hernandez
  2001-11-13 15:03         ` Aldy Hernandez
  1 sibling, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13  4:33 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc patches

On Tue, 2001-11-06 at 18:14, Joseph S. Myers wrote:
> On 6 Nov 2001, Aldy Hernandez wrote:
> 
> > + the current ABI@
> 
> This sentence now seems to be missing its trailing ".".
> 

fixed.
> -- 
> Joseph S. Myers
> jsm28@cam.ac.uk
-- 
Aldy Hernandez			E-mail: aldyh@redhat.com
Professional Gypsy
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-07  8:23     ` Aldy Hernandez
@ 2001-11-13  4:33       ` Aldy Hernandez
  2001-11-13 15:03       ` Aldy Hernandez
  1 sibling, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13  4:33 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Geoff Keating, gcc patches

On Wed, 2001-11-07 at 02:16, Richard Henderson wrote:
> On Mon, Nov 05, 2001 at 01:58:06PM -0800, Geoff Keating wrote:
> > > - #define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
> > > + #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
> > > - #define BIGGEST_ALIGNMENT 64
> > > + #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)
> > 
> > I think you _don't_ want this to be dependent on the ABI.  Changing
> > this isn't an ABI change (I hope!), which is good because...
> 
> Yes it is.  REGNO_POINTER_ALIGN(STACK_POINTER_REGNUM) == STACK_BOUNDARY.

ok, i have reverted to my original code then:

#define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)

> > The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
> > quite right:  it has to happen _only when the ABI is 'altivec'_.
> 
> I _think_ you don't have to worry about this any longer.  The ia64
> eh library interface does not expose the number of registers
> involved.  
> 
> We might ought to have checks added to die more gracefully if the
> target adds registers, since we do statically allocate this space
> and older libgcc would not be able to unwind for newer gcc code.

so can i just up the # of DWARF_FRAME_REGISTERS without any bad side
effects?

-- 
Aldy Hernandez			E-mail: aldyh@redhat.com
Professional Gypsy
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 17:06       ` Aldy Hernandez
@ 2001-11-13  4:33         ` Aldy Hernandez
  2001-11-13 15:03         ` Aldy Hernandez
  1 sibling, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13  4:33 UTC (permalink / raw)
  To: Dale Johannesen; +Cc: Geoff Keating, gcc patches

> This needs an entry for vrsave.

yes i know.  i fixed them all.  they showed up during regression testing
and i fixed them all. am retesting bootstrap plus regressions right now.

> With these fixes I'll approve everything but the builtins, which I'm not
> planning to rule on either way.  You'll have to go through and change all
> the 'altivec' functional units later, but I guess you're aware of that.

yup.  i am aware.

feel free to approve then :-)

-- 
Aldy Hernandez			E-mail: aldyh@redhat.com
Professional Gypsy
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-07  8:30       ` Aldy Hernandez
@ 2001-11-13  4:33         ` Aldy Hernandez
  2001-11-13 15:03         ` Aldy Hernandez
  1 sibling, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13  4:33 UTC (permalink / raw)
  To: Geoff Keating; +Cc: rth, gcc-patches

>>>>> "Geoff" == Geoff Keating <geoffk@geoffk.org> writes:

 >> > > + #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)
 >> > 
 >> > I think you _don't_ want this to be dependent on the ABI.  Changing
 >> > this isn't an ABI change (I hope!), which is good because...
 >> 
 >> Yes it is.  REGNO_POINTER_ALIGN(STACK_POINTER_REGNUM) == STACK_BOUNDARY.
 >> 
 >> Remember that STACK_BOUNDARY != PREFERRED_STACK_BOUNDARY, and that the
 >> later does not help you unless you also have code to enforce stack
 >> alignment, like we're supposed to have for x86 vector code.

 > Here I was talking about BIGGEST_ALIGNMENT only.  Changing
 > STACK_BOUNDARY is of course an ABI change.

Woh, my bad.  Ok, biggest_alignment remains as is.  Nothing changed
from my last post then.

Still waiting approval on patch, and guidance on DWARF_FRAME_REGISTERS.

Aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 16:46       ` Aldy Hernandez
@ 2001-11-13  4:33         ` Aldy Hernandez
  2001-11-13 15:03         ` Aldy Hernandez
  1 sibling, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13  4:33 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: Dale Johannesen, gcc patches, Geoff Keating

> Is there any reasonable way to reflect that in the generated objects,
> then?  Is there a spare bit in the ELF header for this?

sure, i guess i can come up with a patch later... but that _is_ the
general idea of an ABI, you can't mix and match them and expect them to
work.

> 
> -- 
> Daniel Jacobowitz                           Carnegie Mellon University
> MontaVista Software                         Debian GNU/Linux Developer
-- 

Aldy Hernandez			E-mail: aldyh@redhat.com
Professional Gypsy
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 16:12     ` Daniel Jacobowitz
  2001-11-06 16:46       ` Aldy Hernandez
  2001-11-07  2:36       ` Geoff Keating
@ 2001-11-13  4:33       ` Daniel Jacobowitz
  2001-11-13 15:03       ` Daniel Jacobowitz
  3 siblings, 0 replies; 152+ messages in thread
From: Daniel Jacobowitz @ 2001-11-13  4:33 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Dale Johannesen, gcc patches, Geoff Keating

On Mon, Nov 05, 2001 at 09:33:11PM -0500, Aldy Hernandez wrote:
> >>>>> "Dale" == Dale Johannesen <dalej@apple.com> writes:
> 
>  > This is getting better.
> 
> Thanks ;-)
> 
>  > I'd really like to see vrsave in the enums and register macros
>  > (not necessarily the code).  I dislike making a major change to
>  > an area if we know it's going to change again shortly.
> 
> That was supposed to be tommorrow's work.... :)
> 
>  > If you plan to support linking files compiled with and without
>  > -fabi=altivec,
> 
> nope we don't.  You can't just link too different abi's.

Is there any reasonable way to reflect that in the generated objects,
then?  Is there a spare bit in the ELF header for this?

-- 
Daniel Jacobowitz                           Carnegie Mellon University
MontaVista Software                         Debian GNU/Linux Developer

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 17:07     ` Stan Shebs
  2001-11-06 17:15       ` Aldy Hernandez
@ 2001-11-13  4:33       ` Stan Shebs
  2001-11-13 15:03       ` Stan Shebs
  2 siblings, 0 replies; 152+ messages in thread
From: Stan Shebs @ 2001-11-13  4:33 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Geoff Keating, gcc-patches

Aldy Hernandez wrote:
> 
> After a few iterations I think this is finally it-- for the first
> batch of patches anyhow.

It's all looking good to me, modulo the question below.

It would be ever so slightly more convenient for Apple's next import
if vrsave were to be listed ahead of the general vector registers
instead of after (it then becomes part of the "block" of misc regs),
but we can cope with it either way.

> --- 2562,2572 ----
>       "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",           \
>        "mq",  "lr", "ctr",  "ap",                                               \
>       "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",           \
> !   "xer",                                                              \
> !      "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",             \
> !      "v8",  "v9", "v10", "v11", "v12", "v13", "v14", "v15",             \
> !     "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",             \
> !     "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"              \
>   }

Missing a "vrsave" here?

Stan

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-07  2:50     ` Geoff Keating
  2001-11-07  8:30       ` Aldy Hernandez
  2001-11-07 11:41       ` Richard Henderson
@ 2001-11-13  4:33       ` Geoff Keating
  2001-11-13 15:03       ` Geoff Keating
  3 siblings, 0 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-13  4:33 UTC (permalink / raw)
  To: rth; +Cc: aldyh, gcc-patches

> Date: Tue, 6 Nov 2001 23:16:48 -0800
> From: Richard Henderson <rth@redhat.com>
> Cc: aldyh@redhat.com, gcc-patches@gcc.gnu.org
> Mail-Followup-To: Richard Henderson <rth@redhat.com>,
> 	Geoff Keating <geoffk@redhat.com>, aldyh@redhat.com,
> 	gcc-patches@gcc.gnu.org
> Content-Disposition: inline
> User-Agent: Mutt/1.2.5i
> 
> On Mon, Nov 05, 2001 at 01:58:06PM -0800, Geoff Keating wrote:
> > > - #define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
> > > + #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
> > > - #define BIGGEST_ALIGNMENT 64
> > > + #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)
> > 
> > I think you _don't_ want this to be dependent on the ABI.  Changing
> > this isn't an ABI change (I hope!), which is good because...
> 
> Yes it is.  REGNO_POINTER_ALIGN(STACK_POINTER_REGNUM) == STACK_BOUNDARY.
> 
> Remember that STACK_BOUNDARY != PREFERRED_STACK_BOUNDARY, and that the
> later does not help you unless you also have code to enforce stack
> alignment, like we're supposed to have for x86 vector code.

Here I was talking about BIGGEST_ALIGNMENT only.  Changing
STACK_BOUNDARY is of course an ABI change.

> > The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
> > quite right:  it has to happen _only when the ABI is 'altivec'_.
> 
> I _think_ you don't have to worry about this any longer.  The ia64
> eh library interface does not expose the number of registers
> involved.  
> 
> We might ought to have checks added to die more gracefully if the
> target adds registers, since we do statically allocate this space
> and older libgcc would not be able to unwind for newer gcc code.

The complexities of this boggle my mind.  I think we haven't even
decided on how some of the pieces should work yet.

Can we really change the EH library interface like this?  Even in the
presence of a glibc compatibility layer to support pre-gcc3.0 C++
binaries?

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 15:02   ` Aldy Hernandez
                       ` (2 preceding siblings ...)
  2001-11-06 17:07     ` Stan Shebs
@ 2001-11-13  4:33     ` Aldy Hernandez
  2001-11-13 15:03     ` Aldy Hernandez
  4 siblings, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13  4:33 UTC (permalink / raw)
  To: Geoff Keating; +Cc: gcc-patches

hi guys.

After a few iterations I think this is finally it-- for the first
batch of patches anyhow.

Geoff and I had a couple iterations in private to get the alignment
things sorted out, but everything that was suggested has been
implemented: vrsave in bit patterns, alignment, v=v move, etc etc.

I will be working on stack stuff (epilogue, prologue, stack frame,
vrsave) in the next couple days and I wanted to get these standalone
patches in first.

What is left?

        - stack stuff
        - DWARF_FRAME_REGISTERS (unwind-dw2.c work)
        - varargs
        - rest of builtins
        - function units
        - testcases

ok to install now?  I am bootstraping and checking for regressions
again-- assuming these are ok.

Aldy

2001-11-05  Aldy Hernandez  <aldyh@redhat.com>

	* doc/invoke.texi: Add -maltivec, -mno-altivec, and -mabi=altivec
	for rs6000.

	* config/rs6000/rs6000.h (MASK_ALTIVEC): New.
	(TARGET_ALTIVEC): New.
	(TARGET_SWITCHES): Add altivec.
	(FIRST_PSEUDO_REGISTER): Change to 109.
	(CALL_USED_REGISTERS): Same.
	(FIRST_ALTIVEC_REGNO): New.
	(LAST_ALTIVEC_REGNO): New.
	(ALTIVEC_REGNO_P): New.
	(UNITS_PER_ALTIVEC_WORD): New.
	(ALTIVEC_VECTOR_MODE): New.
	(FIXED_REGISTERS): Add altivec registers.
	(REG_ALLOC_ORDER): Same.
	(HARD_REGNO_NREGS): Adjust for altivec registers.
	(HARD_REGNO_MODE_OK): Same.
	(MODES_TIEABLE_P): Same.
	(REGISTER_MOVE_COST): Same.
	(REGNO_REG_CLASS): Same.
	(reg_class): Add ALTIVEC_REGS.
	(REG_CLASS_NAMES): Same.
	(REG_CLASS_CONTENTS): Same.
	(REG_CLASS_FROM_LETTER): Add 'v' constraint for ALTIVEC_REGS.
	(ALTIVEC_ARG_RETURN): New.
	(FUNCTION_VALUE): Handle VECTOR_TYPE.
	(LIBCALL_VALUE): Handle altivec vector modes.
	(VECTOR_MODE_SUPPORTED_P): New.
	(ALTIVEC_ARG_MIN_REG): New.
	(ALTIVEC_ARG_MAX_REG): New.
	(ALTIVEC_ARG_NUM_REG): New.
	(FUNCTION_VALUE_REGNO_P): Return true for altivec return register.
	(FUNCTION_ARG_REGNO_P): Support passing args in altivec registers.
	(REGISTER_NAMES): Add altivec regs.
	(DEBUG_REGISTER_NAMES): Same.
	(ADDITIONAL_REGISTER_NAMES): Same.
	(rs6000_builtins): New.
	(MD_EXPAND_BUILTIN): New.
	(MD_INIT_BUILTINS): New.
	(LEGITIMATE_OFFSET_ADDRESS_P): This addressing mode is not valid
	for AltiVec instructions.
	(LEGITIMATE_LO_SUM_ADDRESS_P): Same.
	(HARD_REGNO_MODE_OK): Altivec modes can only go in altivec
	registers.
	(SECONDARY_MEMORY_NEEDED): We need memory to copy vector modes.
	(TARGET_SWITCHES): Add no-altivec.
	(DATA_ALIGNMENT): Align vectors to 128 bits.
	(TARGET_OPTIONS): Add abi= option.
	Add rs6000_abi_string extern.
	(LOCAL_ALIGNMENT): New.
	(CPP_CPU_SPEC): Define __ALTIVEC__ when -maltivec.
	(MASK_ALTIVEC_ABI): New.
	(TARGET_ALTIVEC_ABI): New.
	(CONDITIONAL_REGISTER_USAGE): Set first 20 AltiVec registers to
	call-saved.
	(STACK_BOUNDARY): Adjust for altivec.
	(BIGGEST_ALIGNMENT): Same.
	(rs6000_args): Add vregno.
	(USE_ALTIVEC_FOR_ARG_P): New.
	(FIXED_REGISTERS): Add vrsave register.
	(CALL_USED_REGISTERS): Same.
	(CONDITIONAL_REGISTER_USAGE): Set VRSAVE info.
	(VRSAVE_REGNO): New.
	(reg_class): Add VRSAVE_REGS.
	(REG_CLASS_NAMES): Same.
	(REG_CLASS_CONTENTS): Same.
	(REGNO_REG_CLASS): Same.
	
	* config/rs6000/sysv4.h (STACK_BOUNDARY): Adjust for altivec.
	(ABI_STACK_BOUNDARY): Same.
	(BIGGEST_ALIGNMENT): Same.
	(ADJUST_FIELD_ALIGN): Remove undef.  Define anew.
	(ROUND_TYPE_ALIGN): Same.
	
	* config/rs6000/rs6000.c (rs6000_expand_builtin): New.
	(altivec_expand_builtin): New.
	(altivec_init_builtins): New.
	(TARGET_EXPAND_BUILTIN): New.
	(TARGET_INIT_BUILTINS): New.
	(rs6000_init_builtins): New.
	(struct builtin_description): New.
	(bdesc_2arg): New.
	(rs6000_reg_names): Add altivec registers.
	(alt_reg_names): Same.
	(secondary_reload_class): Altivec regs can hold altivec regs and
	memory.
	(rs6000_emit_move): Force constants into memory for AltiVec moves.
	(print_operand): Add 'y' case for printing altivec memory
	operands.
	(rs6000_legitimize_address): Legitimize vector addresses into
	[REG+REG] or [REG].
	(altivec_expand_binop_builtin): New.
	New string rs6000_current_abi.
	(rs6000_override_options): Call rs6000_parse_abi_options.
	(rs6000_parse_abi_options): New.
	(function_arg_boundary): Vector arguments must be 16
	byte aligned.
	(function_arg_advance): Handle vector arguments.
	(function_arg_partial_nregs): Same.
	(init_cumulative_args): Same.
	(function_arg): Same.

	* config/rs6000/rs6000.md (altivec_lvx): New.
	(type): Add altivec attribute.
	(movv4si): New.
	(*movv4si_internal): New.
	(movv16qi): New.
	(*movv16qi_internal): New.
	(movv8hi): New.
	(*movv8hi_internal1): New.
	(movv4sf): New.
	(*movv4sf_internal1): New.
	(altivec_stvx): New.
*builtins deleted*

	Index: doc/invoke.texi
===================================================================
RCS file: /cvs/uberbaum/gcc/doc/invoke.texi,v
retrieving revision 1.69
diff -c -p -r1.69 invoke.texi
*** invoke.texi	2001/10/28 19:12:12	1.69
--- invoke.texi	2001/11/06 22:24:35
*************** in the following sections.
*** 424,429 ****
--- 424,430 ----
  -mtune=@var{cpu-type} @gol
  -mpower  -mno-power  -mpower2  -mno-power2 @gol
  -mpowerpc  -mpowerpc64  -mno-powerpc @gol
+ -maltivec -mno-altivec @gol
  -mpowerpc-gpopt  -mno-powerpc-gpopt @gol
  -mpowerpc-gfxopt  -mno-powerpc-gfxopt @gol
  -mnew-mnemonics  -mold-mnemonics @gol
*************** in the following sections.
*** 436,441 ****
--- 437,443 ----
  -mno-relocatable  -mrelocatable-lib  -mno-relocatable-lib @gol
  -mtoc  -mno-toc -mlittle  -mlittle-endian  -mbig  -mbig-endian @gol
  -mcall-aix -mcall-sysv -mcall-netbsd @gol
+ -mabi=altivec @gol
  -mprototype  -mno-prototype @gol
  -msim  -mmvme  -mads  -myellowknife  -memb -msdata @gol
  -msdata=@var{opt}  -mvxworks -G @var{num}}
*************** values for @var{cpu_type} are used for @
*** 6677,6682 ****
--- 6679,6693 ----
  architecture, registers, and mnemonics set by @option{-mcpu}, but the
  scheduling parameters set by @option{-mtune}.
  
+ @item -maltivec
+ @itemx -mno-altivec
+ @opindex maltivec
+ @opindex mno-altivec
+ These switches enable or disable the use of built-in functions that
+ allow access to the AltiVec instruction set.  You may also need to set
+ @option{-mabi=altivec} to adjust the current ABI with AltiVec ABI
+ enhancements.
+ 
  @item -mfull-toc
  @itemx -mno-fp-in-toc
  @itemx -mno-sum-in-toc
*************** Linux-based GNU system.
*** 6904,6909 ****
--- 6915,6926 ----
  @opindex mcall-netbsd
  On System V.4 and embedded PowerPC systems compile code for the
  NetBSD operating system.
+ 
+ @item -mabi=altivec
+ @opindex mabi=altivec
+ Extend the current ABI with AltiVec ABI extensions.  This does not
+ change the default ABI, instead it adds the AltiVec ABI extensions to
+ the current ABI@
  
  @item -mprototype
  @itemx -mno-prototype
Index: rs6000.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.130
diff -c -p -r1.130 rs6000.h
*** rs6000.h	2001/10/02 03:36:44	1.130
--- rs6000.h	2001/11/06 22:24:41
*************** Boston, MA 02111-1307, USA.  */
*** 83,89 ****
  %{mcpu=801: -D_ARCH_PPC} \
  %{mcpu=821: -D_ARCH_PPC} \
  %{mcpu=823: -D_ARCH_PPC} \
! %{mcpu=860: -D_ARCH_PPC}"
  
  /* Common ASM definitions used by ASM_SPEC among the various targets
     for handling -mcpu=xxx switches.  */
--- 83,90 ----
  %{mcpu=801: -D_ARCH_PPC} \
  %{mcpu=821: -D_ARCH_PPC} \
  %{mcpu=823: -D_ARCH_PPC} \
! %{mcpu=860: -D_ARCH_PPC} \
! %{maltivec: -D__ALTIVEC__}"
  
  /* Common ASM definitions used by ASM_SPEC among the various targets
     for handling -mcpu=xxx switches.  */
*************** extern int target_flags;
*** 209,214 ****
--- 210,221 ----
  /* Nonzero if we need to schedule the prolog and epilog.  */
  #define MASK_SCHED_PROLOG	0x00040000
  
+ /* Use AltiVec instructions.  */
+ #define MASK_ALTIVEC		0x00080000
+ 
+ /* Enhance the current ABI with AltiVec extensions.  */
+ #define MASK_ALTIVEC_ABI	0x00100000
+ 
  #define TARGET_POWER		(target_flags & MASK_POWER)
  #define TARGET_POWER2		(target_flags & MASK_POWER2)
  #define TARGET_POWERPC		(target_flags & MASK_POWERPC)
*************** extern int target_flags;
*** 227,232 ****
--- 234,241 ----
  #define TARGET_NO_UPDATE	(target_flags & MASK_NO_UPDATE)
  #define TARGET_NO_FUSED_MADD	(target_flags & MASK_NO_FUSED_MADD)
  #define TARGET_SCHED_PROLOG	(target_flags & MASK_SCHED_PROLOG)
+ #define TARGET_ALTIVEC		(target_flags & MASK_ALTIVEC)
+ #define TARGET_ALTIVEC_ABI	(target_flags & MASK_ALTIVEC_ABI)
  
  #define TARGET_32BIT		(! TARGET_64BIT)
  #define TARGET_HARD_FLOAT	(! TARGET_SOFT_FLOAT)
*************** extern int target_flags;
*** 282,287 ****
--- 291,300 ----
  			N_("Use PowerPC-64 instruction set")},		\
    {"no-powerpc64",	- MASK_POWERPC64,				\
  			N_("Don't use PowerPC-64 instruction set")},	\
+   {"altivec",		MASK_ALTIVEC,					\
+ 			N_("Use AltiVec instructions.")},		\
+   {"no-altivec",	- MASK_ALTIVEC,					\
+ 			N_("Don't use AltiVec instructions.")},	\
    {"new-mnemonics",	MASK_NEW_MNEMONICS,				\
  			N_("Use new mnemonics for PowerPC architecture")},\
    {"old-mnemonics",	-MASK_NEW_MNEMONICS,				\
*************** extern enum processor_type rs6000_cpu;
*** 409,414 ****
--- 422,428 ----
     {"tune=", &rs6000_select[2].string,					\
      N_("Schedule code for given CPU") },				\
     {"debug=", &rs6000_debug_name, N_("Enable debug output") },		\
+    {"abi=", &rs6000_abi_string, N_("Specify ABI to use") },		\
     SUBTARGET_OPTIONS							\
  }
  
*************** struct rs6000_cpu_select
*** 424,430 ****
  extern struct rs6000_cpu_select rs6000_select[];
  
  /* Debug support */
! extern const char *rs6000_debug_name;		/* Name for -mdebug-xxxx option */
  extern int rs6000_debug_stack;		/* debug stack applications */
  extern int rs6000_debug_arg;		/* debug argument handling */
  
--- 438,445 ----
  extern struct rs6000_cpu_select rs6000_select[];
  
  /* Debug support */
! extern const char *rs6000_debug_name;	/* Name for -mdebug-xxxx option */
! extern const char *rs6000_abi_string;	/* for -mabi={sysv,darwin,solaris,eabi,aix,altivec} */
  extern int rs6000_debug_stack;		/* debug stack applications */
  extern int rs6000_debug_arg;		/* debug argument handling */
  
*************** extern int rs6000_debug_arg;		/* debug a
*** 505,510 ****
--- 520,526 ----
  #define UNITS_PER_WORD (! TARGET_POWERPC64 ? 4 : 8)
  #define MIN_UNITS_PER_WORD 4
  #define UNITS_PER_FP_WORD 8
+ #define UNITS_PER_ALTIVEC_WORD 16
  
  /* Type used for ptrdiff_t, as a string used in a declaration.  */
  #define PTRDIFF_TYPE "int"
*************** extern int rs6000_debug_arg;		/* debug a
*** 569,581 ****
  #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
  
  /* Boundary (in *bits*) on which stack pointer should be aligned.  */
! #define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
  
  /* Allocation boundary (in *bits*) for the code of a function.  */
  #define FUNCTION_BOUNDARY 32
  
  /* No data type wants to be aligned rounder than this.  */
! #define BIGGEST_ALIGNMENT 64
  
  /* Handle #pragma pack.  */
  #define HANDLE_PRAGMA_PACK 1
--- 585,604 ----
  #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
  
  /* Boundary (in *bits*) on which stack pointer should be aligned.  */
! #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
  
  /* Allocation boundary (in *bits*) for the code of a function.  */
  #define FUNCTION_BOUNDARY 32
  
  /* No data type wants to be aligned rounder than this.  */
! #define BIGGEST_ALIGNMENT 128
! 
! /* A C expression to compute the alignment for a variables in the
!    local store.  TYPE is the data type, and ALIGN is the alignment
!    that the object would ordinarily have.  */
! #define LOCAL_ALIGNMENT(TYPE, ALIGN)				\
! 	((TARGET_ALTIVEC		    			\
! 	  && TREE_CODE (TYPE)) == VECTOR_TYPE ? 128 : ALIGN)
  
  /* Handle #pragma pack.  */
  #define HANDLE_PRAGMA_PACK 1
*************** extern int rs6000_debug_arg;		/* debug a
*** 594,602 ****
    (TREE_CODE (EXP) == STRING_CST	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
! /* Make arrays of chars word-aligned for the same reasons.  */
  #define DATA_ALIGNMENT(TYPE, ALIGN)		\
!   (TREE_CODE (TYPE) == ARRAY_TYPE		\
     && TYPE_MODE (TREE_TYPE (TYPE)) == QImode	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
--- 617,627 ----
    (TREE_CODE (EXP) == STRING_CST	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
! /* Make arrays of chars word-aligned for the same reasons.
!    Align vectors to 128 bits.  */
  #define DATA_ALIGNMENT(TYPE, ALIGN)		\
!   (TREE_CODE (TYPE) == VECTOR_TYPE ? 128	\
!    : TREE_CODE (TYPE) == ARRAY_TYPE		\
     && TYPE_MODE (TREE_TYPE (TYPE)) == QImode	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
*************** extern int rs6000_debug_arg;		/* debug a
*** 634,643 ****
     a register, in order to work around problems in allocating stack storage
     in inline functions.  */
  
! #define FIRST_PSEUDO_REGISTER 77
  
  /* This must not decrease, for backwards compatibility.  If
     FIRST_PSEUDO_REGISTER increases, this should as well.  */
  #define DWARF_FRAME_REGISTERS 77
  
  /* 1 for registers that have pervasive standard uses
--- 659,670 ----
     a register, in order to work around problems in allocating stack storage
     in inline functions.  */
  
! #define FIRST_PSEUDO_REGISTER 110
  
  /* This must not decrease, for backwards compatibility.  If
     FIRST_PSEUDO_REGISTER increases, this should as well.  */
+ /* fixme: this needs to be defined to "TARGET_ALTIVEC_ABI ? 110 : 77"
+    and then fix usages of DWARF_FRAME_REGISTERS to work.  */
  #define DWARF_FRAME_REGISTERS 77
  
  /* 1 for registers that have pervasive standard uses
*************** extern int rs6000_debug_arg;		/* debug a
*** 655,661 ****
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1}
  
  /* 1 for registers not available across function calls.
     These must include the FIXED_REGISTERS and also any
--- 682,693 ----
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1,	   \
!    /* AltiVec registers.  */			   \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0						   \
! }
  
  /* 1 for registers not available across function calls.
     These must include the FIXED_REGISTERS and also any
*************** extern int rs6000_debug_arg;		/* debug a
*** 669,676 ****
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1}
  
  #define MQ_REGNO     64
  #define CR0_REGNO    68
  #define CR1_REGNO    69
--- 701,714 ----
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1,	   \
!    /* AltiVec registers.  */			   \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0						   \
! }
  
+ 
  #define MQ_REGNO     64
  #define CR0_REGNO    68
  #define CR1_REGNO    69
*************** extern int rs6000_debug_arg;		/* debug a
*** 679,684 ****
--- 717,725 ----
  #define CR4_REGNO    72
  #define MAX_CR_REGNO 75
  #define XER_REGNO    76
+ #define FIRST_ALTIVEC_REGNO	77
+ #define LAST_ALTIVEC_REGNO	108
+ #define VRSAVE_REGNO		109
  
  /* List the order in which to allocate registers.  Each register must be
     listed once, even those in FIXED_REGISTERS.
*************** extern int rs6000_debug_arg;		/* debug a
*** 701,707 ****
  	mq		(not saved; best to use it if we can)
  	ctr		(not saved; when we have the choice ctr is better)
  	lr		(saved)
!         cr5, r1, r2, ap, xer (fixed)  */
  
  #define REG_ALLOC_ORDER					\
    {32, 							\
--- 742,757 ----
  	mq		(not saved; best to use it if we can)
  	ctr		(not saved; when we have the choice ctr is better)
  	lr		(saved)
!         cr5, r1, r2, ap, xer, vrsave (fixed)
! 
! 	AltiVec registers:
! 	v0 - v1         (not saved or used for anything)
! 	v13 - v3        (not saved; incoming vector arg registers)
! 	v2              (not saved; incoming vector arg reg; return value)
! 	v19 - v14       (not saved or used for anything)
! 	v31 - v20       (saved; order given to save least number)
! */
! 						
  
  #define REG_ALLOC_ORDER					\
    {32, 							\
*************** extern int rs6000_debug_arg;		/* debug a
*** 716,722 ****
     31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19,	\
     18, 17, 16, 15, 14, 13, 12,				\
     64, 66, 65, 						\
!    73, 1, 2, 67, 76}
  
  /* True if register is floating-point.  */
  #define FP_REGNO_P(N) ((N) >= 32 && (N) <= 63)
--- 766,779 ----
     31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19,	\
     18, 17, 16, 15, 14, 13, 12,				\
     64, 66, 65, 						\
!    73, 1, 2, 67, 76,					\
!    /* AltiVec registers.  */				\
!    77, 78,						\
!    90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80,		\
!    79,							\
!    96, 95, 94, 93, 92, 91,				\
!    108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97 \
! }
  
  /* True if register is floating-point.  */
  #define FP_REGNO_P(N) ((N) >= 32 && (N) <= 63)
*************** extern int rs6000_debug_arg;		/* debug a
*** 733,738 ****
--- 790,798 ----
  /* True if register is the XER register.  */
  #define XER_REGNO_P(N) ((N) == XER_REGNO)
  
+ /* True if register is an AltiVec register.  */
+ #define ALTIVEC_REGNO_P(N) ((N) >= FIRST_ALTIVEC_REGNO && (N) <= LAST_ALTIVEC_REGNO)
+ 
  /* Return number of consecutive hard regs needed starting at reg REGNO
     to hold something of mode MODE.
     This is ordinarily the length in words of a value of mode MODE
*************** extern int rs6000_debug_arg;		/* debug a
*** 744,751 ****
--- 804,826 ----
  #define HARD_REGNO_NREGS(REGNO, MODE)					\
    (FP_REGNO_P (REGNO)							\
     ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
+    : ALTIVEC_REGNO_P (REGNO)						\
+    ? ((GET_MODE_SIZE (MODE) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD) \
     : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
  
+ #define ALTIVEC_VECTOR_MODE(MODE)	\
+ 	((MODE) == V16QImode		\
+ 	 || (MODE) == V8HImode		\
+ 	 || (MODE) == V4SFmode		\
+ 	 || (MODE) == V4SImode)
+ 
+ /* Define this macro to be nonzero if the port is prepared to handle
+    insns involving vector mode MODE.  At the very least, it must have
+    move patterns for this mode.  */
+ 
+ #define VECTOR_MODE_SUPPORTED_P(MODE)	\
+ 	(TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE))
+ 
  /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
     For POWER and PowerPC, the GPRs can hold any mode, but the float
     registers only can hold floating modes and DImode, and CR register only
*************** extern int rs6000_debug_arg;		/* debug a
*** 757,762 ****
--- 832,838 ----
     (GET_MODE_CLASS (MODE) == MODE_FLOAT					\
      || (GET_MODE_CLASS (MODE) == MODE_INT				\
  	&& GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD))			\
+    : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE)		\
     : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC		\
     : XER_REGNO_P (REGNO) ? (MODE) == PSImode				\
     : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT		\
*************** extern int rs6000_debug_arg;		/* debug a
*** 776,781 ****
--- 852,861 ----
     ? GET_MODE_CLASS (MODE2) == MODE_CC		\
     : GET_MODE_CLASS (MODE2) == MODE_CC		\
     ? GET_MODE_CLASS (MODE1) == MODE_CC		\
+    : ALTIVEC_VECTOR_MODE (MODE1)		\
+    ? ALTIVEC_VECTOR_MODE (MODE2)		\
+    : ALTIVEC_VECTOR_MODE (MODE2)		\
+    ? ALTIVEC_VECTOR_MODE (MODE1)		\
     : 1)
  
  /* A C expression returning the cost of moving data from a register of class
*************** extern int rs6000_debug_arg;		/* debug a
*** 785,793 ****
     registers is expensive.  */
  
  #define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2)		\
!    ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2		\
     : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10	\
     : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10	\
     : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS		\
         || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS		\
         || (CLASS1) == LINK_OR_CTR_REGS)				\
--- 865,875 ----
     registers is expensive.  */
  
  #define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2)		\
!    ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2	\
     : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10	\
     : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10	\
+    : (CLASS1) == ALTIVEC_REGS && (CLASS2) != ALTIVEC_REGS ? 20	\
+    : (CLASS1) != ALTIVEC_REGS && (CLASS2) == ALTIVEC_REGS ? 20	\
     : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS		\
         || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS		\
         || (CLASS1) == LINK_OR_CTR_REGS)				\
*************** extern int rs6000_debug_arg;		/* debug a
*** 839,844 ****
--- 921,932 ----
      global_regs[PIC_OFFSET_TABLE_REGNUM]				\
        = fixed_regs[PIC_OFFSET_TABLE_REGNUM]				\
          = call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;			\
+   if (TARGET_ALTIVEC_ABI)						\
+     {									\
+       fixed_regs[VRSAVE_REGNO] = call_used_regs[VRSAVE_REGNO] = 1;	\
+       for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)	\
+         call_used_regs[i] = 1;						\
+     }									\
  }
  
  /* Specify the registers used for certain standard purposes.
*************** enum reg_class
*** 912,917 ****
--- 1000,1007 ----
    BASE_REGS,
    GENERAL_REGS,
    FLOAT_REGS,
+   ALTIVEC_REGS,
+   VRSAVE_REGS,
    NON_SPECIAL_REGS,
    MQ_REGS,
    LINK_REGS,
*************** enum reg_class
*** 937,942 ****
--- 1027,1034 ----
    "BASE_REGS",								\
    "GENERAL_REGS",							\
    "FLOAT_REGS",								\
+   "ALTIVEC_REGS",							\
+   "VRSAVE_REGS",							\
    "NON_SPECIAL_REGS",							\
    "MQ_REGS",								\
    "LINK_REGS",								\
*************** enum reg_class
*** 955,978 ****
     This is an initializer for a vector of HARD_REG_SET
     of length N_REG_CLASSES.  */
  
! #define REG_CLASS_CONTENTS						\
! {									\
!   { 0x00000000, 0x00000000, 0x00000000 },	/* NO_REGS */		\
!   { 0xfffffffe, 0x00000000, 0x00000008 },	/* BASE_REGS */		\
!   { 0xffffffff, 0x00000000, 0x00000008 },	/* GENERAL_REGS */	\
!   { 0x00000000, 0xffffffff, 0x00000000 },	/* FLOAT_REGS */	\
!   { 0xffffffff, 0xffffffff, 0x00000008 },	/* NON_SPECIAL_REGS */	\
!   { 0x00000000, 0x00000000, 0x00000001 },	/* MQ_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000002 },	/* LINK_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000004 },	/* CTR_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000006 },	/* LINK_OR_CTR_REGS */	\
!   { 0x00000000, 0x00000000, 0x00000007 },	/* SPECIAL_REGS */	\
!   { 0xffffffff, 0x00000000, 0x0000000f },	/* SPEC_OR_GEN_REGS */	\
!   { 0x00000000, 0x00000000, 0x00000010 },	/* CR0_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000ff0 },	/* CR_REGS */		\
!   { 0xffffffff, 0x00000000, 0x0000ffff },	/* NON_FLOAT_REGS */	\
!   { 0x00000000, 0x00000000, 0x00010000 },	/* XER_REGS */		\
!   { 0xffffffff, 0xffffffff, 0x0001ffff }	/* ALL_REGS */		\
  }
  
  /* The same information, inverted:
--- 1047,1072 ----
     This is an initializer for a vector of HARD_REG_SET
     of length N_REG_CLASSES.  */
  
! #define REG_CLASS_CONTENTS						     \
! {									     \
!   { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */	     \
!   { 0xfffffffe, 0x00000000, 0x00000008, 0x00000000 }, /* BASE_REGS */	     \
!   { 0xffffffff, 0x00000000, 0x00000008, 0x00000000 }, /* GENERAL_REGS */     \
!   { 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FLOAT_REGS */       \
!   { 0x00000000, 0x00000000, 0xffffe000, 0x0001ffff }, /* ALTIVEC_REGS */     \
!   { 0x00000000, 0x00000000, 0x00000000, 0x00020000 }, /* VRSAVE_REGS */	     \
!   { 0xffffffff, 0xffffffff, 0x00000008, 0x00000000 }, /* NON_SPECIAL_REGS */ \
!   { 0x00000000, 0x00000000, 0x00000001, 0x00000000 }, /* MQ_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000002, 0x00000000 }, /* LINK_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000004, 0x00000000 }, /* CTR_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000006, 0x00000000 }, /* LINK_OR_CTR_REGS */ \
!   { 0x00000000, 0x00000000, 0x00000007, 0x00000000 }, /* SPECIAL_REGS */     \
!   { 0xffffffff, 0x00000000, 0x0000000f, 0x00000000 }, /* SPEC_OR_GEN_REGS */ \
!   { 0x00000000, 0x00000000, 0x00000010, 0x00000000 }, /* CR0_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */	     \
!   { 0xffffffff, 0x00000000, 0x0000ffff, 0x00000000 }, /* NON_FLOAT_REGS */   \
!   { 0x00000000, 0x00000000, 0x00010000, 0x00000000 }, /* XER_REGS */	     \
!   { 0xffffffff, 0xffffffff, 0xffffffff, 0x0001ffff }  /* ALL_REGS */	     \
  }
  
  /* The same information, inverted:
*************** enum reg_class
*** 984,989 ****
--- 1078,1084 ----
   ((REGNO) == 0 ? GENERAL_REGS			\
    : (REGNO) < 32 ? BASE_REGS			\
    : FP_REGNO_P (REGNO) ? FLOAT_REGS		\
+   : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_REGS	\
    : (REGNO) == CR0_REGNO ? CR0_REGS		\
    : CR_REGNO_P (REGNO) ? CR_REGS		\
    : (REGNO) == MQ_REGNO ? MQ_REGS		\
*************** enum reg_class
*** 991,996 ****
--- 1086,1092 ----
    : (REGNO) == COUNT_REGISTER_REGNUM ? CTR_REGS	\
    : (REGNO) == ARG_POINTER_REGNUM ? BASE_REGS	\
    : (REGNO) == XER_REGNO ? XER_REGS		\
+   : (REGNO) == VRSAVE_REGNO ? VRSAVE_REGS	\
    : NO_REGS)
  
  /* The class value for index registers, and the one for base regs.  */
*************** enum reg_class
*** 1006,1011 ****
--- 1102,1108 ----
     : (C) == 'q' ? MQ_REGS	\
     : (C) == 'c' ? CTR_REGS	\
     : (C) == 'l' ? LINK_REGS	\
+    : (C) == 'v' ? ALTIVEC_REGS	\
     : (C) == 'x' ? CR0_REGS	\
     : (C) == 'y' ? CR_REGS	\
     : (C) == 'z' ? XER_REGS	\
*************** enum reg_class
*** 1103,1113 ****
  #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
    secondary_reload_class (CLASS, MODE, IN)
  
! /* If we are copying between FP registers and anything else, we need a memory
!    location.  */
  
! #define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
!  ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS || (CLASS2) == FLOAT_REGS))
  
  /* Return the maximum number of consecutive registers
     needed to represent mode MODE in a register of class CLASS.
--- 1200,1213 ----
  #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
    secondary_reload_class (CLASS, MODE, IN)
  
! /* If we are copying between FP or AltiVec registers and anything
!    else, we need a memory location.  */
  
! #define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) 		\
!  ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS		\
! 			   || (CLASS2) == FLOAT_REGS		\
! 			   || (CLASS1) == ALTIVEC_REGS		\
! 			   || (CLASS2) == ALTIVEC_REGS))
  
  /* Return the maximum number of consecutive registers
     needed to represent mode MODE in a register of class CLASS.
*************** typedef struct rs6000_stack {
*** 1294,1309 ****
  		&& TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)	\
  	       || POINTER_TYPE_P (VALTYPE)			\
  	       ? word_mode : TYPE_MODE (VALTYPE),		\
! 	       TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT \
                 ? FP_ARG_RETURN : GP_ARG_RETURN)
  
  /* Define how to find the value returned by a library function
     assuming the value has mode MODE.  */
  
! #define LIBCALL_VALUE(MODE)					\
!   gen_rtx_REG (MODE, (GET_MODE_CLASS (MODE) == MODE_FLOAT	\
! 		      && TARGET_HARD_FLOAT			\
! 		      ? FP_ARG_RETURN : GP_ARG_RETURN))
  
  /* The definition of this macro implies that there are cases where
     a scalar value cannot be returned in registers.
--- 1394,1411 ----
  		&& TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)	\
  	       || POINTER_TYPE_P (VALTYPE)			\
  	       ? word_mode : TYPE_MODE (VALTYPE),		\
! 	       TREE_CODE (VALTYPE) == VECTOR_TYPE ? ALTIVEC_ARG_RETURN \
! 	       : TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT \
                 ? FP_ARG_RETURN : GP_ARG_RETURN)
  
  /* Define how to find the value returned by a library function
     assuming the value has mode MODE.  */
  
! #define LIBCALL_VALUE(MODE)						\
!   gen_rtx_REG (MODE, ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_ARG_RETURN	\
! 		     : GET_MODE_CLASS (MODE) == MODE_FLOAT		\
! 		     && TARGET_HARD_FLOAT				\
! 		     ? FP_ARG_RETURN : GP_ARG_RETURN)
  
  /* The definition of this macro implies that there are cases where
     a scalar value cannot be returned in registers.
*************** typedef struct rs6000_stack {
*** 1338,1346 ****
--- 1440,1454 ----
  			? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG)
  #define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1)
  
+ /* Minimum and maximum AltiVec registers used to hold arguments.  */
+ #define ALTIVEC_ARG_MIN_REG (FIRST_ALTIVEC_REGNO + 2)
+ #define ALTIVEC_ARG_MAX_REG (ALTIVEC_ARG_MIN_REG + 11)
+ #define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG - ALTIVEC_ARG_MIN_REG + 1)
+ 
  /* Return registers */
  #define GP_ARG_RETURN GP_ARG_MIN_REG
  #define FP_ARG_RETURN FP_ARG_MIN_REG
+ #define ALTIVEC_ARG_RETURN (FIRST_ALTIVEC_REGNO + 2)
  
  /* Flags for the call/call_value rtl operations set up by function_arg */
  #define CALL_NORMAL		0x00000000	/* no special processing */
*************** typedef struct rs6000_stack {
*** 1352,1364 ****
  /* 1 if N is a possible register number for a function value
     as seen by the caller.
  
!    On RS/6000, this is r3 and fp1.  */
! #define FUNCTION_VALUE_REGNO_P(N)  ((N) == GP_ARG_RETURN || ((N) == FP_ARG_RETURN))
  
  /* 1 if N is a possible register number for function argument passing.
     On RS/6000, these are r3-r10 and fp1-fp13.  */
  #define FUNCTION_ARG_REGNO_P(N)						\
    ((unsigned)(((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG))	\
     || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))
  
  \f
--- 1460,1477 ----
  /* 1 if N is a possible register number for a function value
     as seen by the caller.
  
!    On RS/6000, this is r3, fp1, and v2 (for AltiVec).  */
! #define FUNCTION_VALUE_REGNO_P(N)  ((N) == GP_ARG_RETURN	\
! 				    || ((N) == FP_ARG_RETURN)	\
! 				    || (TARGET_ALTIVEC &&	\
! 					(N) == ALTIVEC_ARG_RETURN))
  
  /* 1 if N is a possible register number for function argument passing.
     On RS/6000, these are r3-r10 and fp1-fp13.  */
  #define FUNCTION_ARG_REGNO_P(N)						\
    ((unsigned)(((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG))	\
+    || (TARGET_ALTIVEC &&						\
+        (unsigned)((N) - ALTIVEC_ARG_MIN_REG) < (unsigned)(ALTIVEC_ARG_MAX_REG)) \
     || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))
  
  \f
*************** typedef struct rs6000_args
*** 1394,1399 ****
--- 1507,1513 ----
  {
    int words;			/* # words used for passing GP registers */
    int fregno;			/* next available FP register */
+   int vregno;			/* next available AltiVec register */
    int nargs_prototype;		/* # args left in the current prototype */
    int orig_nargs;		/* Original value of nargs_prototype */
    int prototype;		/* Whether a prototype was defined */
*************** typedef struct rs6000_args
*** 1436,1441 ****
--- 1550,1561 ----
     && (CUM).fregno <= FP_ARG_MAX_REG    \
     && TARGET_HARD_FLOAT)
  
+ /* Non-zero if we can use an AltiVec register to pass this arg.  */
+ #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE)	\
+   (ALTIVEC_VECTOR_MODE (MODE)			\
+    && (CUM).vregno <= ALTIVEC_ARG_MAX_REG	\
+    && TARGET_ALTIVEC_ABI)
+ 
  /* Determine where to put an argument to a function.
     Value is zero to push the argument on the stack,
     or a hard register in which to store the argument.
*************** typedef struct rs6000_args
*** 1778,1783 ****
--- 1898,1904 ----
    && GET_CODE (XEXP (X, 0)) == REG				\
    && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT))		\
    && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0)		\
+   && (! ALTIVEC_VECTOR_MODE (MODE) || INTVAL (X) == 0)		\
    && (((MODE) != DFmode && (MODE) != DImode)			\
        || (TARGET_32BIT						\
  	  ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) 	\
*************** typedef struct rs6000_args
*** 1805,1810 ****
--- 1926,1932 ----
     && ! flag_pic && ! TARGET_TOC				\
     && (MODE) != DImode						\
     && (MODE) != TImode						\
+    && ! ALTIVEC_VECTOR_MODE (MODE)				\
     && (TARGET_HARD_FLOAT || (MODE) != DFmode)			\
     && GET_CODE (X) == LO_SUM					\
     && GET_CODE (XEXP (X, 0)) == REG				\
*************** extern char rs6000_reg_names[][8];	/* re
*** 2389,2394 ****
--- 2511,2549 ----
    &rs6000_reg_names[75][0],	/* cr7  */				\
  									\
    &rs6000_reg_names[76][0],	/* xer  */				\
+ 									\
+   &rs6000_reg_names[77][0],	/* v0  */				\
+   &rs6000_reg_names[78][0],	/* v1  */				\
+   &rs6000_reg_names[79][0],	/* v2  */				\
+   &rs6000_reg_names[80][0],	/* v3  */				\
+   &rs6000_reg_names[81][0],	/* v4  */				\
+   &rs6000_reg_names[82][0],	/* v5  */				\
+   &rs6000_reg_names[83][0],	/* v6  */				\
+   &rs6000_reg_names[84][0],	/* v7  */				\
+   &rs6000_reg_names[85][0],	/* v8  */				\
+   &rs6000_reg_names[86][0],	/* v9  */				\
+   &rs6000_reg_names[87][0],	/* v10  */				\
+   &rs6000_reg_names[88][0],	/* v11  */				\
+   &rs6000_reg_names[89][0],	/* v12  */				\
+   &rs6000_reg_names[90][0],	/* v13  */				\
+   &rs6000_reg_names[91][0],	/* v14  */				\
+   &rs6000_reg_names[92][0],	/* v15  */				\
+   &rs6000_reg_names[93][0],	/* v16  */				\
+   &rs6000_reg_names[94][0],	/* v17  */				\
+   &rs6000_reg_names[95][0],	/* v18  */				\
+   &rs6000_reg_names[96][0],	/* v19  */				\
+   &rs6000_reg_names[97][0],	/* v20  */				\
+   &rs6000_reg_names[98][0],	/* v21  */				\
+   &rs6000_reg_names[99][0],	/* v22  */				\
+   &rs6000_reg_names[100][0],	/* v23  */				\
+   &rs6000_reg_names[101][0],	/* v24  */				\
+   &rs6000_reg_names[102][0],	/* v25  */				\
+   &rs6000_reg_names[103][0],	/* v26  */				\
+   &rs6000_reg_names[104][0],	/* v27  */				\
+   &rs6000_reg_names[105][0],	/* v28  */				\
+   &rs6000_reg_names[106][0],	/* v29  */				\
+   &rs6000_reg_names[107][0],	/* v30  */				\
+   &rs6000_reg_names[108][0],	/* v31  */				\
  }
  
  /* print-rtl can't handle the above REGISTER_NAMES, so define the
*************** extern char rs6000_reg_names[][8];	/* re
*** 2407,2413 ****
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",		\
       "mq",  "lr", "ctr",  "ap",						\
      "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",		\
!   "xer"									\
  }
  
  /* Table of additional register names to use in user input.  */
--- 2562,2572 ----
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",		\
       "mq",  "lr", "ctr",  "ap",						\
      "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",		\
!   "xer",								\
!      "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",             \
!      "v8",  "v9", "v10", "v11", "v12", "v13", "v14", "v15",             \
!     "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",             \
!     "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"              \
  }
  
  /* Table of additional register names to use in user input.  */
*************** extern char rs6000_reg_names[][8];	/* re
*** 2429,2434 ****
--- 2588,2601 ----
    {"fr20", 52}, {"fr21", 53}, {"fr22", 54}, {"fr23", 55},	\
    {"fr24", 56}, {"fr25", 57}, {"fr26", 58}, {"fr27", 59},	\
    {"fr28", 60}, {"fr29", 61}, {"fr30", 62}, {"fr31", 63},	\
+   {"v0",   77}, {"v1",   78}, {"v2",   79}, {"v3",   80},       \
+   {"v4",   81}, {"v5",   82}, {"v6",   83}, {"v7",   84},       \
+   {"v8",   85}, {"v9",   86}, {"v10",  87}, {"v11",  88},       \
+   {"v12",  89}, {"v13",  90}, {"v14",  91}, {"v15",  92},       \
+   {"v16",  93}, {"v17",  94}, {"v18",  95}, {"v19",  96},       \
+   {"v20",  97}, {"v21",  98}, {"v22",  99}, {"v23",  100},	\
+   {"v24",  101},{"v25",  102},{"v26",  103},{"v27",  104},      \
+   {"v28",  105},{"v29",  106},{"v30",  107},{"v31",  108},      \
    /* no additional names for: mq, lr, ctr, ap */		\
    {"cr0",  68}, {"cr1",  69}, {"cr2",  70}, {"cr3",  71},	\
    {"cr4",  72}, {"cr5",  73}, {"cr6",  74}, {"cr7",  75},	\
*************** extern int flag_pic;
*** 2629,2631 ****
--- 2796,2911 ----
  extern int optimize;
  extern int flag_expensive_optimizations;
  extern int frame_pointer_needed;
+ 
+ enum rs6000_builtins
+ {
+   /* AltiVec builtins.  */
+   ALTIVEC_BUILTIN_ST_INTERNAL,

*builtins deleted*

+ };
Index: sysv4.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/sysv4.h,v
retrieving revision 1.67
diff -c -p -r1.67 sysv4.h
*** sysv4.h	2001/10/29 23:09:43	1.67
--- sysv4.h	2001/11/06 22:24:42
*************** do {									\
*** 400,417 ****
     one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
     versions, just use 64 as the stack boundary.  */
  #undef	STACK_BOUNDARY
! #define	STACK_BOUNDARY	64
  
  /* Real stack boundary as mandated by the appropriate ABI.  */
! #define ABI_STACK_BOUNDARY ((TARGET_EABI) ? 64 : 128)
  
  /* No data type wants to be aligned rounder than this.  */
  #undef	BIGGEST_ALIGNMENT
! #define BIGGEST_ALIGNMENT ((TARGET_EABI) ? 64 : 128)
  
  #undef  BIGGEST_FIELD_ALIGNMENT
  #undef  ADJUST_FIELD_ALIGN
- #undef  ROUND_TYPE_ALIGN
  
  /* Use ELF style section commands.  */
  
--- 400,430 ----
     one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
     versions, just use 64 as the stack boundary.  */
  #undef	STACK_BOUNDARY
! #define	STACK_BOUNDARY	(TARGET_ALTIVEC_ABI ? 128 : 64)
  
  /* Real stack boundary as mandated by the appropriate ABI.  */
! #define ABI_STACK_BOUNDARY ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
  
  /* No data type wants to be aligned rounder than this.  */
  #undef	BIGGEST_ALIGNMENT
! #define BIGGEST_ALIGNMENT (TARGET_EABI ? 64 : 128)
  
+ /* An expression for the alignment of a structure field FIELD if the
+    alignment computed in the usual way is COMPUTED.  */
+ #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)				      \
+ 	((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE)     \
+ 	 ? 128 : COMPUTED)
+ 
+ /* Define this macro as an expression for the alignment of a type
+    (given by TYPE as a tree node) if the alignment computed in the
+    usual way is COMPUTED and the alignment explicitly specified was
+    SPECIFIED.  */
+ #define ROUND_TYPE_ALIGN(TYPE, COMPUTED, SPECIFIED)			\
+ 	((TARGET_ALTIVEC  && TREE_CODE (TYPE) == VECTOR_TYPE)	        \
+ 	 ? 128 : MAX (COMPUTED, SPECIFIED))
+ 
  #undef  BIGGEST_FIELD_ALIGNMENT
  #undef  ADJUST_FIELD_ALIGN
  
  /* Use ELF style section commands.  */
  
Index: rs6000.c
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.224
diff -c -p -r1.224 rs6000.c
*** rs6000.c	2001/10/31 14:08:09	1.224
--- rs6000.c	2001/11/06 22:24:45
*************** int fixuplabelno = 0;
*** 96,101 ****
--- 96,104 ----
  /* ABI enumeration available for subtarget to use.  */
  enum rs6000_abi rs6000_current_abi;
  
+ /* ABI string from -mabi= option.  */
+ const char *rs6000_abi_string;
+ 
  /* Debug flags */
  const char *rs6000_debug_name;
  int rs6000_debug_stack;		/* debug stack applications */
*************** static int rs6000_adjust_cost PARAMS ((r
*** 146,151 ****
--- 149,161 ----
  static int rs6000_adjust_priority PARAMS ((rtx, int));
  static int rs6000_issue_rate PARAMS ((void));
  
+ static void rs6000_init_builtins PARAMS ((tree));
+ static void altivec_init_builtins PARAMS ((void));
+ static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
+ static rtx altivec_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
+ static rtx altivec_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
+ 
+ static void rs6000_parse_abi_options PARAMS ((void));
  \f
  /* Default register names.  */
  char rs6000_reg_names[][8] =
*************** char rs6000_reg_names[][8] =
*** 160,166 ****
       "24", "25", "26", "27", "28", "29", "30", "31",
       "mq", "lr", "ctr","ap",
        "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
!       "xer"
  };
  
  #ifdef TARGET_REGNAMES
--- 170,181 ----
       "24", "25", "26", "27", "28", "29", "30", "31",
       "mq", "lr", "ctr","ap",
        "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
!       "xer",
!       /* AltiVec registers.  */
!       "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6", "v7",
!       "v8",  "v9",  "v10", "v11", "v12", "v13", "v14", "v15",
!       "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
!       "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
  };
  
  #ifdef TARGET_REGNAMES
*************** static const char alt_reg_names[][8] =
*** 176,182 ****
    "%f24",  "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
      "mq",    "lr",  "ctr",   "ap",
    "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
!   "xer"
  };
  #endif
  \f
--- 191,202 ----
    "%f24",  "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
      "mq",    "lr",  "ctr",   "ap",
    "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
!    "xer",
!    /* AltiVec registers.  */
!    "%v0",  "%v1",  "%v2",  "%v3",  "%v4",  "%v5",  "%v6", "%v7",
!    "%v8",  "%v9",  "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
!    "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
!    "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31"
  };
  #endif
  \f
*************** static const char alt_reg_names[][8] =
*** 205,210 ****
--- 225,236 ----
  #undef TARGET_SCHED_ADJUST_PRIORITY
  #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
  
+ #undef TARGET_INIT_BUILTINS
+ #define TARGET_INIT_BUILTINS rs6000_init_builtins
+ 
+ #undef TARGET_EXPAND_BUILTIN
+ #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
+ 
  struct gcc_target targetm = TARGET_INITIALIZER;
  \f
  /* Override command line options.  Mostly we process the processor
*************** rs6000_override_options (default_cpu)
*** 438,443 ****
--- 464,472 ----
  	error ("Unknown -mdebug-%s switch", rs6000_debug_name);
      }
  
+   /* Handle -mabi= options.  */
+   rs6000_parse_abi_options ();
+ 
  #ifdef TARGET_REGNAMES
    /* If the user desires alternate register names, copy in the
       alternate names now.  */
*************** rs6000_override_options (default_cpu)
*** 463,468 ****
--- 492,508 ----
    free_machine_status = rs6000_free_machine_status;
  }
  
+ /* Handle -mabi= options.  */
+ void rs6000_parse_abi_options ()
+ {
+   if (rs6000_abi_string == 0)
+     return;
+   else if (! strcmp (rs6000_abi_string, "altivec"))
+     target_flags |= MASK_ALTIVEC_ABI;
+   else
+     error ("Unknown ABI specified: '%s'", rs6000_abi_string);
+ }
+ 
  void
  optimization_options (level, size)
       int level ATTRIBUTE_UNUSED;
*************** rs6000_legitimize_address (x, oldx, mode
*** 1544,1550 ****
       rtx x;
       rtx oldx ATTRIBUTE_UNUSED;
       enum machine_mode mode;
! { 
    if (GET_CODE (x) == PLUS 
        && GET_CODE (XEXP (x, 0)) == REG
        && GET_CODE (XEXP (x, 1)) == CONST_INT
--- 1584,1590 ----
       rtx x;
       rtx oldx ATTRIBUTE_UNUSED;
       enum machine_mode mode;
! {
    if (GET_CODE (x) == PLUS 
        && GET_CODE (XEXP (x, 0)) == REG
        && GET_CODE (XEXP (x, 1)) == CONST_INT
*************** rs6000_legitimize_address (x, oldx, mode
*** 1570,1575 ****
--- 1610,1627 ----
        return gen_rtx_PLUS (Pmode, XEXP (x, 0),
  			   force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
      }
+   else if (ALTIVEC_VECTOR_MODE (mode))
+     {
+       rtx reg;
+ 
+       /* Make sure both operands are registers.  */
+       if (GET_CODE (x) == PLUS)
+ 	return gen_rtx_PLUS (Pmode, XEXP (x, 0),
+ 			     force_reg (Pmode, XEXP (x, 1)));
+ 
+       reg = force_reg (Pmode, x);
+       return reg;
+     }
    else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic
  	   && GET_CODE (x) != CONST_INT
  	   && GET_CODE (x) != CONST_DOUBLE 
*************** rs6000_emit_move (dest, source, mode)
*** 1862,1867 ****
--- 1914,1928 ----
  	operands[1] = force_const_mem (mode, operands[1]);
        break;
        
+     case V16QImode:
+     case V8HImode:
+     case V4SFmode:
+     case V4SImode:
+       /* fixme: aldyh -- allow vector constants when they are implemented.  */
+       if (CONSTANT_P (operands[1]))
+ 	operands[1] = force_const_mem (mode, operands[1]);
+       break;
+       
      case SImode:
      case DImode:
        /* Use default pattern for address of ELF small data */
*************** init_cumulative_args (cum, fntype, libna
*** 2062,2067 ****
--- 2123,2129 ----
    *cum = zero_cumulative;
    cum->words = 0;
    cum->fregno = FP_ARG_MIN_REG;
+   cum->vregno = ALTIVEC_ARG_MIN_REG;
    cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
    cum->call_cookie = CALL_NORMAL;
    cum->sysv_gregno = GP_ARG_MIN_REG;
*************** function_arg_boundary (mode, type)
*** 2142,2147 ****
--- 2204,2211 ----
    if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
        && (mode == DImode || mode == DFmode))
      return 64;
+   else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
+     return 128;
    else
      return PARM_BOUNDARY;
  }
*************** function_arg_advance (cum, mode, type, n
*** 2159,2165 ****
  {
    cum->nargs_prototype--;
  
!   if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
--- 2223,2236 ----
  {
    cum->nargs_prototype--;
  
!   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
!     {
!       if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
! 	cum->vregno++;
!       else
! 	cum->words += RS6000_ARG_SIZE (mode, type);
!     }
!   else if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
*************** function_arg (cum, mode, type, named)
*** 2287,2293 ****
        return GEN_INT (cum->call_cookie);
      }
  
!   if (abi == ABI_V4 || abi == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
--- 2358,2371 ----
        return GEN_INT (cum->call_cookie);
      }
  
!   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
!     {
!       if (cum->vregno <= ALTIVEC_ARG_MAX_REG)
! 	return gen_rtx_REG (mode, cum->vregno);
!       else
! 	return NULL;
!     }
!   else if (abi == ABI_V4 || abi == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
*************** function_arg_partial_nregs (cum, mode, t
*** 2382,2388 ****
    if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      return 0;
  
!   if (USE_FP_FOR_ARG_P (*cum, mode, type))
      {
        if (cum->nargs_prototype >= 0)
  	return 0;
--- 2460,2467 ----
    if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      return 0;
  
!   if (USE_FP_FOR_ARG_P (*cum, mode, type)
!       || USE_ALTIVEC_FOR_ARG_P (*cum, mode, type))
      {
        if (cum->nargs_prototype >= 0)
  	return 0;
*************** rs6000_va_arg (valist, type)
*** 2838,2843 ****
--- 2917,3392 ----
  
    return addr_rtx;
  }
+ 
+ /* Builtins.  */
+ 
+ #define def_builtin(MASK, NAME, TYPE, CODE)				\
+ do {									\
+   if ((MASK) & target_flags)						\
+     builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL);	\
+ } while (0)
+ 
+ struct builtin_description
+ {
+   const unsigned int mask;
+   const enum insn_code icode;
+   const char *const name;
+   const enum rs6000_builtins code;
+ };
+ 
+ /* Simple binary operatiors: VECc = foo (VECa, VECb).  */
+ static const struct builtin_description bdesc_2arg[] =
+ {
+   { MASK_ALTIVEC, CODE_FOR_altivec_vaddubm, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },

*builtins deleted*

+ };
+ 
+ static rtx
+ altivec_expand_binop_builtin (icode, arglist, target)
+      enum insn_code icode;
+      tree arglist;
+      rtx target;
+ {
+   rtx pat;
+   tree arg0 = TREE_VALUE (arglist);
+   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+   rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+   rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+   enum machine_mode tmode = insn_data[icode].operand[0].mode;
+   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
+   enum machine_mode mode1 = insn_data[icode].operand[2].mode;
+ 
+   if (! target
+       || GET_MODE (target) != tmode
+       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+     target = gen_reg_rtx (tmode);
+ 
+   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+     op0 = copy_to_mode_reg (mode0, op0);
+   if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
+     op1 = copy_to_mode_reg (mode1, op1);
+ 
+   pat = GEN_FCN (icode) (target, op0, op1);
+   if (! pat)
+     return 0;
+   emit_insn (pat);
+ 
+   return target;
+ }
+ 
+ static rtx
+ altivec_expand_builtin (exp, target, subtarget, mode, ignore)
+      tree exp;
+      rtx target;
+      rtx subtarget;
+      enum machine_mode mode;
+      int ignore;
+ {
+   struct builtin_description *d;
+   size_t i;
+   enum insn_code icode;
+   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
+   tree arglist = TREE_OPERAND (exp, 1);
+   tree arg0, arg1, arg2, arg3;
+   rtx op0, op1, op2, pat;
+   enum machine_mode tmode, mode0, mode1, mode2;
+   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+   
+   switch (fcode)
+     {
+     case ALTIVEC_BUILTIN_LD_INTERNAL:
+       icode = CODE_FOR_altivec_lvx;
+       arg0 = TREE_VALUE (arglist);
+       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+       tmode = insn_data[icode].operand[0].mode;
+       mode0 = insn_data[icode].operand[1].mode;
+ 
+       if (! target
+ 	  || GET_MODE (target) != tmode
+ 	  || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ 	target = gen_reg_rtx (tmode);
+ 
+       if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+ 	op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
+ 
+       pat = GEN_FCN (icode) (target, op0);
+       if (! pat)
+ 	return 0;
+       emit_insn (pat);
+       return target;
+ 
+     case ALTIVEC_BUILTIN_ST_INTERNAL:
+       icode = CODE_FOR_altivec_stvx;
+       arg0 = TREE_VALUE (arglist);
+       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+       op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+       mode0 = insn_data[icode].operand[0].mode;
+       mode1 = insn_data[icode].operand[1].mode;
+ 
+       if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
+ 	op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
+       if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
+ 	op1 = copy_to_mode_reg (mode1, op1);
+ 
+       pat = GEN_FCN (icode) (op0, op1);
+       if (! pat)
+ 	return 0;
+       emit_insn (pat);
+       return NULL_RTX;
+     }
+ 
+   /* Handle simple binary operations.  */
+   for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
+     if (d->code == fcode)
+       return altivec_expand_binop_builtin (d->icode, arglist, target);
+ 
+   abort ();
+   return NULL_RTX;
+ }
+ 
+ /* Expand an expression EXP that calls a built-in function,
+    with result going to TARGET if that's convenient
+    (and in mode MODE if that's convenient).
+    SUBTARGET may be used as the target for computing one of EXP's operands.
+    IGNORE is nonzero if the value is to be ignored.  */
+ 
+ static rtx
+ rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
+      tree exp;
+      rtx target;
+      rtx subtarget;
+      enum machine_mode mode;
+      int ignore;
+ {
+   if (TARGET_ALTIVEC)
+     return altivec_expand_builtin (exp, target, subtarget, mode, ignore);
+ 
+   abort ();
+ }
+ 
+ static void
+ rs6000_init_builtins (list_node)
+      tree list_node ATTRIBUTE_UNUSED;
+ {
+   if (TARGET_ALTIVEC)
+     altivec_init_builtins ();
+ }
+ 
+ static void
+ altivec_init_builtins (void)
+ {
+   struct builtin_description * d;
+   size_t i;
+ 
+   tree endlink = void_list_node;
+ 
+   tree pint_type_node = build_pointer_type (integer_type_node);
+ 
+   /* V4SI foo (int *).  */
+   tree v4si_ftype_pint
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, pint_type_node, endlink));
+ 
+   /* void foo (int *, V4SI).  */
+   tree void_ftype_pint_v4si
+     = build_function_type (void_type_node,
+ 			   tree_cons (NULL_TREE, pint_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 
+   tree v4si_ftype_v4si_v4si
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, V4SI_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 
+   tree v4sf_ftype_v4sf_v4sf
+     = build_function_type (V4SF_type_node,
+ 			   tree_cons (NULL_TREE, V4SF_type_node,
+ 				      tree_cons (NULL_TREE, V4SF_type_node,
+ 						 endlink)));
+ 
+   tree v8hi_ftype_v8hi_v8hi
+     = build_function_type (V8HI_type_node,
+ 			   tree_cons (NULL_TREE, V8HI_type_node,
+ 				      tree_cons (NULL_TREE, V8HI_type_node,
+ 						 endlink)));
+ 
+   tree v16qi_ftype_v16qi_v16qi
+     = build_function_type (V16QI_type_node,
+ 			   tree_cons (NULL_TREE, V16QI_type_node,
+ 				      tree_cons (NULL_TREE, V16QI_type_node,
+ 						 endlink)));
+ 
+   tree v4si_ftype_v4sf_v4sf
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, V4SF_type_node,
+ 				      tree_cons (NULL_TREE, V4SF_type_node,
+ 						 endlink)));
+ 
+   tree v8hi_ftype_v16qi_v16qi
+     = build_function_type (V8HI_type_node,
+ 			   tree_cons (NULL_TREE, V16QI_type_node,
+ 				      tree_cons (NULL_TREE, V16QI_type_node,
+ 						 endlink)));
+ 
+   tree v4si_ftype_v8hi_v8hi
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, V8HI_type_node,
+ 				      tree_cons (NULL_TREE, V8HI_type_node,
+ 						 endlink)));
+ 
+   tree v8hi_ftype_v4si_v4si
+     = build_function_type (V8HI_type_node,
+ 			   tree_cons (NULL_TREE, V4SI_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 
+   tree v16qi_ftype_v8hi_v8hi
+     = build_function_type (V16QI_type_node,
+ 			   tree_cons (NULL_TREE, V8HI_type_node,
+ 				      tree_cons (NULL_TREE, V8HI_type_node,
+ 						 endlink)));
+ 
+   tree v4si_ftype_v16qi_v4si
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, V16QI_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 
+   tree v4si_ftype_v8hi_v4si
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, V8HI_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 
+   tree int_ftype_v4si_v4si
+     = build_function_type (integer_type_node,
+ 			   tree_cons (NULL_TREE, V4SI_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 
+   tree int_ftype_v4sf_v4sf
+     = build_function_type (integer_type_node,
+ 			   tree_cons (NULL_TREE, V4SF_type_node,
+ 				      tree_cons (NULL_TREE, V4SF_type_node,
+ 						 endlink)));
+ 
+   tree int_ftype_v16qi_v16qi
+     = build_function_type (integer_type_node,
+ 			   tree_cons (NULL_TREE, V16QI_type_node,
+ 				      tree_cons (NULL_TREE, V16QI_type_node,
+ 						 endlink)));
+ 
+   tree int_ftype_v8hi_v8hi
+     = build_function_type (integer_type_node,
+ 			   tree_cons (NULL_TREE, V8HI_type_node,
+ 				      tree_cons (NULL_TREE, V8HI_type_node,
+ 						 endlink)));
+ 
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal", v4si_ftype_pint, ALTIVEC_BUILTIN_LD_INTERNAL);
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal", void_ftype_pint_v4si, ALTIVEC_BUILTIN_ST_INTERNAL);
+ 
+   /* Add the simple binary operators.  */
+   for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
+     {
+       enum machine_mode mode0, mode1, mode2;
+       tree type;
+ 
+       if (d->name == 0)
+ 	continue;
+       
+       mode0 = insn_data[d->icode].operand[0].mode;
+       mode1 = insn_data[d->icode].operand[1].mode;
+       mode2 = insn_data[d->icode].operand[2].mode;
+ 
+       /* When all three operands are of the same mode.  */
+       if (mode0 == mode1 && mode1 == mode2)
+ 	{
+ 	  switch (mode0)
+ 	    {
+ 	    case V4SFmode:
+ 	      type = v4sf_ftype_v4sf_v4sf;
+ 	      break;
+ 	    case V4SImode:
+ 	      type = v4si_ftype_v4si_v4si;
+ 	      break;
+ 	    case V16QImode:
+ 	      type = v16qi_ftype_v16qi_v16qi;
+ 	      break;
+ 	    case V8HImode:
+ 	      type = v8hi_ftype_v8hi_v8hi;
+ 	      break;
+ 	    default:
+ 	      abort ();
+ 	    }
+ 	}
+ 
+       /* A few other combos we really don't want to do manually.  */
+ 
+       /* vint, vfloat, vfloat.  */
+       else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
+ 	type = v4si_ftype_v4sf_v4sf;
+ 
+       /* vshort, vchar, vchar.  */
+       else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
+ 	type = v8hi_ftype_v16qi_v16qi;
+ 
+       /* vint, vshort, vshort.  */
+       else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
+ 	type = v4si_ftype_v8hi_v8hi;
+ 
+       /* vshort, vint, vint.  */
+       else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
+ 	type = v8hi_ftype_v4si_v4si;
+ 
+       /* vchar, vshort, vshort.  */
+       else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
+ 	type = v16qi_ftype_v8hi_v8hi;
+ 
+       /* vint, vchar, vint.  */
+       else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
+ 	type = v4si_ftype_v16qi_v4si;
+ 
+       /* vint, vshort, vint.  */
+       else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
+ 	type = v4si_ftype_v8hi_v4si;
+ 
+       /* fixme: aldyh */
+       /* int, x, x.  */
+       else if (mode0 == SImode)
+ 	{
+ 	  switch (mode1)
+ 	    {
+ 	    case V4SImode:
+ 	      type = int_ftype_v4si_v4si;
+ 	      break;
+ 	    case V4SFmode:
+ 	      type = int_ftype_v4sf_v4sf;
+ 	      break;
+ 	    case V16QImode:
+ 	      type = int_ftype_v16qi_v16qi;
+ 	      break;
+ 	    case V8HImode:
+ 	      type = int_ftype_v8hi_v8hi;
+ 	      break;
+ 	    default:
+ 	      abort ();
+ 	    }
+ 	}
+ 
+       else
+ 	abort ();
+ 
+       def_builtin (d->mask, d->name, type, d->code);
+     }
+ }
+ 
  \f
  /* Generate a memory reference for expand_block_move, copying volatile,
     and other bits from an original memory reference.  */
*************** secondary_reload_class (class, mode, in)
*** 3941,3946 ****
--- 4490,4500 ----
        && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
      return NO_REGS;
  
+   /* Memory, and AltiVec registers can go into AltiVec registers.  */
+   if ((regno == -1 || ALTIVEC_REGNO_P (regno))
+       && class == ALTIVEC_REGS)
+     return NO_REGS;
+ 
    /* We can copy among the CR registers.  */
    if ((class == CR_REGS || class == CR0_REGS)
        && regno >= 0 && CR_REGNO_P (regno))
*************** print_operand (file, x, code)
*** 4714,4719 ****
--- 5268,5299 ----
  		     reg_names[SMALL_DATA_REG]);
  	}
        return;
+ 
+       /* Print AltiVec memory operand.  */
+     case 'y':
+       {
+ 	rtx tmp;
+ 
+ 	if (GET_CODE (x) != MEM)
+ 	  abort ();
+ 
+ 	tmp = XEXP (x, 0);
+ 
+ 	if (GET_CODE (tmp) == REG)
+ 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
+ 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
+ 	  {
+ 	    if (REGNO (XEXP (tmp, 0)) == 0)
+ 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
+ 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
+ 	    else
+ 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
+ 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
+ 	  }
+ 	else
+ 	  abort ();
+ 	break;
+       }
  			    
      case 0:
        if (GET_CODE (x) == REG)
Index: rs6000.md
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.128
diff -c -p -r1.128 rs6000.md
*** rs6000.md	2001/10/16 00:43:21	1.128
--- rs6000.md	2001/11/06 22:24:51
***************
*** 37,43 ****
  \f
  ;; Define an insn type attribute.  This is used in function unit delay
  ;; computations.
! (define_attr "type" "integer,load,store,fpload,fpstore,imul,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg"
    (const_string "integer"))
  
  ;; Length (in bytes).
--- 37,43 ----
  \f
  ;; Define an insn type attribute.  This is used in function unit delay
  ;; computations.
! (define_attr "type" "integer,load,store,fpload,fpstore,imul,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,altivec"
    (const_string "integer"))
  
  ;; Length (in bytes).
***************
*** 13359,13361 ****
--- 13359,14294 ----
      emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
    DONE;
  }")
+ 
+ ;; AltiVec patterns
+ 
+ ;; Generic LVX load instruction.
+ (define_insn "altivec_lvx"
+   [(set (match_operand:V4SI 0 "register_operand" "=v")
+ 	(match_operand:V4SI 1 "memory_operand" "m"))]
+   "TARGET_ALTIVEC"
+   "lvx\t%0,%y1"
+   [(set_attr "type" "altivec")])
+ 
+ ;; Generic STVX store instruction.
+ (define_insn "altivec_stvx"
+   [(set (match_operand:V4SI 0 "memory_operand" "=m")
+ 	(match_operand:V4SI 1 "register_operand" "v"))]
+   "TARGET_ALTIVEC"
+   "stvx\t%1,%y0"
+   [(set_attr "type" "altivec")])
+ 
+ ;; Vector move instructions.
+ (define_expand "movv4si"
+   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
+ 	(match_operand:V4SI 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V4SImode); DONE; }")
+ 
+ (define_insn "*movv4si_internal"
+   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v,v")
+ 	(match_operand:V4SI 1 "input_operand" "v,m,v"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1
+    vor\t%0,%1,%1"
+   [(set_attr "type" "altivec")])
+ 
+ (define_expand "movv8hi"
+   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
+ 	(match_operand:V8HI 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V8HImode); DONE; }")
+ 
+ (define_insn "*movv8hi_internal1"
+   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=m,v,v")
+ 	(match_operand:V8HI 1 "input_operand" "v,m,v"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1
+    vor\t%0,%1,%1"
+   [(set_attr "type" "altivec")])
+ 
+ (define_expand "movv16qi"
+   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
+ 	(match_operand:V16QI 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V16QImode); DONE; }")
+ 
+ (define_insn "*movv16qi_internal1"
+   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=m,v,v")
+ 	(match_operand:V16QI 1 "input_operand" "v,m,v"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1
+    vor\t%0,%1,%1"
+   [(set_attr "type" "altivec")])
+ 
+ (define_expand "movv4sf"
+   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
+ 	(match_operand:V4SF 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V4SFmode); DONE; }")
+ 
+ (define_insn "*movv4sf_internal1"
+   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=m,v,v")
+ 	(match_operand:V4SF 1 "input_operand" "v,m,v"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1
+    vor\t%0,%1,%1"
+   [(set_attr "type" "altivec")])
+ 
+ ;; Simple binary operations.
+ 
+ (define_insn "altivec_vaddubm"
+   [(set (match_operand:V16QI 0 "register_operand" "=v")
+         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
+                        (match_operand:V16QI 2 "register_operand" "v")] 31))]
+   "TARGET_ALTIVEC"
+   "vaddubm\t%0,%1,%2"
+   [(set_attr "type" "altivec")])

*builtins deleted*

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-07  2:36       ` Geoff Keating
@ 2001-11-13  4:33         ` Geoff Keating
  2001-11-13 15:03         ` Geoff Keating
  1 sibling, 0 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-13  4:33 UTC (permalink / raw)
  To: drow; +Cc: aldyh, dalej, gcc-patches

> Date: Tue, 6 Nov 2001 19:12:03 -0500
> From: Daniel Jacobowitz <drow@mvista.com>
> Cc: Dale Johannesen <dalej@apple.com>, gcc patches <gcc-patches@gcc.gnu.org>,
>         Geoff Keating <geoffk@cygnus.com>

> Is there any reasonable way to reflect that in the generated objects,
> then?  Is there a spare bit in the ELF header for this?

You can create a special .note section.  Using bits in the ELF header
for this is not recommended; consider the problems it causes on MIPS for
instance.

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 17:15       ` Aldy Hernandez
@ 2001-11-13  4:33         ` Aldy Hernandez
  2001-11-13 15:03         ` Aldy Hernandez
  1 sibling, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13  4:33 UTC (permalink / raw)
  To: Stan Shebs; +Cc: Geoff Keating, gcc patches

On Tue, 2001-11-06 at 20:07, Stan Shebs wrote:
> Aldy Hernandez wrote:
> > 
> > After a few iterations I think this is finally it-- for the first
> > batch of patches anyhow.
> 
> It's all looking good to me, modulo the question below.
> 
> It would be ever so slightly more convenient for Apple's next import
> if vrsave were to be listed ahead of the general vector registers
> instead of after (it then becomes part of the "block" of misc regs),
> but we can cope with it either way.
> 

heh.  gcc merges... i bet it's going to be a painful merge.  sorry.

would you mind changing the vrsave order yourself after this gets
committed?  i'm doing my umteenth "make bootstrap; make check" today and
i don't want to do so yet again ;)

> Missing a "vrsave" here?
> 
> Stan

yes typo.  i had already fixed it.


-- 
Aldy Hernandez			E-mail: aldyh@redhat.com
Professional Gypsy
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 17:00     ` Dale Johannesen
  2001-11-06 17:06       ` Aldy Hernandez
@ 2001-11-13  4:33       ` Dale Johannesen
  2001-11-13 15:03       ` Dale Johannesen
  2 siblings, 0 replies; 152+ messages in thread
From: Dale Johannesen @ 2001-11-13  4:33 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Dale Johannesen, Geoff Keating, gcc-patches

On Tuesday, November 6, 2001, at 03:04 PM, Aldy Hernandez wrote:

> *************** extern int rs6000_debug_arg;	
> --- 766,779 ----
>      31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19,	\
>      18, 17, 16, 15, 14, 13, 12,				\
>      64, 66, 65, 						\
> !    73, 1, 2, 67, 76,					\
> !    /* AltiVec registers.  */				\
> !    77, 78,						\
> !    90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80,		\
> !    79,							\
> !    96, 95, 94, 93, 92, 91,				\
> !    108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97 \
> ! }

This needs an entry for vrsave.  (If you leave it out, you can get
a crash in reload on code that has nothing to do with Altivec; trust
me on this one:)

>   /* 1 if N is a possible register number for function argument passing.
>      On RS/6000, these are r3-r10 and fp1-fp13.  */
>   #define FUNCTION_ARG_REGNO_P(N)						\
>     ((unsigned)(((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG))	\
> +    || (TARGET_ALTIVEC &&						\
> +        (unsigned)((N) - ALTIVEC_ARG_MIN_REG) < 
> (unsigned)(ALTIVEC_ARG_MAX_REG)) \
>      || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))\

It would be nice, though not essential, to update the comment.

> --- 2511,2549 ----
...snipped...
> +   &rs6000_reg_names[107][0],	/* v30  */				\
> +   &rs6000_reg_names[108][0],	/* v31  */				\
>   }

This needs an entry for vrsave.

> --- 2562,2572 ----
>       "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",		\
>        "mq",  "lr", "ctr",  "ap",						\
>       "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",		\
> !   "xer",								\
> !      "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",            
>  \
> !      "v8",  "v9", "v10", "v11", "v12", "v13", "v14", "v15",            
>  \
> !     "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",            
>  \
> !     "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"             
>  \
>   }

So does this.

> +   {"v24",  101},{"v25",  102},{"v26",  103},{"v27",  104},      \
> +   {"v28",  105},{"v29",  106},{"v30",  107},{"v31",  108},      \
>     /* no additional names for: mq, lr, ctr, ap */		\
>     {"cr0",  68}, {"cr1",  69}, {"cr2",  70}, {"cr3",  71},	\
>     {"cr4",  72}, {"cr5",  73}, {"cr6",  74}, {"cr7",  75}

Not sure about here, but either the table or the commment should be 
updated.

> --- 170,181 ----
>        "24", "25", "26", "27", "28", "29", "30", "31",
>        "mq", "lr", "ctr","ap",
>         "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
> !       "xer",
> !       /* AltiVec registers.  */
> !       "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6", "v7",
> !       "v8",  "v9",  "v10", "v11", "v12", "v13", "v14", "v15",
> !       "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
> !       "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
>   };

vrsave again.

> --- 191,202 ----
>     "%f24",  "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
>       "mq",    "lr",  "ctr",   "ap",
>     "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
> !    "xer",
> !    /* AltiVec registers.  */
> !    "%v0",  "%v1",  "%v2",  "%v3",  "%v4",  "%v5",  "%v6", "%v7",
> !    "%v8",  "%v9",  "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
> !    "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
> !    "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31"
>   };

and again.

With these fixes I'll approve everything but the builtins, which I'm not
planning to rule on either way.  You'll have to go through and change all
the 'altivec' functional units later, but I guess you're aware of that.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 23:17   ` Richard Henderson
  2001-11-07  2:50     ` Geoff Keating
  2001-11-07  8:23     ` Aldy Hernandez
@ 2001-11-13  4:33     ` Richard Henderson
  2001-11-13 15:03     ` Richard Henderson
  3 siblings, 0 replies; 152+ messages in thread
From: Richard Henderson @ 2001-11-13  4:33 UTC (permalink / raw)
  To: Geoff Keating; +Cc: aldyh, gcc-patches

On Mon, Nov 05, 2001 at 01:58:06PM -0800, Geoff Keating wrote:
> > - #define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
> > + #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
> > - #define BIGGEST_ALIGNMENT 64
> > + #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)
> 
> I think you _don't_ want this to be dependent on the ABI.  Changing
> this isn't an ABI change (I hope!), which is good because...

Yes it is.  REGNO_POINTER_ALIGN(STACK_POINTER_REGNUM) == STACK_BOUNDARY.

Remember that STACK_BOUNDARY != PREFERRED_STACK_BOUNDARY, and that the
later does not help you unless you also have code to enforce stack
alignment, like we're supposed to have for x86 vector code.

> > ! /* A C expression to compute the alignment for a variables in the
> > !    local store.  TYPE is the data type, and ALIGN is the alignment
> > !    that the object would ordinarily have.  */
> > ! #define LOCAL_ALIGNMENT(TYPE, ALIGN)				\
> > ! 	((TARGET_ALTIVEC_ABI		    			\
> > ! 	  && TREE_CODE (TYPE)) == VECTOR_TYPE ? 128 : ALIGN)
> 
> ...as altivec values have to be 128-bit aligned because of the
> hardware, you don't want this ABI-dependent either.

Well, so long as you don't spill...  ;-)

> The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
> quite right:  it has to happen _only when the ABI is 'altivec'_.

I _think_ you don't have to worry about this any longer.  The ia64
eh library interface does not expose the number of registers
involved.  

We might ought to have checks added to die more gracefully if the
target adds registers, since we do statically allocate this space
and older libgcc would not be able to unwind for newer gcc code.



r~

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 15:14     ` Joseph S. Myers
  2001-11-06 16:28       ` Aldy Hernandez
@ 2001-11-13  4:33       ` Joseph S. Myers
  2001-11-13 15:03       ` Joseph S. Myers
  2 siblings, 0 replies; 152+ messages in thread
From: Joseph S. Myers @ 2001-11-13  4:33 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: gcc-patches

On 6 Nov 2001, Aldy Hernandez wrote:

> + the current ABI@

This sentence now seems to be missing its trailing ".".

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-07 12:12         ` Geoff Keating
@ 2001-11-13  5:05           ` Geoff Keating
  2001-11-13 15:03           ` Geoff Keating
  1 sibling, 0 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-13  5:05 UTC (permalink / raw)
  To: rth; +Cc: aldyh, gcc-patches

> Date: Wed, 7 Nov 2001 11:41:11 -0800
> From: Richard Henderson <rth@redhat.com>
> Cc: aldyh@redhat.com, gcc-patches@gcc.gnu.org
> Mail-Followup-To: Richard Henderson <rth@redhat.com>,
> 	Geoff Keating <geoffk@redhat.com>, aldyh@redhat.com,
> 	gcc-patches@gcc.gnu.org
> Content-Disposition: inline
> User-Agent: Mutt/1.2.5i
> 
> On Wed, Nov 07, 2001 at 02:49:15AM -0800, Geoff Keating wrote:
> > Here I was talking about BIGGEST_ALIGNMENT only.  Changing
> > STACK_BOUNDARY is of course an ABI change.
> 
> Well, there is
> 
>   struct {
>     int x __attribute__((aligned));
>     int y;
>   };
> 
> to name one place that BIGGEST_ALIGNMENT affects the ABI.
> I suspect there are other places as well.

Hmmm.  Well, we'll see.

> > Can we really change the EH library interface like this?  Even in the
> > presence of a glibc compatibility layer to support pre-gcc3.0 C++
> > binaries?
> 
> Pre gcc 3.0, we don't support altivec, so we don't have to worry 
> about this.

Yes, but that's the question:  Can this be changed even for
non-altivec compilations?

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-07 11:41       ` Richard Henderson
  2001-11-07 12:12         ` Geoff Keating
@ 2001-11-13  5:05         ` Richard Henderson
  2001-11-13 15:03         ` Richard Henderson
  2 siblings, 0 replies; 152+ messages in thread
From: Richard Henderson @ 2001-11-13  5:05 UTC (permalink / raw)
  To: Geoff Keating; +Cc: aldyh, gcc-patches

On Wed, Nov 07, 2001 at 02:49:15AM -0800, Geoff Keating wrote:
> Here I was talking about BIGGEST_ALIGNMENT only.  Changing
> STACK_BOUNDARY is of course an ABI change.

Well, there is

  struct {
    int x __attribute__((aligned));
    int y;
  };

to name one place that BIGGEST_ALIGNMENT affects the ABI.
I suspect there are other places as well.

> Can we really change the EH library interface like this?  Even in the
> presence of a glibc compatibility layer to support pre-gcc3.0 C++
> binaries?

Pre gcc 3.0, we don't support altivec, so we don't have to worry 
about this.



r~

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-03 20:37           ` Geoff Keating
  2001-11-13  4:26             ` Geoff Keating
@ 2001-11-13 13:21             ` Geoff Keating
  2001-11-13 15:03             ` Aldy Hernandez
  2001-11-13 15:03             ` Geoff Keating
  3 siblings, 0 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-13 13:21 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: gcc-patches

Alan Matsuoka <alanm@cygnus.com> writes:

> 2001-11-05  Alan Matsuoka  <alanm@redhat.com>
> 
>         * rtl.def (INCLUDE) : Define.
> 	* gensupport.c (init_include_reader, process_include, save_string) :  New functions to
> 	  implement an include facility in .md files.
> 	* gensupport.h : Add prototype for init_md_reader_args.
> 	* genattr.c genattrtab.c gencodes.c genconfig.c genemit.c
> 	  genextract.c genflags.c genopinit.c genoutput.c genpeep.c
> 	  genrecog.c: Change call to init_md_reader to init_md_reader_args.
> 	* md.texi: Document (include "path") and -I directives for RTL generation tools.

The patch is OK.

When you commit, please fix the whitespace and line-wrap the ChangeLog
entry to 80 columns.

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-07  2:36       ` Geoff Keating
  2001-11-13  4:33         ` Geoff Keating
@ 2001-11-13 15:03         ` Geoff Keating
  1 sibling, 0 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-13 15:03 UTC (permalink / raw)
  To: drow; +Cc: aldyh, dalej, gcc-patches

> Date: Tue, 6 Nov 2001 19:12:03 -0500
> From: Daniel Jacobowitz <drow@mvista.com>
> Cc: Dale Johannesen <dalej@apple.com>, gcc patches <gcc-patches@gcc.gnu.org>,
>         Geoff Keating <geoffk@cygnus.com>

> Is there any reasonable way to reflect that in the generated objects,
> then?  Is there a spare bit in the ELF header for this?

You can create a special .note section.  Using bits in the ELF header
for this is not recommended; consider the problems it causes on MIPS for
instance.

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 18:28       ` Alan Matsuoka
  2001-11-05 18:41         ` Include facility for .md files - " Alan Matsuoka
  2001-11-13  4:32         ` Alan Matsuoka
@ 2001-11-13 15:03         ` Alan Matsuoka
  2 siblings, 0 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Geoff Keating, gcc-patches

On Mon, 05 Nov 2001, Aldy Hernandez wrote:

> >>>>> "Alan" == Alan Matsuoka <alanm@cygnus.com> writes:
> 
>  >> Do you really need this?  It looks just like the way a normal memory
>  >> operand is printed (for the cases that are allowed for altivec).
>  >> 
>  >> > Index: rs6000.md
>  >> 
>  >> Can you put the altivec insns in their own .md file and use the include
>  >> mechanism?  I believe this is what it was intended for.
> 
> Last i heard, alan matsuoka's include mechanism hadn't been approved.
> Alan, perhaps you should send them again.  We definitely need them
> now.

OK.

Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-13 15:03                       ` Alan Matsuoka
@ 2001-11-13 15:03                         ` Aldy Hernandez
  2001-11-13 15:03                           ` Alan Matsuoka
  0 siblings, 1 reply; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: Alexandre Oliva, gcc-patches


 > OK. Thank you. I didn't  know.

Another thing Alan.

I think you also need to include patches for the build system that
handle dependencies introduced by these .md include files.  See
"md_file" in config.gcc, configure.in, and Makefile.in.

I'd like to see an "extra_mds" variable that is used to specify other
.md's used in the port.

For example, you should be able to do:

powerpc-*-sysv*)
        tm_file="${tm_file} svr4.h rs6000/sysv4.h"
        blah blah
-->     extra_mds="altivec.md"
        ;;

Right now if I use the include mechanism, there is no way for gcc to
know that rs6000.md is dependent on altivec.md.

Cheers.
Aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 13:17     ` Joseph S. Myers
  2001-11-13  4:32       ` Joseph S. Myers
@ 2001-11-13 15:03       ` Joseph S. Myers
  1 sibling, 0 replies; 152+ messages in thread
From: Joseph S. Myers @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: gcc patches

On 5 Nov 2001, Aldy Hernandez wrote:

> > That should end "ABI@." so that spacing after the sentence is correct if
> > more text gets added to that paragraph later.
> 
> huh?  i've never heard that.
> 
> where are the .texi docs?  i'm bound to make more mistakes if i don't
> read the texi docs :)

Included with texinfo, or online at

http://www.gnu.org/manual/texinfo/

in particular

http://www.gnu.org/manual/texinfo/html_chapter/texinfo_14.html#SEC151

which describes this particular issue.

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-06  7:58                   ` Alan Matsuoka
  2001-11-13  4:32                     ` Alan Matsuoka
  2001-11-13 15:03                     ` Alexandre Oliva
@ 2001-11-13 15:03                     ` Alan Matsuoka
  2 siblings, 0 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-13 15:03 UTC (permalink / raw)
  To: gcc-patches

Alan Matsuoka wrote:
> 
> On Tue, 06 Nov 2001, Joseph S. Myers wrote:
> 
> > On Mon, 5 Nov 2001, Alan Matsuoka wrote:
> >
> > > + Where @var{pathname} is a string that specifies the the location of the file,
> > > + specifies the include file to be in gcc/config/{target}/filestuff. The
> >
> > @file{gcc/config/@var{target}/filestuff}.
> >
> > > + directory @file{gcc/config/{target}} is regarded as the default directory.
> >
> > @var{target}.
> >
> > Has this patch passed "make info" and "make dvi"?
> 
> I'll sumbit a revised patch as soon as the cvs server lets me
> generate a patch.
This is a revised patch. It now works with "make info" and "make dvi"
-- 
Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299
The following patch is for the an internal project. This is 
implements a (include "filestuff") mechanism for splitting up 
.md files.

(include "filestuff") expects the include file to be in gcc/config/{target}/filestuff
(include "BOGUS/filestuff") expects the include file to be in gcc/config/{target}/BOGUS/filestuff
(include "/u2/BOGUS/filestuff") expects the include file to be in /u2/BOGUS/filestuff

You can also run things like genrecog -I/p1/abc/proc1 -I/p2/abcd/pro2 target.md

This is used only at build time.

This has been tested for i686-pc-linux-gnu by bootstrapping and testing without 
any regressions.

The DOS pathname style stuff may still be required.


2001-11-05  Alan Matsuoka  <alanm@redhat.com>

        * rtl.def (INCLUDE) : Define.
	* gensupport.c (init_include_reader, process_include, 
	  save_string) :  New functions to
	  implement an include facility in .md files.
	* gensupport.h : Add prototype for init_md_reader_args.
	* genattr.c genattrtab.c gencodes.c genconfig.c genemit.c
	  genextract.c genflags.c genopinit.c genoutput.c genpeep.c
	  genrecog.c: Change call to init_md_reader to init_md_reader_args.
	* md.texi: Document (include "path") and -I directives for RTL 
	  generation tools.

Index: genattr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genattr.c,v
retrieving revision 1.45
diff -c -3 -p -r1.45 genattr.c
*** genattr.c	2001/10/07 16:50:51	1.45
--- genattr.c	2001/11/06 15:51:39
*************** main (argc, argv)
*** 210,216 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genattr'");
--- 210,216 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genattr'");
Index: genattrtab.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genattrtab.c,v
retrieving revision 1.103
diff -c -3 -p -r1.103 genattrtab.c
*** genattrtab.c	2001/10/21 21:32:00	1.103
--- genattrtab.c	2001/11/06 15:51:41
*************** main (argc, argv)
*** 6075,6081 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    obstack_init (hash_obstack);
--- 6075,6081 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    obstack_init (hash_obstack);
Index: gencodes.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gencodes.c,v
retrieving revision 1.42
diff -c -3 -p -r1.42 gencodes.c
*** gencodes.c	2001/08/22 14:35:16	1.42
--- gencodes.c	2001/11/06 15:51:41
*************** main (argc, argv)
*** 56,62 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("\
--- 56,62 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("\
Index: genconfig.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genconfig.c,v
retrieving revision 1.43
diff -c -3 -p -r1.43 genconfig.c
*** genconfig.c	2001/10/11 07:07:26	1.43
--- genconfig.c	2001/11/06 15:51:41
*************** main (argc, argv)
*** 277,283 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genconfig'");
--- 277,283 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genconfig'");
Index: genemit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genemit.c,v
retrieving revision 1.67
diff -c -3 -p -r1.67 genemit.c
*** genemit.c	2001/10/19 19:37:08	1.67
--- genemit.c	2001/11/06 15:51:41
*************** main (argc, argv)
*** 789,795 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
--- 789,795 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
Index: genextract.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genextract.c,v
retrieving revision 1.46
diff -c -3 -p -r1.46 genextract.c
*** genextract.c	2001/10/11 03:15:42	1.46
--- genextract.c	2001/11/06 15:51:41
*************** main (argc, argv)
*** 362,368 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
--- 362,368 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
Index: genflags.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genflags.c,v
retrieving revision 1.39
diff -c -3 -p -r1.39 genflags.c
*** genflags.c	2001/10/11 03:15:42	1.39
--- genflags.c	2001/11/06 15:51:42
*************** main (argc, argv)
*** 230,236 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
    
    puts ("/* Generated automatically by the program `genflags'");
--- 230,236 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
    
    puts ("/* Generated automatically by the program `genflags'");
Index: genopinit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genopinit.c,v
retrieving revision 1.48
diff -c -3 -p -r1.48 genopinit.c
*** genopinit.c	2001/09/13 14:37:11	1.48
--- genopinit.c	2001/11/06 15:51:42
*************** main (argc, argv)
*** 316,322 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genopinit'\n\
--- 316,322 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genopinit'\n\
Index: genoutput.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genoutput.c,v
retrieving revision 1.65
diff -c -3 -p -r1.65 genoutput.c
*** genoutput.c	2001/10/11 03:15:42	1.65
--- genoutput.c	2001/11/06 15:51:42
*************** main (argc, argv)
*** 953,959 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    output_prologue ();
--- 953,959 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    output_prologue ();
Index: genpeep.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genpeep.c,v
retrieving revision 1.49
diff -c -3 -p -r1.49 genpeep.c
*** genpeep.c	2001/10/11 03:15:43	1.49
--- genpeep.c	2001/11/06 15:51:42
*************** main (argc, argv)
*** 385,391 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genpeep'\n\
--- 385,391 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genpeep'\n\
Index: genrecog.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genrecog.c,v
retrieving revision 1.111
diff -c -3 -p -r1.111 genrecog.c
*** genrecog.c	2001/10/28 20:09:14	1.111
--- genrecog.c	2001/11/06 15:51:44
*************** main (argc, argv)
*** 2689,2695 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    next_insn_code = 0;
--- 2689,2695 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    next_insn_code = 0;
Index: gensupport.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gensupport.c,v
retrieving revision 1.23
diff -c -3 -p -r1.23 gensupport.c
*** gensupport.c	2001/10/25 12:55:16	1.23
--- gensupport.c	2001/11/06 15:51:44
*************** static int predicable_default;
*** 42,47 ****
--- 42,49 ----
  static const char *predicable_true;
  static const char *predicable_false;
  
+ static char *base_dir = NULL;
+ 
  /* We initially queue all patterns, process the define_insn and
     define_cond_exec patterns, then return them one at a time.  */
  
*************** static struct queue_elem *other_queue;
*** 62,67 ****
--- 64,86 ----
  static struct queue_elem **other_tail = &other_queue;
  
  static void queue_pattern PARAMS ((rtx, struct queue_elem ***, int));
+ 
+ /* Current maximum length of directory names in the search path
+    for include files.  (Altered as we get more of them.)  */
+ 
+ size_t max_include_len;
+ 
+ struct file_name_list
+   {
+     struct file_name_list *next;
+     const char *fname;
+   };
+ 
+ struct file_name_list *include = 0;     /* First dir to search */
+         /* First dir to search for <file> */
+ struct file_name_list *first_bracket_include = 0;
+ struct file_name_list *last_include = 0;        /* Last in chain */
+ 
  static void remove_constraints PARAMS ((rtx));
  static void process_rtx PARAMS ((rtx, int));
  
*************** static const char *alter_output_for_insn
*** 78,83 ****
--- 97,105 ----
  						  int, int));
  static void process_one_cond_exec PARAMS ((struct queue_elem *));
  static void process_define_cond_exec PARAMS ((void));
+ static int process_include PARAMS ((rtx, int));
+ static char *save_string PARAMS ((const char *, int));
+ static int init_include_reader PARAMS ((FILE  *));
  \f
  void
  message_with_line VPARAMS ((int lineno, const char *msg, ...))
*************** remove_constraints (part)
*** 157,162 ****
--- 179,320 ----
        }
  }
  
+ /* The entry point for initializing the reader.  */
+ 
+ static int
+ init_include_reader (inf)
+      FILE *inf;
+ {
+   int c;
+ 
+   errors = 0;
+ 
+   /* Read the entire file.  */
+   while (1)
+     {
+       rtx desc;
+       int lineno;
+ 
+       c = read_skip_spaces (inf);
+       if (c == EOF)
+ 	break;
+ 
+       ungetc (c, inf);
+       lineno = read_rtx_lineno;
+       desc = read_rtx (inf);
+       process_rtx (desc, lineno);
+     }
+   fclose (inf);
+ 
+   /* Process define_cond_exec patterns.  */
+   if (define_cond_exec_queue != NULL)
+     process_define_cond_exec ();
+ 
+   return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
+ }
+ 
+ /* Process an include file assuming that it lives in gcc/config/{target}/ 
+    if the include looks line (include "file" )  */
+ static int
+ process_include (desc, lineno)
+      rtx desc;
+      int lineno;
+ {
+   const char *filename = XSTR (desc, 0);
+   char *pathname = NULL;
+   FILE *input_file;
+   char *fname;
+   struct file_name_list *stackp;
+   int flen;
+ 
+   stackp = include;
+ 
+   /* If specified file name is absolute, just open it.  */
+   if (IS_ABSOLUTE_PATHNAME (filename) || !stackp)
+     {
+       if (base_dir)
+         {
+           pathname = xmalloc (strlen (base_dir) + strlen (filename) + 1);
+           pathname = strcpy (pathname, base_dir);
+           strcat (pathname, filename);
+           strcat (pathname, "\0");
+ 	}
+       else
+         {
+ 	  pathname = xstrdup (filename);
+         }
+       read_rtx_filename = pathname;
+       input_file = fopen (pathname, "r");
+ 
+       if (input_file == 0)
+ 	{
+ 	  perror (pathname);
+ 	  return FATAL_EXIT_CODE;
+ 	}
+     }
+   else if (stackp)
+     {
+ 
+       flen = strlen (filename);
+ 
+       fname = (char *) alloca (max_include_len + flen + 2);
+ 
+       /* + 2 above for slash and terminating null.  */
+ 
+       /* Search directory path, trying to open the file.
+          Copy each filename tried into FNAME.  */
+ 
+       for (; stackp; stackp = stackp->next)
+ 	{
+ 	  if (stackp->fname)
+ 	    {
+ 	      strcpy (fname, stackp->fname);
+ 	      strcat (fname, "/");
+ 	      fname[strlen (fname) + flen] = 0;
+ 	    }
+ 	  else
+ 	    {
+ 	      fname[0] = 0;
+ 	    }
+ 	  strncat (fname, (const char *) filename, flen);
+ 	  read_rtx_filename = fname;
+ 	  input_file = fopen (fname, "r");
+ 	  if (input_file != NULL) 
+ 	    break;
+ 	}
+       if (stackp == NULL)
+ 	{
+ 	  if (strchr (fname, '/') == NULL || strchr (fname, '\\' ) || base_dir)
+ 	    {
+ 	      if (base_dir)
+ 		{
+ 		  pathname =
+ 		    xmalloc (strlen (base_dir) + strlen (filename) + 1);
+ 		  pathname = strcpy (pathname, base_dir);
+ 		  strcat (pathname, filename);
+ 		  strcat (pathname, "\0");
+ 		}
+ 	      else
+ 		pathname = xstrdup (filename);
+ 	    }
+ 	  read_rtx_filename = pathname;
+ 	  input_file = fopen (pathname, "r");
+ 
+ 	  if (input_file == 0)
+ 	    {
+ 	      perror (filename);
+ 	      return FATAL_EXIT_CODE;
+ 	    }
+ 	}
+ 
+     }
+ 
+   if (init_include_reader (input_file) == FATAL_EXIT_CODE)
+     message_with_line (lineno, "read errors found in include file  %s\n", pathname);
+ 
+   return SUCCESS_EXIT_CODE;
+ }
+ 
  /* Process a top level rtx in some way, queueing as appropriate.  */
  
  static void
*************** process_rtx (desc, lineno)
*** 164,169 ****
--- 322,329 ----
       rtx desc;
       int lineno;
  {
+   const char *filename = XSTR (desc, 0);
+ 
    switch (GET_CODE (desc))
      {
      case DEFINE_INSN:
*************** process_rtx (desc, lineno)
*** 178,183 ****
--- 338,348 ----
        queue_pattern (desc, &define_attr_tail, lineno);
        break;
  
+     case INCLUDE:
+       if (process_include (desc, lineno) == FATAL_EXIT_CODE)
+         message_with_line (lineno, "include file at  %s not found\n", filename);
+       break;
+ 
      case DEFINE_INSN_AND_SPLIT:
        {
  	const char *split_cond;
*************** process_define_cond_exec ()
*** 767,781 ****
--- 932,1022 ----
    for (elem = define_cond_exec_queue; elem ; elem = elem->next)
      process_one_cond_exec (elem);
  }
+ 
+ static char *
+ save_string (s, len)
+      const char *s;
+      int len;
+ {
+   register char *result = xmalloc (len + 1);
+ 
+   memcpy (result, s, len);
+   result[len] = 0;
+   return result;
+ }
+ 
  \f
  /* The entry point for initializing the reader.  */
  
  int
+ init_md_reader_args (argc, argv)
+      int argc;
+      char **argv;
+ {
+   int i;
+   const char *in_fname;
+ 
+   max_include_len = 0;
+   in_fname = NULL;
+   for (i = 1; i < argc; i++)
+     {
+       if (argv[i][0] != '-')
+ 	{
+ 	  if (in_fname == NULL)
+ 	    in_fname = argv[i];
+ 	}
+       else
+ 	{
+ 	  int c = argv[i][1];
+ 	  switch (c)
+ 	    {
+ 	    case 'I':		/* Add directory to path for includes.  */
+ 	      {
+ 		struct file_name_list *dirtmp;
+ 
+ 		dirtmp = (struct file_name_list *)
+ 		  xmalloc (sizeof (struct file_name_list));
+ 		dirtmp->next = 0;	/* New one goes on the end */
+ 		if (include == 0)
+ 		  include = dirtmp;
+ 		else
+ 		  last_include->next = dirtmp;
+ 		last_include = dirtmp;	/* Tail follows the last one */
+ 		if (argv[i][1] == 'I' && argv[i][2] != 0)
+ 		  dirtmp->fname = argv[i] + 2;
+ 		else if (i + 1 == argc)
+ 		  fatal ("Directory name missing after -I option");
+ 		else
+ 		  dirtmp->fname = argv[++i];
+ 		if (strlen (dirtmp->fname) > max_include_len)
+ 		  max_include_len = strlen (dirtmp->fname);
+ 	      }
+ 	      break;
+ 	    default:
+ 	      fatal ("Invalid option `%s'", argv[i]);
+ 
+ 	    }
+ 	}
+     }
+     return init_md_reader (in_fname);
+ }
+ \f
+ /* The entry point for initializing the reader.  */
+ 
+ int
  init_md_reader (filename)
       const char *filename;
  {
    FILE *input_file;
    int c;
+   char *lastsl;
+ 
+   if (!IS_ABSOLUTE_PATHNAME (filename))
+     {
+       lastsl = strrchr (filename, '/');
+       if (lastsl != NULL) 
+ 	base_dir = save_string (filename, lastsl - filename + 1 );
+     }
  
    read_rtx_filename = filename;
    input_file = fopen (filename, "r");
*************** init_md_reader (filename)
*** 797,803 ****
  
        c = read_skip_spaces (input_file);
        if (c == EOF)
! 	break;
  
        ungetc (c, input_file);
        lineno = read_rtx_lineno;
--- 1038,1044 ----
  
        c = read_skip_spaces (input_file);
        if (c == EOF)
!         break;
  
        ungetc (c, input_file);
        lineno = read_rtx_lineno;
Index: gensupport.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gensupport.h,v
retrieving revision 1.3
diff -c -3 -p -r1.3 gensupport.h
*** gensupport.h	2001/08/22 14:35:17	1.3
--- gensupport.h	2001/11/06 15:51:44
*************** Software Foundation, 59 Temple Place - S
*** 21,26 ****
--- 21,27 ----
  struct obstack;
  extern struct obstack *rtl_obstack;
  
+ extern int init_md_reader_args	PARAMS ((int, char **));
  extern int init_md_reader	PARAMS ((const char *));
  extern rtx read_md_rtx		PARAMS ((int *, int *));
  
Index: rtl.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.def,v
retrieving revision 1.50
diff -c -3 -p -r1.50 rtl.def
*** rtl.def	2001/11/03 16:28:33	1.50
--- rtl.def	2001/11/06 15:51:46
*************** DEF_RTL_EXPR(UNKNOWN, "UnKnown", "*", 'x
*** 73,78 ****
--- 73,83 ----
  
  DEF_RTL_EXPR(NIL, "nil", "*", 'x')
  
+ 
+ /* include a file */
+ 
+ DEF_RTL_EXPR(INCLUDE, "include", "s", 'x')
+ 
  /* ---------------------------------------------------------------------
     Expressions used in constructing lists.
     --------------------------------------------------------------------- */
Index: doc/md.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/md.texi,v
retrieving revision 1.26
diff -c -3 -p -r1.26 md.texi
*** md.texi	2001/10/25 18:25:08	1.26
--- md.texi	2001/11/06 15:52:02
*************** See the next chapter for information on 
*** 38,43 ****
--- 38,44 ----
  * Expander Definitions::Generating a sequence of several RTL insns
                            for a standard operation.
  * Insn Splitting::      Splitting Instructions into Multiple Instructions.
+ * Including Patterns::      Including Patterns in Machine Descriptions.
  * Peephole Definitions::Defining machine-specific peephole optimizations.
  * Insn Attributes::     Specifying the value of attributes for generated insns.
  * Conditional Execution::Generating @code{define_insn} patterns for
*************** The @code{define_insn_and_split} constru
*** 3909,3914 ****
--- 3910,3989 ----
  functionality as two separate @code{define_insn} and @code{define_split}
  patterns.  It exists for compactness, and as a maintenance tool to prevent
  having to ensure the two patterns' templates match.
+ 
+ @node Including Patterns
+ @section Including Patterns in Machine Descriptions.
+ @cindex insn includes
+ 
+ @findex include
+ The @code{include} pattern tells the compiler tools where to
+ look for patterns that are in files other than in the file
+ @file{.md}. This is used only at build time and there is no preprocessing allowed.
+ 
+ It looks like:
+ 
+ @smallexample
+ 
+ (include
+   @var{pathname})
+ @end smallexample
+ 
+ For example:
+ 
+ @smallexample
+ 
+ (include "filestuff") 
+ 
+ @end smallexample
+ 
+ Where @var{pathname} is a string that specifies the the location of the file,
+ specifies the include file to be in @file{gcc/config/target/filestuff}. The
+ directory @file{gcc/config/target} is regarded as the default directory.
+ 
+ 
+ Machine descriptions may be split up into smaller more manageable subsections 
+ and placed into subdirectories. 
+ 
+ By specifying:
+ 
+ @smallexample
+ 
+ (include "BOGUS/filestuff") 
+ 
+ @end smallexample
+ 
+ the include file is specified to be in @file{gcc/config/@var{target}/BOGUS/filestuff}.
+ 
+ Specifying an absolute path for the include file such as;
+ @smallexample
+ 
+ (include "/u2/BOGUS/filestuff") 
+ 
+ @end smallexample
+ is permitted but is not encouraged. 
+ 
+ @subsection RTL Generation Tool Options for Directory Search
+ @cindex directory options .md
+ @cindex options, directory search
+ @cindex search options
+ 
+ The @option{-I@var{dir}} option specifies directories to search for machine descriptions.
+ For example:
+ 
+ @smallexample
+ 
+ genrecog -I/p1/abc/proc1 -I/p2/abcd/pro2 target.md
+ 
+ @end smallexample
+ 
+ 
+ Add the directory @var{dir} to the head of the list of directories to be
+ searched for header files.  This can be used to override a system machine definition
+ file, substituting your own version, since these directories are
+ searched before the default machine description file directories.  If you use more than
+ one @option{-I} option, the directories are scanned in left-to-right
+ order; the standard default directory come after.
+ 
  
  @node Peephole Definitions
  @section Machine-Specific Peephole Optimizers

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 14:38   ` Geoff Keating
  2001-11-13  4:32     ` Geoff Keating
@ 2001-11-13 15:03     ` Geoff Keating
  1 sibling, 0 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Dale Johannesen; +Cc: gcc-patches, aldyh

Dale Johannesen <dalej@apple.com> writes:

> >   /* Boundary (in *bits*) on which stack pointer should be aligned.  */
> > ! #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 
> > 128)
> 
> If you plan to support linking files compiled with and without 
> -fabi=altivec,
> shouldn't this be 128 unconditionally?  Otherwise the stack might not be
> 128-bit aligned when you enter an Altivec function.  Also in sysv4.h.

By definition, you can't expect to link together files compiled with
different ABIs.  This is one example of the problem; another is the
varargs changes that Aldy hasn't done yet.

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-13 15:03                     ` Alexandre Oliva
@ 2001-11-13 15:03                       ` Alan Matsuoka
  2001-11-13 15:03                         ` Aldy Hernandez
  0 siblings, 1 reply; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Alexandre Oliva; +Cc: gcc-patches

On Fri, 16 Nov 2001, Alexandre Oliva wrote:

> On Nov  6, 2001, Alan Matsuoka <alanm@redhat.com> wrote:
> 
> > *** gensupport.c	2001/10/25 12:55:16	1.23
> > --- gensupport.c	2001/11/06 15:51:44
> > *************** process_rtx (desc, lineno)
> > *** 164,169 ****
> > --- 322,329 ----
> >        rtx desc;
> >        int lineno;
> >   {
> > +   const char *filename = XSTR (desc, 0);
> > + 
> >     switch (GET_CODE (desc))
> >       {
> >       case DEFINE_INSN:
> > *************** process_rtx (desc, lineno)
> > *** 178,183 ****
> > --- 338,348 ----
> >         queue_pattern (desc, &define_attr_tail, lineno);
> >         break;
>   
> > +     case INCLUDE:
> > +       if (process_include (desc, lineno) == FATAL_EXIT_CODE)
> > +         message_with_line (lineno, "include file at  %s not found\n", filename);
> > +       break;
> > + 
> >       case DEFINE_INSN_AND_SPLIT:
> >         {
> >   	const char *split_cond;
> 
> Alan, you can't assume any RTL will have a string in the first field.
> I caught this by chance, when I enabled all checking, to help track
> a GC bug I'm hunting.  More about it later.
> 
> I'm checking this in, as obviously correct (built on
> athlon-pc-linux-gnu).
> 
OK. Thank you. I didn't  know.



Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 14:31   ` Stan Shebs
  2001-11-05 14:49     ` Geoff Keating
  2001-11-13  4:32     ` Stan Shebs
@ 2001-11-13 15:03     ` Stan Shebs
  2 siblings, 0 replies; 152+ messages in thread
From: Stan Shebs @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Geoff Keating; +Cc: aldyh, gcc-patches

Geoff Keating wrote:
> 
> The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
> quite right:  it has to happen _only when the ABI is 'altivec'_.
> 
> This will be a bit tricky because DWARF_FRAME_REGISTERS is also used
> in libgcc, so you have to #define something when the Altivec ABI is
> chosen, and then key off that if IN_LIBGCC2.

Thus we slide down the slippery slope... Solving this completely
eventually entails having a method to detect whether the CPU
supports AltiVec instructions - in the case of a C++ throw
in code using AltiVec registers, you need to detect dynamically
(Apple's GCC uses a bit set by the kernel) whether you're on a
G4 or a not-G4.  So you may have to generate a frame descriptor
that mentions registers you won't actually manipulate on a not-G4.

Our GCC just sets DWARF_FRAME_REGISTERS to FIRST_PSEUDO_REGISTERS
unconditionally, seems to work well enough for non-AltiVec code.

Stan

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-03 20:37           ` Geoff Keating
  2001-11-13  4:26             ` Geoff Keating
  2001-11-13 13:21             ` Geoff Keating
@ 2001-11-13 15:03             ` Aldy Hernandez
  2001-11-13 15:03               ` Alan Matsuoka
  2001-11-13 15:03               ` Alan Matsuoka
  2001-11-13 15:03             ` Geoff Keating
  3 siblings, 2 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Geoff Keating; +Cc: Alan Matsuoka, gcc-patches

>>>>> "Geoff" == Geoff Keating <geoffk@geoffk.org> writes:

alan can you provide an example on how to use this.  I want to move
all the altivec stuff outside of the .md file.

Aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-05 18:58           ` Aldy Hernandez
                               ` (2 preceding siblings ...)
  2001-11-13  4:32             ` Aldy Hernandez
@ 2001-11-13 15:03             ` Aldy Hernandez
  3 siblings, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: Geoff Keating, gcc patches

is it recursive?  i mean, can you include files from within include
files?

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 20:10     ` Geoff Keating
  2001-11-13  4:32       ` Geoff Keating
@ 2001-11-13 15:03       ` Geoff Keating
  1 sibling, 0 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-13 15:03 UTC (permalink / raw)
  To: aldyh; +Cc: gcc-patches

> Cc: gcc-patches@gcc.gnu.org
> From: Aldy Hernandez <aldyh@redhat.com>
> Date: 05 Nov 2001 22:29:51 -0500

>  > The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
>  > quite right:  it has to happen _only when the ABI is 'altivec'_.
> 
> I took it out because it needs rethinking.  DWARF_FRAME_REGISTERS is
> used as an array size in a few places, particulary unwind-dw2.c.  So I
> need to change all these places to dynamically allocate their space.

Before changing anything in the unwinder code, you must first make
sure that you're not changing an ABI.  I don't know what the new rules
are on this, with shared libgcc and all, so I will leave you to figure
them out (and please tell me when you do!).  You'll probably want to
ask on the glibc lists.

>  > This will be a bit tricky because DWARF_FRAME_REGISTERS is also used
>  > in libgcc, so you have to #define something when the Altivec ABI is
>  > chosen, and then key off that if IN_LIBGCC2.
> 
>  > I wonder if you could assume that the integrated cpplib will always be
>  > used when compiling libgcc?  That would make things easier, because
>  > then you wouldn't have muck with specs so much.
> 
> Please explain.  I only see DWARF_FRAME_REGISTERS being used in
> dwarf2out.c and unwind-dw2.c.  There is nothing in libgcc*.

unwind-dw2.c is part of libgcc, see LIB2ADDEH in Makefile.in.  I don't
knew about the new arrangement, but it used to be that 'struct
_Unwind_Context' (or equivalent) was passed between a bit of libgcc
that was compiled into glibc, and another bit of libgcc that was
compiled into applications.  Thus, you couldn't change
DWARF_FRAME_REGISTERS because that would change a glibc ABI.

For EABI (as opposed to SVR4/Linux), you can probably change this even
for non-altivec EABI, since libgcc doesn't get split up like that for
embedded systems and libgcc isn't part of the EABI and there hasn't
been any real C++ binary compatibility anyway.

>  >> /* No data type wants to be aligned rounder than this.  */
>  >> #undef	BIGGEST_ALIGNMENT
>  >> ! #define BIGGEST_ALIGNMENT ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
>  >> 
>  >> + /* An expression for the alignment of a structure field FIELD if the
>  >> +    alignment computed in the usual way is COMPUTED.  */
>  >> + #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)				      \
>  >> + 	((TARGET_ALTIVEC_ABI && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
>  >> + 	 ? 128 : COMPUTED)
>  >> + 
>  >> + /* Define this macro as an expression for the alignment of a type
>  >> +    (given by TYPE as a tree node) if the alignment computed in the
>  >> +    usual way is COMPUTED and the alignment explicitly specified was
>  >> +    SPECIFIED.  */
>  >> + #define ROUND_TYPE_ALIGN(TYPE, COMPUTED, SPECIFIED)			\
>  >> + 	((TARGET_ALTIVEC_ABI && TREE_CODE (TYPE) == VECTOR_TYPE)	\
>  >> + 	 ? 128 : MAX (COMPUTED, SPECIFIED))
>  >> + 
>  >> #undef  BIGGEST_FIELD_ALIGNMENT
>  >> #undef  ADJUST_FIELD_ALIGN
>  >> 
>  >> /* Use ELF style section commands.  */
> 
>  > This has the same comment as the equivalent stuff in rs6000.h.
> 
> Huh?  What do you mean?

I had some comments about the changes in rs6000.h to BIGGEST_ALIGNMENT
etc.; these are the sysv4.h changes to BIGGEST_ALIGNMENT, and the same
comments apply.

> This is just for unnamed arguments in varargs.  So I'll have to add:
> 
>         if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
>                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> done. (?)

OK, whatever works.  I just wanted to be sure you knew about the
weirdness.

>  >> +       /* Print AltiVec memory operand.  */
>  >> +     case 'y':
>  >> +       {
>  >> + 	rtx tmp;
>  >> + 
>  >> + 	if (GET_CODE (x) != MEM)
>  >> + 	  abort ();
>  >> + 
>  >> + 	tmp = XEXP (x, 0);
>  >> + 
>  >> + 	if (GET_CODE (tmp) == REG)
>  >> + 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
>  >> + 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
>  >> + 	  {
>  >> + 	    if (REGNO (XEXP (tmp, 0)) == 0)
>  >> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
>  >> + 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
>  >> + 	    else
>  >> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
>  >> + 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
>  >> + 	  }
>  >> + 	else
>  >> + 	  abort ();
>  >> + 	break;
>  >> +       }
> 
>  > Do you really need this?  It looks just like the way a normal memory
>  > operand is printed (for the cases that are allowed for altivec).
> 
> Yes I do.  I want "[reg+reg]" to be outputed as "reg,reg" and [reg] to
> be outputed as "reg,0".
> 
> Consider "lvx d,a,b".  I want to match:
> 
>         (set (reg) (mem))
> 
> and have (mem) be dumped as "a,b" (the two registers in the memory
> address: (plus (reg) (reg))).  

I guess it's not quite the same as the behaviour for 'lwz', because of
the behaviour on just (reg).  This bit is OK, then.

>  > Can you put the altivec insns in their own .md file and use the include
>  > mechanism?  I believe this is what it was intended for.
> 
> As soon as you approve Alan's patch, yes :).

I'll look at it :-).

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Include facility for .md files - altivec patches
  2001-11-05 18:41         ` Include facility for .md files - " Alan Matsuoka
                             ` (4 preceding siblings ...)
  2001-11-13  4:32           ` Alan Matsuoka
@ 2001-11-13 15:03           ` Alan Matsuoka
  5 siblings, 0 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Geoff Keating, gcc-patches

On Mon, 05 Nov 2001, Alan Matsuoka wrote:

> On Mon, 05 Nov 2001, Aldy Hernandez wrote:
> 
> > >>>>> "Alan" == Alan Matsuoka <alanm@cygnus.com> writes:
> > 
> >  >> Do you really need this?  It looks just like the way a normal memory
> >  >> operand is printed (for the cases that are allowed for altivec).
> >  >> 
> >  >> > Index: rs6000.md
> >  >> 
> >  >> Can you put the altivec insns in their own .md file and use the include
> >  >> mechanism?  I believe this is what it was intended for.
> > 
> > Last i heard, alan matsuoka's include mechanism hadn't been approved.
> > Alan, perhaps you should send them again.  We definitely need them
> > now.
> 
> OK.
> 

The following patch is for the an internal project. This is 
implements a (include "filestuff") mechanism for splitting up 
.md files.

(include "filestuff") expects the include file to be in gcc/config/{target}/filestuff
(include "BOGUS/filestuff") expects the include file to be in gcc/config/{target}/BOGUS/filestuff
(include "/u2/BOGUS/filestuff") expects the include file to be in /u2/BOGUS/filestuff

You can also run things like genrecog -I/p1/abc/proc1 -I/p2/abcd/pro2 target.md

This is used only at build time.

This has been tested for i686-pc-linux-gnu by bootstrapping and testing without 
any regressions.

The DOS pathname style stuff may still be required.


2001-11-05  Alan Matsuoka  <alanm@redhat.com>

        * rtl.def (INCLUDE) : Define.
	* gensupport.c (init_include_reader, process_include, save_string) :  New functions to
	  implement an include facility in .md files.
	* gensupport.h : Add prototype for init_md_reader_args.
	* genattr.c genattrtab.c gencodes.c genconfig.c genemit.c
	  genextract.c genflags.c genopinit.c genoutput.c genpeep.c
	  genrecog.c: Change call to init_md_reader to init_md_reader_args.
	* md.texi: Document (include "path") and -I directives for RTL generation tools.

Index: genattr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genattr.c,v
retrieving revision 1.45
diff -3 -c -p -r1.45 genattr.c
*** genattr.c	2001/10/07 16:50:51	1.45
--- genattr.c	2001/11/06 02:32:32
*************** main (argc, argv)
*** 210,216 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genattr'");
--- 210,216 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genattr'");
Index: genattrtab.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genattrtab.c,v
retrieving revision 1.103
diff -3 -c -p -r1.103 genattrtab.c
*** genattrtab.c	2001/10/21 21:32:00	1.103
--- genattrtab.c	2001/11/06 02:32:58
*************** main (argc, argv)
*** 6075,6081 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    obstack_init (hash_obstack);
--- 6075,6081 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    obstack_init (hash_obstack);
Index: gencodes.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gencodes.c,v
retrieving revision 1.42
diff -3 -c -p -r1.42 gencodes.c
*** gencodes.c	2001/08/22 14:35:16	1.42
--- gencodes.c	2001/11/06 02:32:58
*************** main (argc, argv)
*** 56,62 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("\
--- 56,62 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("\
Index: genconfig.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genconfig.c,v
retrieving revision 1.43
diff -3 -c -p -r1.43 genconfig.c
*** genconfig.c	2001/10/11 07:07:26	1.43
--- genconfig.c	2001/11/06 02:33:00
*************** main (argc, argv)
*** 277,283 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genconfig'");
--- 277,283 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    puts ("/* Generated automatically by the program `genconfig'");
Index: genemit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genemit.c,v
retrieving revision 1.67
diff -3 -c -p -r1.67 genemit.c
*** genemit.c	2001/10/19 19:37:08	1.67
--- genemit.c	2001/11/06 02:33:05
*************** main (argc, argv)
*** 789,795 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
--- 789,795 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
Index: genextract.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genextract.c,v
retrieving revision 1.46
diff -3 -c -p -r1.46 genextract.c
*** genextract.c	2001/10/11 03:15:42	1.46
--- genextract.c	2001/11/06 02:33:07
*************** main (argc, argv)
*** 362,368 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
--- 362,368 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
Index: genflags.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genflags.c,v
retrieving revision 1.39
diff -3 -c -p -r1.39 genflags.c
*** genflags.c	2001/10/11 03:15:42	1.39
--- genflags.c	2001/11/06 02:33:07
*************** main (argc, argv)
*** 230,236 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
    
    puts ("/* Generated automatically by the program `genflags'");
--- 230,236 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
    
    puts ("/* Generated automatically by the program `genflags'");
Index: genopinit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genopinit.c,v
retrieving revision 1.48
diff -3 -c -p -r1.48 genopinit.c
*** genopinit.c	2001/09/13 14:37:11	1.48
--- genopinit.c	2001/11/06 02:33:07
*************** main (argc, argv)
*** 316,322 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genopinit'\n\
--- 316,322 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genopinit'\n\
Index: genoutput.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genoutput.c,v
retrieving revision 1.65
diff -3 -c -p -r1.65 genoutput.c
*** genoutput.c	2001/10/11 03:15:42	1.65
--- genoutput.c	2001/11/06 02:33:10
*************** main (argc, argv)
*** 953,959 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    output_prologue ();
--- 953,959 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    output_prologue ();
Index: genpeep.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genpeep.c,v
retrieving revision 1.49
diff -3 -c -p -r1.49 genpeep.c
*** genpeep.c	2001/10/11 03:15:43	1.49
--- genpeep.c	2001/11/06 02:33:14
*************** main (argc, argv)
*** 385,391 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genpeep'\n\
--- 385,391 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    printf ("/* Generated automatically by the program `genpeep'\n\
Index: genrecog.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genrecog.c,v
retrieving revision 1.111
diff -3 -c -p -r1.111 genrecog.c
*** genrecog.c	2001/10/28 20:09:14	1.111
--- genrecog.c	2001/11/06 02:33:19
*************** main (argc, argv)
*** 2689,2695 ****
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    next_insn_code = 0;
--- 2689,2695 ----
    if (argc <= 1)
      fatal ("No input file name.");
  
!   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    next_insn_code = 0;
Index: gensupport.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gensupport.c,v
retrieving revision 1.23
diff -3 -c -p -r1.23 gensupport.c
*** gensupport.c	2001/10/25 12:55:16	1.23
--- gensupport.c	2001/11/06 02:33:20
*************** static int predicable_default;
*** 42,47 ****
--- 42,49 ----
  static const char *predicable_true;
  static const char *predicable_false;
  
+ static char *base_dir = NULL;
+ 
  /* We initially queue all patterns, process the define_insn and
     define_cond_exec patterns, then return them one at a time.  */
  
*************** static struct queue_elem *other_queue;
*** 62,67 ****
--- 64,86 ----
  static struct queue_elem **other_tail = &other_queue;
  
  static void queue_pattern PARAMS ((rtx, struct queue_elem ***, int));
+ 
+ /* Current maximum length of directory names in the search path
+    for include files.  (Altered as we get more of them.)  */
+ 
+ size_t max_include_len;
+ 
+ struct file_name_list
+   {
+     struct file_name_list *next;
+     const char *fname;
+   };
+ 
+ struct file_name_list *include = 0;     /* First dir to search */
+         /* First dir to search for <file> */
+ struct file_name_list *first_bracket_include = 0;
+ struct file_name_list *last_include = 0;        /* Last in chain */
+ 
  static void remove_constraints PARAMS ((rtx));
  static void process_rtx PARAMS ((rtx, int));
  
*************** static const char *alter_output_for_insn
*** 78,83 ****
--- 97,105 ----
  						  int, int));
  static void process_one_cond_exec PARAMS ((struct queue_elem *));
  static void process_define_cond_exec PARAMS ((void));
+ static int process_include PARAMS ((rtx, int));
+ static char *save_string PARAMS ((const char *, int));
+ static int init_include_reader PARAMS ((FILE  *));
  \f
  void
  message_with_line VPARAMS ((int lineno, const char *msg, ...))
*************** remove_constraints (part)
*** 157,162 ****
--- 179,320 ----
        }
  }
  
+ /* The entry point for initializing the reader.  */
+ 
+ static int
+ init_include_reader (inf)
+      FILE *inf;
+ {
+   int c;
+ 
+   errors = 0;
+ 
+   /* Read the entire file.  */
+   while (1)
+     {
+       rtx desc;
+       int lineno;
+ 
+       c = read_skip_spaces (inf);
+       if (c == EOF)
+ 	break;
+ 
+       ungetc (c, inf);
+       lineno = read_rtx_lineno;
+       desc = read_rtx (inf);
+       process_rtx (desc, lineno);
+     }
+   fclose (inf);
+ 
+   /* Process define_cond_exec patterns.  */
+   if (define_cond_exec_queue != NULL)
+     process_define_cond_exec ();
+ 
+   return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
+ }
+ 
+ /* Process an include file assuming that it lives in gcc/config/{target}/ 
+    if the include looks line (include "file" )  */
+ static int
+ process_include (desc, lineno)
+      rtx desc;
+      int lineno;
+ {
+   const char *filename = XSTR (desc, 0);
+   char *pathname = NULL;
+   FILE *input_file;
+   char *fname;
+   struct file_name_list *stackp;
+   int flen;
+ 
+   stackp = include;
+ 
+   /* If specified file name is absolute, just open it.  */
+   if (IS_ABSOLUTE_PATHNAME (filename) || !stackp)
+     {
+       if (base_dir)
+         {
+           pathname = xmalloc (strlen (base_dir) + strlen (filename) + 1);
+           pathname = strcpy (pathname, base_dir);
+           strcat (pathname, filename);
+           strcat (pathname, "\0");
+ 	}
+       else
+         {
+ 	  pathname = xstrdup (filename);
+         }
+       read_rtx_filename = pathname;
+       input_file = fopen (pathname, "r");
+ 
+       if (input_file == 0)
+ 	{
+ 	  perror (pathname);
+ 	  return FATAL_EXIT_CODE;
+ 	}
+     }
+   else if (stackp)
+     {
+ 
+       flen = strlen (filename);
+ 
+       fname = (char *) alloca (max_include_len + flen + 2);
+ 
+       /* + 2 above for slash and terminating null.  */
+ 
+       /* Search directory path, trying to open the file.
+          Copy each filename tried into FNAME.  */
+ 
+       for (; stackp; stackp = stackp->next)
+ 	{
+ 	  if (stackp->fname)
+ 	    {
+ 	      strcpy (fname, stackp->fname);
+ 	      strcat (fname, "/");
+ 	      fname[strlen (fname) + flen] = 0;
+ 	    }
+ 	  else
+ 	    {
+ 	      fname[0] = 0;
+ 	    }
+ 	  strncat (fname, (const char *) filename, flen);
+ 	  read_rtx_filename = fname;
+ 	  input_file = fopen (fname, "r");
+ 	  if (input_file != NULL) 
+ 	    break;
+ 	}
+       if (stackp == NULL)
+ 	{
+ 	  if (strchr (fname, '/') == NULL || strchr (fname, '\\' ) || base_dir)
+ 	    {
+ 	      if (base_dir)
+ 		{
+ 		  pathname =
+ 		    xmalloc (strlen (base_dir) + strlen (filename) + 1);
+ 		  pathname = strcpy (pathname, base_dir);
+ 		  strcat (pathname, filename);
+ 		  strcat (pathname, "\0");
+ 		}
+ 	      else
+ 		pathname = xstrdup (filename);
+ 	    }
+ 	  read_rtx_filename = pathname;
+ 	  input_file = fopen (pathname, "r");
+ 
+ 	  if (input_file == 0)
+ 	    {
+ 	      perror (filename);
+ 	      return FATAL_EXIT_CODE;
+ 	    }
+ 	}
+ 
+     }
+ 
+   if (init_include_reader (input_file) == FATAL_EXIT_CODE)
+     message_with_line (lineno, "read errors found in include file  %s\n", pathname);
+ 
+   return SUCCESS_EXIT_CODE;
+ }
+ 
  /* Process a top level rtx in some way, queueing as appropriate.  */
  
  static void
*************** process_rtx (desc, lineno)
*** 164,169 ****
--- 322,329 ----
       rtx desc;
       int lineno;
  {
+   const char *filename = XSTR (desc, 0);
+ 
    switch (GET_CODE (desc))
      {
      case DEFINE_INSN:
*************** process_rtx (desc, lineno)
*** 178,183 ****
--- 338,348 ----
        queue_pattern (desc, &define_attr_tail, lineno);
        break;
  
+     case INCLUDE:
+       if (process_include (desc, lineno) == FATAL_EXIT_CODE)
+         message_with_line (lineno, "include file at  %s not found\n", filename);
+       break;
+ 
      case DEFINE_INSN_AND_SPLIT:
        {
  	const char *split_cond;
*************** process_define_cond_exec ()
*** 767,781 ****
--- 932,1022 ----
    for (elem = define_cond_exec_queue; elem ; elem = elem->next)
      process_one_cond_exec (elem);
  }
+ 
+ static char *
+ save_string (s, len)
+      const char *s;
+      int len;
+ {
+   register char *result = xmalloc (len + 1);
+ 
+   memcpy (result, s, len);
+   result[len] = 0;
+   return result;
+ }
+ 
  \f
  /* The entry point for initializing the reader.  */
  
  int
+ init_md_reader_args (argc, argv)
+      int argc;
+      char **argv;
+ {
+   int i;
+   const char *in_fname;
+ 
+   max_include_len = 0;
+   in_fname = NULL;
+   for (i = 1; i < argc; i++)
+     {
+       if (argv[i][0] != '-')
+ 	{
+ 	  if (in_fname == NULL)
+ 	    in_fname = argv[i];
+ 	}
+       else
+ 	{
+ 	  int c = argv[i][1];
+ 	  switch (c)
+ 	    {
+ 	    case 'I':		/* Add directory to path for includes.  */
+ 	      {
+ 		struct file_name_list *dirtmp;
+ 
+ 		dirtmp = (struct file_name_list *)
+ 		  xmalloc (sizeof (struct file_name_list));
+ 		dirtmp->next = 0;	/* New one goes on the end */
+ 		if (include == 0)
+ 		  include = dirtmp;
+ 		else
+ 		  last_include->next = dirtmp;
+ 		last_include = dirtmp;	/* Tail follows the last one */
+ 		if (argv[i][1] == 'I' && argv[i][2] != 0)
+ 		  dirtmp->fname = argv[i] + 2;
+ 		else if (i + 1 == argc)
+ 		  fatal ("Directory name missing after -I option");
+ 		else
+ 		  dirtmp->fname = argv[++i];
+ 		if (strlen (dirtmp->fname) > max_include_len)
+ 		  max_include_len = strlen (dirtmp->fname);
+ 	      }
+ 	      break;
+ 	    default:
+ 	      fatal ("Invalid option `%s'", argv[i]);
+ 
+ 	    }
+ 	}
+     }
+     return init_md_reader (in_fname);
+ }
+ \f
+ /* The entry point for initializing the reader.  */
+ 
+ int
  init_md_reader (filename)
       const char *filename;
  {
    FILE *input_file;
    int c;
+   char *lastsl;
+ 
+   if (!IS_ABSOLUTE_PATHNAME (filename))
+     {
+       lastsl = strrchr (filename, '/');
+       if (lastsl != NULL) 
+ 	base_dir = save_string (filename, lastsl - filename + 1 );
+     }
  
    read_rtx_filename = filename;
    input_file = fopen (filename, "r");
*************** init_md_reader (filename)
*** 797,803 ****
  
        c = read_skip_spaces (input_file);
        if (c == EOF)
! 	break;
  
        ungetc (c, input_file);
        lineno = read_rtx_lineno;
--- 1038,1044 ----
  
        c = read_skip_spaces (input_file);
        if (c == EOF)
!         break;
  
        ungetc (c, input_file);
        lineno = read_rtx_lineno;
Index: gensupport.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gensupport.h,v
retrieving revision 1.3
diff -3 -c -p -r1.3 gensupport.h
*** gensupport.h	2001/08/22 14:35:17	1.3
--- gensupport.h	2001/11/06 02:33:20
*************** Software Foundation, 59 Temple Place - S
*** 21,26 ****
--- 21,27 ----
  struct obstack;
  extern struct obstack *rtl_obstack;
  
+ extern int init_md_reader_args	PARAMS ((int, char **));
  extern int init_md_reader	PARAMS ((const char *));
  extern rtx read_md_rtx		PARAMS ((int *, int *));
  
Index: rtl.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.def,v
retrieving revision 1.50
diff -3 -c -p -r1.50 rtl.def
*** rtl.def	2001/11/03 16:28:33	1.50
--- rtl.def	2001/11/06 02:33:22
*************** DEF_RTL_EXPR(UNKNOWN, "UnKnown", "*", 'x
*** 73,78 ****
--- 73,83 ----
  
  DEF_RTL_EXPR(NIL, "nil", "*", 'x')
  
+ 
+ /* include a file */
+ 
+ DEF_RTL_EXPR(INCLUDE, "include", "s", 'x')
+ 
  /* ---------------------------------------------------------------------
     Expressions used in constructing lists.
     --------------------------------------------------------------------- */
Index: gcc/gcc/doc/md.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/md.texi,v
retrieving revision 1.23
diff -c -3 -p -r1.23 md.texi
*** md.texi	2001/08/30 20:44:51	1.23
--- md.texi	2001/09/28 20:02:04
*************** See the next chapter for information on 
*** 38,43 ****
--- 38,44 ----
  * Expander Definitions::Generating a sequence of several RTL insns
                            for a standard operation.
  * Insn Splitting::      Splitting Instructions into Multiple Instructions.
+ * Including Patterns::      Including Patterns in Machine Descriptions.
  * Peephole Definitions::Defining machine-specific peephole optimizations.
  * Insn Attributes::     Specifying the value of attributes for generated insns.
  * Conditional Execution::Generating @code{define_insn} patterns for
*************** The @code{define_insn_and_split} constru
*** 3900,3905 ****
--- 3901,3986 ----
  functionality as two separate @code{define_insn} and @code{define_split}
  patterns.  It exists for compactness, and as a maintenance tool to prevent
  having to ensure the two patterns' templates match.
+ 
+ @node Including Patterns
+ @section Including Patterns in Machine Descriptions.
+ @cindex insn includes
+ 
+ @findex include
+ The @code{include} pattern tells the compiler tools where to
+ look for patterns that are in files other than in the file
+ @file{.md}. This is used only at build time and there is no preprocessing allowed.
+ 
+ It looks like:
+ 
+ @smallexample
+ 
+ (include
+   @var{pathname})
+ @end smallexample
+ 
+ For example:
+ 
+ @smallexample
+ 
+ (include "filestuff") 
+ 
+ @end smallexample
+ 
+ Where @var{pathname} is a string that specifies the the location of the file,
+ specifies the include file to be in gcc/config/{target}/filestuff. The
+ directory @file{ gcc/config/{target}} is regarded as the default directory.
+ 
+ 
+ Machine descriptions may be split up into smaller more manageable subsections 
+ and placed into subdirectories. 
+ 
+ By specifying:
+ 
+ @smallexample
+ 
+ (include "BOGUS/filestuff") 
+ 
+ @end smallexample
+ 
+ the include file is specified to be in @file{gcc/config/{target}/BOGUS/filestuff}.
+ 
+ Specifying an absolute path for the include file such as;
+ @smallexample
+ 
+ (include "/u2/BOGUS/filestuff") 
+ 
+ @end smallexample
+ is permitted but is not encouraged. 
+ 
+ @node .md Directory Options
+ @subsection RTL Generation Tool Options for Directory Search
+ @cindex directory options .md
+ @cindex options, directory search
+ @cindex search path
+ 
+ The -I@var{dir} option specifies directories to search for machine descriptions.
+ For example:
+ 
+ @smallexample
+ 
+ genrecog -I/p1/abc/proc1 -I/p2/abcd/pro2 target.md
+ 
+ @end smallexample
+ 
+ 
+ @table @gcctabopt
+ @item -I@var{dir}
+ @opindex I
+ Add the directory @var{dir} to the head of the list of directories to be
+ searched for header files.  This can be used to override a system machine definition
+ file, substituting your own version, since these directories are
+ searched before the default machine description file directories.  If you use more than
+ one @option{-I} option, the directories are scanned in left-to-right
+ order; the standard default directory come after.
+ 
+ @end table
+ 
  
  @node Peephole Definitions
  @section Machine-Specific Peephole Optimizers

Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-03 20:37           ` Geoff Keating
                               ` (2 preceding siblings ...)
  2001-11-13 15:03             ` Aldy Hernandez
@ 2001-11-13 15:03             ` Geoff Keating
  3 siblings, 0 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: gcc-patches

Alan Matsuoka <alanm@cygnus.com> writes:

> 2001-11-05  Alan Matsuoka  <alanm@redhat.com>
> 
>         * rtl.def (INCLUDE) : Define.
> 	* gensupport.c (init_include_reader, process_include, save_string) :  New functions to
> 	  implement an include facility in .md files.
> 	* gensupport.h : Add prototype for init_md_reader_args.
> 	* genattr.c genattrtab.c gencodes.c genconfig.c genemit.c
> 	  genextract.c genflags.c genopinit.c genoutput.c genpeep.c
> 	  genrecog.c: Change call to init_md_reader to init_md_reader_args.
> 	* md.texi: Document (include "path") and -I directives for RTL generation tools.

The patch is OK.

When you commit, please fix the whitespace and line-wrap the ChangeLog
entry to 80 columns.

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 12:59 ` Joseph S. Myers
  2001-11-05 13:04   ` Aldy Hernandez
  2001-11-13  4:32   ` Joseph S. Myers
@ 2001-11-13 15:03   ` Joseph S. Myers
  2 siblings, 0 replies; 152+ messages in thread
From: Joseph S. Myers @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: gcc patches

On 5 Nov 2001, Aldy Hernandez wrote:

> + @item -mabi=altivec
> + @opindex mabi=altivec
> + Extend the current ABI with AltiVec ABI extensions.  This does not
> + change the default ABI, instead it adds the AltiVec ABI extensions to
> + the current ABI.

That should end "ABI@." so that spacing after the sentence is correct if
more text gets added to that paragraph later.

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-07  2:50     ` Geoff Keating
                         ` (2 preceding siblings ...)
  2001-11-13  4:33       ` Geoff Keating
@ 2001-11-13 15:03       ` Geoff Keating
  3 siblings, 0 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-13 15:03 UTC (permalink / raw)
  To: rth; +Cc: aldyh, gcc-patches

> Date: Tue, 6 Nov 2001 23:16:48 -0800
> From: Richard Henderson <rth@redhat.com>
> Cc: aldyh@redhat.com, gcc-patches@gcc.gnu.org
> Mail-Followup-To: Richard Henderson <rth@redhat.com>,
> 	Geoff Keating <geoffk@redhat.com>, aldyh@redhat.com,
> 	gcc-patches@gcc.gnu.org
> Content-Disposition: inline
> User-Agent: Mutt/1.2.5i
> 
> On Mon, Nov 05, 2001 at 01:58:06PM -0800, Geoff Keating wrote:
> > > - #define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
> > > + #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
> > > - #define BIGGEST_ALIGNMENT 64
> > > + #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)
> > 
> > I think you _don't_ want this to be dependent on the ABI.  Changing
> > this isn't an ABI change (I hope!), which is good because...
> 
> Yes it is.  REGNO_POINTER_ALIGN(STACK_POINTER_REGNUM) == STACK_BOUNDARY.
> 
> Remember that STACK_BOUNDARY != PREFERRED_STACK_BOUNDARY, and that the
> later does not help you unless you also have code to enforce stack
> alignment, like we're supposed to have for x86 vector code.

Here I was talking about BIGGEST_ALIGNMENT only.  Changing
STACK_BOUNDARY is of course an ABI change.

> > The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
> > quite right:  it has to happen _only when the ABI is 'altivec'_.
> 
> I _think_ you don't have to worry about this any longer.  The ia64
> eh library interface does not expose the number of registers
> involved.  
> 
> We might ought to have checks added to die more gracefully if the
> target adds registers, since we do statically allocate this space
> and older libgcc would not be able to unwind for newer gcc code.

The complexities of this boggle my mind.  I think we haven't even
decided on how some of the pieces should work yet.

Can we really change the EH library interface like this?  Even in the
presence of a glibc compatibility layer to support pre-gcc3.0 C++
binaries?

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-07 11:41       ` Richard Henderson
  2001-11-07 12:12         ` Geoff Keating
  2001-11-13  5:05         ` Richard Henderson
@ 2001-11-13 15:03         ` Richard Henderson
  2 siblings, 0 replies; 152+ messages in thread
From: Richard Henderson @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Geoff Keating; +Cc: aldyh, gcc-patches

On Wed, Nov 07, 2001 at 02:49:15AM -0800, Geoff Keating wrote:
> Here I was talking about BIGGEST_ALIGNMENT only.  Changing
> STACK_BOUNDARY is of course an ABI change.

Well, there is

  struct {
    int x __attribute__((aligned));
    int y;
  };

to name one place that BIGGEST_ALIGNMENT affects the ABI.
I suspect there are other places as well.

> Can we really change the EH library interface like this?  Even in the
> presence of a glibc compatibility layer to support pre-gcc3.0 C++
> binaries?

Pre gcc 3.0, we don't support altivec, so we don't have to worry 
about this.



r~

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-06  7:58                   ` Alan Matsuoka
  2001-11-13  4:32                     ` Alan Matsuoka
@ 2001-11-13 15:03                     ` Alexandre Oliva
  2001-11-13 15:03                       ` Alan Matsuoka
  2001-11-13 15:03                     ` Alan Matsuoka
  2 siblings, 1 reply; 152+ messages in thread
From: Alexandre Oliva @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1080 bytes --]

On Nov  6, 2001, Alan Matsuoka <alanm@redhat.com> wrote:

> *** gensupport.c	2001/10/25 12:55:16	1.23
> --- gensupport.c	2001/11/06 15:51:44
> *************** process_rtx (desc, lineno)
> *** 164,169 ****
> --- 322,329 ----
>        rtx desc;
>        int lineno;
>   {
> +   const char *filename = XSTR (desc, 0);
> + 
>     switch (GET_CODE (desc))
>       {
>       case DEFINE_INSN:
> *************** process_rtx (desc, lineno)
> *** 178,183 ****
> --- 338,348 ----
>         queue_pattern (desc, &define_attr_tail, lineno);
>         break;
  
> +     case INCLUDE:
> +       if (process_include (desc, lineno) == FATAL_EXIT_CODE)
> +         message_with_line (lineno, "include file at  %s not found\n", filename);
> +       break;
> + 
>       case DEFINE_INSN_AND_SPLIT:
>         {
>   	const char *split_cond;

Alan, you can't assume any RTL will have a string in the first field.
I caught this by chance, when I enabled all checking, to help track
a GC bug I'm hunting.  More about it later.

I'm checking this in, as obviously correct (built on
athlon-pc-linux-gnu).


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: md-include-checkrtl.patch --]
[-- Type: text/x-patch, Size: 1017 bytes --]

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

	* gensupport.c (process_rtx): Don't assume filename is the first
	argument of any rtl.

Index: gcc/gensupport.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/gensupport.c,v
retrieving revision 1.25
diff -u -p -r1.25 gensupport.c
--- gcc/gensupport.c 2001/11/15 16:50:46 1.25
+++ gcc/gensupport.c 2001/11/16 22:55:28
@@ -324,8 +324,6 @@ process_rtx (desc, lineno)
      rtx desc;
      int lineno;
 {
-  const char *filename = XSTR (desc, 0);
-
   switch (GET_CODE (desc))
     {
     case DEFINE_INSN:
@@ -342,7 +340,11 @@ process_rtx (desc, lineno)
 
     case INCLUDE:
       if (process_include (desc, lineno) == FATAL_EXIT_CODE)
-        message_with_line (lineno, "include file at  %s not found\n", filename);
+	{
+	  const char *filename = XSTR (desc, 0);
+	  message_with_line (lineno, "include file at  %s not found\n",
+			     filename);
+	}
       break;
 
     case DEFINE_INSN_AND_SPLIT:

[-- Attachment #3: Type: text/plain, Size: 289 bytes --]


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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* altivec patches
  2001-11-05 12:52 altivec patches Aldy Hernandez
                   ` (5 preceding siblings ...)
  2001-11-13  4:32 ` Aldy Hernandez
@ 2001-11-13 15:03 ` Aldy Hernandez
  6 siblings, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13 15:03 UTC (permalink / raw)
  To: gcc patches; +Cc: Geoff Keating

finally...

i have fixed everything that was commented on.
alignment macros are in place, a new abi extension (TARGET_ALTIVEC_ABI),
documentation, etc. 

i have not documented the builtins because i'm going to write a script
to generate those automagially later.  besides, there's pretty much a
1:1 correspondence between the altivec insns and the builtin names 

i have added an option "-mabi=altivec" that enhances the current abi
with altivec ABI extensions.  this flag does NOT replace the current
abi, but extends the current abi to handle altivec extensions as
documented by the motorola manuals. 

i have promised geoff i will rewrite the -mcall-foo hackery and
implement "-mabi=sysv,eabi,altivec" style abi flags.  i will do this
after i'm done with the altivec stuff.  i don't want to diverge the
purpose of this patch into unrelated abi functionality.  right now
-mabi= only supports -mabi=altivec. 
what is left?
    - the rest of the gazillion builtins
    
    - varargs
    
    - frame stuff: epilogue, prologue, vrsave
    - <altivec.h> for the user.  this .h will implement the overloaded
    altivec functions described in the "altivec programming interface
    model".  Stuff like generic (overloaded) "vec_add(veca, vecb)". 
    
    - test cases.  i will commit a few simple tests, but serious tests
    will come after i'm done playing with the G3 box. 
    
and then there's the front end changes, but that's a different story. 

i have tested this on powerpc-unknown-linux-gnu.  it bootstraps.  no
regressions on testsuite. 

the patch below has the boring builtin stuff deleted (as requested). 
there's just 1 or 2 builtins for proof of concept. 

ok to install? 
2001-11-05  Aldy Hernandez  <aldyh@redhat.com>

	* doc/invoke.texi: Add -maltivec, -mno-altivec, and -mabi=altivec
	for rs6000.

	* config/rs6000/rs6000.h (MASK_ALTIVEC): New.
	(TARGET_ALTIVEC): New.
	(TARGET_SWITCHES): Add altivec.
	(FIRST_PSEUDO_REGISTER): Change to 109.
	(CALL_USED_REGISTERS): Same.
	(FIRST_ALTIVEC_REGNO): New.
	(LAST_ALTIVEC_REGNO): New.
	(ALTIVEC_REGNO_P): New.
	(UNITS_PER_ALTIVEC_WORD): New.
	(ALTIVEC_VECTOR_MODE): New.
	(FIXED_REGISTERS): Add altivec registers.
	(REG_ALLOC_ORDER): Same.
	(HARD_REGNO_NREGS): Adjust for altivec registers.
	(HARD_REGNO_MODE_OK): Same.
	(MODES_TIEABLE_P): Same.
	(REGISTER_MOVE_COST): Same.
	(REGNO_REG_CLASS): Same.
	(reg_class): Add ALTIVEC_REGS.
	(REG_CLASS_NAMES): Same.
	(REG_CLASS_CONTENTS): Same.
	(REG_CLASS_FROM_LETTER): Add 'v' constraint for ALTIVEC_REGS.
	(ALTIVEC_ARG_RETURN): New.
	(FUNCTION_VALUE): Handle VECTOR_TYPE.
	(LIBCALL_VALUE): Handle altivec vector modes.
	(VECTOR_MODE_SUPPORTED_P): New.
	(ALTIVEC_ARG_MIN_REG): New.
	(ALTIVEC_ARG_MAX_REG): New.
	(ALTIVEC_ARG_NUM_REG): New.
	(FUNCTION_VALUE_REGNO_P): Return true for altivec return register.
	(FUNCTION_ARG_REGNO_P): Support passing args in altivec registers.
	(REGISTER_NAMES): Add altivec regs.
	(DEBUG_REGISTER_NAMES): Same.
	(ADDITIONAL_REGISTER_NAMES): Same.
	(rs6000_builtins): New.
	(MD_EXPAND_BUILTIN): New.
	(MD_INIT_BUILTINS): New.
	(LEGITIMATE_OFFSET_ADDRESS_P): This addressing mode is not valid
	for AltiVec instructions.
	(LEGITIMATE_LO_SUM_ADDRESS_P): Same.
	(HARD_REGNO_MODE_OK): Altivec modes can only go in altivec
	registers.
	(SECONDARY_MEMORY_NEEDED): We need memory to copy vector modes.
	(PREDICATE_CODES): Add altivec_register.
	(TARGET_SWITCHES): Add no-altivec.
	(DATA_ALIGNMENT): Align vectors to 128 bits.
	(TARGET_OPTIONS): Add abi= option.
	Add rs6000_abi_string extern.
	(LOCAL_ALIGNMENT): New.
	(CPP_CPU_SPEC): Define __ALTIVEC__ when -maltivec.
	(MASK_ALTIVEC_ABI): New.
	(TARGET_ALTIVEC_ABI): New.
	(CONDITIONAL_REGISTER_USAGE): Set first 20 AltiVec registers to
	call-saved.
	(STACK_BOUNDARY): Adjust for altivec.
	(BIGGEST_ALIGNMENT): Same.
	(rs6000_args): Add vregno.
	(USE_ALTIVEC_FOR_ARG_P): New.
	
	* config/rs6000/sysv4.h (STACK_BOUNDARY): Adjust for altivec.
	(ABI_STACK_BOUNDARY): Same.
	(BIGGEST_ALIGNMENT): Same.
	(ADJUST_FIELD_ALIGN): Remove undef.  Define anew.
	(ROUND_TYPE_ALIGN): Same.
	
	* config/rs6000/rs6000.c (rs6000_expand_builtin): New.
	(altivec_expand_builtin): New.
	(altivec_init_builtins): New.
	(TARGET_EXPAND_BUILTIN): New.
	(TARGET_INIT_BUILTINS): New.
	(rs6000_init_builtins): New.
	(struct builtin_description): New.
	(bdesc_2arg): New.
	(rs6000_reg_names): Add altivec registers.
	(alt_reg_names): Same.
	(altivec_register): New.
	(secondary_reload_class): Altivec regs can hold altivec regs and
	memory.
	(rs6000_emit_move): Force constants into memory for AltiVec moves.
	(print_operand): Add 'y' case for printing altivec memory
	operands.
	(rs6000_legitimize_address): Legitimize vector addresses into
	[REG+REG] or [REG].
	(altivec_expand_binop_builtin): New.
	New string rs6000_current_abi.
	(rs6000_override_options): Call rs6000_parse_abi_options.
	(rs6000_parse_abi_options): New.
	(function_arg_boundary): Vector arguments must be 16
	byte aligned.
	(function_arg_advance): Handle vector arguments.
	(function_arg_partial_nregs): Same.
	(init_cumulative_args): Same.
	(function_arg): Same.

	* config/rs6000/rs6000.md (altivec_lvx): New.
	(type): Add altivec attribute.
	(*altivec_vec_move): New.
	(movv4si): New.
	(*movv4si_internal): New.
	(movv16qi): New.
	(*movv16qi_internal): New.
	(movv8hi): New.
	(*movv8hi_internal1): New.
	(movv4sf): New.
	(*movv4sf_internal1): New.
	(altivec_stvx): New.
	(vaddubm): New.

--builtins changelog removed--
	
	Index: doc/invoke.texi
===================================================================
RCS file: /cvs/uberbaum/gcc/doc/invoke.texi,v
retrieving revision 1.69
diff -c -p -r1.69 invoke.texi
*** invoke.texi	2001/10/28 19:12:12	1.69
--- invoke.texi	2001/11/05 19:49:18
*************** in the following sections.
*** 424,429 ****
--- 424,430 ----
  -mtune=@var{cpu-type} @gol
  -mpower  -mno-power  -mpower2  -mno-power2 @gol
  -mpowerpc  -mpowerpc64  -mno-powerpc @gol
+ -maltivec -mno-altivec @gol
  -mpowerpc-gpopt  -mno-powerpc-gpopt @gol
  -mpowerpc-gfxopt  -mno-powerpc-gfxopt @gol
  -mnew-mnemonics  -mold-mnemonics @gol
*************** in the following sections.
*** 436,441 ****
--- 437,443 ----
  -mno-relocatable  -mrelocatable-lib  -mno-relocatable-lib @gol
  -mtoc  -mno-toc -mlittle  -mlittle-endian  -mbig  -mbig-endian @gol
  -mcall-aix -mcall-sysv -mcall-netbsd @gol
+ -mabi=altivec @gol
  -mprototype  -mno-prototype @gol
  -msim  -mmvme  -mads  -myellowknife  -memb -msdata @gol
  -msdata=@var{opt}  -mvxworks -G @var{num}}
*************** values for @var{cpu_type} are used for @
*** 6677,6682 ****
--- 6679,6693 ----
  architecture, registers, and mnemonics set by @option{-mcpu}, but the
  scheduling parameters set by @option{-mtune}.
  
+ @item -maltivec
+ @itemx -mno-altivec
+ @opindex maltivec
+ @opindex mno-altivec
+ These switches enable or disable the use of built-in functions that
+ allow access to the AltiVec instruction set.  You may also need to set
+ @option{-mabi=altivec} to adjust the current ABI with AltiVec ABI
+ enhancements.
+ 
  @item -mfull-toc
  @itemx -mno-fp-in-toc
  @itemx -mno-sum-in-toc
*************** Linux-based GNU system.
*** 6904,6909 ****
--- 6915,6926 ----
  @opindex mcall-netbsd
  On System V.4 and embedded PowerPC systems compile code for the
  NetBSD operating system.
+ 
+ @item -mabi=altivec
+ @opindex mabi=altivec
+ Extend the current ABI with AltiVec ABI extensions.  This does not
+ change the default ABI, instead it adds the AltiVec ABI extensions to
+ the current ABI.
  
  @item -mprototype
  @itemx -mno-prototype
Index: rs6000.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.130
diff -c -p -r1.130 rs6000.h
*** rs6000.h	2001/10/02 03:36:44	1.130
--- rs6000.h	2001/11/05 19:49:23
*************** Boston, MA 02111-1307, USA.  */
*** 83,89 ****
  %{mcpu=801: -D_ARCH_PPC} \
  %{mcpu=821: -D_ARCH_PPC} \
  %{mcpu=823: -D_ARCH_PPC} \
! %{mcpu=860: -D_ARCH_PPC}"
  
  /* Common ASM definitions used by ASM_SPEC among the various targets
     for handling -mcpu=xxx switches.  */
--- 83,90 ----
  %{mcpu=801: -D_ARCH_PPC} \
  %{mcpu=821: -D_ARCH_PPC} \
  %{mcpu=823: -D_ARCH_PPC} \
! %{mcpu=860: -D_ARCH_PPC} \
! %{maltivec: -D__ALTIVEC__}"
  
  /* Common ASM definitions used by ASM_SPEC among the various targets
     for handling -mcpu=xxx switches.  */
*************** extern int target_flags;
*** 209,214 ****
--- 210,221 ----
  /* Nonzero if we need to schedule the prolog and epilog.  */
  #define MASK_SCHED_PROLOG	0x00040000
  
+ /* Use AltiVec instructions.  */
+ #define MASK_ALTIVEC		0x00080000
+ 
+ /* Enhance the current ABI with AltiVec extensions.  */
+ #define MASK_ALTIVEC_ABI	0x00100000
+ 
  #define TARGET_POWER		(target_flags & MASK_POWER)
  #define TARGET_POWER2		(target_flags & MASK_POWER2)
  #define TARGET_POWERPC		(target_flags & MASK_POWERPC)
*************** extern int target_flags;
*** 227,232 ****
--- 234,241 ----
  #define TARGET_NO_UPDATE	(target_flags & MASK_NO_UPDATE)
  #define TARGET_NO_FUSED_MADD	(target_flags & MASK_NO_FUSED_MADD)
  #define TARGET_SCHED_PROLOG	(target_flags & MASK_SCHED_PROLOG)
+ #define TARGET_ALTIVEC		(target_flags & MASK_ALTIVEC)
+ #define TARGET_ALTIVEC_ABI	(target_flags & MASK_ALTIVEC_ABI)
  
  #define TARGET_32BIT		(! TARGET_64BIT)
  #define TARGET_HARD_FLOAT	(! TARGET_SOFT_FLOAT)
*************** extern int target_flags;
*** 282,287 ****
--- 291,300 ----
  			N_("Use PowerPC-64 instruction set")},		\
    {"no-powerpc64",	- MASK_POWERPC64,				\
  			N_("Don't use PowerPC-64 instruction set")},	\
+   {"altivec",		MASK_ALTIVEC,					\
+ 			N_("Use AltiVec instructions.")},		\
+   {"no-altivec",	- MASK_ALTIVEC,					\
+ 			N_("Don't use AltiVec instructions.")},	\
    {"new-mnemonics",	MASK_NEW_MNEMONICS,				\
  			N_("Use new mnemonics for PowerPC architecture")},\
    {"old-mnemonics",	-MASK_NEW_MNEMONICS,				\
*************** extern enum processor_type rs6000_cpu;
*** 409,414 ****
--- 422,428 ----
     {"tune=", &rs6000_select[2].string,					\
      N_("Schedule code for given CPU") },				\
     {"debug=", &rs6000_debug_name, N_("Enable debug output") },		\
+    {"abi=", &rs6000_abi_string, N_("Specify ABI to use") },		\
     SUBTARGET_OPTIONS							\
  }
  
*************** struct rs6000_cpu_select
*** 424,430 ****
  extern struct rs6000_cpu_select rs6000_select[];
  
  /* Debug support */
! extern const char *rs6000_debug_name;		/* Name for -mdebug-xxxx option */
  extern int rs6000_debug_stack;		/* debug stack applications */
  extern int rs6000_debug_arg;		/* debug argument handling */
  
--- 438,445 ----
  extern struct rs6000_cpu_select rs6000_select[];
  
  /* Debug support */
! extern const char *rs6000_debug_name;	/* Name for -mdebug-xxxx option */
! extern const char *rs6000_abi_string;	/* for -mabi={sysv,darwin,solaris,eabi,aix,altivec} */
  extern int rs6000_debug_stack;		/* debug stack applications */
  extern int rs6000_debug_arg;		/* debug argument handling */
  
*************** extern int rs6000_debug_arg;		/* debug a
*** 505,510 ****
--- 520,526 ----
  #define UNITS_PER_WORD (! TARGET_POWERPC64 ? 4 : 8)
  #define MIN_UNITS_PER_WORD 4
  #define UNITS_PER_FP_WORD 8
+ #define UNITS_PER_ALTIVEC_WORD 16
  
  /* Type used for ptrdiff_t, as a string used in a declaration.  */
  #define PTRDIFF_TYPE "int"
*************** extern int rs6000_debug_arg;		/* debug a
*** 569,581 ****
  #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
  
  /* Boundary (in *bits*) on which stack pointer should be aligned.  */
! #define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
  
  /* Allocation boundary (in *bits*) for the code of a function.  */
  #define FUNCTION_BOUNDARY 32
  
  /* No data type wants to be aligned rounder than this.  */
! #define BIGGEST_ALIGNMENT 64
  
  /* Handle #pragma pack.  */
  #define HANDLE_PRAGMA_PACK 1
--- 585,604 ----
  #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
  
  /* Boundary (in *bits*) on which stack pointer should be aligned.  */
! #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
  
  /* Allocation boundary (in *bits*) for the code of a function.  */
  #define FUNCTION_BOUNDARY 32
  
  /* No data type wants to be aligned rounder than this.  */
! #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)
! 
! /* A C expression to compute the alignment for a variables in the
!    local store.  TYPE is the data type, and ALIGN is the alignment
!    that the object would ordinarily have.  */
! #define LOCAL_ALIGNMENT(TYPE, ALIGN)				\
! 	((TARGET_ALTIVEC_ABI		    			\
! 	  && TREE_CODE (TYPE)) == VECTOR_TYPE ? 128 : ALIGN)
  
  /* Handle #pragma pack.  */
  #define HANDLE_PRAGMA_PACK 1
*************** extern int rs6000_debug_arg;		/* debug a
*** 594,602 ****
    (TREE_CODE (EXP) == STRING_CST	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
! /* Make arrays of chars word-aligned for the same reasons.  */
  #define DATA_ALIGNMENT(TYPE, ALIGN)		\
!   (TREE_CODE (TYPE) == ARRAY_TYPE		\
     && TYPE_MODE (TREE_TYPE (TYPE)) == QImode	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
--- 617,627 ----
    (TREE_CODE (EXP) == STRING_CST	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
! /* Make arrays of chars word-aligned for the same reasons.
!    Align vectors to 128 bits.  */
  #define DATA_ALIGNMENT(TYPE, ALIGN)		\
!   (TREE_CODE (TYPE) == VECTOR_TYPE ? 128	\
!    : TREE_CODE (TYPE) == ARRAY_TYPE		\
     && TYPE_MODE (TREE_TYPE (TYPE)) == QImode	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
*************** extern int rs6000_debug_arg;		/* debug a
*** 634,640 ****
     a register, in order to work around problems in allocating stack storage
     in inline functions.  */
  
! #define FIRST_PSEUDO_REGISTER 77
  
  /* This must not decrease, for backwards compatibility.  If
     FIRST_PSEUDO_REGISTER increases, this should as well.  */
--- 659,665 ----
     a register, in order to work around problems in allocating stack storage
     in inline functions.  */
  
! #define FIRST_PSEUDO_REGISTER 109
  
  /* This must not decrease, for backwards compatibility.  If
     FIRST_PSEUDO_REGISTER increases, this should as well.  */
*************** extern int rs6000_debug_arg;		/* debug a
*** 655,661 ****
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1}
  
  /* 1 for registers not available across function calls.
     These must include the FIXED_REGISTERS and also any
--- 680,690 ----
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1,	   \
!    /* AltiVec registers.  */			   \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  \
! }
  
  /* 1 for registers not available across function calls.
     These must include the FIXED_REGISTERS and also any
*************** extern int rs6000_debug_arg;		/* debug a
*** 669,675 ****
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1}
  
  #define MQ_REGNO     64
  #define CR0_REGNO    68
--- 698,709 ----
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1,	   \
!    /* AltiVec registers.  */			   \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  \
! }
! 
  
  #define MQ_REGNO     64
  #define CR0_REGNO    68
*************** extern int rs6000_debug_arg;		/* debug a
*** 679,684 ****
--- 713,720 ----
  #define CR4_REGNO    72
  #define MAX_CR_REGNO 75
  #define XER_REGNO    76
+ #define FIRST_ALTIVEC_REGNO	77
+ #define LAST_ALTIVEC_REGNO	108
  
  /* List the order in which to allocate registers.  Each register must be
     listed once, even those in FIXED_REGISTERS.
*************** extern int rs6000_debug_arg;		/* debug a
*** 701,708 ****
  	mq		(not saved; best to use it if we can)
  	ctr		(not saved; when we have the choice ctr is better)
  	lr		(saved)
!         cr5, r1, r2, ap, xer (fixed)  */
  
  #define REG_ALLOC_ORDER					\
    {32, 							\
     45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34,	\
--- 737,753 ----
  	mq		(not saved; best to use it if we can)
  	ctr		(not saved; when we have the choice ctr is better)
  	lr		(saved)
!         cr5, r1, r2, ap, xer (fixed)
  
+ 	AltiVec registers:
+ 	v0 - v1         (not saved or used for anything)
+ 	v13 - v3        (not saved; incoming vector arg registers)
+ 	v2              (not saved; incoming vector arg reg; return value)
+ 	v19 - v14       (not saved or used for anything)
+ 	v31 - v20       (saved; order given to save least number)
+ */
+ 						
+ 
  #define REG_ALLOC_ORDER					\
    {32, 							\
     45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34,	\
*************** extern int rs6000_debug_arg;		/* debug a
*** 716,722 ****
     31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19,	\
     18, 17, 16, 15, 14, 13, 12,				\
     64, 66, 65, 						\
!    73, 1, 2, 67, 76}
  
  /* True if register is floating-point.  */
  #define FP_REGNO_P(N) ((N) >= 32 && (N) <= 63)
--- 761,774 ----
     31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19,	\
     18, 17, 16, 15, 14, 13, 12,				\
     64, 66, 65, 						\
!    73, 1, 2, 67, 76,					\
!    /* AltiVec registers.  */				\
!    77, 78,						\
!    90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80,		\
!    79,							\
!    96, 95, 94, 93, 92, 91,				\
!    108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97 \
! }
  
  /* True if register is floating-point.  */
  #define FP_REGNO_P(N) ((N) >= 32 && (N) <= 63)
*************** extern int rs6000_debug_arg;		/* debug a
*** 733,738 ****
--- 785,793 ----
  /* True if register is the XER register.  */
  #define XER_REGNO_P(N) ((N) == XER_REGNO)
  
+ /* True if register is an AltiVec register.  */
+ #define ALTIVEC_REGNO_P(N) ((N) >= FIRST_ALTIVEC_REGNO && (N) <= LAST_ALTIVEC_REGNO)
+ 
  /* Return number of consecutive hard regs needed starting at reg REGNO
     to hold something of mode MODE.
     This is ordinarily the length in words of a value of mode MODE
*************** extern int rs6000_debug_arg;		/* debug a
*** 744,751 ****
--- 799,821 ----
  #define HARD_REGNO_NREGS(REGNO, MODE)					\
    (FP_REGNO_P (REGNO)							\
     ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
+    : ALTIVEC_REGNO_P (REGNO)						\
+    ? ((GET_MODE_SIZE (MODE) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD) \
     : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
  
+ #define ALTIVEC_VECTOR_MODE(MODE)	\
+ 	((MODE) == V16QImode		\
+ 	 || (MODE) == V8HImode		\
+ 	 || (MODE) == V4SFmode		\
+ 	 || (MODE) == V4SImode)
+ 
+ /* Define this macro to be nonzero if the port is prepared to handle
+    insns involving vector mode MODE.  At the very least, it must have
+    move patterns for this mode.  */
+ 
+ #define VECTOR_MODE_SUPPORTED_P(MODE)	\
+ 	(TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE))
+ 
  /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
     For POWER and PowerPC, the GPRs can hold any mode, but the float
     registers only can hold floating modes and DImode, and CR register only
*************** extern int rs6000_debug_arg;		/* debug a
*** 757,762 ****
--- 827,834 ----
     (GET_MODE_CLASS (MODE) == MODE_FLOAT					\
      || (GET_MODE_CLASS (MODE) == MODE_INT				\
  	&& GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD))			\
+    : ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_REGNO_P (REGNO)		\
+    : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE)		\
     : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC		\
     : XER_REGNO_P (REGNO) ? (MODE) == PSImode				\
     : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT		\
*************** extern int rs6000_debug_arg;		/* debug a
*** 776,781 ****
--- 848,857 ----
     ? GET_MODE_CLASS (MODE2) == MODE_CC		\
     : GET_MODE_CLASS (MODE2) == MODE_CC		\
     ? GET_MODE_CLASS (MODE1) == MODE_CC		\
+    : ALTIVEC_VECTOR_MODE (MODE1)		\
+    ? ALTIVEC_VECTOR_MODE (MODE2)		\
+    : ALTIVEC_VECTOR_MODE (MODE2)		\
+    ? ALTIVEC_VECTOR_MODE (MODE1)		\
     : 1)
  
  /* A C expression returning the cost of moving data from a register of class
*************** extern int rs6000_debug_arg;		/* debug a
*** 788,793 ****
--- 864,870 ----
     ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2		\
     : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10	\
     : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10	\
+    : (CLASS1) == ALTIVEC_REGS && (CLASS2) != ALTIVEC_REGS ? 20	\
     : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS		\
         || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS		\
         || (CLASS1) == LINK_OR_CTR_REGS)				\
*************** extern int rs6000_debug_arg;		/* debug a
*** 839,844 ****
--- 916,924 ----
      global_regs[PIC_OFFSET_TABLE_REGNUM]				\
        = fixed_regs[PIC_OFFSET_TABLE_REGNUM]				\
          = call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;			\
+   if (TARGET_ALTIVEC_ABI)						\
+     for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)	\
+       call_used_regs[i] = 1;						\
  }
  
  /* Specify the registers used for certain standard purposes.
*************** enum reg_class
*** 912,917 ****
--- 992,998 ----
    BASE_REGS,
    GENERAL_REGS,
    FLOAT_REGS,
+   ALTIVEC_REGS,
    NON_SPECIAL_REGS,
    MQ_REGS,
    LINK_REGS,
*************** enum reg_class
*** 937,942 ****
--- 1018,1024 ----
    "BASE_REGS",								\
    "GENERAL_REGS",							\
    "FLOAT_REGS",								\
+   "ALTIVEC_REGS",							\
    "NON_SPECIAL_REGS",							\
    "MQ_REGS",								\
    "LINK_REGS",								\
*************** enum reg_class
*** 955,978 ****
     This is an initializer for a vector of HARD_REG_SET
     of length N_REG_CLASSES.  */
  
! #define REG_CLASS_CONTENTS						\
! {									\
!   { 0x00000000, 0x00000000, 0x00000000 },	/* NO_REGS */		\
!   { 0xfffffffe, 0x00000000, 0x00000008 },	/* BASE_REGS */		\
!   { 0xffffffff, 0x00000000, 0x00000008 },	/* GENERAL_REGS */	\
!   { 0x00000000, 0xffffffff, 0x00000000 },	/* FLOAT_REGS */	\
!   { 0xffffffff, 0xffffffff, 0x00000008 },	/* NON_SPECIAL_REGS */	\
!   { 0x00000000, 0x00000000, 0x00000001 },	/* MQ_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000002 },	/* LINK_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000004 },	/* CTR_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000006 },	/* LINK_OR_CTR_REGS */	\
!   { 0x00000000, 0x00000000, 0x00000007 },	/* SPECIAL_REGS */	\
!   { 0xffffffff, 0x00000000, 0x0000000f },	/* SPEC_OR_GEN_REGS */	\
!   { 0x00000000, 0x00000000, 0x00000010 },	/* CR0_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000ff0 },	/* CR_REGS */		\
!   { 0xffffffff, 0x00000000, 0x0000ffff },	/* NON_FLOAT_REGS */	\
!   { 0x00000000, 0x00000000, 0x00010000 },	/* XER_REGS */		\
!   { 0xffffffff, 0xffffffff, 0x0001ffff }	/* ALL_REGS */		\
  }
  
  /* The same information, inverted:
--- 1037,1061 ----
     This is an initializer for a vector of HARD_REG_SET
     of length N_REG_CLASSES.  */
  
! #define REG_CLASS_CONTENTS						     \
! {									     \
!   { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */	     \
!   { 0xfffffffe, 0x00000000, 0x00000008, 0x00000000 }, /* BASE_REGS */	     \
!   { 0xffffffff, 0x00000000, 0x00000008, 0x00000000 }, /* GENERAL_REGS */     \
!   { 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FLOAT_REGS */       \
!   { 0x00000000, 0x00000000, 0xffffe000, 0x0001ffff }, /* ALTIVEC_REGS */     \
!   { 0xffffffff, 0xffffffff, 0x00000008, 0x00000000 }, /* NON_SPECIAL_REGS */ \
!   { 0x00000000, 0x00000000, 0x00000001, 0x00000000 }, /* MQ_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000002, 0x00000000 }, /* LINK_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000004, 0x00000000 }, /* CTR_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000006, 0x00000000 }, /* LINK_OR_CTR_REGS */ \
!   { 0x00000000, 0x00000000, 0x00000007, 0x00000000 }, /* SPECIAL_REGS */     \
!   { 0xffffffff, 0x00000000, 0x0000000f, 0x00000000 }, /* SPEC_OR_GEN_REGS */ \
!   { 0x00000000, 0x00000000, 0x00000010, 0x00000000 }, /* CR0_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */	     \
!   { 0xffffffff, 0x00000000, 0x0000ffff, 0x00000000 }, /* NON_FLOAT_REGS */   \
!   { 0x00000000, 0x00000000, 0x00010000, 0x00000000 }, /* XER_REGS */	     \
!   { 0xffffffff, 0xffffffff, 0xffffffff, 0x0001ffff }  /* ALL_REGS */	     \
  }
  
  /* The same information, inverted:
*************** enum reg_class
*** 984,989 ****
--- 1067,1073 ----
   ((REGNO) == 0 ? GENERAL_REGS			\
    : (REGNO) < 32 ? BASE_REGS			\
    : FP_REGNO_P (REGNO) ? FLOAT_REGS		\
+   : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_REGS	\
    : (REGNO) == CR0_REGNO ? CR0_REGS		\
    : CR_REGNO_P (REGNO) ? CR_REGS		\
    : (REGNO) == MQ_REGNO ? MQ_REGS		\
*************** enum reg_class
*** 1006,1011 ****
--- 1090,1096 ----
     : (C) == 'q' ? MQ_REGS	\
     : (C) == 'c' ? CTR_REGS	\
     : (C) == 'l' ? LINK_REGS	\
+    : (C) == 'v' ? ALTIVEC_REGS	\
     : (C) == 'x' ? CR0_REGS	\
     : (C) == 'y' ? CR_REGS	\
     : (C) == 'z' ? XER_REGS	\
*************** enum reg_class
*** 1103,1113 ****
  #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
    secondary_reload_class (CLASS, MODE, IN)
  
! /* If we are copying between FP registers and anything else, we need a memory
!    location.  */
  
! #define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
!  ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS || (CLASS2) == FLOAT_REGS))
  
  /* Return the maximum number of consecutive registers
     needed to represent mode MODE in a register of class CLASS.
--- 1188,1201 ----
  #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
    secondary_reload_class (CLASS, MODE, IN)
  
! /* If we are copying between FP or AltiVec registers and anything
!    else, we need a memory location.  */
  
! #define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) 		\
!  ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS		\
! 			   || (CLASS2) == FLOAT_REGS		\
! 			   || (CLASS1) == ALTIVEC_REGS		\
! 			   || (CLASS2) == ALTIVEC_REGS))
  
  /* Return the maximum number of consecutive registers
     needed to represent mode MODE in a register of class CLASS.
*************** typedef struct rs6000_stack {
*** 1294,1309 ****
  		&& TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)	\
  	       || POINTER_TYPE_P (VALTYPE)			\
  	       ? word_mode : TYPE_MODE (VALTYPE),		\
! 	       TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT \
                 ? FP_ARG_RETURN : GP_ARG_RETURN)
  
  /* Define how to find the value returned by a library function
     assuming the value has mode MODE.  */
  
! #define LIBCALL_VALUE(MODE)					\
!   gen_rtx_REG (MODE, (GET_MODE_CLASS (MODE) == MODE_FLOAT	\
! 		      && TARGET_HARD_FLOAT			\
! 		      ? FP_ARG_RETURN : GP_ARG_RETURN))
  
  /* The definition of this macro implies that there are cases where
     a scalar value cannot be returned in registers.
--- 1382,1399 ----
  		&& TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)	\
  	       || POINTER_TYPE_P (VALTYPE)			\
  	       ? word_mode : TYPE_MODE (VALTYPE),		\
! 	       TREE_CODE (VALTYPE) == VECTOR_TYPE ? ALTIVEC_ARG_RETURN \
! 	       : TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT \
                 ? FP_ARG_RETURN : GP_ARG_RETURN)
  
  /* Define how to find the value returned by a library function
     assuming the value has mode MODE.  */
  
! #define LIBCALL_VALUE(MODE)						\
!   gen_rtx_REG (MODE, ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_ARG_RETURN	\
! 		     : GET_MODE_CLASS (MODE) == MODE_FLOAT		\
! 		     && TARGET_HARD_FLOAT				\
! 		     ? FP_ARG_RETURN : GP_ARG_RETURN)
  
  /* The definition of this macro implies that there are cases where
     a scalar value cannot be returned in registers.
*************** typedef struct rs6000_stack {
*** 1338,1346 ****
--- 1428,1442 ----
  			? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG)
  #define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1)
  
+ /* Minimum and maximum AltiVec registers used to hold arguments.  */
+ #define ALTIVEC_ARG_MIN_REG 77
+ #define ALTIVEC_ARG_MAX_REG 88
+ #define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG - ALTIVEC_ARG_MIN_REG + 1)
+ 
  /* Return registers */
  #define GP_ARG_RETURN GP_ARG_MIN_REG
  #define FP_ARG_RETURN FP_ARG_MIN_REG
+ #define ALTIVEC_ARG_RETURN 79
  
  /* Flags for the call/call_value rtl operations set up by function_arg */
  #define CALL_NORMAL		0x00000000	/* no special processing */
*************** typedef struct rs6000_stack {
*** 1352,1364 ****
  /* 1 if N is a possible register number for a function value
     as seen by the caller.
  
!    On RS/6000, this is r3 and fp1.  */
! #define FUNCTION_VALUE_REGNO_P(N)  ((N) == GP_ARG_RETURN || ((N) == FP_ARG_RETURN))
  
  /* 1 if N is a possible register number for function argument passing.
     On RS/6000, these are r3-r10 and fp1-fp13.  */
  #define FUNCTION_ARG_REGNO_P(N)						\
    ((unsigned)(((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG))	\
     || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))
  
  \f
--- 1448,1465 ----
  /* 1 if N is a possible register number for a function value
     as seen by the caller.
  
!    On RS/6000, this is r3, fp1, and v2 (for AltiVec).  */
! #define FUNCTION_VALUE_REGNO_P(N)  ((N) == GP_ARG_RETURN	\
! 				    || ((N) == FP_ARG_RETURN)	\
! 				    || (TARGET_ALTIVEC &&	\
! 					(N) == ALTIVEC_ARG_RETURN))
  
  /* 1 if N is a possible register number for function argument passing.
     On RS/6000, these are r3-r10 and fp1-fp13.  */
  #define FUNCTION_ARG_REGNO_P(N)						\
    ((unsigned)(((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG))	\
+    || (TARGET_ALTIVEC &&						\
+        (unsigned)((N) - ALTIVEC_ARG_MIN_REG) < (unsigned)(ALTIVEC_ARG_MAX_REG)) \
     || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))
  
  \f
*************** typedef struct rs6000_args
*** 1394,1399 ****
--- 1495,1501 ----
  {
    int words;			/* # words used for passing GP registers */
    int fregno;			/* next available FP register */
+   int vregno;			/* next available AltiVec register */
    int nargs_prototype;		/* # args left in the current prototype */
    int orig_nargs;		/* Original value of nargs_prototype */
    int prototype;		/* Whether a prototype was defined */
*************** typedef struct rs6000_args
*** 1436,1441 ****
--- 1538,1549 ----
     && (CUM).fregno <= FP_ARG_MAX_REG    \
     && TARGET_HARD_FLOAT)
  
+ /* Non-zero if we can use an AltiVec register to pass this arg.  */
+ #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE)	\
+   (ALTIVEC_VECTOR_MODE (MODE)			\
+    && (CUM).vregno <= ALTIVEC_ARG_MAX_REG	\
+    && TARGET_ALTIVEC_ABI)
+ 
  /* Determine where to put an argument to a function.
     Value is zero to push the argument on the stack,
     or a hard register in which to store the argument.
*************** typedef struct rs6000_args
*** 1778,1783 ****
--- 1886,1892 ----
    && GET_CODE (XEXP (X, 0)) == REG				\
    && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT))		\
    && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0)		\
+   && ! ALTIVEC_VECTOR_MODE (MODE)				\
    && (((MODE) != DFmode && (MODE) != DImode)			\
        || (TARGET_32BIT						\
  	  ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) 	\
*************** typedef struct rs6000_args
*** 1805,1810 ****
--- 1914,1920 ----
     && ! flag_pic && ! TARGET_TOC				\
     && (MODE) != DImode						\
     && (MODE) != TImode						\
+    && ! ALTIVEC_VECTOR_MODE (MODE)				\
     && (TARGET_HARD_FLOAT || (MODE) != DFmode)			\
     && GET_CODE (X) == LO_SUM					\
     && GET_CODE (XEXP (X, 0)) == REG				\
*************** extern char rs6000_reg_names[][8];	/* re
*** 2389,2394 ****
--- 2499,2537 ----
    &rs6000_reg_names[75][0],	/* cr7  */				\
  									\
    &rs6000_reg_names[76][0],	/* xer  */				\
+ 									\
+   &rs6000_reg_names[77][0],	/* v0  */				\
+   &rs6000_reg_names[78][0],	/* v1  */				\
+   &rs6000_reg_names[79][0],	/* v2  */				\
+   &rs6000_reg_names[80][0],	/* v3  */				\
+   &rs6000_reg_names[81][0],	/* v4  */				\
+   &rs6000_reg_names[82][0],	/* v5  */				\
+   &rs6000_reg_names[83][0],	/* v6  */				\
+   &rs6000_reg_names[84][0],	/* v7  */				\
+   &rs6000_reg_names[85][0],	/* v8  */				\
+   &rs6000_reg_names[86][0],	/* v9  */				\
+   &rs6000_reg_names[87][0],	/* v10  */				\
+   &rs6000_reg_names[88][0],	/* v11  */				\
+   &rs6000_reg_names[89][0],	/* v12  */				\
+   &rs6000_reg_names[90][0],	/* v13  */				\
+   &rs6000_reg_names[91][0],	/* v14  */				\
+   &rs6000_reg_names[92][0],	/* v15  */				\
+   &rs6000_reg_names[93][0],	/* v16  */				\
+   &rs6000_reg_names[94][0],	/* v17  */				\
+   &rs6000_reg_names[95][0],	/* v18  */				\
+   &rs6000_reg_names[96][0],	/* v19  */				\
+   &rs6000_reg_names[97][0],	/* v20  */				\
+   &rs6000_reg_names[98][0],	/* v21  */				\
+   &rs6000_reg_names[99][0],	/* v22  */				\
+   &rs6000_reg_names[100][0],	/* v23  */				\
+   &rs6000_reg_names[101][0],	/* v24  */				\
+   &rs6000_reg_names[102][0],	/* v25  */				\
+   &rs6000_reg_names[103][0],	/* v26  */				\
+   &rs6000_reg_names[104][0],	/* v27  */				\
+   &rs6000_reg_names[105][0],	/* v28  */				\
+   &rs6000_reg_names[106][0],	/* v29  */				\
+   &rs6000_reg_names[107][0],	/* v30  */				\
+   &rs6000_reg_names[108][0],	/* v31  */				\
  }
  
  /* print-rtl can't handle the above REGISTER_NAMES, so define the
*************** extern char rs6000_reg_names[][8];	/* re
*** 2407,2413 ****
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",		\
       "mq",  "lr", "ctr",  "ap",						\
      "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",		\
!   "xer"									\
  }
  
  /* Table of additional register names to use in user input.  */
--- 2550,2560 ----
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",		\
       "mq",  "lr", "ctr",  "ap",						\
      "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",		\
!   "xer",								\
!      "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",             \
!      "v8",  "v9", "v10", "v11", "v12", "v13", "v14", "v15",             \
!     "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",             \
!     "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"              \
  }
  
  /* Table of additional register names to use in user input.  */
*************** extern char rs6000_reg_names[][8];	/* re
*** 2429,2434 ****
--- 2576,2589 ----
    {"fr20", 52}, {"fr21", 53}, {"fr22", 54}, {"fr23", 55},	\
    {"fr24", 56}, {"fr25", 57}, {"fr26", 58}, {"fr27", 59},	\
    {"fr28", 60}, {"fr29", 61}, {"fr30", 62}, {"fr31", 63},	\
+   {"v0",   77}, {"v1",   78}, {"v2",   79}, {"v3",   80},       \
+   {"v4",   81}, {"v5",   82}, {"v6",   83}, {"v7",   84},       \
+   {"v8",   85}, {"v9",   86}, {"v10",  87}, {"v11",  88},       \
+   {"v12",  89}, {"v13",  90}, {"v14",  91}, {"v15",  92},       \
+   {"v16",  93}, {"v17",  94}, {"v18",  95}, {"v19",  96},       \
+   {"v20",  97}, {"v21",  98}, {"v22",  99}, {"v23",  100},	\
+   {"v24",  101},{"v25",  102},{"v26",  103},{"v27",  104},      \
+   {"v28",  105},{"v29",  106},{"v30",  107},{"v31",  108},      \
    /* no additional names for: mq, lr, ctr, ap */		\
    {"cr0",  68}, {"cr1",  69}, {"cr2",  70}, {"cr3",  71},	\
    {"cr4",  72}, {"cr5",  73}, {"cr6",  74}, {"cr7",  75},	\
*************** do {									\
*** 2617,2622 ****
--- 2772,2778 ----
  				GT, LEU, LTU, GEU, GTU}},		   \
    {"boolean_operator", {AND, IOR, XOR}},				   \
    {"boolean_or_operator", {IOR, XOR}},					   \
+   {"altivec_register", {REG, SUBREG}},					   \
    {"min_max_operator", {SMIN, SMAX, UMIN, UMAX}},
  
  /* uncomment for disabling the corresponding default options */
*************** extern int flag_pic;
*** 2629,2631 ****
--- 2785,2900 ----
  extern int optimize;
  extern int flag_expensive_optimizations;
  extern int frame_pointer_needed;
+ 
+ enum rs6000_builtins
+ {
+   /* AltiVec builtins.  */
+   ALTIVEC_BUILTIN_ST_INTERNAL,
+   ALTIVEC_BUILTIN_LD_INTERNAL,
+   ALTIVEC_BUILTIN_VADDUBM,

--more boring builtins deleted--

+ };
Index: sysv4.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/sysv4.h,v
retrieving revision 1.67
diff -c -p -r1.67 sysv4.h
*** sysv4.h	2001/10/29 23:09:43	1.67
--- sysv4.h	2001/11/05 19:49:24
*************** do {									\
*** 400,417 ****
     one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
     versions, just use 64 as the stack boundary.  */
  #undef	STACK_BOUNDARY
! #define	STACK_BOUNDARY	64
  
  /* Real stack boundary as mandated by the appropriate ABI.  */
! #define ABI_STACK_BOUNDARY ((TARGET_EABI) ? 64 : 128)
  
  /* No data type wants to be aligned rounder than this.  */
  #undef	BIGGEST_ALIGNMENT
! #define BIGGEST_ALIGNMENT ((TARGET_EABI) ? 64 : 128)
  
  #undef  BIGGEST_FIELD_ALIGNMENT
  #undef  ADJUST_FIELD_ALIGN
- #undef  ROUND_TYPE_ALIGN
  
  /* Use ELF style section commands.  */
  
--- 400,430 ----
     one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
     versions, just use 64 as the stack boundary.  */
  #undef	STACK_BOUNDARY
! #define	STACK_BOUNDARY	(TARGET_ALTIVEC_ABI ? 128 : 64)
  
  /* Real stack boundary as mandated by the appropriate ABI.  */
! #define ABI_STACK_BOUNDARY ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
  
  /* No data type wants to be aligned rounder than this.  */
  #undef	BIGGEST_ALIGNMENT
! #define BIGGEST_ALIGNMENT ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
  
+ /* An expression for the alignment of a structure field FIELD if the
+    alignment computed in the usual way is COMPUTED.  */
+ #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)				      \
+ 	((TARGET_ALTIVEC_ABI && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
+ 	 ? 128 : COMPUTED)
+ 
+ /* Define this macro as an expression for the alignment of a type
+    (given by TYPE as a tree node) if the alignment computed in the
+    usual way is COMPUTED and the alignment explicitly specified was
+    SPECIFIED.  */
+ #define ROUND_TYPE_ALIGN(TYPE, COMPUTED, SPECIFIED)			\
+ 	((TARGET_ALTIVEC_ABI && TREE_CODE (TYPE) == VECTOR_TYPE)	\
+ 	 ? 128 : MAX (COMPUTED, SPECIFIED))
+ 
  #undef  BIGGEST_FIELD_ALIGNMENT
  #undef  ADJUST_FIELD_ALIGN
  
  /* Use ELF style section commands.  */
  
Index: rs6000.c
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.224
diff -c -p -r1.224 rs6000.c
*** rs6000.c	2001/10/31 14:08:09	1.224
--- rs6000.c	2001/11/05 19:49:27
*************** int fixuplabelno = 0;
*** 96,101 ****
--- 96,104 ----
  /* ABI enumeration available for subtarget to use.  */
  enum rs6000_abi rs6000_current_abi;
  
+ /* ABI string from -mabi= option.  */
+ const char *rs6000_abi_string;
+ 
  /* Debug flags */
  const char *rs6000_debug_name;
  int rs6000_debug_stack;		/* debug stack applications */
*************** static int rs6000_adjust_cost PARAMS ((r
*** 146,151 ****
--- 149,161 ----
  static int rs6000_adjust_priority PARAMS ((rtx, int));
  static int rs6000_issue_rate PARAMS ((void));
  
+ static void rs6000_init_builtins PARAMS ((tree));
+ static void altivec_init_builtins PARAMS ((void));
+ static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
+ static rtx altivec_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
+ static rtx altivec_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
+ 
+ static void rs6000_parse_abi_options PARAMS ((void));
  \f
  /* Default register names.  */
  char rs6000_reg_names[][8] =
*************** char rs6000_reg_names[][8] =
*** 160,166 ****
       "24", "25", "26", "27", "28", "29", "30", "31",
       "mq", "lr", "ctr","ap",
        "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
!       "xer"
  };
  
  #ifdef TARGET_REGNAMES
--- 170,181 ----
       "24", "25", "26", "27", "28", "29", "30", "31",
       "mq", "lr", "ctr","ap",
        "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
!       "xer",
!       /* AltiVec registers.  */
!       "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6", "v7",
!       "v8",  "v9",  "v10", "v11", "v12", "v13", "v14", "v15",
!       "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
!       "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
  };
  
  #ifdef TARGET_REGNAMES
*************** static const char alt_reg_names[][8] =
*** 176,182 ****
    "%f24",  "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
      "mq",    "lr",  "ctr",   "ap",
    "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
!   "xer"
  };
  #endif
  \f
--- 191,202 ----
    "%f24",  "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
      "mq",    "lr",  "ctr",   "ap",
    "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
!    "xer",
!    /* AltiVec registers.  */
!    "%v0",  "%v1",  "%v2",  "%v3",  "%v4",  "%v5",  "%v6", "%v7",
!    "%v8",  "%v9",  "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
!    "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
!    "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31"
  };
  #endif
  \f
*************** static const char alt_reg_names[][8] =
*** 205,210 ****
--- 225,236 ----
  #undef TARGET_SCHED_ADJUST_PRIORITY
  #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
  
+ #undef TARGET_INIT_BUILTINS
+ #define TARGET_INIT_BUILTINS rs6000_init_builtins
+ 
+ #undef TARGET_EXPAND_BUILTIN
+ #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
+ 
  struct gcc_target targetm = TARGET_INITIALIZER;
  \f
  /* Override command line options.  Mostly we process the processor
*************** rs6000_override_options (default_cpu)
*** 438,443 ****
--- 464,472 ----
  	error ("Unknown -mdebug-%s switch", rs6000_debug_name);
      }
  
+   /* Handle -mabi= options.  */
+   rs6000_parse_abi_options ();
+ 
  #ifdef TARGET_REGNAMES
    /* If the user desires alternate register names, copy in the
       alternate names now.  */
*************** rs6000_override_options (default_cpu)
*** 463,468 ****
--- 492,508 ----
    free_machine_status = rs6000_free_machine_status;
  }
  
+ /* Handle -mabi= options.  */
+ void rs6000_parse_abi_options ()
+ {
+   if (rs6000_abi_string == 0)
+     return;
+   else if (! strcmp (rs6000_abi_string, "altivec"))
+     target_flags |= MASK_ALTIVEC_ABI;
+   else
+     error ("Unknown ABI specified: '%s'", rs6000_abi_string);
+ }
+ 
  void
  optimization_options (level, size)
       int level ATTRIBUTE_UNUSED;
*************** input_operand (op, mode)
*** 1411,1416 ****
--- 1451,1475 ----
    return 0;
  }
  
+ /* Return 1 if this is an AltiVec vector register.
+ 
+    Actually, what we really want to know is if this is a vector mode,
+    since vectors can only go in AltiVec registers.
+ 
+    This is used in *altivec_vec_move so we can seamlessly convert
+    between vector types.  */
+ int
+ altivec_register (x, mode)
+      rtx x;
+      enum machine_mode mode;
+ {
+   if (register_operand (x, mode)
+       && ALTIVEC_VECTOR_MODE (GET_MODE (x)))
+     return 1;
+ 
+   return 0;
+ }
+ 
  /* Return 1 for an operand in small memory on V.4/eabi.  */
  
  int
*************** rs6000_legitimize_address (x, oldx, mode
*** 1544,1550 ****
       rtx x;
       rtx oldx ATTRIBUTE_UNUSED;
       enum machine_mode mode;
! { 
    if (GET_CODE (x) == PLUS 
        && GET_CODE (XEXP (x, 0)) == REG
        && GET_CODE (XEXP (x, 1)) == CONST_INT
--- 1603,1609 ----
       rtx x;
       rtx oldx ATTRIBUTE_UNUSED;
       enum machine_mode mode;
! {
    if (GET_CODE (x) == PLUS 
        && GET_CODE (XEXP (x, 0)) == REG
        && GET_CODE (XEXP (x, 1)) == CONST_INT
*************** rs6000_legitimize_address (x, oldx, mode
*** 1570,1575 ****
--- 1629,1646 ----
        return gen_rtx_PLUS (Pmode, XEXP (x, 0),
  			   force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
      }
+   else if (ALTIVEC_VECTOR_MODE (mode))
+     {
+       rtx reg;
+ 
+       /* Make sure both operands are registers.  */
+       if (GET_CODE (x) == PLUS)
+ 	return gen_rtx_PLUS (Pmode, XEXP (x, 0),
+ 			     force_reg (Pmode, XEXP (x, 1)));
+ 
+       reg = force_reg (Pmode, x);
+       return reg;
+     }
    else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic
  	   && GET_CODE (x) != CONST_INT
  	   && GET_CODE (x) != CONST_DOUBLE 
*************** rs6000_emit_move (dest, source, mode)
*** 1862,1867 ****
--- 1933,1947 ----
  	operands[1] = force_const_mem (mode, operands[1]);
        break;
        
+     case V16QImode:
+     case V8HImode:
+     case V4SFmode:
+     case V4SImode:
+       /* fixme: aldyh -- allow vector constants when they are implemented.  */
+       if (CONSTANT_P (operands[1]))
+ 	operands[1] = force_const_mem (mode, operands[1]);
+       break;
+       
      case SImode:
      case DImode:
        /* Use default pattern for address of ELF small data */
*************** init_cumulative_args (cum, fntype, libna
*** 2062,2067 ****
--- 2142,2148 ----
    *cum = zero_cumulative;
    cum->words = 0;
    cum->fregno = FP_ARG_MIN_REG;
+   cum->vregno = ALTIVEC_ARG_MIN_REG;
    cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
    cum->call_cookie = CALL_NORMAL;
    cum->sysv_gregno = GP_ARG_MIN_REG;
*************** function_arg_boundary (mode, type)
*** 2142,2147 ****
--- 2223,2230 ----
    if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
        && (mode == DImode || mode == DFmode))
      return 64;
+   else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
+     return 128;
    else
      return PARM_BOUNDARY;
  }
*************** function_arg_advance (cum, mode, type, n
*** 2159,2165 ****
  {
    cum->nargs_prototype--;
  
!   if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
--- 2242,2255 ----
  {
    cum->nargs_prototype--;
  
!   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
!     {
!       if (cum->vregno <= ALTIVEC_ARG_MAX_REG)
! 	cum->vregno++;
!       else
! 	cum->words += RS6000_ARG_SIZE (mode, type);
!     }
!   else if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
*************** function_arg (cum, mode, type, named)
*** 2287,2294 ****
        return GEN_INT (cum->call_cookie);
      }
  
!   if (abi == ABI_V4 || abi == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
  	{
--- 2377,2391 ----
        return GEN_INT (cum->call_cookie);
      }
  
!   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
      {
+       if (cum->vregno <= ALTIVEC_ARG_MAX_REG)
+ 	return gen_rtx_REG (mode, cum->vregno);
+       else
+ 	return NULL;
+     }
+   else if (abi == ABI_V4 || abi == ABI_SOLARIS)
+     {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
  	{
*************** function_arg_partial_nregs (cum, mode, t
*** 2382,2388 ****
    if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      return 0;
  
!   if (USE_FP_FOR_ARG_P (*cum, mode, type))
      {
        if (cum->nargs_prototype >= 0)
  	return 0;
--- 2479,2486 ----
    if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      return 0;
  
!   if (USE_FP_FOR_ARG_P (*cum, mode, type)
!       || USE_ALTIVEC_FOR_ARG_P (*cum, mode, type))
      {
        if (cum->nargs_prototype >= 0)
  	return 0;
*************** rs6000_va_arg (valist, type)
*** 2838,2843 ****
--- 2936,3411 ----
  
    return addr_rtx;
  }
+ 
+ /* Builtins.  */
+ 
+ #define def_builtin(MASK, NAME, TYPE, CODE)				\
+ do {									\
+   if ((MASK) & target_flags)						\
+     builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL);	\
+ } while (0)
+ 
+ struct builtin_description
+ {
+   const unsigned int mask;
+   const enum insn_code icode;
+   const char *const name;
+   const enum rs6000_builtins code;
+ };
+ 
+ /* Simple binary operatiors: VECc = foo (VECa, VECb).  */
+ static const struct builtin_description bdesc_2arg[] =
+ {
+   { MASK_ALTIVEC, CODE_FOR_altivec_vaddubm, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
+   { MASK_ALTIVEC, CODE_FOR_altivec_vadduhm, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },

--more boring builtins deleted--

+ };
+ 
+ static rtx
+ altivec_expand_binop_builtin (icode, arglist, target)
+      enum insn_code icode;
+      tree arglist;
+      rtx target;
+ {
+   rtx pat;
+   tree arg0 = TREE_VALUE (arglist);
+   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+   rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+   rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+   enum machine_mode tmode = insn_data[icode].operand[0].mode;
+   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
+   enum machine_mode mode1 = insn_data[icode].operand[2].mode;
+ 
+   if (! target
+       || GET_MODE (target) != tmode
+       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+     target = gen_reg_rtx (tmode);
+ 
+   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+     op0 = copy_to_mode_reg (mode0, op0);
+   if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
+     op1 = copy_to_mode_reg (mode1, op1);
+ 
+   pat = GEN_FCN (icode) (target, op0, op1);
+   if (! pat)
+     return 0;
+   emit_insn (pat);
+ 
+   return target;
+ }
+ 
+ static rtx
+ altivec_expand_builtin (exp, target, subtarget, mode, ignore)
+      tree exp;
+      rtx target;
+      rtx subtarget;
+      enum machine_mode mode;
+      int ignore;
+ {
+   struct builtin_description *d;
+   size_t i;
+   enum insn_code icode;
+   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
+   tree arglist = TREE_OPERAND (exp, 1);
+   tree arg0, arg1, arg2, arg3;
+   rtx op0, op1, op2, pat;
+   enum machine_mode tmode, mode0, mode1, mode2;
+   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+   
+   switch (fcode)
+     {
+     case ALTIVEC_BUILTIN_LD_INTERNAL:
+       icode = CODE_FOR_altivec_lvx;
+       arg0 = TREE_VALUE (arglist);
+       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+       tmode = insn_data[icode].operand[0].mode;
+       mode0 = insn_data[icode].operand[1].mode;
+ 
+       if (! target
+ 	  || GET_MODE (target) != tmode
+ 	  || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ 	target = gen_reg_rtx (tmode);
+ 
+       if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+ 	op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
+ 
+       pat = GEN_FCN (icode) (target, op0);
+       if (! pat)
+ 	return 0;
+       emit_insn (pat);
+       return target;
+ 
+     case ALTIVEC_BUILTIN_ST_INTERNAL:
+       icode = CODE_FOR_altivec_stvx;
+       arg0 = TREE_VALUE (arglist);
+       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+       op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+       mode0 = insn_data[icode].operand[0].mode;
+       mode1 = insn_data[icode].operand[1].mode;
+ 
+       if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
+ 	op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
+       if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
+ 	op1 = copy_to_mode_reg (mode1, op1);
+ 
+       pat = GEN_FCN (icode) (op0, op1);
+       if (! pat)
+ 	return 0;
+       emit_insn (pat);
+       return NULL_RTX;
+     }
+ 
+   /* Handle simple binary operations.  */
+   for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
+     if (d->code == fcode)
+       return altivec_expand_binop_builtin (d->icode, arglist, target);
+ 
+   abort ();
+   return NULL_RTX;
+ }
+ 
+ /* Expand an expression EXP that calls a built-in function,
+    with result going to TARGET if that's convenient
+    (and in mode MODE if that's convenient).
+    SUBTARGET may be used as the target for computing one of EXP's operands.
+    IGNORE is nonzero if the value is to be ignored.  */
+ 
+ static rtx
+ rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
+      tree exp;
+      rtx target;
+      rtx subtarget;
+      enum machine_mode mode;
+      int ignore;
+ {
+   if (TARGET_ALTIVEC)
+     return altivec_expand_builtin (exp, target, subtarget, mode, ignore);
+ 
+   abort ();
+ }
+ 
+ static void
+ rs6000_init_builtins (list_node)
+      tree list_node ATTRIBUTE_UNUSED;
+ {
+   if (TARGET_ALTIVEC)
+     altivec_init_builtins ();
+ }
+ 
+ static void
+ altivec_init_builtins (void)
+ {
+   struct builtin_description * d;
+   size_t i;
+ 
+   tree endlink = void_list_node;
+ 
+   tree pint_type_node = build_pointer_type (integer_type_node);
+ 
+   /* V4SI foo (int *).  */
+   tree v4si_ftype_pint
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, pint_type_node, endlink));
+ 
+   /* void foo (int *, V4SI).  */
+   tree void_ftype_pint_v4si
+     = build_function_type (void_type_node,
+ 			   tree_cons (NULL_TREE, pint_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 

--more boring types deleted--

+ 
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal", v4si_ftype_pint, ALTIVEC_BUILTIN_LD_INTERNAL);
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal", void_ftype_pint_v4si, ALTIVEC_BUILTIN_ST_INTERNAL);
+ 
+   /* Add the simple binary operators.  */
+   for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
+     {
+       enum machine_mode mode0, mode1, mode2;
+       tree type;
+ 
+       if (d->name == 0)
+ 	continue;
+       
+       mode0 = insn_data[d->icode].operand[0].mode;
+       mode1 = insn_data[d->icode].operand[1].mode;
+       mode2 = insn_data[d->icode].operand[2].mode;
+ 
+       /* When all three operands are of the same mode.  */
+       if (mode0 == mode1 && mode1 == mode2)
+ 	{
+ 	  switch (mode0)
+ 	    {
+ 	    case V4SFmode:
+ 	      type = v4sf_ftype_v4sf_v4sf;
+ 	      break;
+ 	    case V4SImode:
+ 	      type = v4si_ftype_v4si_v4si;
+ 	      break;
+ 	    case V16QImode:
+ 	      type = v16qi_ftype_v16qi_v16qi;
+ 	      break;
+ 	    case V8HImode:
+ 	      type = v8hi_ftype_v8hi_v8hi;
+ 	      break;
+ 	    default:
+ 	      abort ();
+ 	    }
+ 	}
+ 
+       /* A few other combos we really don't want to do manually.  */
+ 
+       /* vint, vfloat, vfloat.  */
+       else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
+ 	type = v4si_ftype_v4sf_v4sf;
+ 
+       /* vshort, vchar, vchar.  */
+       else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
+ 	type = v8hi_ftype_v16qi_v16qi;
+ 
+       /* vint, vshort, vshort.  */
+       else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
+ 	type = v4si_ftype_v8hi_v8hi;
+ 
+       /* vshort, vint, vint.  */
+       else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
+ 	type = v8hi_ftype_v4si_v4si;
+ 
+       /* vchar, vshort, vshort.  */
+       else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
+ 	type = v16qi_ftype_v8hi_v8hi;
+ 
+       /* vint, vchar, vint.  */
+       else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
+ 	type = v4si_ftype_v16qi_v4si;
+ 
+       /* vint, vshort, vint.  */
+       else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
+ 	type = v4si_ftype_v8hi_v4si;
+ 
+       /* fixme: aldyh */
+       /* int, x, x.  */
+       else if (mode0 == SImode)
+ 	{
+ 	  switch (mode1)
+ 	    {
+ 	    case V4SImode:
+ 	      type = int_ftype_v4si_v4si;
+ 	      break;
+ 	    case V4SFmode:
+ 	      type = int_ftype_v4sf_v4sf;
+ 	      break;
+ 	    case V16QImode:
+ 	      type = int_ftype_v16qi_v16qi;
+ 	      break;
+ 	    case V8HImode:
+ 	      type = int_ftype_v8hi_v8hi;
+ 	      break;
+ 	    default:
+ 	      abort ();
+ 	    }
+ 	}
+ 
+       else
+ 	abort ();
+ 
+       def_builtin (d->mask, d->name, type, d->code);
+     }
+ }
+ 
  \f
  /* Generate a memory reference for expand_block_move, copying volatile,
     and other bits from an original memory reference.  */
*************** secondary_reload_class (class, mode, in)
*** 3941,3946 ****
--- 4509,4519 ----
        && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
      return NO_REGS;
  
+   /* Memory, and AltiVec registers can go into AltiVec registers.  */
+   if ((regno == -1 || ALTIVEC_REGNO_P (regno))
+       && class == ALTIVEC_REGS)
+     return NO_REGS;
+ 
    /* We can copy among the CR registers.  */
    if ((class == CR_REGS || class == CR0_REGS)
        && regno >= 0 && CR_REGNO_P (regno))
*************** print_operand (file, x, code)
*** 4714,4719 ****
--- 5287,5318 ----
  		     reg_names[SMALL_DATA_REG]);
  	}
        return;
+ 
+       /* Print AltiVec memory operand.  */
+     case 'y':
+       {
+ 	rtx tmp;
+ 
+ 	if (GET_CODE (x) != MEM)
+ 	  abort ();
+ 
+ 	tmp = XEXP (x, 0);
+ 
+ 	if (GET_CODE (tmp) == REG)
+ 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
+ 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
+ 	  {
+ 	    if (REGNO (XEXP (tmp, 0)) == 0)
+ 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
+ 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
+ 	    else
+ 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
+ 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
+ 	  }
+ 	else
+ 	  abort ();
+ 	break;
+       }
  			    
      case 0:
        if (GET_CODE (x) == REG)
Index: rs6000.md
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.128
diff -c -p -r1.128 rs6000.md
*** rs6000.md	2001/10/16 00:43:21	1.128
--- rs6000.md	2001/11/05 19:49:32
***************
*** 37,43 ****
  \f
  ;; Define an insn type attribute.  This is used in function unit delay
  ;; computations.
! (define_attr "type" "integer,load,store,fpload,fpstore,imul,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg"
    (const_string "integer"))
  
  ;; Length (in bytes).
--- 37,43 ----
  \f
  ;; Define an insn type attribute.  This is used in function unit delay
  ;; computations.
! (define_attr "type" "integer,load,store,fpload,fpstore,imul,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,altivec"
    (const_string "integer"))
  
  ;; Length (in bytes).
***************
*** 13359,13361 ****
--- 13359,14298 ----
      emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
    DONE;
  }")
+ 
+ ;; AltiVec patterns
+ 
+ ;; Generic LVX load instruction.
+ (define_insn "altivec_lvx"
+   [(set (match_operand:V4SI 0 "register_operand" "=v")
+ 	(match_operand:V4SI 1 "memory_operand" "m"))]
+   "TARGET_ALTIVEC"
+   "lvx\t%0,%y1"
+   [(set_attr "type" "altivec")])
+ 
+ ;; Generic STVX store instruction.
+ (define_insn "altivec_stvx"
+   [(set (match_operand:V4SI 0 "memory_operand" "=m")
+ 	(match_operand:V4SI 1 "register_operand" "v"))]
+   "TARGET_ALTIVEC"
+   "stvx\t%1,%y0"
+   [(set_attr "type" "altivec")])
+ 
+ ;; No code is needed to copy between vector registers.
+ (define_insn "*altivec_vec_move"
+   [(set (match_operand 0 "altivec_register" "=v")
+ 	(match_operand 1 "altivec_register" "v"))]
+   "TARGET_ALTIVEC"
+   ""
+   [(set_attr "type" "altivec")])
+ 
+ ;; Vector move instructions.
+ (define_expand "movv4si"
+   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
+ 	(match_operand:V4SI 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V4SImode); DONE; }")
+ 
+ (define_insn "*movv4si_internal"
+   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v")
+ 	(match_operand:V4SI 1 "input_operand" "v,m"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1"
+   [(set_attr "type" "altivec")])
+ 
+ (define_expand "movv8hi"
+   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
+ 	(match_operand:V8HI 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V8HImode); DONE; }")
+ 
+ (define_insn "*movv8hi_internal1"
+   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=m,v")
+ 	(match_operand:V8HI 1 "input_operand" "v,m"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1"
+   [(set_attr "type" "altivec")])
+ 
+ (define_expand "movv16qi"
+   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
+ 	(match_operand:V16QI 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V16QImode); DONE; }")
+ 
+ (define_insn "*movv16qi_internal1"
+   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=m,v")
+ 	(match_operand:V16QI 1 "input_operand" "v,m"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1"
+   [(set_attr "type" "altivec")])
+ 
+ (define_expand "movv4sf"
+   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
+ 	(match_operand:V4SF 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V4SFmode); DONE; }")
+ 
+ (define_insn "*movv4sf_internal1"
+   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=m,v")
+ 	(match_operand:V4SF 1 "input_operand" "v,m"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1"
+   [(set_attr "type" "altivec")])
+ 
+ ;; Simple binary operations.
+ 

-- boring builtins deleted-- 

+ (define_insn "altivec_vxor"
+   [(set (match_operand:V4SI 0 "register_operand" "=v")
+         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
+                       (match_operand:V4SI 2 "register_operand" "v")] 136))]
+   "TARGET_ALTIVEC"
+   "vxor\t%0,%1,%2"
+   [(set_attr "type" "altivec")])

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 19:47   ` Aldy Hernandez
  2001-11-13  4:32     ` Aldy Hernandez
@ 2001-11-13 15:03     ` Aldy Hernandez
  1 sibling, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Dale Johannesen; +Cc: gcc patches, Geoff Keating

> I'd really like to see vrsave in the enums and register macros
> (not necessarily the code).  I dislike making a major change to
> an area if we know it's going to change again shortly.

done

> > +    : ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_REGNO_P (REGNO)		\
> > +    : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE)		\
> >      : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC		\
> >      : XER_REGNO_P (REGNO) ? (MODE) == PSImode				\
> >      : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT		\
> 
> I don't think you want the first changed line here.

fixed

> >      : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10	\
> >      : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10	\
> > +    : (CLASS1) == ALTIVEC_REGS && (CLASS2) != ALTIVEC_REGS ? 20	\
> >      : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS		\
> >          || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS		\
> >          || (CLASS1) == LINK_OR_CTR_REGS)				\
> 
> And here you need
> 	: (CLASS1) != ALTIVEC_REGS && (CLASS2) == ALTIVEC_REGS ? 20
> analogous to the FLOAT case.

whoops.  done.

> > +   && ! ALTIVEC_VECTOR_MODE (MODE)				\
> >     && (((MODE) != DFmode && (MODE) != DImode)			\
> >         || (TARGET_32BIT						\
> >   	  ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) 	\
> 
> That could be
> 	  && ( ! ALTIVEC_VECTOR_MODE (MODE) || INTVAL (X) == 0)
> for better codegen.  It's not wrong as is, though.

done

thanks for your corrections.  hopefully we'll only need one more
iteration through this.

aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 17:00     ` Dale Johannesen
  2001-11-06 17:06       ` Aldy Hernandez
  2001-11-13  4:33       ` Dale Johannesen
@ 2001-11-13 15:03       ` Dale Johannesen
  2 siblings, 0 replies; 152+ messages in thread
From: Dale Johannesen @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Dale Johannesen, Geoff Keating, gcc-patches

On Tuesday, November 6, 2001, at 03:04 PM, Aldy Hernandez wrote:

> *************** extern int rs6000_debug_arg;	
> --- 766,779 ----
>      31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19,	\
>      18, 17, 16, 15, 14, 13, 12,				\
>      64, 66, 65, 						\
> !    73, 1, 2, 67, 76,					\
> !    /* AltiVec registers.  */				\
> !    77, 78,						\
> !    90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80,		\
> !    79,							\
> !    96, 95, 94, 93, 92, 91,				\
> !    108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97 \
> ! }

This needs an entry for vrsave.  (If you leave it out, you can get
a crash in reload on code that has nothing to do with Altivec; trust
me on this one:)

>   /* 1 if N is a possible register number for function argument passing.
>      On RS/6000, these are r3-r10 and fp1-fp13.  */
>   #define FUNCTION_ARG_REGNO_P(N)						\
>     ((unsigned)(((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG))	\
> +    || (TARGET_ALTIVEC &&						\
> +        (unsigned)((N) - ALTIVEC_ARG_MIN_REG) < 
> (unsigned)(ALTIVEC_ARG_MAX_REG)) \
>      || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))\

It would be nice, though not essential, to update the comment.

> --- 2511,2549 ----
...snipped...
> +   &rs6000_reg_names[107][0],	/* v30  */				\
> +   &rs6000_reg_names[108][0],	/* v31  */				\
>   }

This needs an entry for vrsave.

> --- 2562,2572 ----
>       "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",		\
>        "mq",  "lr", "ctr",  "ap",						\
>       "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",		\
> !   "xer",								\
> !      "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",            
>  \
> !      "v8",  "v9", "v10", "v11", "v12", "v13", "v14", "v15",            
>  \
> !     "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",            
>  \
> !     "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"             
>  \
>   }

So does this.

> +   {"v24",  101},{"v25",  102},{"v26",  103},{"v27",  104},      \
> +   {"v28",  105},{"v29",  106},{"v30",  107},{"v31",  108},      \
>     /* no additional names for: mq, lr, ctr, ap */		\
>     {"cr0",  68}, {"cr1",  69}, {"cr2",  70}, {"cr3",  71},	\
>     {"cr4",  72}, {"cr5",  73}, {"cr6",  74}, {"cr7",  75}

Not sure about here, but either the table or the commment should be 
updated.

> --- 170,181 ----
>        "24", "25", "26", "27", "28", "29", "30", "31",
>        "mq", "lr", "ctr","ap",
>         "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
> !       "xer",
> !       /* AltiVec registers.  */
> !       "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6", "v7",
> !       "v8",  "v9",  "v10", "v11", "v12", "v13", "v14", "v15",
> !       "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
> !       "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
>   };

vrsave again.

> --- 191,202 ----
>     "%f24",  "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
>       "mq",    "lr",  "ctr",   "ap",
>     "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
> !    "xer",
> !    /* AltiVec registers.  */
> !    "%v0",  "%v1",  "%v2",  "%v3",  "%v4",  "%v5",  "%v6", "%v7",
> !    "%v8",  "%v9",  "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
> !    "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
> !    "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31"
>   };

and again.

With these fixes I'll approve everything but the builtins, which I'm not
planning to rule on either way.  You'll have to go through and change all
the 'altivec' functional units later, but I guess you're aware of that.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 16:46       ` Aldy Hernandez
  2001-11-13  4:33         ` Aldy Hernandez
@ 2001-11-13 15:03         ` Aldy Hernandez
  1 sibling, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: Dale Johannesen, gcc patches, Geoff Keating

> Is there any reasonable way to reflect that in the generated objects,
> then?  Is there a spare bit in the ELF header for this?

sure, i guess i can come up with a patch later... but that _is_ the
general idea of an ABI, you can't mix and match them and expect them to
work.

> 
> -- 
> Daniel Jacobowitz                           Carnegie Mellon University
> MontaVista Software                         Debian GNU/Linux Developer
-- 

Aldy Hernandez			E-mail: aldyh@redhat.com
Professional Gypsy
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 17:15       ` Aldy Hernandez
  2001-11-13  4:33         ` Aldy Hernandez
@ 2001-11-13 15:03         ` Aldy Hernandez
  1 sibling, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Stan Shebs; +Cc: Geoff Keating, gcc patches

On Tue, 2001-11-06 at 20:07, Stan Shebs wrote:
> Aldy Hernandez wrote:
> > 
> > After a few iterations I think this is finally it-- for the first
> > batch of patches anyhow.
> 
> It's all looking good to me, modulo the question below.
> 
> It would be ever so slightly more convenient for Apple's next import
> if vrsave were to be listed ahead of the general vector registers
> instead of after (it then becomes part of the "block" of misc regs),
> but we can cope with it either way.
> 

heh.  gcc merges... i bet it's going to be a painful merge.  sorry.

would you mind changing the vrsave order yourself after this gets
committed?  i'm doing my umteenth "make bootstrap; make check" today and
i don't want to do so yet again ;)

> Missing a "vrsave" here?
> 
> Stan

yes typo.  i had already fixed it.


-- 
Aldy Hernandez			E-mail: aldyh@redhat.com
Professional Gypsy
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 19:27   ` Aldy Hernandez
  2001-11-05 20:10     ` Geoff Keating
  2001-11-13  4:32     ` Aldy Hernandez
@ 2001-11-13 15:03     ` Aldy Hernandez
  2 siblings, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Geoff Keating; +Cc: gcc-patches

>>>>> "Geoff" == Geoff Keating <geoffk@geoffk.org> writes:

 >> ! #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)

 > I think you _don't_ want this to be dependent on the ABI.  Changing
 > this isn't an ABI change (I hope!), which is good because...

Fixed.  Set to 128 unconditionally.

 >> ! 
 >> ! /* A C expression to compute the alignment for a variables in the
 >> !    local store.  TYPE is the data type, and ALIGN is the alignment
 >> !    that the object would ordinarily have.  */
 >> ! #define LOCAL_ALIGNMENT(TYPE, ALIGN)				\
 >> ! 	((TARGET_ALTIVEC_ABI		    			\
 >> ! 	  && TREE_CODE (TYPE)) == VECTOR_TYPE ? 128 : ALIGN)

 > ..as altivec values have to be 128-bit aligned because of the
 > hardware, you don't want this ABI-dependent either.

Fixed.  Set to TARGET_ALTIVEC.  Actually, that's ambiguous because you
shouldn't have vector types unless you are in altivec mode, but it
won't hurt.

 > The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
 > quite right:  it has to happen _only when the ABI is 'altivec'_.

I took it out because it needs rethinking.  DWARF_FRAME_REGISTERS is
used as an array size in a few places, particulary unwind-dw2.c.  So I
need to change all these places to dynamically allocate their space.

 > This will be a bit tricky because DWARF_FRAME_REGISTERS is also used
 > in libgcc, so you have to #define something when the Altivec ABI is
 > chosen, and then key off that if IN_LIBGCC2.

 > I wonder if you could assume that the integrated cpplib will always be
 > used when compiling libgcc?  That would make things easier, because
 > then you wouldn't have muck with specs so much.

Please explain.  I only see DWARF_FRAME_REGISTERS being used in
dwarf2out.c and unwind-dw2.c.  There is nothing in libgcc*.

 >> !    /* AltiVec registers.  */			   \
 >> !    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
 >> !    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  \
 >> ! }

 > This is correct, but doesn't there need to be a change to them in
 > CONDITIONAL_REGISTER_USAGE when the altivec ABI is chosen (in which
 > some altivec registers are call-saved)?

And there already is: :)

  if (TARGET_ALTIVEC_ABI)
    for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
      call_used_regs[i] = 1;

 > These should be based off FIRST_ALTIVEC_REGISTER rather than being
 > magic numbers...

Fixed.

 >> /* Return registers */
 >> #define GP_ARG_RETURN GP_ARG_MIN_REG
 >> #define FP_ARG_RETURN FP_ARG_MIN_REG
 >> + #define ALTIVEC_ARG_RETURN 79

 > .. this too.

Fixed.

 >> #undef	STACK_BOUNDARY
 >> ! #define	STACK_BOUNDARY	64
 >> 
 >> /* Real stack boundary as mandated by the appropriate ABI.  */
 >> ! #define ABI_STACK_BOUNDARY ((TARGET_EABI) ? 64 : 128)
 >> 
 >> /* No data type wants to be aligned rounder than this.  */
 >> #undef	BIGGEST_ALIGNMENT
 >> ! #define BIGGEST_ALIGNMENT ((TARGET_EABI) ? 64 : 128)
 >> 
 >> #undef  BIGGEST_FIELD_ALIGNMENT
 >> #undef  ADJUST_FIELD_ALIGN
 >> - #undef  ROUND_TYPE_ALIGN
 >> 
 >> /* Use ELF style section commands.  */
 >> 
 >> --- 400,430 ----
 >> one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
 >> versions, just use 64 as the stack boundary.  */
 >> #undef	STACK_BOUNDARY
 >> ! #define	STACK_BOUNDARY	(TARGET_ALTIVEC_ABI ? 128 : 64)
 >> 
 >> /* Real stack boundary as mandated by the appropriate ABI.  */
 >> ! #define ABI_STACK_BOUNDARY ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
 >> 
 >> /* No data type wants to be aligned rounder than this.  */
 >> #undef	BIGGEST_ALIGNMENT
 >> ! #define BIGGEST_ALIGNMENT ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
 >> 
 >> + /* An expression for the alignment of a structure field FIELD if the
 >> +    alignment computed in the usual way is COMPUTED.  */
 >> + #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)				      \
 >> + 	((TARGET_ALTIVEC_ABI && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
 >> + 	 ? 128 : COMPUTED)
 >> + 
 >> + /* Define this macro as an expression for the alignment of a type
 >> +    (given by TYPE as a tree node) if the alignment computed in the
 >> +    usual way is COMPUTED and the alignment explicitly specified was
 >> +    SPECIFIED.  */
 >> + #define ROUND_TYPE_ALIGN(TYPE, COMPUTED, SPECIFIED)			\
 >> + 	((TARGET_ALTIVEC_ABI && TREE_CODE (TYPE) == VECTOR_TYPE)	\
 >> + 	 ? 128 : MAX (COMPUTED, SPECIFIED))
 >> + 
 >> #undef  BIGGEST_FIELD_ALIGNMENT
 >> #undef  ADJUST_FIELD_ALIGN
 >> 
 >> /* Use ELF style section commands.  */

 > This has the same comment as the equivalent stuff in rs6000.h.

Huh?  What do you mean?

 >> *************** function_arg_advance (cum, mode, type, n
 >> *** 2159,2165 ****
 >> {
 cum-> nargs_prototype--;
 >> 
 >> !   if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
 >> {
 >> if (TARGET_HARD_FLOAT
 >> && (mode == SFmode || mode == DFmode))
 >> --- 2242,2255 ----
 >> {
 cum-> nargs_prototype--;
 >> 
 >> !   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
 >> !     {
 >> !       if (cum->vregno <= ALTIVEC_ARG_MAX_REG)
 >> ! 	cum->vregno++;
 >> !       else
 >> ! 	cum->words += RS6000_ARG_SIZE (mode, type);
 >> !     }

 > Something you might not have seen in the ABI documentation: unnamed
 > vector arguments (passed to varargs functions after the '...') get
 > passed in memory, not in registers.  (I don't remember if this is just
 > the unnamed arguments or all the arguments to varargs functions, you
 > should check.)

This is just for unnamed arguments in varargs.  So I'll have to add:

        if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
done. (?)

 >> +       /* Print AltiVec memory operand.  */
 >> +     case 'y':
 >> +       {
 >> + 	rtx tmp;
 >> + 
 >> + 	if (GET_CODE (x) != MEM)
 >> + 	  abort ();
 >> + 
 >> + 	tmp = XEXP (x, 0);
 >> + 
 >> + 	if (GET_CODE (tmp) == REG)
 >> + 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
 >> + 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
 >> + 	  {
 >> + 	    if (REGNO (XEXP (tmp, 0)) == 0)
 >> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
 >> + 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
 >> + 	    else
 >> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
 >> + 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
 >> + 	  }
 >> + 	else
 >> + 	  abort ();
 >> + 	break;
 >> +       }

 > Do you really need this?  It looks just like the way a normal memory
 > operand is printed (for the cases that are allowed for altivec).

Yes I do.  I want "[reg+reg]" to be outputed as "reg,reg" and [reg] to
be outputed as "reg,0".

Consider "lvx d,a,b".  I want to match:

        (set (reg) (mem))

and have (mem) be dumped as "a,b" (the two registers in the memory
address: (plus (reg) (reg))).  And I make sure that addresses get
canonicalized into (mem (reg)) and (mem (plus (reg) (reg))) with
LEGITIM* code.

 > Can you put the altivec insns in their own .md file and use the include
 > mechanism?  I believe this is what it was intended for.

As soon as you approve Alan's patch, yes :).

 >> + ;; No code is needed to copy between vector registers.
 >> + (define_insn "*altivec_vec_move"
 >> +   [(set (match_operand 0 "altivec_register" "=v")
 >> + 	(match_operand 1 "altivec_register" "v"))]
 >> +   "TARGET_ALTIVEC"
 >> +   ""
 >> +   [(set_attr "type" "altivec")])

 > Um, that can't possibly be right.  Also, it should be part of
 > movv4si_internal, because reload needs all the move insns to be the
 > same pattern.

What the hell was that all about?  I should get my cvs access revoked
for that one.  I dunno how that make it there.  M-x doctor

 >> + ;; Vector move instructions.
 >> + (define_expand "movv4si"
 >> +   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
 >> + 	(match_operand:V4SI 1 "any_operand" ""))]
 >> +   "TARGET_ALTIVEC"
 >> +   "{ rs6000_emit_move (operands[0], operands[1], V4SImode); DONE; }")
 >> + 
 >> + (define_insn "*movv4si_internal"
 >> +   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v")
 >> + 	(match_operand:V4SI 1 "input_operand" "v,m"))]
 >> +   "TARGET_ALTIVEC"
 >> +   "@
 >> +    stvx\t%1,%y0
 >> +    ldvx\t%0,%y1"
 >> +   [(set_attr "type" "altivec")])

 > Yes---this needs an alternative to copy a 'v' into a 'v'.  All the
 > ones below probably need it too.

Will do.

Aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 16:28       ` Aldy Hernandez
  2001-11-13  4:33         ` Aldy Hernandez
@ 2001-11-13 15:03         ` Aldy Hernandez
  1 sibling, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc patches

On Tue, 2001-11-06 at 18:14, Joseph S. Myers wrote:
> On 6 Nov 2001, Aldy Hernandez wrote:
> 
> > + the current ABI@
> 
> This sentence now seems to be missing its trailing ".".
> 

fixed.
> -- 
> Joseph S. Myers
> jsm28@cam.ac.uk
-- 
Aldy Hernandez			E-mail: aldyh@redhat.com
Professional Gypsy
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-06  0:23           ` Gerald Pfeifer
  2001-11-13  4:32             ` Gerald Pfeifer
@ 2001-11-13 15:03             ` Gerald Pfeifer
  1 sibling, 0 replies; 152+ messages in thread
From: Gerald Pfeifer @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: gcc-patches

On Mon, 5 Nov 2001, Alan Matsuoka wrote:
> 2001-11-05  Alan Matsuoka  <alanm@redhat.com>
>
>         * rtl.def (INCLUDE) : Define.
> 	* gensupport.c (init_include_reader, process_include, save_string) :  New functions to

This...

> 	  implement an include facility in .md files.
> 	* gensupport.h : Add prototype for init_md_reader_args.
> 	* genattr.c genattrtab.c gencodes.c genconfig.c genemit.c
> 	  genextract.c genflags.c genopinit.c genoutput.c genpeep.c
> 	  genrecog.c: Change call to init_md_reader to init_md_reader_args.
> 	* md.texi: Document (include "path") and -I directives for RTL generation tools.

...and this lines are to long.  (Lines in ChangeLogs and code should not
exceed, say, 77 characters, and definitely must not exceed 80 characters.)

There are a couple of similiar issues in the patch itself.

Gerald
-- 
Gerald "Jerry" pfeifer@dbai.tuwien.ac.at http://www.dbai.tuwien.ac.at/~pfeifer/


^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 15:29       ` Stan Shebs
  2001-11-13  4:32         ` Stan Shebs
@ 2001-11-13 15:03         ` Stan Shebs
  1 sibling, 0 replies; 152+ messages in thread
From: Stan Shebs @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Geoff Keating; +Cc: gcc-patches

Geoff Keating wrote:
> 
> > Our GCC just sets DWARF_FRAME_REGISTERS to FIRST_PSEUDO_REGISTERS
> > unconditionally, seems to work well enough for non-AltiVec code.
> 
> Can't do that; breaks backwards binary compatibility.  That's why
> DWARF_FRAME_REGISTERS was invented, so people could add registers
> without breaking binary compatibility.

Ah, I see what you're getting at.  So we'll move our definition
to darwin.h.

Stan

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 18:30   ` Aldy Hernandez
  2001-11-06 16:12     ` Daniel Jacobowitz
  2001-11-13  4:32     ` Aldy Hernandez
@ 2001-11-13 15:03     ` Aldy Hernandez
  2 siblings, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Dale Johannesen; +Cc: gcc patches, Geoff Keating

>>>>> "Dale" == Dale Johannesen <dalej@apple.com> writes:

 > This is getting better.

Thanks ;-)

 > I'd really like to see vrsave in the enums and register macros
 > (not necessarily the code).  I dislike making a major change to
 > an area if we know it's going to change again shortly.

That was supposed to be tommorrow's work.... :)

 > If you plan to support linking files compiled with and without
 > -fabi=altivec,

nope we don't.  You can't just link too different abi's.

 >> +       /* Print AltiVec memory operand.  */
 >> +     case 'y':
 >> +       {
 >> + 	rtx tmp;
 >> +
 >> + 	if (GET_CODE (x) != MEM)
 >> + 	  abort ();
 >> +
 >> + 	tmp = XEXP (x, 0);
 >> +
 >> + 	if (GET_CODE (tmp) == REG)
 >> + 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
 >> + 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
 >> + 	  {
 >> + 	    if (REGNO (XEXP (tmp, 0)) == 0)
 >> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
 >> + 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
 >> + 	    else
 >> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
 >> + 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
 >> + 	  }
 >> + 	else
 >> + 	  abort ();
 >> + 	break;
 >> +       }

 > I guess this is OK.  Apple/Moto version doesn't have any analogous change
 > here; the patterns in rs6000.md match more elaborate MEM subpatterns,
 > to do the checking that you do here.  Isn't it generally considered
 > preferable
 > to use the existing pattern mechanism whenever possible?

What I do is have some legitimize_address hackery that will transform
incorrect memory addresses into something altivec memory addressing
can handle (mem (plus reg reg)), and then handle [reg+reg] and [reg]
as the %y print operand.

I dislike the idea of having lots of variants of memory addressing in
the MD file.  It seems cleaner to have just memory_operand() and then
have %operands print them out pretty :).

Aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 18:22     ` Aldy Hernandez
  2001-11-05 18:28       ` Alan Matsuoka
  2001-11-13  4:32       ` Aldy Hernandez
@ 2001-11-13 15:03       ` Aldy Hernandez
  2 siblings, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: Geoff Keating, gcc-patches

>>>>> "Alan" == Alan Matsuoka <alanm@cygnus.com> writes:

 >> Do you really need this?  It looks just like the way a normal memory
 >> operand is printed (for the cases that are allowed for altivec).
 >> 
 >> > Index: rs6000.md
 >> 
 >> Can you put the altivec insns in their own .md file and use the include
 >> mechanism?  I believe this is what it was intended for.

Last i heard, alan matsuoka's include mechanism hadn't been approved.
Alan, perhaps you should send them again.  We definitely need them
now.

Aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 14:05 ` Dale Johannesen
                     ` (3 preceding siblings ...)
  2001-11-13  4:32   ` Dale Johannesen
@ 2001-11-13 15:03   ` Dale Johannesen
  4 siblings, 0 replies; 152+ messages in thread
From: Dale Johannesen @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Dale Johannesen, gcc patches, Geoff Keating

This is getting better.

On Monday, November 5, 2001, at 12:54 PM, Aldy Hernandez wrote:

> finally...
> what is left?
>     - the rest of the gazillion builtins
>
>     - varargs
>
>     - frame stuff: epilogue, prologue, vrsave
>     - <altivec.h> for the user.  this .h will implement the overloaded
>     altivec functions described in the "altivec programming interface
>     model".  Stuff like generic (overloaded) "vec_add(veca, vecb)".
>
>     - test cases.  i will commit a few simple tests, but serious tests
>     will come after i'm done playing with the G3 box.

I'd really like to see vrsave in the enums and register macros
(not necessarily the code).  I dislike making a major change to
an area if we know it's going to change again shortly.

>   /* Boundary (in *bits*) on which stack pointer should be aligned.  */
> ! #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 
> 128)

If you plan to support linking files compiled with and without 
-fabi=altivec,
shouldn't this be 128 unconditionally?  Otherwise the stack might not be
128-bit aligned when you enter an Altivec function.  Also in sysv4.h.

> *************** extern int rs6000_debug_arg;		/* debug a
> *** 757,762 ****
> --- 827,834 ----
>      (GET_MODE_CLASS (MODE) == MODE_FLOAT					\
>       || (GET_MODE_CLASS (MODE) == MODE_INT				\
>   	&& GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD))			\
> +    : ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_REGNO_P (REGNO)		\
> +    : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE)		\
>      : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC		\
>      : XER_REGNO_P (REGNO) ? (MODE) == PSImode				\
>      : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT		\

I don't think you want the first changed line here.

> *************** extern int rs6000_debug_arg;		/* debug a
> *** 788,793 ****
> --- 864,870 ----
>      ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2		\
>      : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10	\
>      : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10	\
> +    : (CLASS1) == ALTIVEC_REGS && (CLASS2) != ALTIVEC_REGS ? 20	\
>      : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS		\
>          || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS		\
>          || (CLASS1) == LINK_OR_CTR_REGS)				\

And here you need
	: (CLASS1) != ALTIVEC_REGS && (CLASS2) == ALTIVEC_REGS ? 20
analogous to the FLOAT case.

> *************** typedef struct rs6000_args
> *** 1778,1783 ****
> --- 1886,1892 ----
>     && GET_CODE (XEXP (X, 0)) == REG				\
>     && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT))		\
>     && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0)		\
> +   && ! ALTIVEC_VECTOR_MODE (MODE)				\
>     && (((MODE) != DFmode && (MODE) != DImode)			\
>         || (TARGET_32BIT						\
>   	  ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) 	\

That could be
	  && ( ! ALTIVEC_VECTOR_MODE (MODE) || INTVAL (X) == 0)
for better codegen.  It's not wrong as is, though.

> +
> +       /* Print AltiVec memory operand.  */
> +     case 'y':
> +       {
> + 	rtx tmp;
> +
> + 	if (GET_CODE (x) != MEM)
> + 	  abort ();
> +
> + 	tmp = XEXP (x, 0);
> +
> + 	if (GET_CODE (tmp) == REG)
> + 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
> + 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
> + 	  {
> + 	    if (REGNO (XEXP (tmp, 0)) == 0)
> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
> + 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
> + 	    else
> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
> + 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
> + 	  }
> + 	else
> + 	  abort ();
> + 	break;
> +       }

I guess this is OK.  Apple/Moto version doesn't have any analogous change
here; the patterns in rs6000.md match more elaborate MEM subpatterns,
to do the checking that you do here.  Isn't it generally considered 
preferable
to use the existing pattern mechanism whenever possible?

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 19:30       ` Aldy Hernandez
  2001-11-13  4:32         ` Aldy Hernandez
@ 2001-11-13 15:03         ` Aldy Hernandez
  1 sibling, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Geoff Keating; +Cc: Stan Shebs, gcc-patches

>>>>> "Geoff" == Geoff Keating <geoffk@geoffk.org> writes:

 > DWARF_FRAME_REGISTERS was invented, so people could add registers
 > without breaking binary compatibility.

But as it stands now it's value can't be dynamic-- say, with an abi
flag-- because it's value is used in places where it is expected to be
a constant (array sizes un unwind-dw2.c).

I will remedy this situation in another patch.

Aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 14:49     ` Geoff Keating
                         ` (2 preceding siblings ...)
  2001-11-13  4:32       ` Geoff Keating
@ 2001-11-13 15:03       ` Geoff Keating
  3 siblings, 0 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Stan Shebs; +Cc: gcc-patches

Stan Shebs <shebs@apple.com> writes:

> Geoff Keating wrote:
> > 
> > The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
> > quite right:  it has to happen _only when the ABI is 'altivec'_.
> > 
> > This will be a bit tricky because DWARF_FRAME_REGISTERS is also used
> > in libgcc, so you have to #define something when the Altivec ABI is
> > chosen, and then key off that if IN_LIBGCC2.
> 
> Thus we slide down the slippery slope... Solving this completely
> eventually entails having a method to detect whether the CPU
> supports AltiVec instructions - in the case of a C++ throw
> in code using AltiVec registers, you need to detect dynamically
> (Apple's GCC uses a bit set by the kernel) whether you're on a
> G4 or a not-G4.  So you may have to generate a frame descriptor
> that mentions registers you won't actually manipulate on a not-G4.

Unfortunately, such a method doesn't exist in many environments.  (In
particular, it's not in the powerpc UISA, which is all you can really
rely on in GCC.)

> Our GCC just sets DWARF_FRAME_REGISTERS to FIRST_PSEUDO_REGISTERS
> unconditionally, seems to work well enough for non-AltiVec code.

Can't do that; breaks backwards binary compatibility.  That's why
DWARF_FRAME_REGISTERS was invented, so people could add registers
without breaking binary compatibility.

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-05 18:49           ` Joseph S. Myers
  2001-11-05 19:03             ` Alan Matsuoka
  2001-11-13  4:32             ` Joseph S. Myers
@ 2001-11-13 15:03             ` Joseph S. Myers
  2 siblings, 0 replies; 152+ messages in thread
From: Joseph S. Myers @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: gcc-patches

On Mon, 5 Nov 2001, Alan Matsuoka wrote:

> + Where @var{pathname} is a string that specifies the the location of the file,
> + specifies the include file to be in gcc/config/{target}/filestuff. The

@file{gcc/config/@var{target}/filestuff}.

> + directory @file{ gcc/config/{target}} is regarded as the default directory.

No space after the open brace.  @var{target}.

> + the include file is specified to be in @file{gcc/config/{target}/BOGUS/filestuff}.

@var{target}.

> + The -I@var{dir} option specifies directories to search for machine descriptions.

@option{-I@var{dir}}.

> + @table @gcctabopt
> + @item -I@var{dir}
> + @opindex I

The option index is an index of GCC options, options for support tools
should not have @opindex index entries.

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 23:17   ` Richard Henderson
                       ` (2 preceding siblings ...)
  2001-11-13  4:33     ` Richard Henderson
@ 2001-11-13 15:03     ` Richard Henderson
  3 siblings, 0 replies; 152+ messages in thread
From: Richard Henderson @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Geoff Keating; +Cc: aldyh, gcc-patches

On Mon, Nov 05, 2001 at 01:58:06PM -0800, Geoff Keating wrote:
> > - #define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
> > + #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
> > - #define BIGGEST_ALIGNMENT 64
> > + #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)
> 
> I think you _don't_ want this to be dependent on the ABI.  Changing
> this isn't an ABI change (I hope!), which is good because...

Yes it is.  REGNO_POINTER_ALIGN(STACK_POINTER_REGNUM) == STACK_BOUNDARY.

Remember that STACK_BOUNDARY != PREFERRED_STACK_BOUNDARY, and that the
later does not help you unless you also have code to enforce stack
alignment, like we're supposed to have for x86 vector code.

> > ! /* A C expression to compute the alignment for a variables in the
> > !    local store.  TYPE is the data type, and ALIGN is the alignment
> > !    that the object would ordinarily have.  */
> > ! #define LOCAL_ALIGNMENT(TYPE, ALIGN)				\
> > ! 	((TARGET_ALTIVEC_ABI		    			\
> > ! 	  && TREE_CODE (TYPE)) == VECTOR_TYPE ? 128 : ALIGN)
> 
> ...as altivec values have to be 128-bit aligned because of the
> hardware, you don't want this ABI-dependent either.

Well, so long as you don't spill...  ;-)

> The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
> quite right:  it has to happen _only when the ABI is 'altivec'_.

I _think_ you don't have to worry about this any longer.  The ia64
eh library interface does not expose the number of registers
involved.  

We might ought to have checks added to die more gracefully if the
target adds registers, since we do statically allocate this space
and older libgcc would not be able to unwind for newer gcc code.



r~

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 14:05   ` Alan Matsuoka
  2001-11-05 18:22     ` Aldy Hernandez
  2001-11-13  4:32     ` Alan Matsuoka
@ 2001-11-13 15:03     ` Alan Matsuoka
  2 siblings, 0 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Geoff Keating; +Cc: aldyh, gcc-patches

> Do you really need this?  It looks just like the way a normal memory
> operand is printed (for the cases that are allowed for altivec).
> 
> > Index: rs6000.md
> 
> Can you put the altivec insns in their own .md file and use the include
> mechanism?  I believe this is what it was intended for.

Who does the approvals for my patches? I sent them out ages ago. I
guess I'd better do it again ....



> 
> > + ;; No code is needed to copy between vector registers.
> > + (define_insn "*altivec_vec_move"
> > +   [(set (match_operand 0 "altivec_register" "=v")
> > + 	(match_operand 1 "altivec_register" "v"))]
> > +   "TARGET_ALTIVEC"
> > +   ""
> > +   [(set_attr "type" "altivec")])
> 
> Um, that can't possibly be right.  Also, it should be part of
> movv4si_internal, because reload needs all the move insns to be the
> same pattern.
> 
> > + ;; Vector move instructions.
> > + (define_expand "movv4si"
> > +   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
> > + 	(match_operand:V4SI 1 "any_operand" ""))]
> > +   "TARGET_ALTIVEC"
> > +   "{ rs6000_emit_move (operands[0], operands[1], V4SImode); DONE; }")
> > + 
> > + (define_insn "*movv4si_internal"
> > +   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v")
> > + 	(match_operand:V4SI 1 "input_operand" "v,m"))]
> > +   "TARGET_ALTIVEC"
> > +   "@
> > +    stvx\t%1,%y0
> > +    ldvx\t%0,%y1"
> > +   [(set_attr "type" "altivec")])
> 
> Yes---this needs an alternative to copy a 'v' into a 'v'.  All the
> ones below probably need it too.
> 
> > + (define_expand "movv8hi"
> > +   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
> > + 	(match_operand:V8HI 1 "any_operand" ""))]
> > +   "TARGET_ALTIVEC"
> > +   "{ rs6000_emit_move (operands[0], operands[1], V8HImode); DONE; }")
> > + 
> > + (define_insn "*movv8hi_internal1"
> > +   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=m,v")
> > + 	(match_operand:V8HI 1 "input_operand" "v,m"))]
> > +   "TARGET_ALTIVEC"
> > +   "@
> > +    stvx\t%1,%y0
> > +    ldvx\t%0,%y1"
> > +   [(set_attr "type" "altivec")])
> > + 
> > + (define_expand "movv16qi"
> > +   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
> > + 	(match_operand:V16QI 1 "any_operand" ""))]
> > +   "TARGET_ALTIVEC"
> > +   "{ rs6000_emit_move (operands[0], operands[1], V16QImode); DONE; }")
> > + 
> > + (define_insn "*movv16qi_internal1"
> > +   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=m,v")
> > + 	(match_operand:V16QI 1 "input_operand" "v,m"))]
> > +   "TARGET_ALTIVEC"
> > +   "@
> > +    stvx\t%1,%y0
> > +    ldvx\t%0,%y1"
> > +   [(set_attr "type" "altivec")])
> > + 
> > + (define_expand "movv4sf"
> > +   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
> > + 	(match_operand:V4SF 1 "any_operand" ""))]
> > +   "TARGET_ALTIVEC"
> > +   "{ rs6000_emit_move (operands[0], operands[1], V4SFmode); DONE; }")
> > + 
> > + (define_insn "*movv4sf_internal1"
> > +   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=m,v")
> > + 	(match_operand:V4SF 1 "input_operand" "v,m"))]
> > +   "TARGET_ALTIVEC"
> > +   "@
> > +    stvx\t%1,%y0
> > +    ldvx\t%0,%y1"
> > +   [(set_attr "type" "altivec")])
> > + 
> > + ;; Simple binary operations.
> > + 
> > 
> > -- boring builtins deleted-- 
> > 
> > + (define_insn "altivec_vxor"
> > +   [(set (match_operand:V4SI 0 "register_operand" "=v")
> > +         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
> > +                       (match_operand:V4SI 2 "register_operand" "v")] 136))]
> > +   "TARGET_ALTIVEC"
> > +   "vxor\t%0,%1,%2"
> > +   [(set_attr "type" "altivec")])
> 
> -- 
> - Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>


Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-07 12:12         ` Geoff Keating
  2001-11-13  5:05           ` Geoff Keating
@ 2001-11-13 15:03           ` Geoff Keating
  1 sibling, 0 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-13 15:03 UTC (permalink / raw)
  To: rth; +Cc: aldyh, gcc-patches

> Date: Wed, 7 Nov 2001 11:41:11 -0800
> From: Richard Henderson <rth@redhat.com>
> Cc: aldyh@redhat.com, gcc-patches@gcc.gnu.org
> Mail-Followup-To: Richard Henderson <rth@redhat.com>,
> 	Geoff Keating <geoffk@redhat.com>, aldyh@redhat.com,
> 	gcc-patches@gcc.gnu.org
> Content-Disposition: inline
> User-Agent: Mutt/1.2.5i
> 
> On Wed, Nov 07, 2001 at 02:49:15AM -0800, Geoff Keating wrote:
> > Here I was talking about BIGGEST_ALIGNMENT only.  Changing
> > STACK_BOUNDARY is of course an ABI change.
> 
> Well, there is
> 
>   struct {
>     int x __attribute__((aligned));
>     int y;
>   };
> 
> to name one place that BIGGEST_ALIGNMENT affects the ABI.
> I suspect there are other places as well.

Hmmm.  Well, we'll see.

> > Can we really change the EH library interface like this?  Even in the
> > presence of a glibc compatibility layer to support pre-gcc3.0 C++
> > binaries?
> 
> Pre gcc 3.0, we don't support altivec, so we don't have to worry 
> about this.

Yes, but that's the question:  Can this be changed even for
non-altivec compilations?

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 17:07     ` Stan Shebs
  2001-11-06 17:15       ` Aldy Hernandez
  2001-11-13  4:33       ` Stan Shebs
@ 2001-11-13 15:03       ` Stan Shebs
  2 siblings, 0 replies; 152+ messages in thread
From: Stan Shebs @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Geoff Keating, gcc-patches

Aldy Hernandez wrote:
> 
> After a few iterations I think this is finally it-- for the first
> batch of patches anyhow.

It's all looking good to me, modulo the question below.

It would be ever so slightly more convenient for Apple's next import
if vrsave were to be listed ahead of the general vector registers
instead of after (it then becomes part of the "block" of misc regs),
but we can cope with it either way.

> --- 2562,2572 ----
>       "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",           \
>        "mq",  "lr", "ctr",  "ap",                                               \
>       "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",           \
> !   "xer",                                                              \
> !      "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",             \
> !      "v8",  "v9", "v10", "v11", "v12", "v13", "v14", "v15",             \
> !     "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",             \
> !     "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"              \
>   }

Missing a "vrsave" here?

Stan

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 17:06       ` Aldy Hernandez
  2001-11-13  4:33         ` Aldy Hernandez
@ 2001-11-13 15:03         ` Aldy Hernandez
  1 sibling, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Dale Johannesen; +Cc: Geoff Keating, gcc patches

> This needs an entry for vrsave.

yes i know.  i fixed them all.  they showed up during regression testing
and i fixed them all. am retesting bootstrap plus regressions right now.

> With these fixes I'll approve everything but the builtins, which I'm not
> planning to rule on either way.  You'll have to go through and change all
> the 'altivec' functional units later, but I guess you're aware of that.

yup.  i am aware.

feel free to approve then :-)

-- 
Aldy Hernandez			E-mail: aldyh@redhat.com
Professional Gypsy
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-13 15:03             ` Aldy Hernandez
  2001-11-13 15:03               ` Alan Matsuoka
@ 2001-11-13 15:03               ` Alan Matsuoka
  1 sibling, 0 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Geoff Keating, gcc-patches

On Wed, 14 Nov 2001, Aldy Hernandez wrote:

> >>>>> "Geoff" == Geoff Keating <geoffk@geoffk.org> writes:
> 
> alan can you provide an example on how to use this.  I want to move
> all the altivec stuff outside of the .md file.
> 

It's pretty simple.

My i386.md contains:


;; Scheduling
(include "sched.inc")
;; Compare instructions.
(include "compare.inc")


sched contains

(include "SCHED/part1.inc")
(include "SCHED/part2.inc")
(include "SCHED/part3.inc")
(include "SCHED/part4.inc")
(include "SCHED/part5.inc")

There is a subdirectory gcc/config/i386/SCHED
that contains part1.inc etc..

You can also specify the directories with -Ipathname as usual when you invoke
the gen* tools if you like.

Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-07  8:23     ` Aldy Hernandez
  2001-11-13  4:33       ` Aldy Hernandez
@ 2001-11-13 15:03       ` Aldy Hernandez
  1 sibling, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Geoff Keating, gcc patches

On Wed, 2001-11-07 at 02:16, Richard Henderson wrote:
> On Mon, Nov 05, 2001 at 01:58:06PM -0800, Geoff Keating wrote:
> > > - #define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
> > > + #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
> > > - #define BIGGEST_ALIGNMENT 64
> > > + #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)
> > 
> > I think you _don't_ want this to be dependent on the ABI.  Changing
> > this isn't an ABI change (I hope!), which is good because...
> 
> Yes it is.  REGNO_POINTER_ALIGN(STACK_POINTER_REGNUM) == STACK_BOUNDARY.

ok, i have reverted to my original code then:

#define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)

> > The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
> > quite right:  it has to happen _only when the ABI is 'altivec'_.
> 
> I _think_ you don't have to worry about this any longer.  The ia64
> eh library interface does not expose the number of registers
> involved.  
> 
> We might ought to have checks added to die more gracefully if the
> target adds registers, since we do statically allocate this space
> and older libgcc would not be able to unwind for newer gcc code.

so can i just up the # of DWARF_FRAME_REGISTERS without any bad side
effects?

-- 
Aldy Hernandez			E-mail: aldyh@redhat.com
Professional Gypsy
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 18:35   ` Aldy Hernandez
  2001-11-13  4:32     ` Aldy Hernandez
@ 2001-11-13 15:03     ` Aldy Hernandez
  1 sibling, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Dale Johannesen; +Cc: gcc patches, Geoff Keating

>>>>> "Dale" == Dale Johannesen <dalej@apple.com> writes:

 > On Monday, November 5, 2001, at 12:54 PM, Aldy Hernandez wrote:
 >> + /* Minimum and maximum AltiVec registers used to hold arguments.  */
 >> + #define ALTIVEC_ARG_MIN_REG 77
 >> + #define ALTIVEC_ARG_MAX_REG 88
 >> + #define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG -
 >> ALTIVEC_ARG_MIN_REG + 1)

 > Incidentally, on Darwin and I think some others, the vector param
 > regs are V2..V13, not V0..V11.  I guess this is ABI-dependent too.

Whoops.  You are right.  Fixed.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 14:39 ` Dale Johannesen
  2001-11-05 18:35   ` Aldy Hernandez
  2001-11-13  4:32   ` Dale Johannesen
@ 2001-11-13 15:03   ` Dale Johannesen
  2 siblings, 0 replies; 152+ messages in thread
From: Dale Johannesen @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Dale Johannesen, gcc patches, Geoff Keating

On Monday, November 5, 2001, at 12:54 PM, Aldy Hernandez wrote:
> + /* Minimum and maximum AltiVec registers used to hold arguments.  */
> + #define ALTIVEC_ARG_MIN_REG 77
> + #define ALTIVEC_ARG_MAX_REG 88
> + #define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG - ALTIVEC_ARG_MIN_REG 
> + 1)

Incidentally, on Darwin and I think some others, the vector param
regs are V2..V13, not V0..V11.  I guess this is ABI-dependent too.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-06  4:56                 ` Alan Matsuoka
  2001-11-06  7:58                   ` Alan Matsuoka
  2001-11-13  4:32                   ` Alan Matsuoka
@ 2001-11-13 15:03                   ` Alan Matsuoka
  2 siblings, 0 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc-patches

On Tue, 06 Nov 2001, Joseph S. Myers wrote:

> On Mon, 5 Nov 2001, Alan Matsuoka wrote:
> 
> > + Where @var{pathname} is a string that specifies the the location of the file,
> > + specifies the include file to be in gcc/config/{target}/filestuff. The
> 
> @file{gcc/config/@var{target}/filestuff}.
> 
> > + directory @file{gcc/config/{target}} is regarded as the default directory.
> 
> @var{target}.
> 
> Has this patch passed "make info" and "make dvi"?


I'll sumbit a revised patch as soon as the cvs server lets me
generate a patch.


Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 15:14     ` Joseph S. Myers
  2001-11-06 16:28       ` Aldy Hernandez
  2001-11-13  4:33       ` Joseph S. Myers
@ 2001-11-13 15:03       ` Joseph S. Myers
  2 siblings, 0 replies; 152+ messages in thread
From: Joseph S. Myers @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: gcc-patches

On 6 Nov 2001, Aldy Hernandez wrote:

> + the current ABI@

This sentence now seems to be missing its trailing ".".

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-06  1:03               ` Joseph S. Myers
  2001-11-06  4:56                 ` Alan Matsuoka
  2001-11-13  4:32                 ` Joseph S. Myers
@ 2001-11-13 15:03                 ` Joseph S. Myers
  2 siblings, 0 replies; 152+ messages in thread
From: Joseph S. Myers @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Alan Matsuoka; +Cc: gcc-patches

On Mon, 5 Nov 2001, Alan Matsuoka wrote:

> + Where @var{pathname} is a string that specifies the the location of the file,
> + specifies the include file to be in gcc/config/{target}/filestuff. The

@file{gcc/config/@var{target}/filestuff}.

> + directory @file{gcc/config/{target}} is regarded as the default directory.

@var{target}.

Has this patch passed "make info" and "make dvi"?

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 12:58 ` Aldy Hernandez
  2001-11-13  4:32   ` Aldy Hernandez
@ 2001-11-13 15:03   ` Aldy Hernandez
  1 sibling, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13 15:03 UTC (permalink / raw)
  To: gcc patches; +Cc: Geoff Keating

>>>>> "Aldy" == Aldy Hernandez <aldyh@redhat.com> writes:

 > what is left?

Oh yeah, and I also need to fill in pipeline info (altivec function
units, etc).

Aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-13 15:03             ` Aldy Hernandez
@ 2001-11-13 15:03               ` Alan Matsuoka
  2001-11-13 15:03               ` Alan Matsuoka
  1 sibling, 0 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Geoff Keating, gcc-patches

On Wed, 14 Nov 2001, Aldy Hernandez wrote:

> >>>>> "Geoff" == Geoff Keating <geoffk@geoffk.org> writes:
> 
> alan can you provide an example on how to use this.  I want to move
> all the altivec stuff outside of the .md file.


Thank's for reminding me to commit this stuff. I'll post  an example
sometime today when I get a chance. I've been preoccupied with another
port.


Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 15:02   ` Aldy Hernandez
                       ` (3 preceding siblings ...)
  2001-11-13  4:33     ` Aldy Hernandez
@ 2001-11-13 15:03     ` Aldy Hernandez
  4 siblings, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Geoff Keating; +Cc: gcc-patches

hi guys.

After a few iterations I think this is finally it-- for the first
batch of patches anyhow.

Geoff and I had a couple iterations in private to get the alignment
things sorted out, but everything that was suggested has been
implemented: vrsave in bit patterns, alignment, v=v move, etc etc.

I will be working on stack stuff (epilogue, prologue, stack frame,
vrsave) in the next couple days and I wanted to get these standalone
patches in first.

What is left?

        - stack stuff
        - DWARF_FRAME_REGISTERS (unwind-dw2.c work)
        - varargs
        - rest of builtins
        - function units
        - testcases

ok to install now?  I am bootstraping and checking for regressions
again-- assuming these are ok.

Aldy

2001-11-05  Aldy Hernandez  <aldyh@redhat.com>

	* doc/invoke.texi: Add -maltivec, -mno-altivec, and -mabi=altivec
	for rs6000.

	* config/rs6000/rs6000.h (MASK_ALTIVEC): New.
	(TARGET_ALTIVEC): New.
	(TARGET_SWITCHES): Add altivec.
	(FIRST_PSEUDO_REGISTER): Change to 109.
	(CALL_USED_REGISTERS): Same.
	(FIRST_ALTIVEC_REGNO): New.
	(LAST_ALTIVEC_REGNO): New.
	(ALTIVEC_REGNO_P): New.
	(UNITS_PER_ALTIVEC_WORD): New.
	(ALTIVEC_VECTOR_MODE): New.
	(FIXED_REGISTERS): Add altivec registers.
	(REG_ALLOC_ORDER): Same.
	(HARD_REGNO_NREGS): Adjust for altivec registers.
	(HARD_REGNO_MODE_OK): Same.
	(MODES_TIEABLE_P): Same.
	(REGISTER_MOVE_COST): Same.
	(REGNO_REG_CLASS): Same.
	(reg_class): Add ALTIVEC_REGS.
	(REG_CLASS_NAMES): Same.
	(REG_CLASS_CONTENTS): Same.
	(REG_CLASS_FROM_LETTER): Add 'v' constraint for ALTIVEC_REGS.
	(ALTIVEC_ARG_RETURN): New.
	(FUNCTION_VALUE): Handle VECTOR_TYPE.
	(LIBCALL_VALUE): Handle altivec vector modes.
	(VECTOR_MODE_SUPPORTED_P): New.
	(ALTIVEC_ARG_MIN_REG): New.
	(ALTIVEC_ARG_MAX_REG): New.
	(ALTIVEC_ARG_NUM_REG): New.
	(FUNCTION_VALUE_REGNO_P): Return true for altivec return register.
	(FUNCTION_ARG_REGNO_P): Support passing args in altivec registers.
	(REGISTER_NAMES): Add altivec regs.
	(DEBUG_REGISTER_NAMES): Same.
	(ADDITIONAL_REGISTER_NAMES): Same.
	(rs6000_builtins): New.
	(MD_EXPAND_BUILTIN): New.
	(MD_INIT_BUILTINS): New.
	(LEGITIMATE_OFFSET_ADDRESS_P): This addressing mode is not valid
	for AltiVec instructions.
	(LEGITIMATE_LO_SUM_ADDRESS_P): Same.
	(HARD_REGNO_MODE_OK): Altivec modes can only go in altivec
	registers.
	(SECONDARY_MEMORY_NEEDED): We need memory to copy vector modes.
	(TARGET_SWITCHES): Add no-altivec.
	(DATA_ALIGNMENT): Align vectors to 128 bits.
	(TARGET_OPTIONS): Add abi= option.
	Add rs6000_abi_string extern.
	(LOCAL_ALIGNMENT): New.
	(CPP_CPU_SPEC): Define __ALTIVEC__ when -maltivec.
	(MASK_ALTIVEC_ABI): New.
	(TARGET_ALTIVEC_ABI): New.
	(CONDITIONAL_REGISTER_USAGE): Set first 20 AltiVec registers to
	call-saved.
	(STACK_BOUNDARY): Adjust for altivec.
	(BIGGEST_ALIGNMENT): Same.
	(rs6000_args): Add vregno.
	(USE_ALTIVEC_FOR_ARG_P): New.
	(FIXED_REGISTERS): Add vrsave register.
	(CALL_USED_REGISTERS): Same.
	(CONDITIONAL_REGISTER_USAGE): Set VRSAVE info.
	(VRSAVE_REGNO): New.
	(reg_class): Add VRSAVE_REGS.
	(REG_CLASS_NAMES): Same.
	(REG_CLASS_CONTENTS): Same.
	(REGNO_REG_CLASS): Same.
	
	* config/rs6000/sysv4.h (STACK_BOUNDARY): Adjust for altivec.
	(ABI_STACK_BOUNDARY): Same.
	(BIGGEST_ALIGNMENT): Same.
	(ADJUST_FIELD_ALIGN): Remove undef.  Define anew.
	(ROUND_TYPE_ALIGN): Same.
	
	* config/rs6000/rs6000.c (rs6000_expand_builtin): New.
	(altivec_expand_builtin): New.
	(altivec_init_builtins): New.
	(TARGET_EXPAND_BUILTIN): New.
	(TARGET_INIT_BUILTINS): New.
	(rs6000_init_builtins): New.
	(struct builtin_description): New.
	(bdesc_2arg): New.
	(rs6000_reg_names): Add altivec registers.
	(alt_reg_names): Same.
	(secondary_reload_class): Altivec regs can hold altivec regs and
	memory.
	(rs6000_emit_move): Force constants into memory for AltiVec moves.
	(print_operand): Add 'y' case for printing altivec memory
	operands.
	(rs6000_legitimize_address): Legitimize vector addresses into
	[REG+REG] or [REG].
	(altivec_expand_binop_builtin): New.
	New string rs6000_current_abi.
	(rs6000_override_options): Call rs6000_parse_abi_options.
	(rs6000_parse_abi_options): New.
	(function_arg_boundary): Vector arguments must be 16
	byte aligned.
	(function_arg_advance): Handle vector arguments.
	(function_arg_partial_nregs): Same.
	(init_cumulative_args): Same.
	(function_arg): Same.

	* config/rs6000/rs6000.md (altivec_lvx): New.
	(type): Add altivec attribute.
	(movv4si): New.
	(*movv4si_internal): New.
	(movv16qi): New.
	(*movv16qi_internal): New.
	(movv8hi): New.
	(*movv8hi_internal1): New.
	(movv4sf): New.
	(*movv4sf_internal1): New.
	(altivec_stvx): New.
*builtins deleted*

	Index: doc/invoke.texi
===================================================================
RCS file: /cvs/uberbaum/gcc/doc/invoke.texi,v
retrieving revision 1.69
diff -c -p -r1.69 invoke.texi
*** invoke.texi	2001/10/28 19:12:12	1.69
--- invoke.texi	2001/11/06 22:24:35
*************** in the following sections.
*** 424,429 ****
--- 424,430 ----
  -mtune=@var{cpu-type} @gol
  -mpower  -mno-power  -mpower2  -mno-power2 @gol
  -mpowerpc  -mpowerpc64  -mno-powerpc @gol
+ -maltivec -mno-altivec @gol
  -mpowerpc-gpopt  -mno-powerpc-gpopt @gol
  -mpowerpc-gfxopt  -mno-powerpc-gfxopt @gol
  -mnew-mnemonics  -mold-mnemonics @gol
*************** in the following sections.
*** 436,441 ****
--- 437,443 ----
  -mno-relocatable  -mrelocatable-lib  -mno-relocatable-lib @gol
  -mtoc  -mno-toc -mlittle  -mlittle-endian  -mbig  -mbig-endian @gol
  -mcall-aix -mcall-sysv -mcall-netbsd @gol
+ -mabi=altivec @gol
  -mprototype  -mno-prototype @gol
  -msim  -mmvme  -mads  -myellowknife  -memb -msdata @gol
  -msdata=@var{opt}  -mvxworks -G @var{num}}
*************** values for @var{cpu_type} are used for @
*** 6677,6682 ****
--- 6679,6693 ----
  architecture, registers, and mnemonics set by @option{-mcpu}, but the
  scheduling parameters set by @option{-mtune}.
  
+ @item -maltivec
+ @itemx -mno-altivec
+ @opindex maltivec
+ @opindex mno-altivec
+ These switches enable or disable the use of built-in functions that
+ allow access to the AltiVec instruction set.  You may also need to set
+ @option{-mabi=altivec} to adjust the current ABI with AltiVec ABI
+ enhancements.
+ 
  @item -mfull-toc
  @itemx -mno-fp-in-toc
  @itemx -mno-sum-in-toc
*************** Linux-based GNU system.
*** 6904,6909 ****
--- 6915,6926 ----
  @opindex mcall-netbsd
  On System V.4 and embedded PowerPC systems compile code for the
  NetBSD operating system.
+ 
+ @item -mabi=altivec
+ @opindex mabi=altivec
+ Extend the current ABI with AltiVec ABI extensions.  This does not
+ change the default ABI, instead it adds the AltiVec ABI extensions to
+ the current ABI@
  
  @item -mprototype
  @itemx -mno-prototype
Index: rs6000.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.130
diff -c -p -r1.130 rs6000.h
*** rs6000.h	2001/10/02 03:36:44	1.130
--- rs6000.h	2001/11/06 22:24:41
*************** Boston, MA 02111-1307, USA.  */
*** 83,89 ****
  %{mcpu=801: -D_ARCH_PPC} \
  %{mcpu=821: -D_ARCH_PPC} \
  %{mcpu=823: -D_ARCH_PPC} \
! %{mcpu=860: -D_ARCH_PPC}"
  
  /* Common ASM definitions used by ASM_SPEC among the various targets
     for handling -mcpu=xxx switches.  */
--- 83,90 ----
  %{mcpu=801: -D_ARCH_PPC} \
  %{mcpu=821: -D_ARCH_PPC} \
  %{mcpu=823: -D_ARCH_PPC} \
! %{mcpu=860: -D_ARCH_PPC} \
! %{maltivec: -D__ALTIVEC__}"
  
  /* Common ASM definitions used by ASM_SPEC among the various targets
     for handling -mcpu=xxx switches.  */
*************** extern int target_flags;
*** 209,214 ****
--- 210,221 ----
  /* Nonzero if we need to schedule the prolog and epilog.  */
  #define MASK_SCHED_PROLOG	0x00040000
  
+ /* Use AltiVec instructions.  */
+ #define MASK_ALTIVEC		0x00080000
+ 
+ /* Enhance the current ABI with AltiVec extensions.  */
+ #define MASK_ALTIVEC_ABI	0x00100000
+ 
  #define TARGET_POWER		(target_flags & MASK_POWER)
  #define TARGET_POWER2		(target_flags & MASK_POWER2)
  #define TARGET_POWERPC		(target_flags & MASK_POWERPC)
*************** extern int target_flags;
*** 227,232 ****
--- 234,241 ----
  #define TARGET_NO_UPDATE	(target_flags & MASK_NO_UPDATE)
  #define TARGET_NO_FUSED_MADD	(target_flags & MASK_NO_FUSED_MADD)
  #define TARGET_SCHED_PROLOG	(target_flags & MASK_SCHED_PROLOG)
+ #define TARGET_ALTIVEC		(target_flags & MASK_ALTIVEC)
+ #define TARGET_ALTIVEC_ABI	(target_flags & MASK_ALTIVEC_ABI)
  
  #define TARGET_32BIT		(! TARGET_64BIT)
  #define TARGET_HARD_FLOAT	(! TARGET_SOFT_FLOAT)
*************** extern int target_flags;
*** 282,287 ****
--- 291,300 ----
  			N_("Use PowerPC-64 instruction set")},		\
    {"no-powerpc64",	- MASK_POWERPC64,				\
  			N_("Don't use PowerPC-64 instruction set")},	\
+   {"altivec",		MASK_ALTIVEC,					\
+ 			N_("Use AltiVec instructions.")},		\
+   {"no-altivec",	- MASK_ALTIVEC,					\
+ 			N_("Don't use AltiVec instructions.")},	\
    {"new-mnemonics",	MASK_NEW_MNEMONICS,				\
  			N_("Use new mnemonics for PowerPC architecture")},\
    {"old-mnemonics",	-MASK_NEW_MNEMONICS,				\
*************** extern enum processor_type rs6000_cpu;
*** 409,414 ****
--- 422,428 ----
     {"tune=", &rs6000_select[2].string,					\
      N_("Schedule code for given CPU") },				\
     {"debug=", &rs6000_debug_name, N_("Enable debug output") },		\
+    {"abi=", &rs6000_abi_string, N_("Specify ABI to use") },		\
     SUBTARGET_OPTIONS							\
  }
  
*************** struct rs6000_cpu_select
*** 424,430 ****
  extern struct rs6000_cpu_select rs6000_select[];
  
  /* Debug support */
! extern const char *rs6000_debug_name;		/* Name for -mdebug-xxxx option */
  extern int rs6000_debug_stack;		/* debug stack applications */
  extern int rs6000_debug_arg;		/* debug argument handling */
  
--- 438,445 ----
  extern struct rs6000_cpu_select rs6000_select[];
  
  /* Debug support */
! extern const char *rs6000_debug_name;	/* Name for -mdebug-xxxx option */
! extern const char *rs6000_abi_string;	/* for -mabi={sysv,darwin,solaris,eabi,aix,altivec} */
  extern int rs6000_debug_stack;		/* debug stack applications */
  extern int rs6000_debug_arg;		/* debug argument handling */
  
*************** extern int rs6000_debug_arg;		/* debug a
*** 505,510 ****
--- 520,526 ----
  #define UNITS_PER_WORD (! TARGET_POWERPC64 ? 4 : 8)
  #define MIN_UNITS_PER_WORD 4
  #define UNITS_PER_FP_WORD 8
+ #define UNITS_PER_ALTIVEC_WORD 16
  
  /* Type used for ptrdiff_t, as a string used in a declaration.  */
  #define PTRDIFF_TYPE "int"
*************** extern int rs6000_debug_arg;		/* debug a
*** 569,581 ****
  #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
  
  /* Boundary (in *bits*) on which stack pointer should be aligned.  */
! #define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
  
  /* Allocation boundary (in *bits*) for the code of a function.  */
  #define FUNCTION_BOUNDARY 32
  
  /* No data type wants to be aligned rounder than this.  */
! #define BIGGEST_ALIGNMENT 64
  
  /* Handle #pragma pack.  */
  #define HANDLE_PRAGMA_PACK 1
--- 585,604 ----
  #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
  
  /* Boundary (in *bits*) on which stack pointer should be aligned.  */
! #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
  
  /* Allocation boundary (in *bits*) for the code of a function.  */
  #define FUNCTION_BOUNDARY 32
  
  /* No data type wants to be aligned rounder than this.  */
! #define BIGGEST_ALIGNMENT 128
! 
! /* A C expression to compute the alignment for a variables in the
!    local store.  TYPE is the data type, and ALIGN is the alignment
!    that the object would ordinarily have.  */
! #define LOCAL_ALIGNMENT(TYPE, ALIGN)				\
! 	((TARGET_ALTIVEC		    			\
! 	  && TREE_CODE (TYPE)) == VECTOR_TYPE ? 128 : ALIGN)
  
  /* Handle #pragma pack.  */
  #define HANDLE_PRAGMA_PACK 1
*************** extern int rs6000_debug_arg;		/* debug a
*** 594,602 ****
    (TREE_CODE (EXP) == STRING_CST	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
! /* Make arrays of chars word-aligned for the same reasons.  */
  #define DATA_ALIGNMENT(TYPE, ALIGN)		\
!   (TREE_CODE (TYPE) == ARRAY_TYPE		\
     && TYPE_MODE (TREE_TYPE (TYPE)) == QImode	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
--- 617,627 ----
    (TREE_CODE (EXP) == STRING_CST	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
! /* Make arrays of chars word-aligned for the same reasons.
!    Align vectors to 128 bits.  */
  #define DATA_ALIGNMENT(TYPE, ALIGN)		\
!   (TREE_CODE (TYPE) == VECTOR_TYPE ? 128	\
!    : TREE_CODE (TYPE) == ARRAY_TYPE		\
     && TYPE_MODE (TREE_TYPE (TYPE)) == QImode	\
     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  
*************** extern int rs6000_debug_arg;		/* debug a
*** 634,643 ****
     a register, in order to work around problems in allocating stack storage
     in inline functions.  */
  
! #define FIRST_PSEUDO_REGISTER 77
  
  /* This must not decrease, for backwards compatibility.  If
     FIRST_PSEUDO_REGISTER increases, this should as well.  */
  #define DWARF_FRAME_REGISTERS 77
  
  /* 1 for registers that have pervasive standard uses
--- 659,670 ----
     a register, in order to work around problems in allocating stack storage
     in inline functions.  */
  
! #define FIRST_PSEUDO_REGISTER 110
  
  /* This must not decrease, for backwards compatibility.  If
     FIRST_PSEUDO_REGISTER increases, this should as well.  */
+ /* fixme: this needs to be defined to "TARGET_ALTIVEC_ABI ? 110 : 77"
+    and then fix usages of DWARF_FRAME_REGISTERS to work.  */
  #define DWARF_FRAME_REGISTERS 77
  
  /* 1 for registers that have pervasive standard uses
*************** extern int rs6000_debug_arg;		/* debug a
*** 655,661 ****
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1}
  
  /* 1 for registers not available across function calls.
     These must include the FIXED_REGISTERS and also any
--- 682,693 ----
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1,	   \
!    /* AltiVec registers.  */			   \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0						   \
! }
  
  /* 1 for registers not available across function calls.
     These must include the FIXED_REGISTERS and also any
*************** extern int rs6000_debug_arg;		/* debug a
*** 669,676 ****
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1}
  
  #define MQ_REGNO     64
  #define CR0_REGNO    68
  #define CR1_REGNO    69
--- 701,714 ----
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1,	   \
!    /* AltiVec registers.  */			   \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
!    0						   \
! }
  
+ 
  #define MQ_REGNO     64
  #define CR0_REGNO    68
  #define CR1_REGNO    69
*************** extern int rs6000_debug_arg;		/* debug a
*** 679,684 ****
--- 717,725 ----
  #define CR4_REGNO    72
  #define MAX_CR_REGNO 75
  #define XER_REGNO    76
+ #define FIRST_ALTIVEC_REGNO	77
+ #define LAST_ALTIVEC_REGNO	108
+ #define VRSAVE_REGNO		109
  
  /* List the order in which to allocate registers.  Each register must be
     listed once, even those in FIXED_REGISTERS.
*************** extern int rs6000_debug_arg;		/* debug a
*** 701,707 ****
  	mq		(not saved; best to use it if we can)
  	ctr		(not saved; when we have the choice ctr is better)
  	lr		(saved)
!         cr5, r1, r2, ap, xer (fixed)  */
  
  #define REG_ALLOC_ORDER					\
    {32, 							\
--- 742,757 ----
  	mq		(not saved; best to use it if we can)
  	ctr		(not saved; when we have the choice ctr is better)
  	lr		(saved)
!         cr5, r1, r2, ap, xer, vrsave (fixed)
! 
! 	AltiVec registers:
! 	v0 - v1         (not saved or used for anything)
! 	v13 - v3        (not saved; incoming vector arg registers)
! 	v2              (not saved; incoming vector arg reg; return value)
! 	v19 - v14       (not saved or used for anything)
! 	v31 - v20       (saved; order given to save least number)
! */
! 						
  
  #define REG_ALLOC_ORDER					\
    {32, 							\
*************** extern int rs6000_debug_arg;		/* debug a
*** 716,722 ****
     31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19,	\
     18, 17, 16, 15, 14, 13, 12,				\
     64, 66, 65, 						\
!    73, 1, 2, 67, 76}
  
  /* True if register is floating-point.  */
  #define FP_REGNO_P(N) ((N) >= 32 && (N) <= 63)
--- 766,779 ----
     31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19,	\
     18, 17, 16, 15, 14, 13, 12,				\
     64, 66, 65, 						\
!    73, 1, 2, 67, 76,					\
!    /* AltiVec registers.  */				\
!    77, 78,						\
!    90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80,		\
!    79,							\
!    96, 95, 94, 93, 92, 91,				\
!    108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97 \
! }
  
  /* True if register is floating-point.  */
  #define FP_REGNO_P(N) ((N) >= 32 && (N) <= 63)
*************** extern int rs6000_debug_arg;		/* debug a
*** 733,738 ****
--- 790,798 ----
  /* True if register is the XER register.  */
  #define XER_REGNO_P(N) ((N) == XER_REGNO)
  
+ /* True if register is an AltiVec register.  */
+ #define ALTIVEC_REGNO_P(N) ((N) >= FIRST_ALTIVEC_REGNO && (N) <= LAST_ALTIVEC_REGNO)
+ 
  /* Return number of consecutive hard regs needed starting at reg REGNO
     to hold something of mode MODE.
     This is ordinarily the length in words of a value of mode MODE
*************** extern int rs6000_debug_arg;		/* debug a
*** 744,751 ****
--- 804,826 ----
  #define HARD_REGNO_NREGS(REGNO, MODE)					\
    (FP_REGNO_P (REGNO)							\
     ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
+    : ALTIVEC_REGNO_P (REGNO)						\
+    ? ((GET_MODE_SIZE (MODE) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD) \
     : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
  
+ #define ALTIVEC_VECTOR_MODE(MODE)	\
+ 	((MODE) == V16QImode		\
+ 	 || (MODE) == V8HImode		\
+ 	 || (MODE) == V4SFmode		\
+ 	 || (MODE) == V4SImode)
+ 
+ /* Define this macro to be nonzero if the port is prepared to handle
+    insns involving vector mode MODE.  At the very least, it must have
+    move patterns for this mode.  */
+ 
+ #define VECTOR_MODE_SUPPORTED_P(MODE)	\
+ 	(TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE))
+ 
  /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
     For POWER and PowerPC, the GPRs can hold any mode, but the float
     registers only can hold floating modes and DImode, and CR register only
*************** extern int rs6000_debug_arg;		/* debug a
*** 757,762 ****
--- 832,838 ----
     (GET_MODE_CLASS (MODE) == MODE_FLOAT					\
      || (GET_MODE_CLASS (MODE) == MODE_INT				\
  	&& GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD))			\
+    : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE)		\
     : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC		\
     : XER_REGNO_P (REGNO) ? (MODE) == PSImode				\
     : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT		\
*************** extern int rs6000_debug_arg;		/* debug a
*** 776,781 ****
--- 852,861 ----
     ? GET_MODE_CLASS (MODE2) == MODE_CC		\
     : GET_MODE_CLASS (MODE2) == MODE_CC		\
     ? GET_MODE_CLASS (MODE1) == MODE_CC		\
+    : ALTIVEC_VECTOR_MODE (MODE1)		\
+    ? ALTIVEC_VECTOR_MODE (MODE2)		\
+    : ALTIVEC_VECTOR_MODE (MODE2)		\
+    ? ALTIVEC_VECTOR_MODE (MODE1)		\
     : 1)
  
  /* A C expression returning the cost of moving data from a register of class
*************** extern int rs6000_debug_arg;		/* debug a
*** 785,793 ****
     registers is expensive.  */
  
  #define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2)		\
!    ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2		\
     : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10	\
     : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10	\
     : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS		\
         || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS		\
         || (CLASS1) == LINK_OR_CTR_REGS)				\
--- 865,875 ----
     registers is expensive.  */
  
  #define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2)		\
!    ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2	\
     : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10	\
     : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10	\
+    : (CLASS1) == ALTIVEC_REGS && (CLASS2) != ALTIVEC_REGS ? 20	\
+    : (CLASS1) != ALTIVEC_REGS && (CLASS2) == ALTIVEC_REGS ? 20	\
     : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS		\
         || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS		\
         || (CLASS1) == LINK_OR_CTR_REGS)				\
*************** extern int rs6000_debug_arg;		/* debug a
*** 839,844 ****
--- 921,932 ----
      global_regs[PIC_OFFSET_TABLE_REGNUM]				\
        = fixed_regs[PIC_OFFSET_TABLE_REGNUM]				\
          = call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;			\
+   if (TARGET_ALTIVEC_ABI)						\
+     {									\
+       fixed_regs[VRSAVE_REGNO] = call_used_regs[VRSAVE_REGNO] = 1;	\
+       for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)	\
+         call_used_regs[i] = 1;						\
+     }									\
  }
  
  /* Specify the registers used for certain standard purposes.
*************** enum reg_class
*** 912,917 ****
--- 1000,1007 ----
    BASE_REGS,
    GENERAL_REGS,
    FLOAT_REGS,
+   ALTIVEC_REGS,
+   VRSAVE_REGS,
    NON_SPECIAL_REGS,
    MQ_REGS,
    LINK_REGS,
*************** enum reg_class
*** 937,942 ****
--- 1027,1034 ----
    "BASE_REGS",								\
    "GENERAL_REGS",							\
    "FLOAT_REGS",								\
+   "ALTIVEC_REGS",							\
+   "VRSAVE_REGS",							\
    "NON_SPECIAL_REGS",							\
    "MQ_REGS",								\
    "LINK_REGS",								\
*************** enum reg_class
*** 955,978 ****
     This is an initializer for a vector of HARD_REG_SET
     of length N_REG_CLASSES.  */
  
! #define REG_CLASS_CONTENTS						\
! {									\
!   { 0x00000000, 0x00000000, 0x00000000 },	/* NO_REGS */		\
!   { 0xfffffffe, 0x00000000, 0x00000008 },	/* BASE_REGS */		\
!   { 0xffffffff, 0x00000000, 0x00000008 },	/* GENERAL_REGS */	\
!   { 0x00000000, 0xffffffff, 0x00000000 },	/* FLOAT_REGS */	\
!   { 0xffffffff, 0xffffffff, 0x00000008 },	/* NON_SPECIAL_REGS */	\
!   { 0x00000000, 0x00000000, 0x00000001 },	/* MQ_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000002 },	/* LINK_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000004 },	/* CTR_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000006 },	/* LINK_OR_CTR_REGS */	\
!   { 0x00000000, 0x00000000, 0x00000007 },	/* SPECIAL_REGS */	\
!   { 0xffffffff, 0x00000000, 0x0000000f },	/* SPEC_OR_GEN_REGS */	\
!   { 0x00000000, 0x00000000, 0x00000010 },	/* CR0_REGS */		\
!   { 0x00000000, 0x00000000, 0x00000ff0 },	/* CR_REGS */		\
!   { 0xffffffff, 0x00000000, 0x0000ffff },	/* NON_FLOAT_REGS */	\
!   { 0x00000000, 0x00000000, 0x00010000 },	/* XER_REGS */		\
!   { 0xffffffff, 0xffffffff, 0x0001ffff }	/* ALL_REGS */		\
  }
  
  /* The same information, inverted:
--- 1047,1072 ----
     This is an initializer for a vector of HARD_REG_SET
     of length N_REG_CLASSES.  */
  
! #define REG_CLASS_CONTENTS						     \
! {									     \
!   { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */	     \
!   { 0xfffffffe, 0x00000000, 0x00000008, 0x00000000 }, /* BASE_REGS */	     \
!   { 0xffffffff, 0x00000000, 0x00000008, 0x00000000 }, /* GENERAL_REGS */     \
!   { 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FLOAT_REGS */       \
!   { 0x00000000, 0x00000000, 0xffffe000, 0x0001ffff }, /* ALTIVEC_REGS */     \
!   { 0x00000000, 0x00000000, 0x00000000, 0x00020000 }, /* VRSAVE_REGS */	     \
!   { 0xffffffff, 0xffffffff, 0x00000008, 0x00000000 }, /* NON_SPECIAL_REGS */ \
!   { 0x00000000, 0x00000000, 0x00000001, 0x00000000 }, /* MQ_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000002, 0x00000000 }, /* LINK_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000004, 0x00000000 }, /* CTR_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000006, 0x00000000 }, /* LINK_OR_CTR_REGS */ \
!   { 0x00000000, 0x00000000, 0x00000007, 0x00000000 }, /* SPECIAL_REGS */     \
!   { 0xffffffff, 0x00000000, 0x0000000f, 0x00000000 }, /* SPEC_OR_GEN_REGS */ \
!   { 0x00000000, 0x00000000, 0x00000010, 0x00000000 }, /* CR0_REGS */	     \
!   { 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */	     \
!   { 0xffffffff, 0x00000000, 0x0000ffff, 0x00000000 }, /* NON_FLOAT_REGS */   \
!   { 0x00000000, 0x00000000, 0x00010000, 0x00000000 }, /* XER_REGS */	     \
!   { 0xffffffff, 0xffffffff, 0xffffffff, 0x0001ffff }  /* ALL_REGS */	     \
  }
  
  /* The same information, inverted:
*************** enum reg_class
*** 984,989 ****
--- 1078,1084 ----
   ((REGNO) == 0 ? GENERAL_REGS			\
    : (REGNO) < 32 ? BASE_REGS			\
    : FP_REGNO_P (REGNO) ? FLOAT_REGS		\
+   : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_REGS	\
    : (REGNO) == CR0_REGNO ? CR0_REGS		\
    : CR_REGNO_P (REGNO) ? CR_REGS		\
    : (REGNO) == MQ_REGNO ? MQ_REGS		\
*************** enum reg_class
*** 991,996 ****
--- 1086,1092 ----
    : (REGNO) == COUNT_REGISTER_REGNUM ? CTR_REGS	\
    : (REGNO) == ARG_POINTER_REGNUM ? BASE_REGS	\
    : (REGNO) == XER_REGNO ? XER_REGS		\
+   : (REGNO) == VRSAVE_REGNO ? VRSAVE_REGS	\
    : NO_REGS)
  
  /* The class value for index registers, and the one for base regs.  */
*************** enum reg_class
*** 1006,1011 ****
--- 1102,1108 ----
     : (C) == 'q' ? MQ_REGS	\
     : (C) == 'c' ? CTR_REGS	\
     : (C) == 'l' ? LINK_REGS	\
+    : (C) == 'v' ? ALTIVEC_REGS	\
     : (C) == 'x' ? CR0_REGS	\
     : (C) == 'y' ? CR_REGS	\
     : (C) == 'z' ? XER_REGS	\
*************** enum reg_class
*** 1103,1113 ****
  #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
    secondary_reload_class (CLASS, MODE, IN)
  
! /* If we are copying between FP registers and anything else, we need a memory
!    location.  */
  
! #define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
!  ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS || (CLASS2) == FLOAT_REGS))
  
  /* Return the maximum number of consecutive registers
     needed to represent mode MODE in a register of class CLASS.
--- 1200,1213 ----
  #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
    secondary_reload_class (CLASS, MODE, IN)
  
! /* If we are copying between FP or AltiVec registers and anything
!    else, we need a memory location.  */
  
! #define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) 		\
!  ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS		\
! 			   || (CLASS2) == FLOAT_REGS		\
! 			   || (CLASS1) == ALTIVEC_REGS		\
! 			   || (CLASS2) == ALTIVEC_REGS))
  
  /* Return the maximum number of consecutive registers
     needed to represent mode MODE in a register of class CLASS.
*************** typedef struct rs6000_stack {
*** 1294,1309 ****
  		&& TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)	\
  	       || POINTER_TYPE_P (VALTYPE)			\
  	       ? word_mode : TYPE_MODE (VALTYPE),		\
! 	       TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT \
                 ? FP_ARG_RETURN : GP_ARG_RETURN)
  
  /* Define how to find the value returned by a library function
     assuming the value has mode MODE.  */
  
! #define LIBCALL_VALUE(MODE)					\
!   gen_rtx_REG (MODE, (GET_MODE_CLASS (MODE) == MODE_FLOAT	\
! 		      && TARGET_HARD_FLOAT			\
! 		      ? FP_ARG_RETURN : GP_ARG_RETURN))
  
  /* The definition of this macro implies that there are cases where
     a scalar value cannot be returned in registers.
--- 1394,1411 ----
  		&& TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)	\
  	       || POINTER_TYPE_P (VALTYPE)			\
  	       ? word_mode : TYPE_MODE (VALTYPE),		\
! 	       TREE_CODE (VALTYPE) == VECTOR_TYPE ? ALTIVEC_ARG_RETURN \
! 	       : TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT \
                 ? FP_ARG_RETURN : GP_ARG_RETURN)
  
  /* Define how to find the value returned by a library function
     assuming the value has mode MODE.  */
  
! #define LIBCALL_VALUE(MODE)						\
!   gen_rtx_REG (MODE, ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_ARG_RETURN	\
! 		     : GET_MODE_CLASS (MODE) == MODE_FLOAT		\
! 		     && TARGET_HARD_FLOAT				\
! 		     ? FP_ARG_RETURN : GP_ARG_RETURN)
  
  /* The definition of this macro implies that there are cases where
     a scalar value cannot be returned in registers.
*************** typedef struct rs6000_stack {
*** 1338,1346 ****
--- 1440,1454 ----
  			? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG)
  #define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1)
  
+ /* Minimum and maximum AltiVec registers used to hold arguments.  */
+ #define ALTIVEC_ARG_MIN_REG (FIRST_ALTIVEC_REGNO + 2)
+ #define ALTIVEC_ARG_MAX_REG (ALTIVEC_ARG_MIN_REG + 11)
+ #define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG - ALTIVEC_ARG_MIN_REG + 1)
+ 
  /* Return registers */
  #define GP_ARG_RETURN GP_ARG_MIN_REG
  #define FP_ARG_RETURN FP_ARG_MIN_REG
+ #define ALTIVEC_ARG_RETURN (FIRST_ALTIVEC_REGNO + 2)
  
  /* Flags for the call/call_value rtl operations set up by function_arg */
  #define CALL_NORMAL		0x00000000	/* no special processing */
*************** typedef struct rs6000_stack {
*** 1352,1364 ****
  /* 1 if N is a possible register number for a function value
     as seen by the caller.
  
!    On RS/6000, this is r3 and fp1.  */
! #define FUNCTION_VALUE_REGNO_P(N)  ((N) == GP_ARG_RETURN || ((N) == FP_ARG_RETURN))
  
  /* 1 if N is a possible register number for function argument passing.
     On RS/6000, these are r3-r10 and fp1-fp13.  */
  #define FUNCTION_ARG_REGNO_P(N)						\
    ((unsigned)(((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG))	\
     || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))
  
  \f
--- 1460,1477 ----
  /* 1 if N is a possible register number for a function value
     as seen by the caller.
  
!    On RS/6000, this is r3, fp1, and v2 (for AltiVec).  */
! #define FUNCTION_VALUE_REGNO_P(N)  ((N) == GP_ARG_RETURN	\
! 				    || ((N) == FP_ARG_RETURN)	\
! 				    || (TARGET_ALTIVEC &&	\
! 					(N) == ALTIVEC_ARG_RETURN))
  
  /* 1 if N is a possible register number for function argument passing.
     On RS/6000, these are r3-r10 and fp1-fp13.  */
  #define FUNCTION_ARG_REGNO_P(N)						\
    ((unsigned)(((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG))	\
+    || (TARGET_ALTIVEC &&						\
+        (unsigned)((N) - ALTIVEC_ARG_MIN_REG) < (unsigned)(ALTIVEC_ARG_MAX_REG)) \
     || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))
  
  \f
*************** typedef struct rs6000_args
*** 1394,1399 ****
--- 1507,1513 ----
  {
    int words;			/* # words used for passing GP registers */
    int fregno;			/* next available FP register */
+   int vregno;			/* next available AltiVec register */
    int nargs_prototype;		/* # args left in the current prototype */
    int orig_nargs;		/* Original value of nargs_prototype */
    int prototype;		/* Whether a prototype was defined */
*************** typedef struct rs6000_args
*** 1436,1441 ****
--- 1550,1561 ----
     && (CUM).fregno <= FP_ARG_MAX_REG    \
     && TARGET_HARD_FLOAT)
  
+ /* Non-zero if we can use an AltiVec register to pass this arg.  */
+ #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE)	\
+   (ALTIVEC_VECTOR_MODE (MODE)			\
+    && (CUM).vregno <= ALTIVEC_ARG_MAX_REG	\
+    && TARGET_ALTIVEC_ABI)
+ 
  /* Determine where to put an argument to a function.
     Value is zero to push the argument on the stack,
     or a hard register in which to store the argument.
*************** typedef struct rs6000_args
*** 1778,1783 ****
--- 1898,1904 ----
    && GET_CODE (XEXP (X, 0)) == REG				\
    && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT))		\
    && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0)		\
+   && (! ALTIVEC_VECTOR_MODE (MODE) || INTVAL (X) == 0)		\
    && (((MODE) != DFmode && (MODE) != DImode)			\
        || (TARGET_32BIT						\
  	  ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) 	\
*************** typedef struct rs6000_args
*** 1805,1810 ****
--- 1926,1932 ----
     && ! flag_pic && ! TARGET_TOC				\
     && (MODE) != DImode						\
     && (MODE) != TImode						\
+    && ! ALTIVEC_VECTOR_MODE (MODE)				\
     && (TARGET_HARD_FLOAT || (MODE) != DFmode)			\
     && GET_CODE (X) == LO_SUM					\
     && GET_CODE (XEXP (X, 0)) == REG				\
*************** extern char rs6000_reg_names[][8];	/* re
*** 2389,2394 ****
--- 2511,2549 ----
    &rs6000_reg_names[75][0],	/* cr7  */				\
  									\
    &rs6000_reg_names[76][0],	/* xer  */				\
+ 									\
+   &rs6000_reg_names[77][0],	/* v0  */				\
+   &rs6000_reg_names[78][0],	/* v1  */				\
+   &rs6000_reg_names[79][0],	/* v2  */				\
+   &rs6000_reg_names[80][0],	/* v3  */				\
+   &rs6000_reg_names[81][0],	/* v4  */				\
+   &rs6000_reg_names[82][0],	/* v5  */				\
+   &rs6000_reg_names[83][0],	/* v6  */				\
+   &rs6000_reg_names[84][0],	/* v7  */				\
+   &rs6000_reg_names[85][0],	/* v8  */				\
+   &rs6000_reg_names[86][0],	/* v9  */				\
+   &rs6000_reg_names[87][0],	/* v10  */				\
+   &rs6000_reg_names[88][0],	/* v11  */				\
+   &rs6000_reg_names[89][0],	/* v12  */				\
+   &rs6000_reg_names[90][0],	/* v13  */				\
+   &rs6000_reg_names[91][0],	/* v14  */				\
+   &rs6000_reg_names[92][0],	/* v15  */				\
+   &rs6000_reg_names[93][0],	/* v16  */				\
+   &rs6000_reg_names[94][0],	/* v17  */				\
+   &rs6000_reg_names[95][0],	/* v18  */				\
+   &rs6000_reg_names[96][0],	/* v19  */				\
+   &rs6000_reg_names[97][0],	/* v20  */				\
+   &rs6000_reg_names[98][0],	/* v21  */				\
+   &rs6000_reg_names[99][0],	/* v22  */				\
+   &rs6000_reg_names[100][0],	/* v23  */				\
+   &rs6000_reg_names[101][0],	/* v24  */				\
+   &rs6000_reg_names[102][0],	/* v25  */				\
+   &rs6000_reg_names[103][0],	/* v26  */				\
+   &rs6000_reg_names[104][0],	/* v27  */				\
+   &rs6000_reg_names[105][0],	/* v28  */				\
+   &rs6000_reg_names[106][0],	/* v29  */				\
+   &rs6000_reg_names[107][0],	/* v30  */				\
+   &rs6000_reg_names[108][0],	/* v31  */				\
  }
  
  /* print-rtl can't handle the above REGISTER_NAMES, so define the
*************** extern char rs6000_reg_names[][8];	/* re
*** 2407,2413 ****
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",		\
       "mq",  "lr", "ctr",  "ap",						\
      "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",		\
!   "xer"									\
  }
  
  /* Table of additional register names to use in user input.  */
--- 2562,2572 ----
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",		\
       "mq",  "lr", "ctr",  "ap",						\
      "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",		\
!   "xer",								\
!      "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",             \
!      "v8",  "v9", "v10", "v11", "v12", "v13", "v14", "v15",             \
!     "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",             \
!     "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"              \
  }
  
  /* Table of additional register names to use in user input.  */
*************** extern char rs6000_reg_names[][8];	/* re
*** 2429,2434 ****
--- 2588,2601 ----
    {"fr20", 52}, {"fr21", 53}, {"fr22", 54}, {"fr23", 55},	\
    {"fr24", 56}, {"fr25", 57}, {"fr26", 58}, {"fr27", 59},	\
    {"fr28", 60}, {"fr29", 61}, {"fr30", 62}, {"fr31", 63},	\
+   {"v0",   77}, {"v1",   78}, {"v2",   79}, {"v3",   80},       \
+   {"v4",   81}, {"v5",   82}, {"v6",   83}, {"v7",   84},       \
+   {"v8",   85}, {"v9",   86}, {"v10",  87}, {"v11",  88},       \
+   {"v12",  89}, {"v13",  90}, {"v14",  91}, {"v15",  92},       \
+   {"v16",  93}, {"v17",  94}, {"v18",  95}, {"v19",  96},       \
+   {"v20",  97}, {"v21",  98}, {"v22",  99}, {"v23",  100},	\
+   {"v24",  101},{"v25",  102},{"v26",  103},{"v27",  104},      \
+   {"v28",  105},{"v29",  106},{"v30",  107},{"v31",  108},      \
    /* no additional names for: mq, lr, ctr, ap */		\
    {"cr0",  68}, {"cr1",  69}, {"cr2",  70}, {"cr3",  71},	\
    {"cr4",  72}, {"cr5",  73}, {"cr6",  74}, {"cr7",  75},	\
*************** extern int flag_pic;
*** 2629,2631 ****
--- 2796,2911 ----
  extern int optimize;
  extern int flag_expensive_optimizations;
  extern int frame_pointer_needed;
+ 
+ enum rs6000_builtins
+ {
+   /* AltiVec builtins.  */
+   ALTIVEC_BUILTIN_ST_INTERNAL,

*builtins deleted*

+ };
Index: sysv4.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/sysv4.h,v
retrieving revision 1.67
diff -c -p -r1.67 sysv4.h
*** sysv4.h	2001/10/29 23:09:43	1.67
--- sysv4.h	2001/11/06 22:24:42
*************** do {									\
*** 400,417 ****
     one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
     versions, just use 64 as the stack boundary.  */
  #undef	STACK_BOUNDARY
! #define	STACK_BOUNDARY	64
  
  /* Real stack boundary as mandated by the appropriate ABI.  */
! #define ABI_STACK_BOUNDARY ((TARGET_EABI) ? 64 : 128)
  
  /* No data type wants to be aligned rounder than this.  */
  #undef	BIGGEST_ALIGNMENT
! #define BIGGEST_ALIGNMENT ((TARGET_EABI) ? 64 : 128)
  
  #undef  BIGGEST_FIELD_ALIGNMENT
  #undef  ADJUST_FIELD_ALIGN
- #undef  ROUND_TYPE_ALIGN
  
  /* Use ELF style section commands.  */
  
--- 400,430 ----
     one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
     versions, just use 64 as the stack boundary.  */
  #undef	STACK_BOUNDARY
! #define	STACK_BOUNDARY	(TARGET_ALTIVEC_ABI ? 128 : 64)
  
  /* Real stack boundary as mandated by the appropriate ABI.  */
! #define ABI_STACK_BOUNDARY ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
  
  /* No data type wants to be aligned rounder than this.  */
  #undef	BIGGEST_ALIGNMENT
! #define BIGGEST_ALIGNMENT (TARGET_EABI ? 64 : 128)
  
+ /* An expression for the alignment of a structure field FIELD if the
+    alignment computed in the usual way is COMPUTED.  */
+ #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)				      \
+ 	((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE)     \
+ 	 ? 128 : COMPUTED)
+ 
+ /* Define this macro as an expression for the alignment of a type
+    (given by TYPE as a tree node) if the alignment computed in the
+    usual way is COMPUTED and the alignment explicitly specified was
+    SPECIFIED.  */
+ #define ROUND_TYPE_ALIGN(TYPE, COMPUTED, SPECIFIED)			\
+ 	((TARGET_ALTIVEC  && TREE_CODE (TYPE) == VECTOR_TYPE)	        \
+ 	 ? 128 : MAX (COMPUTED, SPECIFIED))
+ 
  #undef  BIGGEST_FIELD_ALIGNMENT
  #undef  ADJUST_FIELD_ALIGN
  
  /* Use ELF style section commands.  */
  
Index: rs6000.c
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.224
diff -c -p -r1.224 rs6000.c
*** rs6000.c	2001/10/31 14:08:09	1.224
--- rs6000.c	2001/11/06 22:24:45
*************** int fixuplabelno = 0;
*** 96,101 ****
--- 96,104 ----
  /* ABI enumeration available for subtarget to use.  */
  enum rs6000_abi rs6000_current_abi;
  
+ /* ABI string from -mabi= option.  */
+ const char *rs6000_abi_string;
+ 
  /* Debug flags */
  const char *rs6000_debug_name;
  int rs6000_debug_stack;		/* debug stack applications */
*************** static int rs6000_adjust_cost PARAMS ((r
*** 146,151 ****
--- 149,161 ----
  static int rs6000_adjust_priority PARAMS ((rtx, int));
  static int rs6000_issue_rate PARAMS ((void));
  
+ static void rs6000_init_builtins PARAMS ((tree));
+ static void altivec_init_builtins PARAMS ((void));
+ static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
+ static rtx altivec_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
+ static rtx altivec_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
+ 
+ static void rs6000_parse_abi_options PARAMS ((void));
  \f
  /* Default register names.  */
  char rs6000_reg_names[][8] =
*************** char rs6000_reg_names[][8] =
*** 160,166 ****
       "24", "25", "26", "27", "28", "29", "30", "31",
       "mq", "lr", "ctr","ap",
        "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
!       "xer"
  };
  
  #ifdef TARGET_REGNAMES
--- 170,181 ----
       "24", "25", "26", "27", "28", "29", "30", "31",
       "mq", "lr", "ctr","ap",
        "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
!       "xer",
!       /* AltiVec registers.  */
!       "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6", "v7",
!       "v8",  "v9",  "v10", "v11", "v12", "v13", "v14", "v15",
!       "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
!       "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
  };
  
  #ifdef TARGET_REGNAMES
*************** static const char alt_reg_names[][8] =
*** 176,182 ****
    "%f24",  "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
      "mq",    "lr",  "ctr",   "ap",
    "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
!   "xer"
  };
  #endif
  \f
--- 191,202 ----
    "%f24",  "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
      "mq",    "lr",  "ctr",   "ap",
    "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
!    "xer",
!    /* AltiVec registers.  */
!    "%v0",  "%v1",  "%v2",  "%v3",  "%v4",  "%v5",  "%v6", "%v7",
!    "%v8",  "%v9",  "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
!    "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
!    "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31"
  };
  #endif
  \f
*************** static const char alt_reg_names[][8] =
*** 205,210 ****
--- 225,236 ----
  #undef TARGET_SCHED_ADJUST_PRIORITY
  #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
  
+ #undef TARGET_INIT_BUILTINS
+ #define TARGET_INIT_BUILTINS rs6000_init_builtins
+ 
+ #undef TARGET_EXPAND_BUILTIN
+ #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
+ 
  struct gcc_target targetm = TARGET_INITIALIZER;
  \f
  /* Override command line options.  Mostly we process the processor
*************** rs6000_override_options (default_cpu)
*** 438,443 ****
--- 464,472 ----
  	error ("Unknown -mdebug-%s switch", rs6000_debug_name);
      }
  
+   /* Handle -mabi= options.  */
+   rs6000_parse_abi_options ();
+ 
  #ifdef TARGET_REGNAMES
    /* If the user desires alternate register names, copy in the
       alternate names now.  */
*************** rs6000_override_options (default_cpu)
*** 463,468 ****
--- 492,508 ----
    free_machine_status = rs6000_free_machine_status;
  }
  
+ /* Handle -mabi= options.  */
+ void rs6000_parse_abi_options ()
+ {
+   if (rs6000_abi_string == 0)
+     return;
+   else if (! strcmp (rs6000_abi_string, "altivec"))
+     target_flags |= MASK_ALTIVEC_ABI;
+   else
+     error ("Unknown ABI specified: '%s'", rs6000_abi_string);
+ }
+ 
  void
  optimization_options (level, size)
       int level ATTRIBUTE_UNUSED;
*************** rs6000_legitimize_address (x, oldx, mode
*** 1544,1550 ****
       rtx x;
       rtx oldx ATTRIBUTE_UNUSED;
       enum machine_mode mode;
! { 
    if (GET_CODE (x) == PLUS 
        && GET_CODE (XEXP (x, 0)) == REG
        && GET_CODE (XEXP (x, 1)) == CONST_INT
--- 1584,1590 ----
       rtx x;
       rtx oldx ATTRIBUTE_UNUSED;
       enum machine_mode mode;
! {
    if (GET_CODE (x) == PLUS 
        && GET_CODE (XEXP (x, 0)) == REG
        && GET_CODE (XEXP (x, 1)) == CONST_INT
*************** rs6000_legitimize_address (x, oldx, mode
*** 1570,1575 ****
--- 1610,1627 ----
        return gen_rtx_PLUS (Pmode, XEXP (x, 0),
  			   force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
      }
+   else if (ALTIVEC_VECTOR_MODE (mode))
+     {
+       rtx reg;
+ 
+       /* Make sure both operands are registers.  */
+       if (GET_CODE (x) == PLUS)
+ 	return gen_rtx_PLUS (Pmode, XEXP (x, 0),
+ 			     force_reg (Pmode, XEXP (x, 1)));
+ 
+       reg = force_reg (Pmode, x);
+       return reg;
+     }
    else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic
  	   && GET_CODE (x) != CONST_INT
  	   && GET_CODE (x) != CONST_DOUBLE 
*************** rs6000_emit_move (dest, source, mode)
*** 1862,1867 ****
--- 1914,1928 ----
  	operands[1] = force_const_mem (mode, operands[1]);
        break;
        
+     case V16QImode:
+     case V8HImode:
+     case V4SFmode:
+     case V4SImode:
+       /* fixme: aldyh -- allow vector constants when they are implemented.  */
+       if (CONSTANT_P (operands[1]))
+ 	operands[1] = force_const_mem (mode, operands[1]);
+       break;
+       
      case SImode:
      case DImode:
        /* Use default pattern for address of ELF small data */
*************** init_cumulative_args (cum, fntype, libna
*** 2062,2067 ****
--- 2123,2129 ----
    *cum = zero_cumulative;
    cum->words = 0;
    cum->fregno = FP_ARG_MIN_REG;
+   cum->vregno = ALTIVEC_ARG_MIN_REG;
    cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
    cum->call_cookie = CALL_NORMAL;
    cum->sysv_gregno = GP_ARG_MIN_REG;
*************** function_arg_boundary (mode, type)
*** 2142,2147 ****
--- 2204,2211 ----
    if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
        && (mode == DImode || mode == DFmode))
      return 64;
+   else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
+     return 128;
    else
      return PARM_BOUNDARY;
  }
*************** function_arg_advance (cum, mode, type, n
*** 2159,2165 ****
  {
    cum->nargs_prototype--;
  
!   if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
--- 2223,2236 ----
  {
    cum->nargs_prototype--;
  
!   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
!     {
!       if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
! 	cum->vregno++;
!       else
! 	cum->words += RS6000_ARG_SIZE (mode, type);
!     }
!   else if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
*************** function_arg (cum, mode, type, named)
*** 2287,2293 ****
        return GEN_INT (cum->call_cookie);
      }
  
!   if (abi == ABI_V4 || abi == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
--- 2358,2371 ----
        return GEN_INT (cum->call_cookie);
      }
  
!   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
!     {
!       if (cum->vregno <= ALTIVEC_ARG_MAX_REG)
! 	return gen_rtx_REG (mode, cum->vregno);
!       else
! 	return NULL;
!     }
!   else if (abi == ABI_V4 || abi == ABI_SOLARIS)
      {
        if (TARGET_HARD_FLOAT
  	  && (mode == SFmode || mode == DFmode))
*************** function_arg_partial_nregs (cum, mode, t
*** 2382,2388 ****
    if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      return 0;
  
!   if (USE_FP_FOR_ARG_P (*cum, mode, type))
      {
        if (cum->nargs_prototype >= 0)
  	return 0;
--- 2460,2467 ----
    if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      return 0;
  
!   if (USE_FP_FOR_ARG_P (*cum, mode, type)
!       || USE_ALTIVEC_FOR_ARG_P (*cum, mode, type))
      {
        if (cum->nargs_prototype >= 0)
  	return 0;
*************** rs6000_va_arg (valist, type)
*** 2838,2843 ****
--- 2917,3392 ----
  
    return addr_rtx;
  }
+ 
+ /* Builtins.  */
+ 
+ #define def_builtin(MASK, NAME, TYPE, CODE)				\
+ do {									\
+   if ((MASK) & target_flags)						\
+     builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL);	\
+ } while (0)
+ 
+ struct builtin_description
+ {
+   const unsigned int mask;
+   const enum insn_code icode;
+   const char *const name;
+   const enum rs6000_builtins code;
+ };
+ 
+ /* Simple binary operatiors: VECc = foo (VECa, VECb).  */
+ static const struct builtin_description bdesc_2arg[] =
+ {
+   { MASK_ALTIVEC, CODE_FOR_altivec_vaddubm, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },

*builtins deleted*

+ };
+ 
+ static rtx
+ altivec_expand_binop_builtin (icode, arglist, target)
+      enum insn_code icode;
+      tree arglist;
+      rtx target;
+ {
+   rtx pat;
+   tree arg0 = TREE_VALUE (arglist);
+   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+   rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+   rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+   enum machine_mode tmode = insn_data[icode].operand[0].mode;
+   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
+   enum machine_mode mode1 = insn_data[icode].operand[2].mode;
+ 
+   if (! target
+       || GET_MODE (target) != tmode
+       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+     target = gen_reg_rtx (tmode);
+ 
+   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+     op0 = copy_to_mode_reg (mode0, op0);
+   if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
+     op1 = copy_to_mode_reg (mode1, op1);
+ 
+   pat = GEN_FCN (icode) (target, op0, op1);
+   if (! pat)
+     return 0;
+   emit_insn (pat);
+ 
+   return target;
+ }
+ 
+ static rtx
+ altivec_expand_builtin (exp, target, subtarget, mode, ignore)
+      tree exp;
+      rtx target;
+      rtx subtarget;
+      enum machine_mode mode;
+      int ignore;
+ {
+   struct builtin_description *d;
+   size_t i;
+   enum insn_code icode;
+   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
+   tree arglist = TREE_OPERAND (exp, 1);
+   tree arg0, arg1, arg2, arg3;
+   rtx op0, op1, op2, pat;
+   enum machine_mode tmode, mode0, mode1, mode2;
+   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+   
+   switch (fcode)
+     {
+     case ALTIVEC_BUILTIN_LD_INTERNAL:
+       icode = CODE_FOR_altivec_lvx;
+       arg0 = TREE_VALUE (arglist);
+       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+       tmode = insn_data[icode].operand[0].mode;
+       mode0 = insn_data[icode].operand[1].mode;
+ 
+       if (! target
+ 	  || GET_MODE (target) != tmode
+ 	  || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ 	target = gen_reg_rtx (tmode);
+ 
+       if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+ 	op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
+ 
+       pat = GEN_FCN (icode) (target, op0);
+       if (! pat)
+ 	return 0;
+       emit_insn (pat);
+       return target;
+ 
+     case ALTIVEC_BUILTIN_ST_INTERNAL:
+       icode = CODE_FOR_altivec_stvx;
+       arg0 = TREE_VALUE (arglist);
+       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+       op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+       mode0 = insn_data[icode].operand[0].mode;
+       mode1 = insn_data[icode].operand[1].mode;
+ 
+       if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
+ 	op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
+       if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
+ 	op1 = copy_to_mode_reg (mode1, op1);
+ 
+       pat = GEN_FCN (icode) (op0, op1);
+       if (! pat)
+ 	return 0;
+       emit_insn (pat);
+       return NULL_RTX;
+     }
+ 
+   /* Handle simple binary operations.  */
+   for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
+     if (d->code == fcode)
+       return altivec_expand_binop_builtin (d->icode, arglist, target);
+ 
+   abort ();
+   return NULL_RTX;
+ }
+ 
+ /* Expand an expression EXP that calls a built-in function,
+    with result going to TARGET if that's convenient
+    (and in mode MODE if that's convenient).
+    SUBTARGET may be used as the target for computing one of EXP's operands.
+    IGNORE is nonzero if the value is to be ignored.  */
+ 
+ static rtx
+ rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
+      tree exp;
+      rtx target;
+      rtx subtarget;
+      enum machine_mode mode;
+      int ignore;
+ {
+   if (TARGET_ALTIVEC)
+     return altivec_expand_builtin (exp, target, subtarget, mode, ignore);
+ 
+   abort ();
+ }
+ 
+ static void
+ rs6000_init_builtins (list_node)
+      tree list_node ATTRIBUTE_UNUSED;
+ {
+   if (TARGET_ALTIVEC)
+     altivec_init_builtins ();
+ }
+ 
+ static void
+ altivec_init_builtins (void)
+ {
+   struct builtin_description * d;
+   size_t i;
+ 
+   tree endlink = void_list_node;
+ 
+   tree pint_type_node = build_pointer_type (integer_type_node);
+ 
+   /* V4SI foo (int *).  */
+   tree v4si_ftype_pint
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, pint_type_node, endlink));
+ 
+   /* void foo (int *, V4SI).  */
+   tree void_ftype_pint_v4si
+     = build_function_type (void_type_node,
+ 			   tree_cons (NULL_TREE, pint_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 
+   tree v4si_ftype_v4si_v4si
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, V4SI_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 
+   tree v4sf_ftype_v4sf_v4sf
+     = build_function_type (V4SF_type_node,
+ 			   tree_cons (NULL_TREE, V4SF_type_node,
+ 				      tree_cons (NULL_TREE, V4SF_type_node,
+ 						 endlink)));
+ 
+   tree v8hi_ftype_v8hi_v8hi
+     = build_function_type (V8HI_type_node,
+ 			   tree_cons (NULL_TREE, V8HI_type_node,
+ 				      tree_cons (NULL_TREE, V8HI_type_node,
+ 						 endlink)));
+ 
+   tree v16qi_ftype_v16qi_v16qi
+     = build_function_type (V16QI_type_node,
+ 			   tree_cons (NULL_TREE, V16QI_type_node,
+ 				      tree_cons (NULL_TREE, V16QI_type_node,
+ 						 endlink)));
+ 
+   tree v4si_ftype_v4sf_v4sf
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, V4SF_type_node,
+ 				      tree_cons (NULL_TREE, V4SF_type_node,
+ 						 endlink)));
+ 
+   tree v8hi_ftype_v16qi_v16qi
+     = build_function_type (V8HI_type_node,
+ 			   tree_cons (NULL_TREE, V16QI_type_node,
+ 				      tree_cons (NULL_TREE, V16QI_type_node,
+ 						 endlink)));
+ 
+   tree v4si_ftype_v8hi_v8hi
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, V8HI_type_node,
+ 				      tree_cons (NULL_TREE, V8HI_type_node,
+ 						 endlink)));
+ 
+   tree v8hi_ftype_v4si_v4si
+     = build_function_type (V8HI_type_node,
+ 			   tree_cons (NULL_TREE, V4SI_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 
+   tree v16qi_ftype_v8hi_v8hi
+     = build_function_type (V16QI_type_node,
+ 			   tree_cons (NULL_TREE, V8HI_type_node,
+ 				      tree_cons (NULL_TREE, V8HI_type_node,
+ 						 endlink)));
+ 
+   tree v4si_ftype_v16qi_v4si
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, V16QI_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 
+   tree v4si_ftype_v8hi_v4si
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, V8HI_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 
+   tree int_ftype_v4si_v4si
+     = build_function_type (integer_type_node,
+ 			   tree_cons (NULL_TREE, V4SI_type_node,
+ 				      tree_cons (NULL_TREE, V4SI_type_node,
+ 						 endlink)));
+ 
+   tree int_ftype_v4sf_v4sf
+     = build_function_type (integer_type_node,
+ 			   tree_cons (NULL_TREE, V4SF_type_node,
+ 				      tree_cons (NULL_TREE, V4SF_type_node,
+ 						 endlink)));
+ 
+   tree int_ftype_v16qi_v16qi
+     = build_function_type (integer_type_node,
+ 			   tree_cons (NULL_TREE, V16QI_type_node,
+ 				      tree_cons (NULL_TREE, V16QI_type_node,
+ 						 endlink)));
+ 
+   tree int_ftype_v8hi_v8hi
+     = build_function_type (integer_type_node,
+ 			   tree_cons (NULL_TREE, V8HI_type_node,
+ 				      tree_cons (NULL_TREE, V8HI_type_node,
+ 						 endlink)));
+ 
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal", v4si_ftype_pint, ALTIVEC_BUILTIN_LD_INTERNAL);
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal", void_ftype_pint_v4si, ALTIVEC_BUILTIN_ST_INTERNAL);
+ 
+   /* Add the simple binary operators.  */
+   for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
+     {
+       enum machine_mode mode0, mode1, mode2;
+       tree type;
+ 
+       if (d->name == 0)
+ 	continue;
+       
+       mode0 = insn_data[d->icode].operand[0].mode;
+       mode1 = insn_data[d->icode].operand[1].mode;
+       mode2 = insn_data[d->icode].operand[2].mode;
+ 
+       /* When all three operands are of the same mode.  */
+       if (mode0 == mode1 && mode1 == mode2)
+ 	{
+ 	  switch (mode0)
+ 	    {
+ 	    case V4SFmode:
+ 	      type = v4sf_ftype_v4sf_v4sf;
+ 	      break;
+ 	    case V4SImode:
+ 	      type = v4si_ftype_v4si_v4si;
+ 	      break;
+ 	    case V16QImode:
+ 	      type = v16qi_ftype_v16qi_v16qi;
+ 	      break;
+ 	    case V8HImode:
+ 	      type = v8hi_ftype_v8hi_v8hi;
+ 	      break;
+ 	    default:
+ 	      abort ();
+ 	    }
+ 	}
+ 
+       /* A few other combos we really don't want to do manually.  */
+ 
+       /* vint, vfloat, vfloat.  */
+       else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
+ 	type = v4si_ftype_v4sf_v4sf;
+ 
+       /* vshort, vchar, vchar.  */
+       else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
+ 	type = v8hi_ftype_v16qi_v16qi;
+ 
+       /* vint, vshort, vshort.  */
+       else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
+ 	type = v4si_ftype_v8hi_v8hi;
+ 
+       /* vshort, vint, vint.  */
+       else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
+ 	type = v8hi_ftype_v4si_v4si;
+ 
+       /* vchar, vshort, vshort.  */
+       else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
+ 	type = v16qi_ftype_v8hi_v8hi;
+ 
+       /* vint, vchar, vint.  */
+       else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
+ 	type = v4si_ftype_v16qi_v4si;
+ 
+       /* vint, vshort, vint.  */
+       else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
+ 	type = v4si_ftype_v8hi_v4si;
+ 
+       /* fixme: aldyh */
+       /* int, x, x.  */
+       else if (mode0 == SImode)
+ 	{
+ 	  switch (mode1)
+ 	    {
+ 	    case V4SImode:
+ 	      type = int_ftype_v4si_v4si;
+ 	      break;
+ 	    case V4SFmode:
+ 	      type = int_ftype_v4sf_v4sf;
+ 	      break;
+ 	    case V16QImode:
+ 	      type = int_ftype_v16qi_v16qi;
+ 	      break;
+ 	    case V8HImode:
+ 	      type = int_ftype_v8hi_v8hi;
+ 	      break;
+ 	    default:
+ 	      abort ();
+ 	    }
+ 	}
+ 
+       else
+ 	abort ();
+ 
+       def_builtin (d->mask, d->name, type, d->code);
+     }
+ }
+ 
  \f
  /* Generate a memory reference for expand_block_move, copying volatile,
     and other bits from an original memory reference.  */
*************** secondary_reload_class (class, mode, in)
*** 3941,3946 ****
--- 4490,4500 ----
        && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
      return NO_REGS;
  
+   /* Memory, and AltiVec registers can go into AltiVec registers.  */
+   if ((regno == -1 || ALTIVEC_REGNO_P (regno))
+       && class == ALTIVEC_REGS)
+     return NO_REGS;
+ 
    /* We can copy among the CR registers.  */
    if ((class == CR_REGS || class == CR0_REGS)
        && regno >= 0 && CR_REGNO_P (regno))
*************** print_operand (file, x, code)
*** 4714,4719 ****
--- 5268,5299 ----
  		     reg_names[SMALL_DATA_REG]);
  	}
        return;
+ 
+       /* Print AltiVec memory operand.  */
+     case 'y':
+       {
+ 	rtx tmp;
+ 
+ 	if (GET_CODE (x) != MEM)
+ 	  abort ();
+ 
+ 	tmp = XEXP (x, 0);
+ 
+ 	if (GET_CODE (tmp) == REG)
+ 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
+ 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
+ 	  {
+ 	    if (REGNO (XEXP (tmp, 0)) == 0)
+ 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
+ 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
+ 	    else
+ 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
+ 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
+ 	  }
+ 	else
+ 	  abort ();
+ 	break;
+       }
  			    
      case 0:
        if (GET_CODE (x) == REG)
Index: rs6000.md
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.128
diff -c -p -r1.128 rs6000.md
*** rs6000.md	2001/10/16 00:43:21	1.128
--- rs6000.md	2001/11/06 22:24:51
***************
*** 37,43 ****
  \f
  ;; Define an insn type attribute.  This is used in function unit delay
  ;; computations.
! (define_attr "type" "integer,load,store,fpload,fpstore,imul,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg"
    (const_string "integer"))
  
  ;; Length (in bytes).
--- 37,43 ----
  \f
  ;; Define an insn type attribute.  This is used in function unit delay
  ;; computations.
! (define_attr "type" "integer,load,store,fpload,fpstore,imul,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,altivec"
    (const_string "integer"))
  
  ;; Length (in bytes).
***************
*** 13359,13361 ****
--- 13359,14294 ----
      emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
    DONE;
  }")
+ 
+ ;; AltiVec patterns
+ 
+ ;; Generic LVX load instruction.
+ (define_insn "altivec_lvx"
+   [(set (match_operand:V4SI 0 "register_operand" "=v")
+ 	(match_operand:V4SI 1 "memory_operand" "m"))]
+   "TARGET_ALTIVEC"
+   "lvx\t%0,%y1"
+   [(set_attr "type" "altivec")])
+ 
+ ;; Generic STVX store instruction.
+ (define_insn "altivec_stvx"
+   [(set (match_operand:V4SI 0 "memory_operand" "=m")
+ 	(match_operand:V4SI 1 "register_operand" "v"))]
+   "TARGET_ALTIVEC"
+   "stvx\t%1,%y0"
+   [(set_attr "type" "altivec")])
+ 
+ ;; Vector move instructions.
+ (define_expand "movv4si"
+   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
+ 	(match_operand:V4SI 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V4SImode); DONE; }")
+ 
+ (define_insn "*movv4si_internal"
+   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v,v")
+ 	(match_operand:V4SI 1 "input_operand" "v,m,v"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1
+    vor\t%0,%1,%1"
+   [(set_attr "type" "altivec")])
+ 
+ (define_expand "movv8hi"
+   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
+ 	(match_operand:V8HI 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V8HImode); DONE; }")
+ 
+ (define_insn "*movv8hi_internal1"
+   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=m,v,v")
+ 	(match_operand:V8HI 1 "input_operand" "v,m,v"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1
+    vor\t%0,%1,%1"
+   [(set_attr "type" "altivec")])
+ 
+ (define_expand "movv16qi"
+   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
+ 	(match_operand:V16QI 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V16QImode); DONE; }")
+ 
+ (define_insn "*movv16qi_internal1"
+   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=m,v,v")
+ 	(match_operand:V16QI 1 "input_operand" "v,m,v"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1
+    vor\t%0,%1,%1"
+   [(set_attr "type" "altivec")])
+ 
+ (define_expand "movv4sf"
+   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
+ 	(match_operand:V4SF 1 "any_operand" ""))]
+   "TARGET_ALTIVEC"
+   "{ rs6000_emit_move (operands[0], operands[1], V4SFmode); DONE; }")
+ 
+ (define_insn "*movv4sf_internal1"
+   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=m,v,v")
+ 	(match_operand:V4SF 1 "input_operand" "v,m,v"))]
+   "TARGET_ALTIVEC"
+   "@
+    stvx\t%1,%y0
+    ldvx\t%0,%y1
+    vor\t%0,%1,%1"
+   [(set_attr "type" "altivec")])
+ 
+ ;; Simple binary operations.
+ 
+ (define_insn "altivec_vaddubm"
+   [(set (match_operand:V16QI 0 "register_operand" "=v")
+         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
+                        (match_operand:V16QI 2 "register_operand" "v")] 31))]
+   "TARGET_ALTIVEC"
+   "vaddubm\t%0,%1,%2"
+   [(set_attr "type" "altivec")])

*builtins deleted*

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 13:59 ` Geoff Keating
                     ` (5 preceding siblings ...)
  2001-11-13  4:32   ` Geoff Keating
@ 2001-11-13 15:03   ` Geoff Keating
  6 siblings, 0 replies; 152+ messages in thread
From: Geoff Keating @ 2001-11-13 15:03 UTC (permalink / raw)
  To: aldyh; +Cc: gcc-patches

> From: Aldy Hernandez <aldyh@redhat.com>
> Cc: Geoff Keating <geoffk@cygnus.com>
> Date: 05 Nov 2001 15:54:20 -0500

Hi Aldy,

> *************** extern int rs6000_debug_arg;		/* debug a
> *** 569,581 ****
>   #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
>   
>   /* Boundary (in *bits*) on which stack pointer should be aligned.  */
> ! #define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
>   
>   /* Allocation boundary (in *bits*) for the code of a function.  */
>   #define FUNCTION_BOUNDARY 32
>   
>   /* No data type wants to be aligned rounder than this.  */
> ! #define BIGGEST_ALIGNMENT 64
>   
>   /* Handle #pragma pack.  */
>   #define HANDLE_PRAGMA_PACK 1
> --- 585,604 ----
>   #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
>   
>   /* Boundary (in *bits*) on which stack pointer should be aligned.  */
> ! #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
>   
>   /* Allocation boundary (in *bits*) for the code of a function.  */
>   #define FUNCTION_BOUNDARY 32
>   
>   /* No data type wants to be aligned rounder than this.  */
> ! #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)

I think you _don't_ want this to be dependent on the ABI.  Changing
this isn't an ABI change (I hope!), which is good because...

> ! 
> ! /* A C expression to compute the alignment for a variables in the
> !    local store.  TYPE is the data type, and ALIGN is the alignment
> !    that the object would ordinarily have.  */
> ! #define LOCAL_ALIGNMENT(TYPE, ALIGN)				\
> ! 	((TARGET_ALTIVEC_ABI		    			\
> ! 	  && TREE_CODE (TYPE)) == VECTOR_TYPE ? 128 : ALIGN)

...as altivec values have to be 128-bit aligned because of the
hardware, you don't want this ABI-dependent either.

> *************** extern int rs6000_debug_arg;		/* debug a
> *** 634,640 ****
>      a register, in order to work around problems in allocating stack storage
>      in inline functions.  */
>   
> ! #define FIRST_PSEUDO_REGISTER 77
>   
>   /* This must not decrease, for backwards compatibility.  If
>      FIRST_PSEUDO_REGISTER increases, this should as well.  */
> --- 659,665 ----
>      a register, in order to work around problems in allocating stack storage
>      in inline functions.  */
>   
> ! #define FIRST_PSEUDO_REGISTER 109
>   
>   /* This must not decrease, for backwards compatibility.  If
>      FIRST_PSEUDO_REGISTER increases, this should as well.  */

The DWARF_FRAME_REGISTERS change seems to have gone away, which is not
quite right:  it has to happen _only when the ABI is 'altivec'_.

This will be a bit tricky because DWARF_FRAME_REGISTERS is also used
in libgcc, so you have to #define something when the Altivec ABI is
chosen, and then key off that if IN_LIBGCC2.

I wonder if you could assume that the integrated cpplib will always be
used when compiling libgcc?  That would make things easier, because
then you wouldn't have muck with specs so much.

> *************** extern int rs6000_debug_arg;		/* debug a
> *** 655,661 ****
>      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
>      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
>      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
> !    0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1}
>   
>   /* 1 for registers not available across function calls.
>      These must include the FIXED_REGISTERS and also any
> --- 680,690 ----
>      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
>      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
>      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
> !    0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1,	   \
> !    /* AltiVec registers.  */			   \
> !    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
> !    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  \
> ! }

This is correct, but doesn't there need to be a change to them in
CONDITIONAL_REGISTER_USAGE when the altivec ABI is chosen (in which
some altivec registers are call-saved)?

> *************** typedef struct rs6000_stack {
> *** 1338,1346 ****
> --- 1428,1442 ----
>   			? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG)
>   #define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1)
>   
> + /* Minimum and maximum AltiVec registers used to hold arguments.  */
> + #define ALTIVEC_ARG_MIN_REG 77
> + #define ALTIVEC_ARG_MAX_REG 88
> + #define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG - ALTIVEC_ARG_MIN_REG + 1)

These should be based off FIRST_ALTIVEC_REGISTER rather than being
magic numbers...

>   /* Return registers */
>   #define GP_ARG_RETURN GP_ARG_MIN_REG
>   #define FP_ARG_RETURN FP_ARG_MIN_REG
> + #define ALTIVEC_ARG_RETURN 79

... this too.


> Index: sysv4.h
> ===================================================================
> RCS file: /cvs/uberbaum/gcc/config/rs6000/sysv4.h,v
> retrieving revision 1.67
> diff -c -p -r1.67 sysv4.h
> *** sysv4.h	2001/10/29 23:09:43	1.67
> --- sysv4.h	2001/11/05 19:49:24
> *************** do {									\
> *** 400,417 ****
>      one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
>      versions, just use 64 as the stack boundary.  */
>   #undef	STACK_BOUNDARY
> ! #define	STACK_BOUNDARY	64
>   
>   /* Real stack boundary as mandated by the appropriate ABI.  */
> ! #define ABI_STACK_BOUNDARY ((TARGET_EABI) ? 64 : 128)
>   
>   /* No data type wants to be aligned rounder than this.  */
>   #undef	BIGGEST_ALIGNMENT
> ! #define BIGGEST_ALIGNMENT ((TARGET_EABI) ? 64 : 128)
>   
>   #undef  BIGGEST_FIELD_ALIGNMENT
>   #undef  ADJUST_FIELD_ALIGN
> - #undef  ROUND_TYPE_ALIGN
>   
>   /* Use ELF style section commands.  */
>   
> --- 400,430 ----
>      one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
>      versions, just use 64 as the stack boundary.  */
>   #undef	STACK_BOUNDARY
> ! #define	STACK_BOUNDARY	(TARGET_ALTIVEC_ABI ? 128 : 64)
>   
>   /* Real stack boundary as mandated by the appropriate ABI.  */
> ! #define ABI_STACK_BOUNDARY ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
>   
>   /* No data type wants to be aligned rounder than this.  */
>   #undef	BIGGEST_ALIGNMENT
> ! #define BIGGEST_ALIGNMENT ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
>   
> + /* An expression for the alignment of a structure field FIELD if the
> +    alignment computed in the usual way is COMPUTED.  */
> + #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)				      \
> + 	((TARGET_ALTIVEC_ABI && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
> + 	 ? 128 : COMPUTED)
> + 
> + /* Define this macro as an expression for the alignment of a type
> +    (given by TYPE as a tree node) if the alignment computed in the
> +    usual way is COMPUTED and the alignment explicitly specified was
> +    SPECIFIED.  */
> + #define ROUND_TYPE_ALIGN(TYPE, COMPUTED, SPECIFIED)			\
> + 	((TARGET_ALTIVEC_ABI && TREE_CODE (TYPE) == VECTOR_TYPE)	\
> + 	 ? 128 : MAX (COMPUTED, SPECIFIED))
> + 
>   #undef  BIGGEST_FIELD_ALIGNMENT
>   #undef  ADJUST_FIELD_ALIGN
>   
>   /* Use ELF style section commands.  */

This has the same comment as the equivalent stuff in rs6000.h.


> *************** function_arg_advance (cum, mode, type, n
> *** 2159,2165 ****
>   {
>     cum->nargs_prototype--;
>   
> !   if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
>       {
>         if (TARGET_HARD_FLOAT
>   	  && (mode == SFmode || mode == DFmode))
> --- 2242,2255 ----
>   {
>     cum->nargs_prototype--;
>   
> !   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
> !     {
> !       if (cum->vregno <= ALTIVEC_ARG_MAX_REG)
> ! 	cum->vregno++;
> !       else
> ! 	cum->words += RS6000_ARG_SIZE (mode, type);
> !     }

Something you might not have seen in the ABI documentation: unnamed
vector arguments (passed to varargs functions after the '...') get
passed in memory, not in registers.  (I don't remember if this is just
the unnamed arguments or all the arguments to varargs functions, you
should check.)

> *************** print_operand (file, x, code)
> *** 4714,4719 ****
> --- 5287,5318 ----
>   		     reg_names[SMALL_DATA_REG]);
>   	}
>         return;
> + 
> +       /* Print AltiVec memory operand.  */
> +     case 'y':
> +       {
> + 	rtx tmp;
> + 
> + 	if (GET_CODE (x) != MEM)
> + 	  abort ();
> + 
> + 	tmp = XEXP (x, 0);
> + 
> + 	if (GET_CODE (tmp) == REG)
> + 	  fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
> + 	else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
> + 	  {
> + 	    if (REGNO (XEXP (tmp, 0)) == 0)
> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
> + 		       reg_names[ REGNO (XEXP (tmp, 0)) ]);
> + 	    else
> + 	      fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
> + 		       reg_names[ REGNO (XEXP (tmp, 1)) ]);
> + 	  }
> + 	else
> + 	  abort ();
> + 	break;
> +       }

Do you really need this?  It looks just like the way a normal memory
operand is printed (for the cases that are allowed for altivec).

> Index: rs6000.md

Can you put the altivec insns in their own .md file and use the include
mechanism?  I believe this is what it was intended for.

> + ;; No code is needed to copy between vector registers.
> + (define_insn "*altivec_vec_move"
> +   [(set (match_operand 0 "altivec_register" "=v")
> + 	(match_operand 1 "altivec_register" "v"))]
> +   "TARGET_ALTIVEC"
> +   ""
> +   [(set_attr "type" "altivec")])

Um, that can't possibly be right.  Also, it should be part of
movv4si_internal, because reload needs all the move insns to be the
same pattern.

> + ;; Vector move instructions.
> + (define_expand "movv4si"
> +   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
> + 	(match_operand:V4SI 1 "any_operand" ""))]
> +   "TARGET_ALTIVEC"
> +   "{ rs6000_emit_move (operands[0], operands[1], V4SImode); DONE; }")
> + 
> + (define_insn "*movv4si_internal"
> +   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v")
> + 	(match_operand:V4SI 1 "input_operand" "v,m"))]
> +   "TARGET_ALTIVEC"
> +   "@
> +    stvx\t%1,%y0
> +    ldvx\t%0,%y1"
> +   [(set_attr "type" "altivec")])

Yes---this needs an alternative to copy a 'v' into a 'v'.  All the
ones below probably need it too.

> + (define_expand "movv8hi"
> +   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
> + 	(match_operand:V8HI 1 "any_operand" ""))]
> +   "TARGET_ALTIVEC"
> +   "{ rs6000_emit_move (operands[0], operands[1], V8HImode); DONE; }")
> + 
> + (define_insn "*movv8hi_internal1"
> +   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=m,v")
> + 	(match_operand:V8HI 1 "input_operand" "v,m"))]
> +   "TARGET_ALTIVEC"
> +   "@
> +    stvx\t%1,%y0
> +    ldvx\t%0,%y1"
> +   [(set_attr "type" "altivec")])
> + 
> + (define_expand "movv16qi"
> +   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
> + 	(match_operand:V16QI 1 "any_operand" ""))]
> +   "TARGET_ALTIVEC"
> +   "{ rs6000_emit_move (operands[0], operands[1], V16QImode); DONE; }")
> + 
> + (define_insn "*movv16qi_internal1"
> +   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=m,v")
> + 	(match_operand:V16QI 1 "input_operand" "v,m"))]
> +   "TARGET_ALTIVEC"
> +   "@
> +    stvx\t%1,%y0
> +    ldvx\t%0,%y1"
> +   [(set_attr "type" "altivec")])
> + 
> + (define_expand "movv4sf"
> +   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
> + 	(match_operand:V4SF 1 "any_operand" ""))]
> +   "TARGET_ALTIVEC"
> +   "{ rs6000_emit_move (operands[0], operands[1], V4SFmode); DONE; }")
> + 
> + (define_insn "*movv4sf_internal1"
> +   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=m,v")
> + 	(match_operand:V4SF 1 "input_operand" "v,m"))]
> +   "TARGET_ALTIVEC"
> +   "@
> +    stvx\t%1,%y0
> +    ldvx\t%0,%y1"
> +   [(set_attr "type" "altivec")])
> + 
> + ;; Simple binary operations.
> + 
> 
> -- boring builtins deleted-- 
> 
> + (define_insn "altivec_vxor"
> +   [(set (match_operand:V4SI 0 "register_operand" "=v")
> +         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
> +                       (match_operand:V4SI 2 "register_operand" "v")] 136))]
> +   "TARGET_ALTIVEC"
> +   "vxor\t%0,%1,%2"
> +   [(set_attr "type" "altivec")])

-- 
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-05 19:03             ` Alan Matsuoka
  2001-11-06  1:03               ` Joseph S. Myers
  2001-11-13  4:32               ` Alan Matsuoka
@ 2001-11-13 15:03               ` Alan Matsuoka
  2 siblings, 0 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc-patches

On Tue, 06 Nov 2001, Joseph S. Myers wrote:

> On Mon, 5 Nov 2001, Alan Matsuoka wrote:
> 
> > + Where @var{pathname} is a string that specifies the the location of the file,
> > + specifies the include file to be in gcc/config/{target}/filestuff. The
> 
> @file{gcc/config/@var{target}/filestuff}.
> 
> > + directory @file{ gcc/config/{target}} is regarded as the default directory.
> 
> No space after the open brace.  @var{target}.

Fixed.
> 
> > + the include file is specified to be in @file{gcc/config/{target}/BOGUS/filestuff}.
> 
> @var{target}.
> 
> > + The -I@var{dir} option specifies directories to search for machine descriptions.

Fixed.
> 
> @option{-I@var{dir}}.
> 
> > + @table @gcctabopt
> > + @item -I@var{dir}
> > + @opindex I

deleted.
> 
> The option index is an index of GCC options, options for support tools
> should not have @opindex index entries.
> 
> -- 
> 

Thank you.

Index: md.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/md.texi,v
retrieving revision 1.26
diff -3 -c -p -r1.26 md.texi
*** md.texi	2001/10/25 18:25:08	1.26
--- md.texi	2001/11/06 02:58:26
*************** See the next chapter for information on 
*** 38,43 ****
--- 38,44 ----
  * Expander Definitions::Generating a sequence of several RTL insns
                            for a standard operation.
  * Insn Splitting::      Splitting Instructions into Multiple Instructions.
+ * Including Patterns::      Including Patterns in Machine Descriptions.
  * Peephole Definitions::Defining machine-specific peephole optimizations.
  * Insn Attributes::     Specifying the value of attributes for generated insns.
  * Conditional Execution::Generating @code{define_insn} patterns for
*************** The @code{define_insn_and_split} constru
*** 3909,3914 ****
--- 3910,3992 ----
  functionality as two separate @code{define_insn} and @code{define_split}
  patterns.  It exists for compactness, and as a maintenance tool to prevent
  having to ensure the two patterns' templates match.
+ 
+ @node Including Patterns
+ @section Including Patterns in Machine Descriptions.
+ @cindex insn includes
+ 
+ @findex include
+ The @code{include} pattern tells the compiler tools where to
+ look for patterns that are in files other than in the file
+ @file{.md}. This is used only at build time and there is no preprocessing allowed.
+ 
+ It looks like:
+ 
+ @smallexample
+ 
+ (include
+   @var{pathname})
+ @end smallexample
+ 
+ For example:
+ 
+ @smallexample
+ 
+ (include "filestuff") 
+ 
+ @end smallexample
+ 
+ Where @var{pathname} is a string that specifies the the location of the file,
+ specifies the include file to be in gcc/config/{target}/filestuff. The
+ directory @file{gcc/config/{target}} is regarded as the default directory.
+ 
+ 
+ Machine descriptions may be split up into smaller more manageable subsections 
+ and placed into subdirectories. 
+ 
+ By specifying:
+ 
+ @smallexample
+ 
+ (include "BOGUS/filestuff") 
+ 
+ @end smallexample
+ 
+ the include file is specified to be in @file{gcc/config/@var{target}/BOGUS/filestuff}.
+ 
+ Specifying an absolute path for the include file such as;
+ @smallexample
+ 
+ (include "/u2/BOGUS/filestuff") 
+ 
+ @end smallexample
+ is permitted but is not encouraged. 
+ 
+ @node .md Directory Options
+ @subsection RTL Generation Tool Options for Directory Search
+ @cindex directory options .md
+ @cindex options, directory search
+ @cindex search path
+ 
+ The @option{-I@var{dir}} option specifies directories to search for machine descriptions.
+ For example:
+ 
+ @smallexample
+ 
+ genrecog -I/p1/abc/proc1 -I/p2/abcd/pro2 target.md
+ 
+ @end smallexample
+ 
+ 
+ Add the directory @var{dir} to the head of the list of directories to be
+ searched for header files.  This can be used to override a system machine definition
+ file, substituting your own version, since these directories are
+ searched before the default machine description file directories.  If you use more than
+ one @option{-I} option, the directories are scanned in left-to-right
+ order; the standard default directory come after.
+ 
+ @end table
+ 
  
  @node Peephole Definitions
  @section Machine-Specific Peephole Optimizers


Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-07  8:30       ` Aldy Hernandez
  2001-11-13  4:33         ` Aldy Hernandez
@ 2001-11-13 15:03         ` Aldy Hernandez
  1 sibling, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Geoff Keating; +Cc: rth, gcc-patches

>>>>> "Geoff" == Geoff Keating <geoffk@geoffk.org> writes:

 >> > > + #define BIGGEST_ALIGNMENT (TARGET_ALTIVEC_ABI ? 128 : 64)
 >> > 
 >> > I think you _don't_ want this to be dependent on the ABI.  Changing
 >> > this isn't an ABI change (I hope!), which is good because...
 >> 
 >> Yes it is.  REGNO_POINTER_ALIGN(STACK_POINTER_REGNUM) == STACK_BOUNDARY.
 >> 
 >> Remember that STACK_BOUNDARY != PREFERRED_STACK_BOUNDARY, and that the
 >> later does not help you unless you also have code to enforce stack
 >> alignment, like we're supposed to have for x86 vector code.

 > Here I was talking about BIGGEST_ALIGNMENT only.  Changing
 > STACK_BOUNDARY is of course an ABI change.

Woh, my bad.  Ok, biggest_alignment remains as is.  Nothing changed
from my last post then.

Still waiting approval on patch, and guidance on DWARF_FRAME_REGISTERS.

Aldy

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-05 13:04   ` Aldy Hernandez
  2001-11-05 13:17     ` Joseph S. Myers
  2001-11-13  4:32     ` Aldy Hernandez
@ 2001-11-13 15:03     ` Aldy Hernandez
  2 siblings, 0 replies; 152+ messages in thread
From: Aldy Hernandez @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc patches

On Mon, 2001-11-05 at 15:59, Joseph S. Myers wrote:
> On 5 Nov 2001, Aldy Hernandez wrote:
> 
> > + @item -mabi=altivec
> > + @opindex mabi=altivec
> > + Extend the current ABI with AltiVec ABI extensions.  This does not
> > + change the default ABI, instead it adds the AltiVec ABI extensions to
> > + the current ABI.
> 
> That should end "ABI@." so that spacing after the sentence is correct if
> more text gets added to that paragraph later.

huh?  i've never heard that.

where are the .texi docs?  i'm bound to make more mistakes if i don't
read the texi docs :)
> 
> -- 
> Joseph S. Myers
> jsm28@cam.ac.uk
-- 
Aldy Hernandez			E-mail: aldyh@redhat.com
Professional Gypsy
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-05 19:01             ` Alan Matsuoka
  2001-11-13  4:32               ` Alan Matsuoka
@ 2001-11-13 15:03               ` Alan Matsuoka
  1 sibling, 0 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Geoff Keating, gcc patches

On Mon, 05 Nov 2001, Aldy Hernandez wrote:

> is it recursive?  i mean, can you include files from within include
> files?

Yes it is. 


Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: altivec patches
  2001-11-06 16:12     ` Daniel Jacobowitz
                         ` (2 preceding siblings ...)
  2001-11-13  4:33       ` Daniel Jacobowitz
@ 2001-11-13 15:03       ` Daniel Jacobowitz
  3 siblings, 0 replies; 152+ messages in thread
From: Daniel Jacobowitz @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Dale Johannesen, gcc patches, Geoff Keating

On Mon, Nov 05, 2001 at 09:33:11PM -0500, Aldy Hernandez wrote:
> >>>>> "Dale" == Dale Johannesen <dalej@apple.com> writes:
> 
>  > This is getting better.
> 
> Thanks ;-)
> 
>  > I'd really like to see vrsave in the enums and register macros
>  > (not necessarily the code).  I dislike making a major change to
>  > an area if we know it's going to change again shortly.
> 
> That was supposed to be tommorrow's work.... :)
> 
>  > If you plan to support linking files compiled with and without
>  > -fabi=altivec,
> 
> nope we don't.  You can't just link too different abi's.

Is there any reasonable way to reflect that in the generated objects,
then?  Is there a spare bit in the ELF header for this?

-- 
Daniel Jacobowitz                           Carnegie Mellon University
MontaVista Software                         Debian GNU/Linux Developer

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-13 15:03                         ` Aldy Hernandez
@ 2001-11-13 15:03                           ` Alan Matsuoka
  0 siblings, 0 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Alexandre Oliva, gcc-patches

On Sat, 17 Nov 2001, Aldy Hernandez wrote:

> 
>  > OK. Thank you. I didn't  know.
> 
> Another thing Alan.
> 
> I think you also need to include patches for the build system that
> handle dependencies introduced by these .md include files.  See
> "md_file" in config.gcc, configure.in, and Makefile.in.
> 
> I'd like to see an "extra_mds" variable that is used to specify other
> .md's used in the port.
> 
> For example, you should be able to do:
> 
> powerpc-*-sysv*)
>         tm_file="${tm_file} svr4.h rs6000/sysv4.h"
>         blah blah
> -->     extra_mds="altivec.md"
>         ;;
> 
> Right now if I use the include mechanism, there is no way for gcc to
> know that rs6000.md is dependent on altivec.md.

Good idea. I'll look at it when I get a chance. 

Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: Include facility for .md files - altivec patches
  2001-11-05 21:37             ` Alan Matsuoka
  2001-11-13  4:32               ` Alan Matsuoka
@ 2001-11-13 15:03               ` Alan Matsuoka
  1 sibling, 0 replies; 152+ messages in thread
From: Alan Matsuoka @ 2001-11-13 15:03 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Geoff Keating, gcc patches

On Mon, 05 Nov 2001, Aldy Hernandez wrote:

> is it recursive?  i mean, can you include files from within include
> files?

If you mean nested includes yes. If you mean mutually recursive or self 
recursive references, no.


Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299

^ permalink raw reply	[flat|nested] 152+ messages in thread

end of thread, other threads:[~2001-11-17 20:54 UTC | newest]

Thread overview: 152+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-11-05 12:52 altivec patches Aldy Hernandez
2001-11-05 12:58 ` Aldy Hernandez
2001-11-13  4:32   ` Aldy Hernandez
2001-11-13 15:03   ` Aldy Hernandez
2001-11-05 12:59 ` Joseph S. Myers
2001-11-05 13:04   ` Aldy Hernandez
2001-11-05 13:17     ` Joseph S. Myers
2001-11-13  4:32       ` Joseph S. Myers
2001-11-13 15:03       ` Joseph S. Myers
2001-11-13  4:32     ` Aldy Hernandez
2001-11-13 15:03     ` Aldy Hernandez
2001-11-13  4:32   ` Joseph S. Myers
2001-11-13 15:03   ` Joseph S. Myers
2001-11-05 13:59 ` Geoff Keating
2001-11-05 14:05   ` Alan Matsuoka
2001-11-05 18:22     ` Aldy Hernandez
2001-11-05 18:28       ` Alan Matsuoka
2001-11-05 18:41         ` Include facility for .md files - " Alan Matsuoka
2001-11-03 20:37           ` Geoff Keating
2001-11-13  4:26             ` Geoff Keating
2001-11-13 13:21             ` Geoff Keating
2001-11-13 15:03             ` Aldy Hernandez
2001-11-13 15:03               ` Alan Matsuoka
2001-11-13 15:03               ` Alan Matsuoka
2001-11-13 15:03             ` Geoff Keating
2001-11-05 18:49           ` Joseph S. Myers
2001-11-05 19:03             ` Alan Matsuoka
2001-11-06  1:03               ` Joseph S. Myers
2001-11-06  4:56                 ` Alan Matsuoka
2001-11-06  7:58                   ` Alan Matsuoka
2001-11-13  4:32                     ` Alan Matsuoka
2001-11-13 15:03                     ` Alexandre Oliva
2001-11-13 15:03                       ` Alan Matsuoka
2001-11-13 15:03                         ` Aldy Hernandez
2001-11-13 15:03                           ` Alan Matsuoka
2001-11-13 15:03                     ` Alan Matsuoka
2001-11-13  4:32                   ` Alan Matsuoka
2001-11-13 15:03                   ` Alan Matsuoka
2001-11-13  4:32                 ` Joseph S. Myers
2001-11-13 15:03                 ` Joseph S. Myers
2001-11-13  4:32               ` Alan Matsuoka
2001-11-13 15:03               ` Alan Matsuoka
2001-11-13  4:32             ` Joseph S. Myers
2001-11-13 15:03             ` Joseph S. Myers
2001-11-05 18:58           ` Aldy Hernandez
2001-11-05 19:01             ` Alan Matsuoka
2001-11-13  4:32               ` Alan Matsuoka
2001-11-13 15:03               ` Alan Matsuoka
2001-11-05 21:37             ` Alan Matsuoka
2001-11-13  4:32               ` Alan Matsuoka
2001-11-13 15:03               ` Alan Matsuoka
2001-11-13  4:32             ` Aldy Hernandez
2001-11-13 15:03             ` Aldy Hernandez
2001-11-06  0:23           ` Gerald Pfeifer
2001-11-13  4:32             ` Gerald Pfeifer
2001-11-13 15:03             ` Gerald Pfeifer
2001-11-13  4:32           ` Alan Matsuoka
2001-11-13 15:03           ` Alan Matsuoka
2001-11-13  4:32         ` Alan Matsuoka
2001-11-13 15:03         ` Alan Matsuoka
2001-11-13  4:32       ` Aldy Hernandez
2001-11-13 15:03       ` Aldy Hernandez
2001-11-13  4:32     ` Alan Matsuoka
2001-11-13 15:03     ` Alan Matsuoka
2001-11-05 14:31   ` Stan Shebs
2001-11-05 14:49     ` Geoff Keating
2001-11-05 15:29       ` Stan Shebs
2001-11-13  4:32         ` Stan Shebs
2001-11-13 15:03         ` Stan Shebs
2001-11-05 19:30       ` Aldy Hernandez
2001-11-13  4:32         ` Aldy Hernandez
2001-11-13 15:03         ` Aldy Hernandez
2001-11-13  4:32       ` Geoff Keating
2001-11-13 15:03       ` Geoff Keating
2001-11-13  4:32     ` Stan Shebs
2001-11-13 15:03     ` Stan Shebs
2001-11-05 19:27   ` Aldy Hernandez
2001-11-05 20:10     ` Geoff Keating
2001-11-13  4:32       ` Geoff Keating
2001-11-13 15:03       ` Geoff Keating
2001-11-13  4:32     ` Aldy Hernandez
2001-11-13 15:03     ` Aldy Hernandez
2001-11-06 15:02   ` Aldy Hernandez
2001-11-06 15:14     ` Joseph S. Myers
2001-11-06 16:28       ` Aldy Hernandez
2001-11-13  4:33         ` Aldy Hernandez
2001-11-13 15:03         ` Aldy Hernandez
2001-11-13  4:33       ` Joseph S. Myers
2001-11-13 15:03       ` Joseph S. Myers
2001-11-06 17:00     ` Dale Johannesen
2001-11-06 17:06       ` Aldy Hernandez
2001-11-13  4:33         ` Aldy Hernandez
2001-11-13 15:03         ` Aldy Hernandez
2001-11-13  4:33       ` Dale Johannesen
2001-11-13 15:03       ` Dale Johannesen
2001-11-06 17:07     ` Stan Shebs
2001-11-06 17:15       ` Aldy Hernandez
2001-11-13  4:33         ` Aldy Hernandez
2001-11-13 15:03         ` Aldy Hernandez
2001-11-13  4:33       ` Stan Shebs
2001-11-13 15:03       ` Stan Shebs
2001-11-13  4:33     ` Aldy Hernandez
2001-11-13 15:03     ` Aldy Hernandez
2001-11-06 23:17   ` Richard Henderson
2001-11-07  2:50     ` Geoff Keating
2001-11-07  8:30       ` Aldy Hernandez
2001-11-13  4:33         ` Aldy Hernandez
2001-11-13 15:03         ` Aldy Hernandez
2001-11-07 11:41       ` Richard Henderson
2001-11-07 12:12         ` Geoff Keating
2001-11-13  5:05           ` Geoff Keating
2001-11-13 15:03           ` Geoff Keating
2001-11-13  5:05         ` Richard Henderson
2001-11-13 15:03         ` Richard Henderson
2001-11-13  4:33       ` Geoff Keating
2001-11-13 15:03       ` Geoff Keating
2001-11-07  8:23     ` Aldy Hernandez
2001-11-13  4:33       ` Aldy Hernandez
2001-11-13 15:03       ` Aldy Hernandez
2001-11-13  4:33     ` Richard Henderson
2001-11-13 15:03     ` Richard Henderson
2001-11-13  4:32   ` Geoff Keating
2001-11-13 15:03   ` Geoff Keating
2001-11-05 14:05 ` Dale Johannesen
2001-11-05 14:38   ` Geoff Keating
2001-11-13  4:32     ` Geoff Keating
2001-11-13 15:03     ` Geoff Keating
2001-11-05 18:30   ` Aldy Hernandez
2001-11-06 16:12     ` Daniel Jacobowitz
2001-11-06 16:46       ` Aldy Hernandez
2001-11-13  4:33         ` Aldy Hernandez
2001-11-13 15:03         ` Aldy Hernandez
2001-11-07  2:36       ` Geoff Keating
2001-11-13  4:33         ` Geoff Keating
2001-11-13 15:03         ` Geoff Keating
2001-11-13  4:33       ` Daniel Jacobowitz
2001-11-13 15:03       ` Daniel Jacobowitz
2001-11-13  4:32     ` Aldy Hernandez
2001-11-13 15:03     ` Aldy Hernandez
2001-11-05 19:47   ` Aldy Hernandez
2001-11-13  4:32     ` Aldy Hernandez
2001-11-13 15:03     ` Aldy Hernandez
2001-11-13  4:32   ` Dale Johannesen
2001-11-13 15:03   ` Dale Johannesen
2001-11-05 14:39 ` Dale Johannesen
2001-11-05 18:35   ` Aldy Hernandez
2001-11-13  4:32     ` Aldy Hernandez
2001-11-13 15:03     ` Aldy Hernandez
2001-11-13  4:32   ` Dale Johannesen
2001-11-13 15:03   ` Dale Johannesen
2001-11-13  4:32 ` Aldy Hernandez
2001-11-13 15:03 ` Aldy Hernandez

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).