This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Committed powerpc patch
- To: gcc-patches at gcc dot gnu dot org
- Subject: [PATCH] Committed powerpc patch
- From: Daniel Berlin <dan at cgsoftware dot com>
- Date: Tue, 31 Jul 2001 13:33:05 -0400
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