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


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

[PATCH] Committed powerpc patch


This had been bootstrapped and tested on powerpc-linux-gnu.
Also tested cross compilers for powerpc-eabi, darwin, aix, and
powerpc64-linux to make sure their output looked the same (except
where it was different because of constant emitting changes).

2001-07-31  Daniel Berlin  <dan@cgsoftware.com>

	PowerPC reorg and support for powerpc64-*-linux*.

	Also fixes emitting of constants on 32 bit and 64 bit
	platforms.
	
	* config.gcc: powerpc64-*-linux* is a new target.
	Things that needed aix.h now also include xcoff.h	

	* config/rs6000/rs6000.h: Split XCOFF specific stuff into
	xcoff.h. 
	Move AIX specific stuff into aix.h.
	(ASM_LONG): Use DOUBLE_INT_ASM_OP if we are on a 64 bit target.
	(ASM_OUTPUT_DOUBLE_INT): Ditto.
	(TARGET_AIX): Renamed to TARGET_XCOFF, since the AIX ABI is used
	with more than just XCOFF now.
	(SET_ASM_OP): Remove, now defined where needed.
	(FUNCTION_PROLOGUE): New macro definition.
	(FUNCTION_EPILOGUE): New macro definition.
	(CONST_OK_FOR_LETTER_P): Change N to require that value is
	positive, too.
	(ASM_OPEN_PAREN, ASM_CLOSE_PAREN): New macro definition.
	(PREDICATE_CODES): Added exact_log2_cint_operand,
	reg_or_add_cint64_operand, reg_or_sub_cint64_operand.

	* config/rs6000/rs6000.c: #ifdef XCOFF debugging info stuff on
	XCOFF_DEBUGGING_INFO.
	Use DOUBLE_INT_ASM_OP where approriate.
	(rs6000_emit_set_long_const): New function.
	(rs6000_emit_set_const): New function.
	(reg_or_sub_cint64_operand): New function.
	(reg_or_add_cint64_operand): New function.
	(exact_log2_cint_operand): New function.

	* config/rs6000/rs6000.md: Fix emitting of constants.
	Fix patterns that were AIX ABI specific, but depended on
	!TARGET_ELF (instead of DEFAULT_ABI == ABI_AIX).	
	
	* config/rs6000/xcoff.h: New file.

	* config/rs6000/linux64.h: New file.

	* config/rs6000/darwin.h: Copy needed AIX alignment definitions.


Index: config.gcc
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config.gcc,v
retrieving revision 1.75
diff -c -3 -p -w -B -b -r1.75 config.gcc
*** config.gcc	2001/07/25 01:49:45	1.75
--- config.gcc	2001/07/31 17:16:48
*************** romp-*-openbsd*)
*** 2559,2567 ****
  powerpc-*-openbsd*)
  	tmake_file="${tmake_file} rs6000/t-rs6000 rs6000/t-openbsd"
  	;;
  powerpc-*-beos*)
  	cpu_type=rs6000
! 	tm_file="${tm_file} rs6000/aix.h rs6000/beos.h"
  	xm_defines=POSIX
  	xm_file=rs6000/xm-beos.h
  	tmake_file=rs6000/t-beos
--- 2559,2574 ----
  powerpc-*-openbsd*)
  	tmake_file="${tmake_file} rs6000/t-rs6000 rs6000/t-openbsd"
  	;;
+ powerpc64-*-linux*)
+ 	tm_file="${tm_file} svr4.h rs6000/sysv4.h rs6000/linux64.h"
+ 	out_file=rs6000/rs6000.c
+ 	tmake_file="rs6000/t-ppcos t-slibgcc-elf-ver t-linux rs6000/t-ppccomm"
+ 	xmake_file=x-linux
+ 	extra_headers=ppc-asm.h
+ 	;;
  powerpc-*-beos*)
  	cpu_type=rs6000
! 	tm_file="${tm_file} rs6000/aix.h rs6000/beos.h rs6000/xcoff.h"
  	xm_defines=POSIX
  	xm_file=rs6000/xm-beos.h
  	tmake_file=rs6000/t-beos
*************** powerpcle-*-solaris2*)
*** 2700,2726 ****
  	;;
  rs6000-ibm-aix3.[01]*)
  	xm_defines=POSIX
! 	tm_file="${tm_file} rs6000/aix.h rs6000/aix31.h"
  	float_format=none
  	use_collect2=yes
  	;;
  rs6000-ibm-aix3.2.[456789]* | powerpc-ibm-aix3.2.[456789]*)
  	xm_defines=POSIX
! 	tm_file="${tm_file} rs6000/aix.h rs6000/aix3newas.h"
  	tmake_file=rs6000/t-newas
  	float_format=none
  	use_collect2=yes
  	;;
  rs6000-ibm-aix4.[12]* | powerpc-ibm-aix4.[12]*)
  	xm_defines=POSIX
! 	tm_file="${tm_file} rs6000/aix.h rs6000/aix41.h"
  	tmake_file=rs6000/t-newas
  	float_format=none
  	use_collect2=yes
  	;;
  rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*)
  	xm_defines=POSIX
! 	tm_file="${tm_file} rs6000/aix.h rs6000/aix43.h"
  	tmake_file=rs6000/t-aix43
  	float_format=none
  	use_collect2=yes
--- 2707,2733 ----
  	;;
  rs6000-ibm-aix3.[01]*)
  	xm_defines=POSIX
! 	tm_file="${tm_file} rs6000/aix.h rs6000/aix31.h rs6000/xcoff.h"
  	float_format=none
  	use_collect2=yes
  	;;
  rs6000-ibm-aix3.2.[456789]* | powerpc-ibm-aix3.2.[456789]*)
  	xm_defines=POSIX
! 	tm_file="${tm_file} rs6000/aix.h rs6000/aix3newas.h rs6000/xcoff.h"
  	tmake_file=rs6000/t-newas
  	float_format=none
  	use_collect2=yes
  	;;
  rs6000-ibm-aix4.[12]* | powerpc-ibm-aix4.[12]*)
  	xm_defines=POSIX
! 	tm_file="${tm_file} rs6000/aix.h rs6000/aix41.h rs6000/xcoff.h"
  	tmake_file=rs6000/t-newas
  	float_format=none
  	use_collect2=yes
  	;;
  rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*)
  	xm_defines=POSIX
! 	tm_file="${tm_file} rs6000/aix.h rs6000/aix43.h rs6000/xcoff.h"
  	tmake_file=rs6000/t-aix43
  	float_format=none
  	use_collect2=yes
*************** rs6000-ibm-aix4.[3456789]* | powerpc-ibm
*** 2728,2734 ****
  	;;
  rs6000-ibm-aix[56789].* | powerpc-ibm-aix[56789].*)
  	xm_defines=POSIX
! 	tm_file="${tm_file} rs6000/aix.h rs6000/aix51.h"
  	tmake_file=rs6000/t-aix43
  	float_format=none
  	use_collect2=yes
--- 2735,2741 ----
  	;;
  rs6000-ibm-aix[56789].* | powerpc-ibm-aix[56789].*)
  	xm_defines=POSIX
! 	tm_file="${tm_file} rs6000/aix.h rs6000/aix51.h rs6000/xcoff.h"
  	tmake_file=rs6000/t-aix43
  	float_format=none
  	use_collect2=yes
*************** rs6000-ibm-aix[56789].* | powerpc-ibm-ai
*** 2736,2748 ****
  	;;
  rs6000-ibm-aix*)
  	xm_defines=POSIX
! 	tm_file="${tm_file} rs6000/aix.h"
  	float_format=none
  	use_collect2=yes
  	;;
  rs6000-bull-bosx)
  	xm_defines=POSIX
! 	tm_file="${tm_file} rs6000/aix.h"
  	float_format=none
  	use_collect2=yes
  	;;
--- 2743,2755 ----
  	;;
  rs6000-ibm-aix*)
  	xm_defines=POSIX
! 	tm_file="${tm_file} rs6000/aix.h rs6000/xcoff.h"
  	float_format=none
  	use_collect2=yes
  	;;
  rs6000-bull-bosx)
  	xm_defines=POSIX
! 	tm_file="${tm_file} rs6000/aix.h rs6000/xcoff.h"
  	float_format=none
  	use_collect2=yes
  	;;
Index: config/rs6000/aix.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/aix.h,v
retrieving revision 1.20
diff -c -3 -p -w -B -b -r1.20 aix.h
*** aix.h	2001/05/25 22:08:30	1.20
--- aix.h	2001/07/31 17:16:48
*************** Boston, MA 02111-1307, USA.  */
*** 21,78 ****
  
  /* Yes!  We are AIX!  */
  #define DEFAULT_ABI ABI_AIX
! #define TARGET_OBJECT_FORMAT OBJECT_XCOFF
! 
  /* The AIX linker will discard static constructors in object files before
     collect has a chance to see them, so scan the object files directly.  */
  #define COLLECT_EXPORT_LIST
  
- /* The RS/6000 uses the XCOFF format.  */
- #define XCOFF_DEBUGGING_INFO
- 
- /* Define if the object format being used is COFF or a superset.  */
- #define OBJECT_FORMAT_COFF
- 
- /* Define the magic numbers that we recognize as COFF.
-  
-     AIX 4.3 adds U803XTOCMAGIC (0757) for 64-bit objects and AIX V5 adds
-     U64_TOCMAGIC (0767), but collect2.c does not include files in the
-     correct order to conditionally define the symbolic name in this macro.
-  
-     The AIX linker accepts import/export files as object files,
-     so accept "#!" (0x2321) magic number.  */
- #define MY_ISCOFF(magic) \
-   ((magic) == U802WRMAGIC || (magic) == U802ROMAGIC \
-    || (magic) == U802TOCMAGIC || (magic) == 0757 || (magic) == 0767 \
-    || (magic) == 0x2321)
- 
  /* This is the only version of nm that collect2 can work with.  */
  #define REAL_NM_FILE_NAME "/usr/ucb/nm"
  
- /* We don't have GAS for the RS/6000 yet, so don't write out special
-     .stabs in cc1plus.  */
- 
- #define FASCIST_ASSEMBLER
- 
- /* We define this to prevent the name mangler from putting dollar signs into
-    function names.  */
- 
- #define NO_DOLLAR_IN_LABEL
- 
- /* We define this to 0 so that gcc will never accept a dollar sign in a
-    variable name.  This is needed because the AIX assembler will not accept
-    dollar signs.  */
- 
- #define DOLLARS_IN_IDENTIFIERS 0
- 
  /* AIX does not have any init/fini or ctor/dtor sections, so create
      static constructors and destructors as normal functions.  */
  /* #define ASM_OUTPUT_CONSTRUCTOR(file, name) */
  /* #define ASM_OUTPUT_DESTRUCTOR(file, name) */
- 
- /* The prefix to add to user-visible assembler symbols. */
  #define USER_LABEL_PREFIX ""
- 
  /* Don't turn -B into -L if the argument specifies a relative file name.  */
  #define RELATIVE_PREFIX_NOT_LINKDIR
  
--- 21,40 ----
  
  /* Yes!  We are AIX!  */
  #define DEFAULT_ABI ABI_AIX
! #undef TARGET_AIX
! #define TARGET_AIX 1
  /* The AIX linker will discard static constructors in object files before
     collect has a chance to see them, so scan the object files directly.  */
  #define COLLECT_EXPORT_LIST
  
  /* This is the only version of nm that collect2 can work with.  */
  #define REAL_NM_FILE_NAME "/usr/ucb/nm"
  
  /* AIX does not have any init/fini or ctor/dtor sections, so create
      static constructors and destructors as normal functions.  */
  /* #define ASM_OUTPUT_CONSTRUCTOR(file, name) */
  /* #define ASM_OUTPUT_DESTRUCTOR(file, name) */
  #define USER_LABEL_PREFIX  ""
  /* Don't turn -B into -L if the argument specifies a relative file name.  */
  #define RELATIVE_PREFIX_NOT_LINKDIR
  
*************** Boston, MA 02111-1307, USA.  */
*** 90,95 ****
--- 52,133 ----
     %{ansi: -D_ANSI_C_SOURCE}\
     %(cpp_cpu)"
  
+ /* Common CPP definitions used by CPP_SPEC among the various targets
+    for handling -mcpu=xxx switches.  */
+ #define CPP_CPU_SPEC \
+ "%{!mcpu*: \
+   %{mpower: %{!mpower2: -D_ARCH_PWR}} \
+   %{mpower2: -D_ARCH_PWR2} \
+   %{mpowerpc*: -D_ARCH_PPC} \
+   %{mno-power: %{!mpowerpc*: -D_ARCH_COM}} \
+   %{!mno-power: %{!mpower2: %(cpp_default)}}} \
+ %{mcpu=common: -D_ARCH_COM} \
+ %{mcpu=power: -D_ARCH_PWR} \
+ %{mcpu=power2: -D_ARCH_PWR2} \
+ %{mcpu=powerpc: -D_ARCH_PPC} \
+ %{mcpu=rios: -D_ARCH_PWR} \
+ %{mcpu=rios1: -D_ARCH_PWR} \
+ %{mcpu=rios2: -D_ARCH_PWR2} \
+ %{mcpu=rsc: -D_ARCH_PWR} \
+ %{mcpu=rsc1: -D_ARCH_PWR} \
+ %{mcpu=401: -D_ARCH_PPC} \
+ %{mcpu=403: -D_ARCH_PPC} \
+ %{mcpu=505: -D_ARCH_PPC} \
+ %{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
+ %{mcpu=602: -D_ARCH_PPC} \
+ %{mcpu=603: -D_ARCH_PPC} \
+ %{mcpu=603e: -D_ARCH_PPC} \
+ %{mcpu=ec603e: -D_ARCH_PPC} \
+ %{mcpu=604: -D_ARCH_PPC} \
+ %{mcpu=604e: -D_ARCH_PPC} \
+ %{mcpu=620: -D_ARCH_PPC} \
+ %{mcpu=740: -D_ARCH_PPC} \
+ %{mcpu=750: -D_ARCH_PPC} \
+ %{mcpu=801: -D_ARCH_PPC} \
+ %{mcpu=821: -D_ARCH_PPC} \
+ %{mcpu=823: -D_ARCH_PPC} \
+ %{mcpu=860: -D_ARCH_PPC}"
+ 
+ #define CPP_DEFAULT_SPEC "-D_ARCH_PWR"
+ 
+ /* Common ASM definitions used by ASM_SPEC among the various targets
+    for handling -mcpu=xxx switches.  */
+ #define ASM_CPU_SPEC \
+ "%{!mcpu*: \
+   %{mpower: %{!mpower2: -mpwr}} \
+   %{mpower2: -mpwrx} \
+   %{mpowerpc*: -mppc} \
+   %{mno-power: %{!mpowerpc*: -mcom}} \
+   %{!mno-power: %{!mpower2: %(asm_default)}}} \
+ %{mcpu=common: -mcom} \
+ %{mcpu=power: -mpwr} \
+ %{mcpu=power2: -mpwrx} \
+ %{mcpu=powerpc: -mppc} \
+ %{mcpu=rios: -mpwr} \
+ %{mcpu=rios1: -mpwr} \
+ %{mcpu=rios2: -mpwrx} \
+ %{mcpu=rsc: -mpwr} \
+ %{mcpu=rsc1: -mpwr} \
+ %{mcpu=401: -mppc} \
+ %{mcpu=403: -mppc} \
+ %{mcpu=505: -mppc} \
+ %{mcpu=601: -m601} \
+ %{mcpu=602: -mppc} \
+ %{mcpu=603: -mppc} \
+ %{mcpu=603e: -mppc} \
+ %{mcpu=ec603e: -mppc} \
+ %{mcpu=604: -mppc} \
+ %{mcpu=604e: -mppc} \
+ %{mcpu=620: -mppc} \
+ %{mcpu=740: -mppc} \
+ %{mcpu=750: -mppc} \
+ %{mcpu=801: -mppc} \
+ %{mcpu=821: -mppc} \
+ %{mcpu=823: -mppc} \
+ %{mcpu=860: -mppc}"
+ 
+ #define ASM_DEFAULT_SPEC ""
+ 
  /* Tell the assembler to assume that all undefined names are external.
  
     Don't do this until the fixed IBM assembler is more generally available.
*************** Boston, MA 02111-1307, USA.  */
*** 135,296 ****
  /* Profiled library versions are used by linking with special directories.  */
  #define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
  %{p:-L/lib/profiled -L/usr/lib/profiled} %{!shared:%{g*:-lg}} -lc"
- 
- /* Define the extra sections we need.  We define three: one is the read-only
-    data section which is used for constants.  This is a csect whose name is
-    derived from the name of the input file.  The second is for initialized
-    global variables.  This is a csect whose name is that of the variable.
-    The third is the TOC.  */
- 
- #define EXTRA_SECTIONS \
-    read_only_data, private_data, read_only_private_data, toc, bss
- 
- /* Define the routines to implement these extra sections.
-    BIGGEST_ALIGNMENT is 64, so align the sections that much.  */
- 
- #define EXTRA_SECTION_FUNCTIONS				\
- 							\
- void							\
- read_only_data_section ()				\
- {							\
-   if (in_section != read_only_data)			\
-     {							\
-       fprintf (asm_out_file, "\t.csect %s[RO],3\n",	\
- 	       xcoff_read_only_section_name);		\
-       in_section = read_only_data;			\
-     }							\
- }							\
- 							\
- void							\
- private_data_section ()					\
- {							\
-   if (in_section != private_data)			\
-     {							\
-       fprintf (asm_out_file, "\t.csect %s[RW],3\n",	\
- 	       xcoff_private_data_section_name);	\
-       in_section = private_data;			\
-     }							\
- }							\
- 							\
- void							\
- read_only_private_data_section ()			\
- {							\
-   if (in_section != read_only_private_data)		\
-     {							\
-       fprintf (asm_out_file, "\t.csect %s[RO],3\n",	\
- 	       xcoff_private_data_section_name);	\
-       in_section = read_only_private_data;		\
-     }							\
- }							\
- 							\
- void							\
- toc_section ()						\
- {							\
-   if (TARGET_MINIMAL_TOC)				\
-     {							\
-       /* toc_section is always called at least once from ASM_FILE_START, \
- 	 so this is guaranteed to always be defined once and only once   \
- 	 in each file.  */						 \
-       if (! toc_initialized)				\
- 	{						\
- 	  fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);	\
- 	  fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file); \
- 	  toc_initialized = 1;				\
- 	}						\
- 							\
-       if (in_section != toc)				\
- 	fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",	\
- 		 (TARGET_32BIT ? "" : ",3"));		\
-     }							\
-   else							\
-     {							\
-       if (in_section != toc)				\
-         fputs ("\t.toc\n", asm_out_file);		\
-     }							\
-   in_section = toc;					\
- }
- 
- /* Define the name of our readonly data section.  */
  
! #define READONLY_DATA_SECTION read_only_data_section
  
- /* Select the section for an initialized data object.
- 
-    On the RS/6000, we have a special section for all variables except those
-    that are static.  */
- 
- #define SELECT_SECTION(EXP,RELOC)			\
- {							\
-   if ((TREE_CODE (EXP) == STRING_CST			\
-        && ! flag_writable_strings)			\
-       || (TREE_CODE_CLASS (TREE_CODE (EXP)) == 'd'	\
- 	  && TREE_READONLY (EXP) && ! TREE_THIS_VOLATILE (EXP) \
- 	  && DECL_INITIAL (EXP)				\
- 	  && (DECL_INITIAL (EXP) == error_mark_node	\
- 	      || TREE_CONSTANT (DECL_INITIAL (EXP)))	\
- 	  && ! (RELOC)))				\
-     {							\
-       if (TREE_PUBLIC (EXP))				\
-         read_only_data_section ();			\
-       else						\
-         read_only_private_data_section ();		\
-     }							\
-   else							\
-     {							\
-       if (TREE_PUBLIC (EXP))				\
-         data_section ();				\
-       else						\
-         private_data_section ();			\
-     }							\
- }
  
- /* Return non-zero if this entry is to be written into the constant
-    pool in a special way.  We do so if this is a SYMBOL_REF, LABEL_REF
-    or a CONST containing one of them.  If -mfp-in-toc (the default),
-    we also do this for floating-point constants.  We actually can only
-    do this if the FP formats of the target and host machines are the
-    same, but we can't check that since not every file that uses
-    GO_IF_LEGITIMATE_ADDRESS_P includes real.h.  We also do this when
-    we can write the entry into the TOC and the entry is not larger
-    than a TOC entry.  */
- 
- #define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X, MODE)			\
-   (TARGET_TOC								\
-    && (GET_CODE (X) == SYMBOL_REF					\
-        || (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS	\
- 	   && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF)		\
-        || GET_CODE (X) == LABEL_REF					\
-        || (GET_CODE (X) == CONST_INT 					\
- 	   && GET_MODE_BITSIZE (MODE) <= GET_MODE_BITSIZE (Pmode))	\
-        || (GET_CODE (X) == CONST_DOUBLE					\
- 	   && (TARGET_POWERPC64						\
- 	       || TARGET_MINIMAL_TOC					\
- 	       || (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT		\
- 		   && ! TARGET_NO_FP_IN_TOC)))))
- 
- /* Select section for constant in constant pool.
- 
-    On RS/6000, all constants are in the private read-only data area.
-    However, if this is being placed in the TOC it must be output as a
-    toc entry.  */
- 
- #define SELECT_RTX_SECTION(MODE, X)			\
- { if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (X, MODE))	\
-     toc_section ();					\
-   else							\
-     read_only_private_data_section ();			\
- }
- 
- /* If we are referencing a function that is static or is known to be
-    in this file, make the SYMBOL_REF special.  We can use this to indicate
-    that we can branch to this function without emitting a no-op after the
-    call.  Do not set this flag if the function is weakly defined. */
- 
- #define ENCODE_SECTION_INFO(DECL)			\
-   if (TREE_CODE (DECL) == FUNCTION_DECL			\
-       && (TREE_ASM_WRITTEN (DECL) || ! TREE_PUBLIC (DECL)) \
-       && ! DECL_WEAK (DECL))				\
-     SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1;
  
  /* Indicate that jump tables go in the text section.  */
  
--- 173,198 ----
  /* Profiled library versions are used by linking with special directories.  */
  #define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
  %{p:-L/lib/profiled -L/usr/lib/profiled} %{!shared:%{g*:-lg}} -lc"
  
! /* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints.  */
! #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
!   (TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
! 	      ? get_inner_array_type (FIELD) \
! 	      : TREE_TYPE (FIELD)) == DFmode \
!    ? MIN ((COMPUTED), 32) : (COMPUTED))
! 
! /* AIX increases natural record alignment to doubleword if the first
!    field is an FP double while the FP fields remain word aligned.  */
! #define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED)	\
!   ((TREE_CODE (STRUCT) == RECORD_TYPE			\
!     || TREE_CODE (STRUCT) == UNION_TYPE			\
!     || TREE_CODE (STRUCT) == QUAL_UNION_TYPE)		\
!    && TYPE_FIELDS (STRUCT) != 0				\
!    && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode	\
!    ? MAX (MAX ((COMPUTED), (SPECIFIED)), BIGGEST_ALIGNMENT) \
!    : MAX ((COMPUTED), (SPECIFIED)))
  
  
  
  /* Indicate that jump tables go in the text section.  */
  
*************** toc_section ()						\
*** 315,337 ****
    { "link_syscalls",            LINK_SYSCALLS_SPEC },			\
    { "link_libg",                LINK_LIBG_SPEC }
  
- /* FP save and restore routines.  */
- #define	SAVE_FP_PREFIX "._savef"
- #define SAVE_FP_SUFFIX ""
- #define	RESTORE_FP_PREFIX "._restf"
- #define RESTORE_FP_SUFFIX ""
- 
  /* Define cutoff for using external functions to save floating point.  */
  #define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) == 62 || (FIRST_REG) == 63)
  
- /* Function name to call to do profiling.  */
- #define RS6000_MCOUNT ".__mcount"
- 
- /* Function names to call to do floating point truncation.  */
- 
- #define RS6000_ITRUNC "__itrunc"
- #define RS6000_UITRUNC "__uitrunc"
- 
  /* Optabs entries for the int->float routines, using the standard
     AIX names.  */
  #define INIT_TARGET_OPTABS						\
--- 217,225 ----
*************** toc_section ()						\
*** 349,598 ****
  
  /* AIX allows r13 to be used.  */
  #define FIXED_R13 0
- 
- /* This outputs NAME to FILE up to the first null or '['.  */
- 
- #define RS6000_OUTPUT_BASENAME(FILE, NAME)	\
-   {						\
-     const char *_p;				\
- 						\
-     STRIP_NAME_ENCODING (_p, (NAME));		\
-     assemble_name ((FILE), _p);			\
-   }
- 
- /* This is how to output the definition of a user-level label named NAME,
-    such as the label on a static function or variable NAME.  */
- 
- #define ASM_OUTPUT_LABEL(FILE,NAME)	\
-   do { RS6000_OUTPUT_BASENAME (FILE, NAME); fputs (":\n", FILE); } while (0)
- 
- /* This is how to output a command to make the user-level label named NAME
-    defined for reference from other files.  */
- 
- #define ASM_GLOBALIZE_LABEL(FILE,NAME)	\
-   do { fputs ("\t.globl ", FILE);	\
-        RS6000_OUTPUT_BASENAME (FILE, NAME); putc ('\n', FILE);} while (0)
- 
- /* Remove any trailing [DS] or the like from the symbol name.  */
- 
- #define STRIP_NAME_ENCODING(VAR,NAME)			\
-   do							\
-     {							\
-       const char *_name = (NAME);			\
-       size_t _len;					\
-       if (*_name == '*')				\
-         _name++;					\
-       _len = strlen (_name);				\
-       if (_name[_len - 1] != ']')			\
- 	(VAR) = _name;					\
-       else						\
- 	{						\
- 	  char *_new_name = (char *) alloca (_len + 1);	\
- 	  strcpy (_new_name, _name);			\
- 	  _new_name[_len - 4] = '\0';			\
- 	  (VAR) = _new_name;				\
- 	}						\
-     }							\
-   while (0)
- 
- /* Output at beginning of assembler file.
- 
-    Initialize the section names for the RS/6000 at this point.
- 
-    Specify filename, including full path, to assembler.
- 
-    We want to go into the TOC section so at least one .toc will be emitted.
-    Also, in order to output proper .bs/.es pairs, we need at least one static
-    [RW] section emitted.
- 
-    Finally, declare mcount when profiling to make the assembler happy.  */
- 
- #define ASM_FILE_START(FILE)					\
- {								\
-   rs6000_gen_section_name (&xcoff_bss_section_name,		\
- 			   main_input_filename, ".bss_");	\
-   rs6000_gen_section_name (&xcoff_private_data_section_name,	\
- 			   main_input_filename, ".rw_");	\
-   rs6000_gen_section_name (&xcoff_read_only_section_name,	\
- 			   main_input_filename, ".ro_");	\
- 								\
-   fprintf (FILE, "\t.file\t\"%s\"\n", main_input_filename);	\
-   if (TARGET_64BIT)						\
-     fputs ("\t.machine\t\"ppc64\"\n", FILE);			\
-   toc_section ();						\
-   if (write_symbols != NO_DEBUG)				\
-     private_data_section ();					\
-   text_section ();						\
-   if (profile_flag)						\
-     fprintf (FILE, "\t.extern %s\n", RS6000_MCOUNT);		\
-   rs6000_file_start (FILE, TARGET_CPU_DEFAULT);			\
- }
- 
- /* Output at end of assembler file.
- 
-    On the RS/6000, referencing data should automatically pull in text.  */
- 
- #define ASM_FILE_END(FILE)					\
- {								\
-   text_section ();						\
-   fputs ("_section_.text:\n", FILE);				\
-   data_section ();						\
-   fputs (TARGET_32BIT						\
- 	 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n", FILE); \
- }
- 
- /* This macro produces the initial definition of a function name.
-    On the RS/6000, we need to place an extra '.' in the function name and
-    output the function descriptor.
- 
-    The csect for the function will have already been created by the
-    `text_section' call previously done.  We do have to go back to that
-    csect, however.
- 
-    The third and fourth parameters to the .function pseudo-op (16 and 044)
-    are placeholders which no longer have any use.  */
- 
- #define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL)		\
- { if (TREE_PUBLIC (DECL))					\
-     {								\
-       fputs ("\t.globl .", FILE);				\
-       RS6000_OUTPUT_BASENAME (FILE, NAME);			\
-       putc ('\n', FILE);					\
-     }								\
-   else								\
-     {								\
-       fputs ("\t.lglobl .", FILE);				\
-       RS6000_OUTPUT_BASENAME (FILE, NAME);			\
-       putc ('\n', FILE);					\
-     }								\
-   fputs ("\t.csect ", FILE);					\
-   RS6000_OUTPUT_BASENAME (FILE, NAME);				\
-   fputs (TARGET_32BIT ? "[DS]\n" : "[DS],3\n", FILE);		\
-   RS6000_OUTPUT_BASENAME (FILE, NAME);				\
-   fputs (":\n", FILE);						\
-   fputs (TARGET_32BIT ? "\t.long ." : "\t.llong .", FILE);	\
-   RS6000_OUTPUT_BASENAME (FILE, NAME);				\
-   fputs (", TOC[tc0], 0\n", FILE);				\
-   in_section = no_section;					\
-   function_section(DECL);					\
-   putc ('.', FILE);						\
-   RS6000_OUTPUT_BASENAME (FILE, NAME);				\
-   fputs (":\n", FILE);						\
-   if (write_symbols == XCOFF_DEBUG)				\
-     xcoffout_declare_function (FILE, DECL, NAME);		\
- }
- 
- /* Output a reference to SYM on FILE.  */
- 
- #define ASM_OUTPUT_SYMBOL_REF(FILE, SYM) \
-   rs6000_output_symbol_ref (FILE, SYM)
- 
- /* This says how to output an external.  */
- 
- #define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME)	\
- { rtx _symref = XEXP (DECL_RTL (DECL), 0);	\
-   if ((TREE_CODE (DECL) == VAR_DECL		\
-        || TREE_CODE (DECL) == FUNCTION_DECL)	\
-       && (NAME)[strlen (NAME) - 1] != ']')	\
-     {						\
-       char *_name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \
-       strcpy (_name, XSTR (_symref, 0));	\
-       strcat (_name, TREE_CODE (DECL) == FUNCTION_DECL ? "[DS]" : "[RW]"); \
-       XSTR (_symref, 0) = _name;		\
-     }						\
- }
- 
- /* This is how to output an internal numbered label where
-    PREFIX is the class of label and NUM is the number within the class.  */
- 
- #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)	\
-   fprintf (FILE, "%s..%d:\n", PREFIX, NUM)
- 
- /* This is how to output an internal label prefix.  rs6000.c uses this
-    when generating traceback tables.  */
- 
- #define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX)   \
-   fprintf (FILE, "%s..", PREFIX)
- 
- /* This is how to output a label for a jump table.  Arguments are the same as
-    for ASM_OUTPUT_INTERNAL_LABEL, except the insn for the jump table is
-    passed. */
- 
- #define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN)	\
- { ASM_OUTPUT_ALIGN (FILE, 2); ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); }
- 
- /* This is how to store into the string LABEL
-    the symbol_ref name of an internal numbered label where
-    PREFIX is the class of label and NUM is the number within the class.
-    This is suitable for output with `assemble_name'.  */
- 
- #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)	\
-   sprintf (LABEL, "*%s..%ld", (PREFIX), (long)(NUM))
- 
- /* This is how to output an assembler line to define N characters starting
-    at P to FILE.  */
- 
- #define ASM_OUTPUT_ASCII(FILE, P, N)  output_ascii ((FILE), (P), (N))
- 
- /* This is how to advance the location counter by SIZE bytes.  */
- 
- #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
-   fprintf (FILE, "\t.space %d\n", (SIZE))
- 
- /* This says how to output an assembler line
-    to define a global common symbol.  */
- 
- #define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGNMENT)	\
-   do { fputs (".comm ", (FILE));			\
-        RS6000_OUTPUT_BASENAME ((FILE), (NAME));		\
-        if ( (SIZE) > 4)					\
-          fprintf ((FILE), ",%d,3\n", (SIZE));		\
-        else						\
- 	 fprintf( (FILE), ",%d\n", (SIZE));		\
-   } while (0)
- 
- /* These are various definitions for DWARF output.  They could just
-    use '.long' or '.word', but that aligns to a 4-byte boundary which
-    is not what is required.  So we define a million macros...  */
- 
- #define UNALIGNED_SHORT_ASM_OP		"\t.vbyte\t2,"
- #define UNALIGNED_INT_ASM_OP		"\t.vbyte\t4,"
- #define UNALIGNED_DOUBLE_INT_ASM_OP	"\t.vbyte\t8,"
- 
- /* Output before instructions.  */
- #define TEXT_SECTION_ASM_OP "\t.csect .text[PR]"
- 
- /* Output before writable data.
-    Align entire section to BIGGEST_ALIGNMENT.  */
- #define DATA_SECTION_ASM_OP "\t.csect .data[RW],3"
- 
- /* Define unique section name -- functions only.  */
- #define UNIQUE_SECTION(DECL,RELOC)			\
-   do {							\
-     int len;						\
-     const char *name;					\
-     char *string;					\
- 							\
-     if (TREE_CODE (DECL) == FUNCTION_DECL) {		\
-       name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \
-       len = strlen (name) + 5;				\
-       string = alloca (len) + 1;			\
-       sprintf (string, ".%s[PR]", name);		\
-       DECL_SECTION_NAME (DECL) = build_string (len, string); \
-     }							\
-   } while (0)
- 
- #define ASM_OUTPUT_SECTION_NAME(ASM_OUT_FILE,DECL,NAME,RELOC)	\
-   do { fputs ("\t.csect ", ASM_OUT_FILE);			\
-        fputs (TREE_STRING_POINTER (DECL_SECTION_NAME (DECL)), ASM_OUT_FILE); \
-        putc ('\n', ASM_OUT_FILE);				\
-   } while (0)
- 
- /* Define the name of the section to use for the exception tables.
-    TODO: test and see if we can use read_only_data_section, if so,
-    remove this.  */
- 
- #define EXCEPTION_SECTION data_section
  
  /* __throw will restore its own return address to be the same as the
     return address of the function that the throw is being made to.
--- 237,242 ----
Index: config/rs6000/darwin.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/darwin.h,v
retrieving revision 1.1
diff -c -3 -p -w -B -b -r1.1 darwin.h
*** darwin.h	2001/04/12 02:12:59	1.1
--- darwin.h	2001/07/31 17:16:48
*************** Boston, MA 02111-1307, USA.  */
*** 173,175 ****
--- 173,193 ----
  
  /* Fix for emit_group_load (): force large constants to be pushed via regs.  */
  #define ALWAYS_PUSH_CONSTS_USING_REGS_P		1
+ 
+ /* Darwin word-aligns FP doubles but doubleword-aligns 64-bit ints.  */
+ #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
+   (TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
+ 	      ? get_inner_array_type (FIELD) \
+ 	      : TREE_TYPE (FIELD)) == DFmode \
+    ? MIN ((COMPUTED), 32) : (COMPUTED))
+ 
+ /* Darwin increases natural record alignment to doubleword if the first
+    field is an FP double while the FP fields remain word aligned.  */
+ #define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED)	\
+   ((TREE_CODE (STRUCT) == RECORD_TYPE			\
+     || TREE_CODE (STRUCT) == UNION_TYPE			\
+     || TREE_CODE (STRUCT) == QUAL_UNION_TYPE)		\
+    && TYPE_FIELDS (STRUCT) != 0				\
+    && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode	\
+    ? MAX (MAX ((COMPUTED), (SPECIFIED)), BIGGEST_ALIGNMENT) \
+    : MAX ((COMPUTED), (SPECIFIED)))
Index: config/rs6000/linux.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/linux.h,v
retrieving revision 1.27
diff -c -3 -p -w -B -b -r1.27 linux.h
*** linux.h	2001/07/21 09:42:20	1.27
--- linux.h	2001/07/31 17:16:48
*************** Boston, MA 02111-1307, USA.  */
*** 69,74 ****
--- 69,79 ----
  #undef ASM_APP_OFF
  #define ASM_APP_OFF "#NO_APP\n"
  
+ #undef DEFAULT_VTABLE_THUNKS
+ #ifndef USE_GNULIBC_1
+ #define DEFAULT_VTABLE_THUNKS 1
+ #endif
+ 
  /* Do code reading to identify a signal frame, and set the frame
     state data appropriately.  See unwind-dw2.c for the structs.  */
  
Index: config/rs6000/rs6000-protos.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000-protos.h,v
retrieving revision 1.22
diff -c -3 -p -w -B -b -r1.22 rs6000-protos.h
*** rs6000-protos.h	2001/07/06 18:40:15	1.22
--- rs6000-protos.h	2001/07/31 17:16:49
*************** extern int any_operand PARAMS ((rtx, enu
*** 34,39 ****
--- 34,40 ----
  extern int short_cint_operand PARAMS ((rtx, enum machine_mode));
  extern int u_short_cint_operand PARAMS ((rtx, enum machine_mode));
  extern int non_short_cint_operand PARAMS ((rtx, enum machine_mode));
+ extern int exact_log2_cint_operand PARAMS ((rtx, enum machine_mode));
  extern int gpc_reg_operand PARAMS ((rtx, enum machine_mode));
  extern int cc_reg_operand PARAMS ((rtx, enum machine_mode));
  extern int cc_reg_not_cr0_operand PARAMS ((rtx, enum machine_mode));
*************** extern int reg_or_neg_short_operand PARA
*** 42,47 ****
--- 43,50 ----
  extern int reg_or_u_short_operand PARAMS ((rtx, enum machine_mode));
  extern int reg_or_cint_operand PARAMS ((rtx, enum machine_mode));
  extern int reg_or_arith_cint_operand PARAMS ((rtx, enum machine_mode));
+ extern int reg_or_add_cint64_operand PARAMS ((rtx, enum machine_mode));
+ extern int reg_or_sub_cint64_operand PARAMS ((rtx, enum machine_mode));
  extern int reg_or_logical_cint_operand PARAMS ((rtx, enum machine_mode));
  extern int got_operand PARAMS ((rtx, enum machine_mode));
  extern int got_no_const_operand PARAMS ((rtx, enum machine_mode));
*************** extern enum rtx_code rs6000_reverse_cond
*** 96,101 ****
--- 99,105 ----
  extern void rs6000_emit_sCOND PARAMS ((enum rtx_code, rtx));
  extern void rs6000_emit_cbranch PARAMS ((enum rtx_code, rtx));
  extern char * output_cbranch PARAMS ((rtx, const char *, int, rtx));
+ extern rtx rs6000_emit_set_const PARAMS ((rtx, enum machine_mode, rtx, int));
  extern int rs6000_emit_cmove PARAMS ((rtx, rtx, rtx, rtx));
  extern void rs6000_emit_minmax PARAMS ((rtx, enum rtx_code, rtx, rtx));
  extern void output_toc PARAMS ((FILE *, rtx, int, enum machine_mode));
Index: config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.193
diff -c -3 -p -w -B -b -r1.193 rs6000.c
*** rs6000.c	2001/07/11 20:35:54	1.193
--- rs6000.c	2001/07/31 17:16:56
*************** static int rs6000_ra_ever_killed PARAMS 
*** 128,133 ****
--- 128,135 ----
  static int rs6000_valid_type_attribute_p PARAMS ((tree, tree, tree, tree));
  static void rs6000_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
  static void rs6000_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
+ static rtx rs6000_emit_set_long_const PARAMS ((rtx,
+   HOST_WIDE_INT, HOST_WIDE_INT));
  
  /* Default register names.  */
  char rs6000_reg_names[][8] =
*************** rs6000_override_options (default_cpu)
*** 364,378 ****
  	}
      }
  
!   if (flag_pic && (DEFAULT_ABI == ABI_AIX))
      {
!       warning ("-f%s ignored for AIX (all code is position independent)",
  	       (flag_pic > 1) ? "PIC" : "pic");
        flag_pic = 0;
      }
  
    if (flag_function_sections && (write_symbols != NO_DEBUG)
!       && (DEFAULT_ABI == ABI_AIX))
      {
        warning ("-ffunction-sections disabled on AIX when debugging");
        flag_function_sections = 0;
--- 366,381 ----
  	}
      }
  
!   if (flag_pic && DEFAULT_ABI == ABI_AIX)
      {
!       warning ("-f%s ignored (all code is position independent)",
  	       (flag_pic > 1) ? "PIC" : "pic");
        flag_pic = 0;
      }
  
+ #ifdef XCOFF_DEBUGGING_INFO
    if (flag_function_sections && (write_symbols != NO_DEBUG)
!       && DEFAULT_ABI == ABI_AIX)
      {
        warning ("-ffunction-sections disabled on AIX when debugging");
        flag_function_sections = 0;
*************** rs6000_override_options (default_cpu)
*** 383,388 ****
--- 386,392 ----
        warning ("-fdata-sections not supported on AIX");
        flag_data_sections = 0;
      }
+ #endif
  
    /* Set debug flags */
    if (rs6000_debug_name)
*************** non_short_cint_operand (op, mode)
*** 585,590 ****
--- 589,607 ----
  	  && (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) >= 0x10000);
  }
  
+ /* Returns 1 if OP is a CONST_INT that is a positive value
+    and an exact power of 2.  */
+ 
+ int
+ exact_log2_cint_operand (op, mode)
+      register rtx op;
+      enum machine_mode mode ATTRIBUTE_UNUSED;
+ {
+   return (GET_CODE (op) == CONST_INT
+ 	  && INTVAL (op) > 0
+ 	  && exact_log2 (INTVAL (op)) >= 0);
+ }
+ 
  /* Returns 1 if OP is a register that is not special (i.e., not MQ,
     ctr, or lr).  */
  
*************** reg_or_arith_cint_operand (op, mode)
*** 693,698 ****
--- 710,751 ----
  		 ));
  }
  
+ /* Return 1 is the operand is either a non-special register or a 32-bit
+    signed constant integer valid for 64-bit addition.  */
+ 
+ int
+ reg_or_add_cint64_operand (op, mode)
+     register rtx op;
+     enum machine_mode mode;
+ {
+      return (gpc_reg_operand (op, mode)
+ 	     || (GET_CODE (op) == CONST_INT
+ 		 && INTVAL (op) < 0x7fff8000
+ #if HOST_BITS_PER_WIDE_INT != 32
+ 		 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80008000)
+ 		     < 0x100000000ll)
+ #endif
+ 		 ));
+ }
+ 
+ /* Return 1 is the operand is either a non-special register or a 32-bit
+    signed constant integer valid for 64-bit subtraction.  */
+ 
+ int
+ reg_or_sub_cint64_operand (op, mode)
+     register rtx op;
+     enum machine_mode mode;
+ {
+      return (gpc_reg_operand (op, mode)
+ 	     || (GET_CODE (op) == CONST_INT
+ 		 && (- INTVAL (op)) < 0x7fff8000
+ #if HOST_BITS_PER_WIDE_INT != 32
+ 		 && ((unsigned HOST_WIDE_INT) ((- INTVAL (op)) + 0x80008000)
+ 		     < 0x100000000ll)
+ #endif
+ 		 ));
+ }
+ 
  /* Return 1 is the operand is either a non-special register or ANY
     32-bit unsigned constant integer.  */
  
*************** add_operand (op, mode)
*** 996,1004 ****
      register rtx op;
      enum machine_mode mode;
  {
!   return (reg_or_short_operand (op, mode)
! 	  || (GET_CODE (op) == CONST_INT
! 	      && CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')));
  }
  
  /* Return 1 if OP is a constant but not a valid add_operand.  */
--- 1049,1059 ----
      register rtx op;
      enum machine_mode mode;
  {
!   if (GET_CODE (op) == CONST_INT)
!     return (CONST_OK_FOR_LETTER_P (INTVAL(op), 'I')
! 	    || CONST_OK_FOR_LETTER_P (INTVAL(op), 'L'));
! 
!   return gpc_reg_operand (op, mode);
  }
  
  /* Return 1 if OP is a constant but not a valid add_operand.  */
*************** rs6000_legitimate_address (mode, x, reg_
*** 1636,1641 ****
--- 1691,1814 ----
    return 0;
  }
  
+ /* Try to output insns to set TARGET equal to the constant C if it can be
+    done in less than N insns.  Do all computations in MODE.  Returns the place
+    where the output has been placed if it can be done and the insns have been
+    emitted.  If it would take more than N insns, zero is returned and no
+    insns and emitted.  */
+ 
+ rtx
+ rs6000_emit_set_const (dest, mode, source, n)
+      rtx dest, source;
+      enum machine_mode mode;
+      int n ATTRIBUTE_UNUSED;
+ {
+   HOST_WIDE_INT c0, c1;
+ 
+   if (mode == QImode || mode == HImode || mode == SImode)
+     {
+       if (dest == NULL)
+         dest = gen_reg_rtx (mode);
+       emit_insn (gen_rtx_SET (VOIDmode, dest, source));
+       return dest;
+     }
+ 
+   if (GET_CODE (source) == CONST_INT)
+     {
+       c0 = INTVAL (source);
+       c1 = -(c0 < 0);
+     }
+   else if (GET_CODE (source) == CONST_DOUBLE)
+     {
+ #if HOST_BITS_PER_WIDE_INT >= 64
+       c0 = CONST_DOUBLE_LOW (source);
+       c1 = -(c0 < 0);
+ #else
+       c0 = CONST_DOUBLE_LOW (source);
+       c1 = CONST_DOUBLE_HIGH (source);
+ #endif
+     }
+   else
+     abort();
+ 
+   return rs6000_emit_set_long_const (dest, c0, c1);
+ }
+ 
+ /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
+    fall back to a straight forward decomposition.  We do this to avoid
+    exponential run times encountered when looking for longer sequences
+    with rs6000_emit_set_const.  */
+ static rtx
+ rs6000_emit_set_long_const (dest, c1, c2)
+      rtx dest;
+      HOST_WIDE_INT c1, c2;
+ {
+   if (!TARGET_POWERPC64)
+     {
+       rtx operand1, operand2;
+ 
+       operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
+ 					DImode);
+       operand2 = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
+ 					DImode);
+       emit_move_insn (operand1, GEN_INT (c1));
+       emit_move_insn (operand2, GEN_INT (c2));
+     }
+   else
+     {
+       HOST_WIDE_INT d1, d2, d3, d4;
+ 
+   /* Decompose the entire word */
+ #if HOST_BITS_PER_WIDE_INT >= 64
+       if (c2 != -(c1 < 0))
+ 	abort ();
+       d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
+       c1 -= d1;
+       d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
+       c1 = (c1 - d2) >> 32;
+       d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
+       c1 -= d3;
+       d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
+       if (c1 != d4)
+ 	abort ();
+ #else
+       d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
+       c1 -= d1;
+       d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
+       if (c1 != d2)
+ 	abort ();
+       c2 += (d2 < 0);
+       d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000;
+       c2 -= d3;
+       d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000;
+       if (c2 != d4)
+ 	abort ();
+ #endif
+ 
+       /* Construct the high word */
+       if (d4)
+ 	{
+ 	  emit_move_insn (dest, GEN_INT (d4));
+ 	  if (d3)
+ 	    emit_move_insn (dest,
+ 			    gen_rtx_PLUS (DImode, dest, GEN_INT (d3)));
+ 	}
+       else
+ 	emit_move_insn (dest, GEN_INT (d3));
+ 
+       /* Shift it into place */
+       emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
+ 
+       /* Add in the low bits.  */
+       if (d2)
+ 	emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, GEN_INT (d2)));
+       if (d1)
+ 	emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, GEN_INT (d1)));
+     }
+ 
+   return dest;
+ }
+ 
  /* Emit a move from SOURCE to DEST in mode MODE.  */
  void
  rs6000_emit_move (dest, source, mode)
*************** print_operand (file, x, code)
*** 4107,4112 ****
--- 4280,4286 ----
      case 'p':
        /* X is a CONST_INT that is a power of two.  Output the logarithm.  */
        if (! INT_P (x)
+ 	  || INT_LOWPART (x) < 0
  	  || (i = exact_log2 (INT_LOWPART (x))) < 0)
  	output_operand_lossage ("invalid %%p value");
        else
*************** print_operand_address (file, x)
*** 4512,4521 ****
  #endif
    else if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
      {
!       if (TARGET_AIX)
  	{
  	  rtx contains_minus = XEXP (x, 1); 
! 	  rtx minus;
  	  
  	  /* Find the (minus (sym) (toc)) buried in X, and temporarily
  	     turn it into (sym) for output_addr_const. */
--- 4686,4696 ----
  #endif
    else if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
      {
!       if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
  	{
  	  rtx contains_minus = XEXP (x, 1);
! 	  rtx minus, symref;
! 	  const char *name;
  	  
  	  /* Find the (minus (sym) (toc)) buried in X, and temporarily
  	     turn it into (sym) for output_addr_const. */
*************** print_operand_address (file, x)
*** 4523,4530 ****
  	    contains_minus = XEXP (contains_minus, 0);
  
  	  minus = XEXP (contains_minus, 0); 
! 	  XEXP (contains_minus, 0) = XEXP (minus, 0);
  	  output_addr_const (file, XEXP (x, 1)); 	  
  	  XEXP (contains_minus, 0) = minus;
  	}
        else
--- 4698,4718 ----
  	    contains_minus = XEXP (contains_minus, 0);
  
  	  minus = XEXP (contains_minus, 0);
! 	  symref = XEXP (minus, 0);
! 	  XEXP (contains_minus, 0) = symref;
! 	  if (TARGET_ELF)
! 	    {
! 	      char *newname;
! 
! 	      name = XSTR (symref, 0);
! 	      newname = alloca (strlen (name) + sizeof ("@toc"));
! 	      strcpy (newname, name);
! 	      strcat (newname, "@toc");
! 	      XSTR (symref, 0) = newname;
! 	    }
  	  output_addr_const (file, XEXP (x, 1));
+ 	  if (TARGET_ELF)
+ 	    XSTR (symref, 0) = name;
  	  XEXP (contains_minus, 0) = minus;
  	}
        else
*************** rs6000_stack_info ()
*** 5137,5143 ****
    info_ptr->first_gp_reg_save = first_reg_to_save ();
    /* Assume that we will have to save PIC_OFFSET_TABLE_REGNUM, 
       even if it currently looks like we won't.  */
!   if (((flag_pic == 1
  	&& (abi == ABI_V4 || abi == ABI_SOLARIS))
         || (flag_pic &&
  	   abi == ABI_DARWIN))
--- 5325,5332 ----
    info_ptr->first_gp_reg_save = first_reg_to_save ();
    /* Assume that we will have to save PIC_OFFSET_TABLE_REGNUM, 
       even if it currently looks like we won't.  */
!   if (((TARGET_TOC && TARGET_MINIMAL_TOC)
!        || (flag_pic == 1
  	   && (abi == ABI_V4 || abi == ABI_SOLARIS))
         || (flag_pic &&
  	   abi == ABI_DARWIN))
*************** rs6000_emit_load_toc_table (fromprolog)
*** 5459,5465 ****
    rtx dest;
    dest = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
  
!   if (TARGET_ELF)
      {
        if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) 
  	  && flag_pic == 1)
--- 5648,5654 ----
    rtx dest;
    dest = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
  
!   if (TARGET_ELF && DEFAULT_ABI != ABI_AIX)
      {
        if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) 
  	  && flag_pic == 1)
*************** rs6000_emit_load_toc_table (fromprolog)
*** 5467,5476 ****
  	  rtx temp = (fromprolog 
  		      ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
  		      : gen_reg_rtx (Pmode));
- 	  if (TARGET_32BIT)
  	    rs6000_maybe_dead (emit_insn (gen_load_toc_v4_pic_si (temp)));
- 	  else
- 	    rs6000_maybe_dead (emit_insn (gen_load_toc_v4_pic_di (temp)));
  	  rs6000_maybe_dead (emit_move_insn (dest, temp));
  	}
        else if (flag_pic == 2)
--- 5656,5662 ----
*************** output_toc (file, x, labelno, mode)
*** 7259,7277 ****
        if (TARGET_64BIT)
  	{
  	  if (TARGET_MINIMAL_TOC)
! 	    fprintf (file, "\t.llong 0x%lx%08lx\n", k[0], k[1]);
  	  else
! 	    fprintf (file, "\t.tc FD_%lx_%lx[TC],0x%lx%08lx\n",
! 		     k[0], k[1], k[0] & 0xffffffff, k[1] & 0xffffffff);
  	  return;
  	}
        else
  	{
  	  if (TARGET_MINIMAL_TOC)
! 	    fprintf (file, "\t.long 0x%lx\n\t.long 0x%lx\n", k[0], k[1]);
  	  else
! 	    fprintf (file, "\t.tc FD_%lx_%lx[TC],0x%lx,0x%lx\n",
! 		     k[0], k[1], k[0], k[1]);
  	  return;
  	}
      }
--- 7445,7463 ----
        if (TARGET_64BIT)
  	{
  	  if (TARGET_MINIMAL_TOC)
! 	    fputs (DOUBLE_INT_ASM_OP, file);
  	  else
! 	    fprintf (file, "\t.tc FD_%lx_%lx[TC],", k[0], k[1]);
! 	  fprintf (file, "0x%lx%08lx\n", k[0], k[1]);
  	  return;
  	}
        else
  	{
  	  if (TARGET_MINIMAL_TOC)
! 	    fputs ("\t.long ", file);
  	  else
! 	    fprintf (file, "\t.tc FD_%lx_%lx[TC],", k[0], k[1]);
! 	  fprintf (file, "0x%lx,0x%lx\n", k[0], k[1]);
  	  return;
  	}
      }
*************** output_toc (file, x, labelno, mode)
*** 7286,7302 ****
        if (TARGET_64BIT)
  	{
  	  if (TARGET_MINIMAL_TOC)
! 	    fprintf (file, "\t.llong 0x%lx00000000\n", l);
  	  else
! 	    fprintf (file, "\t.tc FS_%lx[TC],0x%lx00000000\n", l, l);
  	  return;
  	}
        else
  	{
  	  if (TARGET_MINIMAL_TOC)
! 	    fprintf (file, "\t.long 0x%lx\n", l);
  	  else
! 	    fprintf (file, "\t.tc FS_%lx[TC],0x%lx\n", l, l);
  	  return;
  	}
      }
--- 7472,7490 ----
        if (TARGET_64BIT)
  	{
  	  if (TARGET_MINIMAL_TOC)
! 	    fputs (DOUBLE_INT_ASM_OP, file);
  	  else
! 	    fprintf (file, "\t.tc FS_%lx[TC],", l);
! 	  fprintf (file, "0x%lx00000000\n", l);
  	  return;
  	}
        else
  	{
  	  if (TARGET_MINIMAL_TOC)
! 	    fputs ("\t.long ", file);
  	  else
! 	    fprintf (file, "\t.tc FS_%lx[TC],", l);
! 	  fprintf (file, "0x%lx\n", l);
  	  return;
  	}
      }
*************** output_toc (file, x, labelno, mode)
*** 7344,7353 ****
        if (TARGET_64BIT)
  	{
  	  if (TARGET_MINIMAL_TOC)
! 	    fprintf (file, "\t.llong 0x%lx%08lx\n", (long)high, (long)low);
  	  else
! 	    fprintf (file, "\t.tc ID_%lx_%lx[TC],0x%lx%08lx\n",
! 		     (long)high, (long)low, (long)high, (long)low);
  	  return;
  	}
        else
--- 7532,7541 ----
        if (TARGET_64BIT)
  	{
  	  if (TARGET_MINIMAL_TOC)
! 	    fputs (DOUBLE_INT_ASM_OP, file);
  	  else
! 	    fprintf (file, "\t.tc ID_%lx_%lx[TC],", (long)high, (long)low);
! 	  fprintf (file, "0x%lx%08lx\n", (long) high, (long) low);
  	  return;
  	}
        else
*************** output_toc (file, x, labelno, mode)
*** 7355,7374 ****
  	  if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
  	    {
  	      if (TARGET_MINIMAL_TOC)
! 		fprintf (file, "\t.long 0x%lx\n\t.long 0x%lx\n",
! 			 (long)high, (long)low);
  	      else
! 		fprintf (file, "\t.tc ID_%lx_%lx[TC],0x%lx,0x%lx\n",
! 			 (long)high, (long)low, (long)high, (long)low);
  	    }
  	  else
  	    {
  	      if (TARGET_MINIMAL_TOC)
! 		fprintf (file, "\t.long 0x%lx\n",
! 			 (long)low);
  	      else
! 		fprintf (file, "\t.tc IS_%lx[TC],0x%lx\n",
! 			 (long)low, (long)low);
  	    }
  	  return;
  	}
--- 7543,7561 ----
  	  if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
  	    {
  	      if (TARGET_MINIMAL_TOC)
! 		fputs ("\t.long ", file);
  	      else
! 		fprintf (file, "\t.tc ID_%lx_%lx[TC],",
! 			 (long)high, (long)low);
! 	      fprintf (file, "0x%lx,0x%lx\n", (long) high, (long) low);
  	    }
  	  else
  	    {
  	      if (TARGET_MINIMAL_TOC)
! 		fputs ("\t.long ", file);
  	      else
! 		fprintf (file, "\t.tc IS_%lx[TC],", (long) low);
! 	      fprintf (file, "0x%lx\n", (long) low);
  	    }
  	  return;
  	}
*************** output_toc (file, x, labelno, mode)
*** 7376,7381 ****
--- 7563,7571 ----
  
    if (GET_CODE (x) == CONST)
      {
+       if (GET_CODE (XEXP (x, 0)) != PLUS)
+ 	abort ();
+ 
        base = XEXP (XEXP (x, 0), 0);
        offset = INTVAL (XEXP (XEXP (x, 0), 1));
      }
*************** output_toc (file, x, labelno, mode)
*** 7391,7397 ****
  
    STRIP_NAME_ENCODING (real_name, name);
    if (TARGET_MINIMAL_TOC)
!     fputs (TARGET_32BIT ? "\t.long " : "\t.llong ", file);
    else
      {
        fprintf (file, "\t.tc %s", real_name);
--- 7581,7587 ----
  
    STRIP_NAME_ENCODING (real_name, name);
    if (TARGET_MINIMAL_TOC)
!     fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
    else
      {
        fprintf (file, "\t.tc %s", real_name);
Index: config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.119
diff -c -3 -p -w -B -b -r1.119 rs6000.h
*** rs6000.h	2001/07/09 06:10:05	1.119
--- rs6000.h	2001/07/31 17:17:00
*************** Boston, MA 02111-1307, USA.  */
*** 33,42 ****
  #define OBJECT_MACHO 4
  
  #define TARGET_ELF (TARGET_OBJECT_FORMAT == OBJECT_ELF)
! #define TARGET_AIX (TARGET_OBJECT_FORMAT == OBJECT_XCOFF)
  #define TARGET_MACOS (TARGET_OBJECT_FORMAT == OBJECT_PEF)
  #define TARGET_MACHO (TARGET_OBJECT_FORMAT == OBJECT_MACHO)
  
  /* Print subsidiary information on the compiler version in use.  */
  #define TARGET_VERSION ;
  
--- 33,46 ----
  #define OBJECT_MACHO 4
  
  #define TARGET_ELF (TARGET_OBJECT_FORMAT == OBJECT_ELF)
! #define TARGET_XCOFF (TARGET_OBJECT_FORMAT == OBJECT_XCOFF)
  #define TARGET_MACOS (TARGET_OBJECT_FORMAT == OBJECT_PEF)
  #define TARGET_MACHO (TARGET_OBJECT_FORMAT == OBJECT_MACHO)
  
+ #ifndef TARGET_AIX
+ #define TARGET_AIX 0
+ #endif
+ 
  /* Print subsidiary information on the compiler version in use.  */
  #define TARGET_VERSION ;
  
*************** Boston, MA 02111-1307, USA.  */
*** 45,126 ****
  #define TARGET_CPU_DEFAULT ((char *)0)
  #endif
  
- /* Common CPP definitions used by CPP_SPEC among the various targets
-    for handling -mcpu=xxx switches.  */
- #define CPP_CPU_SPEC \
- "%{!mcpu*: \
-   %{mpower: %{!mpower2: -D_ARCH_PWR}} \
-   %{mpower2: -D_ARCH_PWR2} \
-   %{mpowerpc*: -D_ARCH_PPC} \
-   %{mno-power: %{!mpowerpc*: -D_ARCH_COM}} \
-   %{!mno-power: %{!mpower2: %(cpp_default)}}} \
- %{mcpu=common: -D_ARCH_COM} \
- %{mcpu=power: -D_ARCH_PWR} \
- %{mcpu=power2: -D_ARCH_PWR2} \
- %{mcpu=powerpc: -D_ARCH_PPC} \
- %{mcpu=rios: -D_ARCH_PWR} \
- %{mcpu=rios1: -D_ARCH_PWR} \
- %{mcpu=rios2: -D_ARCH_PWR2} \
- %{mcpu=rsc: -D_ARCH_PWR} \
- %{mcpu=rsc1: -D_ARCH_PWR} \
- %{mcpu=401: -D_ARCH_PPC} \
- %{mcpu=403: -D_ARCH_PPC} \
- %{mcpu=505: -D_ARCH_PPC} \
- %{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
- %{mcpu=602: -D_ARCH_PPC} \
- %{mcpu=603: -D_ARCH_PPC} \
- %{mcpu=603e: -D_ARCH_PPC} \
- %{mcpu=ec603e: -D_ARCH_PPC} \
- %{mcpu=604: -D_ARCH_PPC} \
- %{mcpu=604e: -D_ARCH_PPC} \
- %{mcpu=620: -D_ARCH_PPC} \
- %{mcpu=740: -D_ARCH_PPC} \
- %{mcpu=750: -D_ARCH_PPC} \
- %{mcpu=801: -D_ARCH_PPC} \
- %{mcpu=821: -D_ARCH_PPC} \
- %{mcpu=823: -D_ARCH_PPC} \
- %{mcpu=860: -D_ARCH_PPC}"
- 
- #define CPP_DEFAULT_SPEC "-D_ARCH_PWR"
- 
- /* Common ASM definitions used by ASM_SPEC among the various targets
-    for handling -mcpu=xxx switches.  */
- #define ASM_CPU_SPEC \
- "%{!mcpu*: \
-   %{mpower: %{!mpower2: -mpwr}} \
-   %{mpower2: -mpwrx} \
-   %{mpowerpc*: -mppc} \
-   %{mno-power: %{!mpowerpc*: -mcom}} \
-   %{!mno-power: %{!mpower2: %(asm_default)}}} \
- %{mcpu=common: -mcom} \
- %{mcpu=power: -mpwr} \
- %{mcpu=power2: -mpwrx} \
- %{mcpu=powerpc: -mppc} \
- %{mcpu=rios: -mpwr} \
- %{mcpu=rios1: -mpwr} \
- %{mcpu=rios2: -mpwrx} \
- %{mcpu=rsc: -mpwr} \
- %{mcpu=rsc1: -mpwr} \
- %{mcpu=401: -mppc} \
- %{mcpu=403: -mppc} \
- %{mcpu=505: -mppc} \
- %{mcpu=601: -m601} \
- %{mcpu=602: -mppc} \
- %{mcpu=603: -mppc} \
- %{mcpu=603e: -mppc} \
- %{mcpu=ec603e: -mppc} \
- %{mcpu=604: -mppc} \
- %{mcpu=604e: -mppc} \
- %{mcpu=620: -mppc} \
- %{mcpu=740: -mppc} \
- %{mcpu=750: -mppc} \
- %{mcpu=801: -mppc} \
- %{mcpu=821: -mppc} \
- %{mcpu=823: -mppc} \
- %{mcpu=860: -mppc}"
- 
- #define ASM_DEFAULT_SPEC ""
- 
  /* This macro defines names of additional specifications to put in the specs
     that can be used in various specifications like CC1_SPEC.  Its definition
     is an initializer with a subgrouping for each command option.
--- 49,54 ----
*************** extern int rs6000_debug_arg;		/* debug a
*** 574,586 ****
  /* Handle #pragma pack.  */
  #define HANDLE_PRAGMA_PACK 1
  
- /* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints.  */
- #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
-   (TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
- 	      ? get_inner_array_type (FIELD) \
- 	      : TREE_TYPE (FIELD)) == DFmode \
-    ? MIN ((COMPUTED), 32) : (COMPUTED))
- 
  /* Alignment of field after `int : 0' in a structure.  */
  #define EMPTY_FIELD_BOUNDARY 32
  
--- 502,507 ----
*************** extern int rs6000_debug_arg;		/* debug a
*** 590,606 ****
  /* A bitfield declared as `int' forces `int' alignment for the struct.  */
  #define PCC_BITFIELD_TYPE_MATTERS 1
  
- /* AIX increases natural record alignment to doubleword if the first
-    field is an FP double while the FP fields remain word aligned.  */
- #define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED)	\
-   ((TREE_CODE (STRUCT) == RECORD_TYPE			\
-     || TREE_CODE (STRUCT) == UNION_TYPE			\
-     || TREE_CODE (STRUCT) == QUAL_UNION_TYPE)		\
-    && TYPE_FIELDS (STRUCT) != 0				\
-    && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode	\
-    ? MAX (MAX ((COMPUTED), (SPECIFIED)), BIGGEST_ALIGNMENT) \
-    : MAX ((COMPUTED), (SPECIFIED)))
- 
  /* Make strings word-aligned so strcpy from constants will be faster.  */
  #define CONSTANT_ALIGNMENT(EXP, ALIGN)  \
    (TREE_CODE (EXP) == STRING_CST	\
--- 511,516 ----
*************** enum reg_class
*** 1050,1056 ****
     `K' is a constant with only the low-order 16 bits non-zero
     `L' is a signed 16-bit constant shifted left 16 bits
     `M' is a constant that is greater than 31
!    `N' is a constant that is an exact power of two
     `O' is the constant zero
     `P' is a constant whose negation is a signed 16-bit constant */
  
--- 960,966 ----
     `K' is a constant with only the low-order 16 bits non-zero
     `L' is a signed 16-bit constant shifted left 16 bits
     `M' is a constant that is greater than 31
!    `N' is a positive constant that is an exact power of two
     `O' is the constant zero
     `P' is a constant whose negation is a signed 16-bit constant */
  
*************** enum reg_class
*** 1061,1067 ****
     : (C) == 'L' ? (((VALUE) & 0xffff) == 0				\
  		   && ((VALUE) >> 31 == -1 || (VALUE) >> 31 == 0))	\
     : (C) == 'M' ? (VALUE) > 31						\
!    : (C) == 'N' ? exact_log2 (VALUE) >= 0				\
     : (C) == 'O' ? (VALUE) == 0						\
     : (C) == 'P' ? (unsigned HOST_WIDE_INT) ((- (VALUE)) + 0x8000) < 0x10000 \
     : 0)
--- 971,977 ----
     : (C) == 'L' ? (((VALUE) & 0xffff) == 0				\
  		   && ((VALUE) >> 31 == -1 || (VALUE) >> 31 == 0))	\
     : (C) == 'M' ? (VALUE) > 31						\
!    : (C) == 'N' ? (VALUE) > 0 && exact_log2 (VALUE) >= 0		\
     : (C) == 'O' ? (VALUE) == 0						\
     : (C) == 'P' ? (unsigned HOST_WIDE_INT) ((- (VALUE)) + 0x8000) < 0x10000 \
     : 0)
*************** typedef struct rs6000_stack {
*** 1384,1391 ****
  /* 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)))
  
  
  /* A C structure for machine-specific, per-function data.
--- 1294,1301 ----
  /* 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)						\
!   ((((N) - GP_ARG_MIN_REG) < (GP_ARG_NUM_REG))	\
!    || (((N) - FP_ARG_MIN_REG) < (FP_ARG_NUM_REG)))
  
  
  /* A C structure for machine-specific, per-function data.
*************** typedef struct rs6000_args
*** 1551,1556 ****
--- 1461,1476 ----
     argument is passed depends on whether or not it is a named argument.  */
  #define STRICT_ARGUMENT_NAMING 1
  
+ /* This macro generates the assembly code for function entry.
+    FILE is a stdio stream to output the code to.
+    SIZE is an int: how many units of temporary storage to allocate.
+    Refer to the array `regs_ever_live' to determine which registers
+    to save; `regs_ever_live[I]' is nonzero if register number I
+    is ever used in the function.  This macro is responsible for
+    knowing which registers should not be saved even if used.  */
+ 
+ #define FUNCTION_PROLOGUE(FILE, SIZE) output_prolog (FILE, SIZE)
+ 
  /* Output assembler code to FILE to increment profiler label # LABELNO
     for profiling a function entry.  */
  
*************** typedef struct rs6000_args
*** 1576,1581 ****
--- 1496,1513 ----
         && TARGET_AIX						\
         && (REGNO) == TOC_REGISTER))
  
+ /* This macro generates the assembly code for function exit,
+    on machines that need it.  If FUNCTION_EPILOGUE is not defined
+    then individual return instructions are generated for each
+    return statement.  Args are same as for FUNCTION_PROLOGUE.
+ 
+    The function epilogue should not depend on the current stack pointer!
+    It should use the frame pointer only.  This is mandatory because
+    of alloca; we also take advantage of it to omit stack adjustments
+    before returning.  */
+ 
+ #define FUNCTION_EPILOGUE(FILE, SIZE) output_epilog (FILE, SIZE)
+ 
  /* TRAMPOLINE_TEMPLATE deleted */
  
  /* Length in units of the trampoline for entering a nested function.  */
*************** extern int toc_initialized;
*** 2281,2290 ****
      }									  \
  }
  
- /* This is how we tell the assembler that two symbols have the same value.  */
- 
- #define SET_ASM_OP "\t.set\t"
- 
  /* This implementes the `alias' attribute.  */
  
  #define ASM_OUTPUT_DEF_FROM_DECLS(FILE,decl,target)	\
--- 2213,2218 ----
*************** do {									\
*** 2498,2504 ****
      }									\
    else									\
      {									\
!       fputs ("\t.llong ", FILE);					\
        output_addr_const (FILE, (VALUE));				\
        putc ('\n', FILE);						\
      }									\
--- 2426,2432 ----
      }									\
    else									\
      {									\
!       fprintf (FILE, "\t%s ", DOUBLE_INT_ASM_OP);			\
        output_addr_const (FILE, (VALUE));				\
        putc ('\n', FILE);						\
      }									\
*************** do {									\
*** 2527,2533 ****
    fprintf (FILE, "\t.byte 0x%x\n", (VALUE))
  
  /* This is used by the definition of ASM_OUTPUT_ADDR_ELT in defaults.h.  */
! #define ASM_LONG (TARGET_32BIT ? ".long" : ".quad")
  
  /* This is how to output an element of a case-vector that is relative.  */
  
--- 2455,2461 ----
    fprintf (FILE, "\t.byte 0x%x\n", (VALUE))
  
  /* This is used by the definition of ASM_OUTPUT_ADDR_ELT in defaults.h.  */
! #define ASM_LONG (TARGET_32BIT ? ".long" : DOUBLE_INT_ASM_OP)
  
  /* This is how to output an element of a case-vector that is relative.  */
  
*************** do {									\
*** 2550,2568 ****
    if ((LOG) != 0)			\
      fprintf (FILE, "\t.align %d\n", (LOG))
  
- /* This says how to output an assembler line
-    to define a local common symbol.
-    Alignment cannot be specified, but we can try to maintain
-    alignment after preceding TOC section if it was aligned
-    for 64-bit mode.  */
- 
- #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)	\
-   do { fputs (".lcomm ", (FILE));			\
-        RS6000_OUTPUT_BASENAME ((FILE), (NAME));		\
-        fprintf ((FILE), ",%d,%s\n", (TARGET_32BIT ? (SIZE) : (ROUNDED)), \
- 		xcoff_bss_section_name);		\
-      } while (0)
- 
  /* Store in OUTPUT a string (made with alloca) containing
     an assembler-name for a local static variable named NAME.
     LABELNO is an integer which is different for each call.  */
--- 2478,2483 ----
*************** do {									\
*** 2571,2576 ****
--- 2486,2497 ----
  ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),	\
    sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
  
+ /* Define the parentheses used to group arithmetic operations
+    in assembler code.  */
+ 
+ #define ASM_OPEN_PAREN "("
+ #define ASM_CLOSE_PAREN ")"
+ 
  /* Pick up the return address upon entry to a procedure. Used for
     dwarf2 unwind information.  This also enables the table driven
     mechanism.  */
*************** do {									\
*** 2603,2608 ****
--- 2524,2530 ----
    {"short_cint_operand", {CONST_INT}},					   \
    {"u_short_cint_operand", {CONST_INT}},				   \
    {"non_short_cint_operand", {CONST_INT}},				   \
+   {"exact_log2_cint_operand", {CONST_INT}},				   \
    {"gpc_reg_operand", {SUBREG, REG}},					   \
    {"cc_reg_operand", {SUBREG, REG}},					   \
    {"cc_reg_not_cr0_operand", {SUBREG, REG}},				   \
*************** do {									\
*** 2611,2616 ****
--- 2533,2540 ----
    {"reg_or_u_short_operand", {SUBREG, REG, CONST_INT}},			   \
    {"reg_or_cint_operand", {SUBREG, REG, CONST_INT}},			   \
    {"reg_or_arith_cint_operand", {SUBREG, REG, CONST_INT}},		   \
+   {"reg_or_add_cint64_operand", {SUBREG, REG, CONST_INT}},		   \
+   {"reg_or_sub_cint64_operand", {SUBREG, REG, CONST_INT}},		   \
    {"reg_or_logical_cint_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
    {"got_operand", {SYMBOL_REF, CONST, LABEL_REF}},			   \
    {"got_no_const_operand", {SYMBOL_REF, LABEL_REF}},			   \
Index: config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.120
diff -c -3 -p -w -B -b -r1.120 rs6000.md
*** rs6000.md	2001/07/04 17:43:18	1.120
--- rs6000.md	2001/07/31 17:17:08
***************
*** 1422,1440 ****
        rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
  		 ? operands[0] : gen_reg_rtx (SImode));
  
!       HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff;
!       HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
  
-       if (low & 0x8000)
- 	{
- 	  high = trunc_int_for_mode (high + 0x10000, SImode);
- 	  low = trunc_int_for_mode (low, HImode);
- 	}
- 
        /* The ordering here is important for the prolog expander.
  	 When space is allocated from the stack, adding 'low' first may
  	 produce a temporary deallocation (which would be bad).  */
!       emit_insn (gen_addsi3 (tmp, operands[1], GEN_INT (high)));
        emit_insn (gen_addsi3 (operands[0], tmp, GEN_INT (low)));
        DONE;
      }
--- 1422,1435 ----
        rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
  		 ? operands[0] : gen_reg_rtx (SImode));
  
!       HOST_WIDE_INT val = INTVAL (operands[2]);
!       HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
!       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, SImode);
  
        /* The ordering here is important for the prolog expander.
  	 When space is allocated from the stack, adding 'low' first may
  	 produce a temporary deallocation (which would be bad).  */
!       emit_insn (gen_addsi3 (tmp, operands[1], GEN_INT (rest)));
        emit_insn (gen_addsi3 (operands[0], tmp, GEN_INT (low)));
        DONE;
      }
***************
*** 1536,1551 ****
     (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
  "
  {
!   HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff;
!   HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
! 
!   if (low & 0x8000)
!     {
!       high = trunc_int_for_mode (high + 0x10000, SImode);
!       low = trunc_int_for_mode (low, HImode);
!     }
  
!   operands[3] = GEN_INT (high);
    operands[4] = GEN_INT (low);
  }")
  
--- 1531,1541 ----
     (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
  "
  {
!   HOST_WIDE_INT val = INTVAL (operands[2]);
!   HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
!   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, SImode);
  
!   operands[3] = GEN_INT (rest);
    operands[4] = GEN_INT (low);
  }")
  
***************
*** 2277,2282 ****
--- 2267,2273 ----
    "
  {
    if (GET_CODE (operands[2]) == CONST_INT
+       && INTVAL (operands[2]) > 0
        && exact_log2 (INTVAL (operands[2])) >= 0)
      ;
    else if (TARGET_POWERPC)
***************
*** 2328,2339 ****
    rtx temp1;
    rtx temp2;
  
!   if (GET_CODE (operands[2]) != CONST_INT)
!     FAIL;
! 
!   i = exact_log2 (INTVAL (operands[2]));
! 
!   if (i < 0)
      FAIL;
  
    temp1 = gen_reg_rtx (SImode);
--- 2319,2327 ----
    rtx temp1;
    rtx temp2;
  
!   if (GET_CODE (operands[2]) != CONST_INT
!       || INTVAL (operands[2]) < 0
!       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
      FAIL;
  
    temp1 = gen_reg_rtx (SImode);
***************
*** 2348,2365 ****
  (define_insn ""
    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
  	(div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
! 		(match_operand:SI 2 "const_int_operand" "N")))]
!   "exact_log2 (INTVAL (operands[2])) >= 0"
    "{srai|srawi} %0,%1,%p2\;{aze|addze} %0,%0"
    [(set_attr "length" "8")])
  
  (define_insn ""
    [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
  	(compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
! 			    (match_operand:SI 2 "const_int_operand" "N,N"))
  		    (const_int 0)))
     (clobber (match_scratch:SI 3 "=r,r"))]
!   "exact_log2 (INTVAL (operands[2])) >= 0"
    "@
     {srai|srawi} %3,%1,%p2\;{aze.|addze.} %3,%3
     #"
--- 2336,2353 ----
  (define_insn ""
    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
  	(div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
! 		(match_operand:SI 2 "exact_log2_cint_operand" "N")))]
!   ""
    "{srai|srawi} %0,%1,%p2\;{aze|addze} %0,%0"
    [(set_attr "length" "8")])
  
  (define_insn ""
    [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
  	(compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
! 			    (match_operand:SI 2 "exact_log2_cint_operand" "N,N"))
  		    (const_int 0)))
     (clobber (match_scratch:SI 3 "=r,r"))]
!   ""
    "@
     {srai|srawi} %3,%1,%p2\;{aze.|addze.} %3,%3
     #"
***************
*** 2369,2378 ****
  (define_split
    [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
  	(compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "")
! 			    (match_operand:SI 2 "const_int_operand" ""))
  		    (const_int 0)))
     (clobber (match_scratch:SI 3 ""))]
!   "exact_log2 (INTVAL (operands[2])) >= 0 && reload_completed"
    [(set (match_dup 3)
  	(div:SI (match_dup 1) (match_dup 2)))
     (set (match_dup 0)
--- 2357,2366 ----
  (define_split
    [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
  	(compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "")
! 			    (match_operand:SI 2 "exact_log2_cint_operand" ""))
  		    (const_int 0)))
     (clobber (match_scratch:SI 3 ""))]
!   "reload_completed"
    [(set (match_dup 3)
  	(div:SI (match_dup 1) (match_dup 2)))
     (set (match_dup 0)
***************
*** 2383,2393 ****
  (define_insn ""
    [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
  	(compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
! 			    (match_operand:SI 2 "const_int_operand" "N,N"))
  		    (const_int 0)))
     (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
  	(div:SI (match_dup 1) (match_dup 2)))]
!   "exact_log2 (INTVAL (operands[2])) >= 0"
    "@
     {srai|srawi} %0,%1,%p2\;{aze.|addze.} %0,%0
     #"
--- 2371,2381 ----
  (define_insn ""
    [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
  	(compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
! 			    (match_operand:SI 2 "exact_log2_cint_operand" "N,N"))
  		    (const_int 0)))
     (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
  	(div:SI (match_dup 1) (match_dup 2)))]
!   ""
    "@
     {srai|srawi} %0,%1,%p2\;{aze.|addze.} %0,%0
     #"
***************
*** 2397,2407 ****
  (define_split
    [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
  	(compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "")
! 			    (match_operand:SI 2 "const_int_operand" ""))
  		    (const_int 0)))
     (set (match_operand:SI 0 "gpc_reg_operand" "")
  	(div:SI (match_dup 1) (match_dup 2)))]
!   "exact_log2 (INTVAL (operands[2])) >= 0 && reload_completed"
    [(set (match_dup 0)
  	(div:SI (match_dup 1) (match_dup 2)))
     (set (match_dup 3)
--- 2385,2395 ----
  (define_split
    [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
  	(compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "")
! 			    (match_operand:SI 2 "exact_log2_cint_operand" ""))
  		    (const_int 0)))
     (set (match_operand:SI 0 "gpc_reg_operand" "")
  	(div:SI (match_dup 1) (match_dup 2)))]
!   "reload_completed"
    [(set (match_dup 0)
  	(div:SI (match_dup 1) (match_dup 2)))
     (set (match_dup 3)
***************
*** 5589,5595 ****
  (define_expand "adddi3"
    [(set (match_operand:DI 0 "gpc_reg_operand" "")
  	(plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
! 		 (match_operand:DI 2 "reg_or_arith_cint_operand" "")))]
    ""
    "
  {
--- 5577,5583 ----
  (define_expand "adddi3"
    [(set (match_operand:DI 0 "gpc_reg_operand" "")
  	(plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
! 		 (match_operand:DI 2 "reg_or_add_cint64_operand" "")))]
    ""
    "
  {
***************
*** 5605,5620 ****
  	rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
  		   ? operands[0] : gen_reg_rtx (DImode));
  
! 	HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff;
! 	HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
  
! 	if (low & 0x8000)
! 	  {
! 	    high = trunc_int_for_mode (high + 0x10000, SImode);
! 	    low = trunc_int_for_mode (low, HImode);
! 	  }
  
! 	emit_insn (gen_adddi3 (tmp, operands[1], GEN_INT (high)));
  	emit_insn (gen_adddi3 (operands[0], tmp, GEN_INT (low)));
  	DONE;
        }
--- 5593,5609 ----
  	rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
  		   ? operands[0] : gen_reg_rtx (DImode));
  
! 	HOST_WIDE_INT val = INTVAL (operands[2]);
! 	HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
! 	HOST_WIDE_INT rest = trunc_int_for_mode (val - low, DImode);
  
! 	if (!CONST_OK_FOR_LETTER_P (rest, 'L'))
! 	  FAIL;
  
! 	/* The ordering here is important for the prolog expander.
! 	   When space is allocated from the stack, adding 'low' first may
! 	   produce a temporary deallocation (which would be bad).  */
! 	emit_insn (gen_adddi3 (tmp, operands[1], GEN_INT (rest)));
  	emit_insn (gen_adddi3 (operands[0], tmp, GEN_INT (low)));
  	DONE;
        }
***************
*** 5707,5723 ****
     (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
  "
  {
!   HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff;
!   HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
  
!   if (low & 0x8000)
      {
!       high = trunc_int_for_mode (high + 0x10000, SImode);
!       low = trunc_int_for_mode (low, HImode);
      }
! 
!   operands[3] = GEN_INT (high);
!   operands[4] = GEN_INT (low);
  }")
  
  (define_insn "one_cmpldi2"
--- 5696,5717 ----
     (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
  "
  {
!   HOST_WIDE_INT val = INTVAL (operands[2]);
!   HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
!   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, DImode);
  
!   operands[4] = GEN_INT (low);
!   if (CONST_OK_FOR_LETTER_P (rest, 'L'))
!     operands[3] = GEN_INT (rest);
!   else if (! no_new_pseudos)
      {
!       operands[3] = gen_reg_rtx (DImode);
!       emit_move_insn (operands[3], operands[2]);
!       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
!       DONE;
      }
!   else
!     FAIL;
  }")
  
  (define_insn "one_cmpldi2"
***************
*** 5846,5852 ****
  (define_expand "subdi3"
    [(set (match_operand:DI 0 "gpc_reg_operand" "")
  	(minus:DI (match_operand:DI 1 "reg_or_short_operand" "")
! 		  (match_operand:DI 2 "reg_or_arith_cint_operand" "")))]
    ""
    "
  {
--- 5840,5846 ----
  (define_expand "subdi3"
    [(set (match_operand:DI 0 "gpc_reg_operand" "")
  	(minus:DI (match_operand:DI 1 "reg_or_short_operand" "")
! 		  (match_operand:DI 2 "reg_or_sub_cint64_operand" "")))]
    ""
    "
  {
***************
*** 6005,6010 ****
--- 5999,6005 ----
    "
  {
    if (GET_CODE (operands[2]) == CONST_INT
+       && INTVAL (operands[2]) > 0
        && exact_log2 (INTVAL (operands[2])) >= 0)
      ;
    else
***************
*** 6018,6028 ****
    "TARGET_POWERPC64"
    "
  {
!   int i = exact_log2 (INTVAL (operands[2]));
    rtx temp1;
    rtx temp2;
  
!   if (GET_CODE (operands[2]) != CONST_INT || i < 0)
      FAIL;
  
    temp1 = gen_reg_rtx (DImode);
--- 6013,6025 ----
    "TARGET_POWERPC64"
    "
  {
!   int i;
    rtx temp1;
    rtx temp2;
  
!   if (GET_CODE (operands[2]) != CONST_INT
!       || INTVAL (operands[2]) <= 0
!       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
      FAIL;
  
    temp1 = gen_reg_rtx (DImode);
***************
*** 6037,6054 ****
  (define_insn ""
    [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
  	(div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
! 		(match_operand:DI 2 "const_int_operand" "N")))]
!   "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
    "sradi %0,%1,%p2\;addze %0,%0"
    [(set_attr "length" "8")])
  
  (define_insn ""
    [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
  	(compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
! 			    (match_operand:DI 2 "const_int_operand" "N,N"))
  		    (const_int 0)))
     (clobber (match_scratch:DI 3 "=r,r"))]
!   "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
    "@
     sradi %3,%1,%p2\;addze. %3,%3
     #"
--- 6034,6051 ----
  (define_insn ""
    [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
  	(div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
! 		(match_operand:DI 2 "exact_log2_cint_operand" "N")))]
!   "TARGET_POWERPC64"
    "sradi %0,%1,%p2\;addze %0,%0"
    [(set_attr "length" "8")])
  
  (define_insn ""
    [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
  	(compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
! 			    (match_operand:DI 2 "exact_log2_cint_operand" "N,N"))
  		    (const_int 0)))
     (clobber (match_scratch:DI 3 "=r,r"))]
!   "TARGET_POWERPC64"
    "@
     sradi %3,%1,%p2\;addze. %3,%3
     #"
***************
*** 6058,6067 ****
  (define_split
    [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
  	(compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "")
! 			    (match_operand:DI 2 "const_int_operand" ""))
  		    (const_int 0)))
     (clobber (match_scratch:DI 3 ""))]
!   "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0 && reload_completed"
    [(set (match_dup 3)
  	(div:DI (match_dup 1) (match_dup 2)))
     (set (match_dup 0)
--- 6055,6064 ----
  (define_split
    [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
  	(compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "")
! 			    (match_operand:DI 2 "exact_log2_cint_operand" ""))
  		    (const_int 0)))
     (clobber (match_scratch:DI 3 ""))]
!   "TARGET_POWERPC64 && reload_completed"
    [(set (match_dup 3)
  	(div:DI (match_dup 1) (match_dup 2)))
     (set (match_dup 0)
***************
*** 6072,6082 ****
  (define_insn ""
    [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
  	(compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
! 			    (match_operand:DI 2 "const_int_operand" "N,N"))
  		    (const_int 0)))
     (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
  	(div:DI (match_dup 1) (match_dup 2)))]
!   "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
    "@
     sradi %0,%1,%p2\;addze. %0,%0
     #"
--- 6069,6079 ----
  (define_insn ""
    [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
  	(compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
! 			    (match_operand:DI 2 "exact_log2_cint_operand" "N,N"))
  		    (const_int 0)))
     (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
  	(div:DI (match_dup 1) (match_dup 2)))]
!   "TARGET_POWERPC64"
    "@
     sradi %0,%1,%p2\;addze. %0,%0
     #"
***************
*** 6086,6096 ****
  (define_split
    [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
  	(compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "")
! 			    (match_operand:DI 2 "const_int_operand" ""))
  		    (const_int 0)))
     (set (match_operand:DI 0 "gpc_reg_operand" "")
  	(div:DI (match_dup 1) (match_dup 2)))]
!   "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0 && reload_completed"
    [(set (match_dup 0)
  	(div:DI (match_dup 1) (match_dup 2)))
     (set (match_dup 3)
--- 6083,6093 ----
  (define_split
    [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
  	(compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "")
! 			    (match_operand:DI 2 "exact_log2_cint_operand" ""))
  		    (const_int 0)))
     (set (match_operand:DI 0 "gpc_reg_operand" "")
  	(div:DI (match_dup 1) (match_dup 2)))]
!   "TARGET_POWERPC64 && reload_completed"
    [(set (match_dup 0)
  	(div:DI (match_dup 1) (match_dup 2)))
     (set (match_dup 3)
***************
*** 7877,8011 ****
  	 ? \"li %0,%1\" : \"lis %0,%v1\";
  }")
  
- ;; sign-extended 32-bit value
- (define_split
-   [(set (match_operand:DI 0 "gpc_reg_operand" "")
- 	(match_operand:DI 1 "const_int_operand" ""))]
-   "HOST_BITS_PER_WIDE_INT == 32 && TARGET_POWERPC64
-    && num_insns_constant (operands[1], DImode) > 1"
-   [(set (match_dup 0)
- 	(match_dup 2))
-    (set (match_dup 0)
- 	(ior:DI (match_dup 0)
- 		(match_dup 3)))]
-   "
- {
-   operands[2] = GEN_INT (INTVAL (operands[1]) & (~ (HOST_WIDE_INT) 0xffff));
-   operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff);
- }")
- 
- (define_split
-   [(set (match_operand:DI 0 "gpc_reg_operand" "")
- 	(match_operand:DI 1 "const_double_operand" ""))]
-   "HOST_BITS_PER_WIDE_INT == 32 && TARGET_POWERPC64
-    && GET_CODE (operands[1]) == CONST_DOUBLE
-    && ((CONST_DOUBLE_HIGH (operands[1]) == 0
-         && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
-        || (CONST_DOUBLE_HIGH (operands[1]) == -1
-            && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))"
-   [(set (match_dup 0)
- 	(match_dup 2))
-    (set (match_dup 0)
- 	(ior:DI (match_dup 0)
- 		(match_dup 3)))]
-   "
- {
-   operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & (~ (HOST_WIDE_INT) 0xffff));
-   operands[3] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xffff);
- }")
- 
- (define_split
-   [(set (match_operand:DI 0 "gpc_reg_operand" "")
- 	(match_operand:DI 1 "const_int_operand" ""))]
-   "HOST_BITS_PER_WIDE_INT != 32 && TARGET_POWERPC64
-    && GET_CODE (operands[1]) == CONST_INT
-    && (((INTVAL (operands[1]) >> 32) == 0
-         && (INTVAL (operands[1]) & 0x80000000) == 0)
-        || ((INTVAL (operands[1]) >> 32) == -1
-            && (INTVAL (operands[1]) & 0x80000000) != 0))
-    && num_insns_constant (operands[1], DImode) > 1"
-   [(set (match_dup 0)
- 	(match_dup 2))
-    (set (match_dup 0)
- 	(ior:DI (match_dup 0)
- 		(match_dup 3)))]
-   "
- {
-   operands[2] = GEN_INT (INTVAL (operands[1]) & (~ (HOST_WIDE_INT) 0xffff));
-   operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff);
- }")
- 
- ;; zero-extended 32-bit value
- (define_split
-   [(set (match_operand:DI 0 "gpc_reg_operand" "")
- 	(match_operand:DI 1 "const_double_operand" ""))]
-   "HOST_BITS_PER_WIDE_INT == 32 && TARGET_POWERPC64
-    && GET_CODE (operands[1]) == CONST_DOUBLE
-    && CONST_DOUBLE_HIGH (operands[1]) == 0
-    && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0"
-   [(set (match_dup 0)
- 	(match_dup 2))
-    (set (match_dup 0)
- 	(zero_extend:DI (match_dup 3)))]
-   "
- { 
-   operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); 
-   operands[3] = gen_lowpart_common (SImode, operands[0]);
- }")
- 
- (define_split
-   [(set (match_operand:DI 0 "gpc_reg_operand" "")
- 	(match_operand:DI 1 "const_int_operand" ""))]
-   "HOST_BITS_PER_WIDE_INT != 32 && TARGET_POWERPC64
-    && GET_CODE (operands[1]) == CONST_INT
-    && INTVAL (operands[1]) >> 32 == 0
-    && (INTVAL (operands[1]) & 0x80000000) != 0
-    && num_insns_constant (operands[1], DImode) > 1"
-   [(set (match_dup 0)
- 	(match_dup 2))
-    (set (match_dup 0)
- 	(zero_extend:DI (match_dup 3)))]
-   "
- {
- #if HOST_BITS_PER_WIDE_INT != 32
-   operands[2] = GEN_INT ((INTVAL (operands[1]) ^ 0x80000000) - 0x80000000);
- #endif
-   operands[3] = gen_lowpart_common (SImode, operands[0]);
- }")
- 
- ;; 32-bit value in upper half of doubleword
- (define_split
-   [(set (match_operand:DI 0 "gpc_reg_operand" "")
- 	(match_operand:DI 1 "const_double_operand" ""))]
-   "HOST_BITS_PER_WIDE_INT == 32 && TARGET_POWERPC64
-    && GET_CODE (operands[1]) == CONST_DOUBLE
-    && CONST_DOUBLE_LOW (operands[1]) == 0"
-   [(set (match_dup 0)
- 	(match_dup 2))
-    (set (match_dup 0)
- 	(ashift:DI (match_dup 0)
- 		   (const_int 32)))]
-   "
- { operands[2] = GEN_INT (CONST_DOUBLE_HIGH (operands[1])); }")
- 
- (define_split
-   [(set (match_operand:DI 0 "gpc_reg_operand" "")
- 	(match_operand:DI 1 "const_int_operand" ""))]
-   "HOST_BITS_PER_WIDE_INT != 32 && TARGET_POWERPC64
-    && GET_CODE (operands[1]) == CONST_INT
-    && (INTVAL (operands[1]) & 0xffffffff) == 0"
-   [(set (match_dup 0)
- 	(match_dup 2))
-    (set (match_dup 0)
- 	(ashift:DI (match_dup 0)
- 		   (const_int 32)))]
-   "
- {
- #if HOST_BITS_PER_WIDE_INT != 32
- operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
- #endif
- }")
- 
  ;; Generate all one-bits and clear left or right.
  ;; Use (and:DI (rotate:DI ...)) to avoid anddi3 unnecessary clobber.
  (define_split
--- 7874,7879 ----
*************** operands[2] = GEN_INT (INTVAL (operands[
*** 8025,8079 ****
  ;; easy_fp_constant predicate.
  (define_split
    [(set (match_operand:DI 0 "gpc_reg_operand" "")
! 	(match_operand:DI 1 "const_double_operand" ""))]
!   "HOST_BITS_PER_WIDE_INT == 32 && TARGET_POWERPC64
!    && num_insns_constant (operands[1], DImode) > 1"
!   [(set (match_dup 0)
! 	(match_dup 2))
!    (set (match_dup 0)
! 	(ashift:DI (match_dup 0)
! 		   (const_int 32)))
!    (set (match_dup 0)
! 	(ior:DI (match_dup 0)
! 		(match_dup 3)))]
    "
! {
!   if (GET_CODE (operands[1]) == CONST_DOUBLE)
!     {
!       operands[2] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
!       operands[3] = immed_double_const (CONST_DOUBLE_LOW (operands[1]),
! 					0, DImode);
!     }
    else
!     {
!       HOST_WIDE_INT value = INTVAL (operands[1]);
!       operands[2] = (value & 0x80000000) ? constm1_rtx : const0_rtx;
!       operands[3] = immed_double_const (value, 0, DImode);
!     }
  }")
  
  (define_split
    [(set (match_operand:DI 0 "gpc_reg_operand" "")
! 	(match_operand:DI 1 "const_int_operand" ""))]
!   "HOST_BITS_PER_WIDE_INT != 32 && TARGET_POWERPC64
!    && num_insns_constant (operands[1], DImode) > 1"
!   [(set (match_dup 0)
! 	(match_dup 2))
!    (set (match_dup 0)
! 	(ashift:DI (match_dup 0)
! 		   (const_int 32)))
!    (set (match_dup 0)
! 	(ior:DI (match_dup 0)
! 		(match_dup 3)))]
    "
! {
! #if HOST_BITS_PER_WIDE_INT != 32
!   HOST_WIDE_INT value = INTVAL (operands[1]);
!   operands[2] = GEN_INT (value >> 32);
!   operands[3] = GEN_INT ((value & 0x7fffffff) - (value & 0x80000000));
! #endif
  }")
  
  (define_insn "*movdi_internal2"
    [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
  	(compare:CC (match_operand:DI 1 "gpc_reg_operand" "r,r")
--- 7893,7927 ----
  ;; easy_fp_constant predicate.
  (define_split
    [(set (match_operand:DI 0 "gpc_reg_operand" "")
! 	(match_operand:DI 1 "const_int_operand" ""))]
!   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
!   [(set (match_dup 0) (match_dup 2))
!    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
    "
! { rtx tem = rs6000_emit_set_const (operands[0], DImode, operands[1], 5);
! 
!   if (tem == operands[0])
!     DONE;
    else
!     FAIL;
  }")
  
  (define_split
    [(set (match_operand:DI 0 "gpc_reg_operand" "")
! 	(match_operand:DI 1 "const_double_operand" ""))]
!   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
!   [(set (match_dup 0) (match_dup 2))
!    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
    "
! { rtx tem = rs6000_emit_set_const (operands[0], DImode, operands[1], 5);
! 
!   if (tem == operands[0])
!     DONE;
!   else
!     FAIL;
  }")
  
+ ;; Split a load of a large constant into the appropriate five-instruction
  (define_insn "*movdi_internal2"
    [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
  	(compare:CC (match_operand:DI 1 "gpc_reg_operand" "r,r")
*************** operands[2] = GEN_INT (INTVAL (operands[
*** 9068,9074 ****
  (define_insn "load_toc_aix_si"
    [(set (match_operand:SI 0 "register_operand" "=r")
  	(unspec:SI [(const_int 0)] 7))]
!   "! TARGET_ELF && TARGET_32BIT"
    "*
  {
    char buf[30];
--- 8916,8922 ----
  (define_insn "load_toc_aix_si"
    [(set (match_operand:SI 0 "register_operand" "=r")
  	(unspec:SI [(const_int 0)] 7))]
!   "DEFAULT_ABI == ABI_AIX && TARGET_32BIT"
    "*
  {
    char buf[30];
*************** operands[2] = GEN_INT (INTVAL (operands[
*** 9082,9092 ****
  (define_insn "load_toc_aix_di"
    [(set (match_operand:DI 0 "register_operand" "=r")
  	(unspec:DI [(const_int 0)] 7))]
!   "! TARGET_ELF && TARGET_64BIT"
    "*
  {
    char buf[30];
    ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
    operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
    operands[2] = gen_rtx_REG (Pmode, 2);
    return \"ld %0,%1(%2)\";
--- 8930,8942 ----
  (define_insn "load_toc_aix_di"
    [(set (match_operand:DI 0 "register_operand" "=r")
  	(unspec:DI [(const_int 0)] 7))]
!   "DEFAULT_ABI == ABI_AIX && TARGET_64BIT"
    "*
  {
    char buf[30];
    ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
+   if (TARGET_ELF)
+     strcat (buf, \"@toc\");
    operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
    operands[2] = gen_rtx_REG (Pmode, 2);
    return \"ld %0,%1(%2)\";
*************** operands[2] = GEN_INT (INTVAL (operands[
*** 9098,9112 ****
  	(unspec:SI [(const_int 0)] 7))]
    "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1
     && TARGET_32BIT"
-   "bl _GLOBAL_OFFSET_TABLE_@local-4"
-   [(set_attr "type" "branch")
-    (set_attr "length" "4")])
- 
- (define_insn "load_toc_v4_pic_di"
-   [(set (match_operand:DI 0 "register_operand" "=l")
- 	(unspec:DI [(const_int 0)] 7))]
-   "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1
-    && TARGET_64BIT"
    "bl _GLOBAL_OFFSET_TABLE_@local-4"
    [(set_attr "type" "branch")
     (set_attr "length" "4")])
--- 8948,8953 ----
Index: config/rs6000/sysv4.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/sysv4.h,v
retrieving revision 1.50
diff -c -3 -p -w -B -b -r1.50 sysv4.h
*** sysv4.h	2001/07/15 10:22:51	1.50
--- sysv4.h	2001/07/31 17:17:09
*************** Boston, MA 02111-1307, USA.  */
*** 37,42 ****
--- 37,115 ----
  /* Override rs6000.h definition.  */
  #undef	CPP_DEFAULT_SPEC
  #define	CPP_DEFAULT_SPEC "-D_ARCH_PPC"
+ /* Common CPP definitions used by CPP_SPEC among the various targets
+    for handling -mcpu=xxx switches.  */
+ #define CPP_CPU_SPEC \
+ "%{!mcpu*: \
+   %{mpower: %{!mpower2: -D_ARCH_PWR}} \
+   %{mpower2: -D_ARCH_PWR2} \
+   %{mpowerpc*: -D_ARCH_PPC} \
+   %{mno-power: %{!mpowerpc*: -D_ARCH_COM}} \
+   %{!mno-power: %{!mpower2: %(cpp_default)}}} \
+ %{mcpu=common: -D_ARCH_COM} \
+ %{mcpu=power: -D_ARCH_PWR} \
+ %{mcpu=power2: -D_ARCH_PWR2} \
+ %{mcpu=powerpc: -D_ARCH_PPC} \
+ %{mcpu=rios: -D_ARCH_PWR} \
+ %{mcpu=rios1: -D_ARCH_PWR} \
+ %{mcpu=rios2: -D_ARCH_PWR2} \
+ %{mcpu=rsc: -D_ARCH_PWR} \
+ %{mcpu=rsc1: -D_ARCH_PWR} \
+ %{mcpu=401: -D_ARCH_PPC} \
+ %{mcpu=403: -D_ARCH_PPC} \
+ %{mcpu=505: -D_ARCH_PPC} \
+ %{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
+ %{mcpu=602: -D_ARCH_PPC} \
+ %{mcpu=603: -D_ARCH_PPC} \
+ %{mcpu=603e: -D_ARCH_PPC} \
+ %{mcpu=ec603e: -D_ARCH_PPC} \
+ %{mcpu=604: -D_ARCH_PPC} \
+ %{mcpu=604e: -D_ARCH_PPC} \
+ %{mcpu=620: -D_ARCH_PPC} \
+ %{mcpu=740: -D_ARCH_PPC} \
+ %{mcpu=750: -D_ARCH_PPC} \
+ %{mcpu=801: -D_ARCH_PPC} \
+ %{mcpu=821: -D_ARCH_PPC} \
+ %{mcpu=823: -D_ARCH_PPC} \
+ %{mcpu=860: -D_ARCH_PPC}"
+ 
+ #define CPP_DEFAULT_SPEC "-D_ARCH_PPC"
+ 
+ /* Common ASM definitions used by ASM_SPEC among the various targets
+    for handling -mcpu=xxx switches.  */
+ #define ASM_CPU_SPEC \
+ "%{!mcpu*: \
+   %{mpower: %{!mpower2: -mpwr}} \
+   %{mpower2: -mpwrx} \
+   %{mpowerpc*: -mppc} \
+   %{mno-power: %{!mpowerpc*: -mcom}} \
+   %{!mno-power: %{!mpower2: %(asm_default)}}} \
+ %{mcpu=common: -mcom} \
+ %{mcpu=power: -mpwr} \
+ %{mcpu=power2: -mpwrx} \
+ %{mcpu=powerpc: -mppc} \
+ %{mcpu=rios: -mpwr} \
+ %{mcpu=rios1: -mpwr} \
+ %{mcpu=rios2: -mpwrx} \
+ %{mcpu=rsc: -mpwr} \
+ %{mcpu=rsc1: -mpwr} \
+ %{mcpu=401: -mppc} \
+ %{mcpu=403: -mppc} \
+ %{mcpu=505: -mppc} \
+ %{mcpu=601: -m601} \
+ %{mcpu=602: -mppc} \
+ %{mcpu=603: -mppc} \
+ %{mcpu=603e: -mppc} \
+ %{mcpu=ec603e: -mppc} \
+ %{mcpu=604: -mppc} \
+ %{mcpu=604e: -mppc} \
+ %{mcpu=620: -mppc} \
+ %{mcpu=740: -mppc} \
+ %{mcpu=750: -mppc} \
+ %{mcpu=801: -mppc} \
+ %{mcpu=821: -mppc} \
+ %{mcpu=823: -mppc} \
+ %{mcpu=860: -mppc}"
  
  /* Small data support types.  */
  enum rs6000_sdata_type {
*************** extern int rs6000_pic_labelno;
*** 694,703 ****
      the return address.  Hence returning from FUNCTION will return to whoever
      called the current thunk'.
  
!     The effect must be as if FUNCTION had been called directly with
!     the adjusted first argument.  This macro is responsible for
!     emitting all of the code for a thunk function;
!     output_function_prologue() and output_function_epilogue() are not
      invoked.
  
      The THUNK_FNDECL is redundant.  (DELTA and FUNCTION have already been
--- 767,775 ----
      the return address.  Hence returning from FUNCTION will return to whoever
      called the current thunk'.
  
!     The effect must be as if FUNCTION had been called directly with the adjusted
!     first argument.  This macro is responsible for emitting all of the code for
!     a thunk function; FUNCTION_PROLOGUE' and FUNCTION_EPILOGUE' are not
      invoked.
  
      The THUNK_FNDECL is redundant.  (DELTA and FUNCTION have already been
*************** do {									\
*** 1191,1201 ****
  
  #define	CPP_SYSV_DEFAULT_SPEC "-D_CALL_SYSV"
  
! #define CPP_ENDIAN_BIG_SPEC "-D_BIG_ENDIAN -D__BIG_ENDIAN__ -Aendian=big"
  
! #define CPP_ENDIAN_LITTLE_SPEC "-D_LITTLE_ENDIAN -D__LITTLE_ENDIAN__ -Aendian=little"
  
! #define CPP_ENDIAN_SOLARIS_SPEC "-D__LITTLE_ENDIAN__ -Aendian=little"
  
  /* For solaris, don't define _LITTLE_ENDIAN, it conflicts with a header file.  */
  #define	CPP_ENDIAN_SPEC \
--- 1263,1273 ----
  
  #define	CPP_SYSV_DEFAULT_SPEC "-D_CALL_SYSV"
  
! #define CPP_ENDIAN_BIG_SPEC "-D_BIG_ENDIAN -D__BIG_ENDIAN__ -Amachine=bigendian"
  
! #define CPP_ENDIAN_LITTLE_SPEC "-D_LITTLE_ENDIAN -D__LITTLE_ENDIAN__ -Amachine=littleendian"
  
! #define CPP_ENDIAN_SOLARIS_SPEC "-D__LITTLE_ENDIAN__ -Amachine=littleendian"
  
  /* For solaris, don't define _LITTLE_ENDIAN, it conflicts with a header file.  */
  #define	CPP_ENDIAN_SPEC \
*************** do {									\
*** 1606,1608 ****
--- 1678,1681 ----
     : DW_EH_PE_absptr)
  
  #define EXCEPTION_SECTION readonly_data_section
+ #define DOUBLE_INT_ASM_OP ".quad"


-- 
"Last time I went to the movies I was thrown out for bringing my
own food.  My argument was that the concession stand prices are
outrageous.  Besides, I haven't had a Bar-B-Que in a long time.
"-Steven Wright


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