/* Definitions of target machine for GNU compiler, for IBM RS/6000.
- Copyright (C) 1992, 93-8, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GNU CC.
/* Note that some other tm.h files include this one and then override
- many of the definitions that relate to assembler syntax. */
+ many of the definitions. */
+/* Definitions for the object file format. These are set at
+ compile-time. */
-/* Names to predefine in the preprocessor for this target machine. */
+#define OBJECT_XCOFF 1
+#define OBJECT_ELF 2
+#define OBJECT_PEF 3
+#define OBJECT_MACHO 4
-#define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_AIX -D_AIX32 -D_LONG_LONG \
--Asystem(unix) -Asystem(aix) -Acpu(rs6000) -Amachine(rs6000)"
+#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 ;
#define TARGET_CPU_DEFAULT ((char *)0)
#endif
-/* Tell the assembler to assume that all undefined names are external.
-
- Don't do this until the fixed IBM assembler is more generally available.
- When this becomes permanently defined, the ASM_OUTPUT_EXTERNAL,
- ASM_OUTPUT_EXTERNAL_LIBCALL, and RS6000_OUTPUT_BASENAME macros will no
- longer be needed. Also, the extern declaration of mcount in ASM_FILE_START
- will no longer be needed. */
-
-/* #define ASM_SPEC "-u %(asm_cpu)" */
-
-/* Define appropriate architecture macros for preprocessor depending on
- target switches. */
-
-#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} %(cpp_cpu)"
-
/* Common CPP definitions used by CPP_SPEC among the various targets
for handling -mcpu=xxx switches. */
#define CPP_CPU_SPEC \
%{mcpu=801: -D_ARCH_PPC} \
%{mcpu=821: -D_ARCH_PPC} \
%{mcpu=823: -D_ARCH_PPC} \
-%{mcpu=860: -D_ARCH_PPC}"
-
-#ifndef CPP_DEFAULT_SPEC
-#define CPP_DEFAULT_SPEC "-D_ARCH_PWR"
-#endif
-
-#ifndef CPP_SYSV_SPEC
-#define CPP_SYSV_SPEC ""
-#endif
-
-#ifndef CPP_ENDIAN_SPEC
-#define CPP_ENDIAN_SPEC ""
-#endif
-
-#ifndef CPP_ENDIAN_DEFAULT_SPEC
-#define CPP_ENDIAN_DEFAULT_SPEC ""
-#endif
-
-#ifndef CPP_SYSV_DEFAULT_SPEC
-#define CPP_SYSV_DEFAULT_SPEC ""
-#endif
+%{mcpu=860: -D_ARCH_PPC} \
+%{maltivec: -D__ALTIVEC__}"
/* Common ASM definitions used by ASM_SPEC among the various targets
for handling -mcpu=xxx switches. */
%{mcpu=823: -mppc} \
%{mcpu=860: -mppc}"
-#ifndef ASM_DEFAULT_SPEC
+#define CPP_DEFAULT_SPEC ""
+
#define ASM_DEFAULT_SPEC ""
-#endif
/* This macro defines names of additional specifications to put in the specs
that can be used in various specifications like CC1_SPEC. Its definition
Do not define this macro if it does not need to do anything. */
-#ifndef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS
-#endif
#define EXTRA_SPECS \
{ "cpp_cpu", CPP_CPU_SPEC }, \
{ "cpp_default", CPP_DEFAULT_SPEC }, \
- { "cpp_sysv", CPP_SYSV_SPEC }, \
- { "cpp_sysv_default", CPP_SYSV_DEFAULT_SPEC }, \
- { "cpp_endian_default", CPP_ENDIAN_DEFAULT_SPEC }, \
- { "cpp_endian", CPP_ENDIAN_SPEC }, \
{ "asm_cpu", ASM_CPU_SPEC }, \
{ "asm_default", ASM_DEFAULT_SPEC }, \
- { "link_syscalls", LINK_SYSCALLS_SPEC }, \
- { "link_libg", LINK_LIBG_SPEC }, \
SUBTARGET_EXTRA_SPECS
-/* Default location of syscalls.exp under AIX */
-#ifndef CROSS_COMPILE
-#define LINK_SYSCALLS_SPEC "-bI:/lib/syscalls.exp"
-#else
-#define LINK_SYSCALLS_SPEC ""
-#endif
-
-/* Default location of libg.exp under AIX */
-#ifndef CROSS_COMPILE
-#define LINK_LIBG_SPEC "-bexport:/usr/lib/libg.exp"
-#else
-#define LINK_LIBG_SPEC ""
-#endif
-
-/* Define the options for the binder: Start text at 512, align all segments
- to 512 bytes, and warn if there is text relocation.
-
- The -bhalt:4 option supposedly changes the level at which ld will abort,
- but it also suppresses warnings about multiply defined symbols and is
- used by the AIX cc command. So we use it here.
-
- -bnodelcsect undoes a poor choice of default relating to multiply-defined
- csects. See AIX documentation for more information about this.
-
- -bM:SRE tells the linker that the output file is Shared REusable. Note
- that to actually build a shared library you will also need to specify an
- export list with the -Wl,-bE option. */
-
-#define LINK_SPEC "-T512 -H512 %{!r:-btextro} -bhalt:4 -bnodelcsect\
- %{static:-bnso %(link_syscalls) } \
- %{!shared:%{g*: %(link_libg) }} %{shared:-bM:SRE}"
-
-/* 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"
-
-/* gcc must do the search itself to find libgcc.a, not use -l. */
-#define LIBGCC_SPEC "libgcc.a%s"
-
-/* Don't turn -B into -L if the argument specifies a relative file name. */
-#define RELATIVE_PREFIX_NOT_LINKDIR
-
/* Architecture type. */
extern int target_flags;
/* Disable fused multiply/add operations */
#define MASK_NO_FUSED_MADD 0x00020000
+/* Nonzero if we need to schedule the prolog and epilog. */
+#define MASK_SCHED_PROLOG 0x00040000
+
+/* Use AltiVec instructions. */
+#define MASK_ALTIVEC 0x00080000
+
+/* Enhance the current ABI with AltiVec extensions. */
+#define MASK_ALTIVEC_ABI 0x00100000
+
#define TARGET_POWER (target_flags & MASK_POWER)
#define TARGET_POWER2 (target_flags & MASK_POWER2)
#define TARGET_POWERPC (target_flags & MASK_POWERPC)
#define TARGET_PPC_GPOPT (target_flags & MASK_PPC_GPOPT)
#define TARGET_PPC_GFXOPT (target_flags & MASK_PPC_GFXOPT)
-#define TARGET_POWERPC64 (target_flags & MASK_POWERPC64)
#define TARGET_NEW_MNEMONICS (target_flags & MASK_NEW_MNEMONICS)
#define TARGET_NO_FP_IN_TOC (target_flags & MASK_NO_FP_IN_TOC)
#define TARGET_NO_SUM_IN_TOC (target_flags & MASK_NO_SUM_IN_TOC)
#define TARGET_STRING_SET (target_flags & MASK_STRING_SET)
#define TARGET_NO_UPDATE (target_flags & MASK_NO_UPDATE)
#define TARGET_NO_FUSED_MADD (target_flags & MASK_NO_FUSED_MADD)
+#define TARGET_SCHED_PROLOG (target_flags & MASK_SCHED_PROLOG)
+#define TARGET_ALTIVEC (target_flags & MASK_ALTIVEC)
+#define TARGET_ALTIVEC_ABI (target_flags & MASK_ALTIVEC_ABI)
#define TARGET_32BIT (! TARGET_64BIT)
#define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT)
#define TARGET_UPDATE (! TARGET_NO_UPDATE)
#define TARGET_FUSED_MADD (! TARGET_NO_FUSED_MADD)
-/* Pseudo target to indicate whether the object format is ELF
- (to get around not having conditional compilation in the md file) */
-#ifndef TARGET_ELF
-#define TARGET_ELF 0
-#endif
-
-/* If this isn't V.4, don't support -mno-toc. */
-#ifndef TARGET_NO_TOC
-#define TARGET_NO_TOC 0
-#define TARGET_TOC 1
-#endif
-
-/* Pseudo target to say whether this is Windows NT */
-#ifndef TARGET_WINDOWS_NT
-#define TARGET_WINDOWS_NT 0
-#endif
-
-/* Pseudo target to say whether this is MAC */
-#ifndef TARGET_MACOS
-#define TARGET_MACOS 0
-#endif
-
-/* Pseudo target to say whether this is AIX */
-#ifndef TARGET_AIX
-#if (TARGET_ELF || TARGET_WINDOWS_NT || TARGET_MACOS)
-#define TARGET_AIX 0
+#ifdef IN_LIBGCC2
+/* For libgcc2 we make sure this is a compile time constant */
+#ifdef __64BIT__
+#define TARGET_POWERPC64 1
#else
-#define TARGET_AIX 1
+#define TARGET_POWERPC64 0
#endif
+#else
+#define TARGET_POWERPC64 (target_flags & MASK_POWERPC64)
#endif
-#ifndef TARGET_XL_CALL
#define TARGET_XL_CALL 0
-#endif
/* Run-time compilation parameters selecting different hardware subsets.
where VALUE is the bits to set or minus the bits to clear.
An empty string NAME is used to identify the default VALUE. */
-/* This is meant to be redefined in the host dependent files */
-#ifndef SUBTARGET_SWITCHES
-#define SUBTARGET_SWITCHES
-#endif
-
#define TARGET_SWITCHES \
- {{"power", MASK_POWER | MASK_MULTIPLE | MASK_STRING}, \
+ {{"power", MASK_POWER | MASK_MULTIPLE | MASK_STRING, \
+ N_("Use POWER instruction set")}, \
{"power2", (MASK_POWER | MASK_MULTIPLE | MASK_STRING \
- | MASK_POWER2)}, \
- {"no-power2", - MASK_POWER2}, \
+ | MASK_POWER2), \
+ N_("Use POWER2 instruction set")}, \
+ {"no-power2", - MASK_POWER2, \
+ N_("Do not use POWER2 instruction set")}, \
{"no-power", - (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE \
- | MASK_STRING)}, \
- {"powerpc", MASK_POWERPC}, \
+ | MASK_STRING), \
+ N_("Do not use POWER instruction set")}, \
+ {"powerpc", MASK_POWERPC, \
+ N_("Use PowerPC instruction set")}, \
{"no-powerpc", - (MASK_POWERPC | MASK_PPC_GPOPT \
- | MASK_PPC_GFXOPT | MASK_POWERPC64)}, \
- {"powerpc-gpopt", MASK_POWERPC | MASK_PPC_GPOPT}, \
- {"no-powerpc-gpopt", - MASK_PPC_GPOPT}, \
- {"powerpc-gfxopt", MASK_POWERPC | MASK_PPC_GFXOPT}, \
- {"no-powerpc-gfxopt", - MASK_PPC_GFXOPT}, \
- {"powerpc64", MASK_POWERPC64}, \
- {"no-powerpc64", - MASK_POWERPC64}, \
- {"new-mnemonics", MASK_NEW_MNEMONICS}, \
- {"old-mnemonics", -MASK_NEW_MNEMONICS}, \
+ | MASK_PPC_GFXOPT | MASK_POWERPC64), \
+ N_("Do not use PowerPC instruction set")}, \
+ {"powerpc-gpopt", MASK_POWERPC | MASK_PPC_GPOPT, \
+ N_("Use PowerPC General Purpose group optional instructions")},\
+ {"no-powerpc-gpopt", - MASK_PPC_GPOPT, \
+ N_("Don't use PowerPC General Purpose group optional instructions")},\
+ {"powerpc-gfxopt", MASK_POWERPC | MASK_PPC_GFXOPT, \
+ N_("Use PowerPC Graphics group optional instructions")},\
+ {"no-powerpc-gfxopt", - MASK_PPC_GFXOPT, \
+ N_("Don't use PowerPC Graphics group optional instructions")},\
+ {"powerpc64", MASK_POWERPC64, \
+ N_("Use PowerPC-64 instruction set")}, \
+ {"no-powerpc64", - MASK_POWERPC64, \
+ N_("Don't use PowerPC-64 instruction set")}, \
+ {"altivec", MASK_ALTIVEC, \
+ N_("Use AltiVec instructions.")}, \
+ {"no-altivec", - MASK_ALTIVEC, \
+ N_("Don't use AltiVec instructions.")}, \
+ {"new-mnemonics", MASK_NEW_MNEMONICS, \
+ N_("Use new mnemonics for PowerPC architecture")},\
+ {"old-mnemonics", -MASK_NEW_MNEMONICS, \
+ N_("Use old mnemonics for PowerPC architecture")},\
{"full-toc", - (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC \
- | MASK_MINIMAL_TOC)}, \
- {"fp-in-toc", - MASK_NO_FP_IN_TOC}, \
- {"no-fp-in-toc", MASK_NO_FP_IN_TOC}, \
- {"sum-in-toc", - MASK_NO_SUM_IN_TOC}, \
- {"no-sum-in-toc", MASK_NO_SUM_IN_TOC}, \
- {"minimal-toc", MASK_MINIMAL_TOC}, \
- {"minimal-toc", - (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC)}, \
- {"no-minimal-toc", - MASK_MINIMAL_TOC}, \
- {"hard-float", - MASK_SOFT_FLOAT}, \
- {"soft-float", MASK_SOFT_FLOAT}, \
- {"multiple", MASK_MULTIPLE | MASK_MULTIPLE_SET}, \
- {"no-multiple", - MASK_MULTIPLE}, \
- {"no-multiple", MASK_MULTIPLE_SET}, \
- {"string", MASK_STRING | MASK_STRING_SET}, \
- {"no-string", - MASK_STRING}, \
- {"no-string", MASK_STRING_SET}, \
- {"update", - MASK_NO_UPDATE}, \
- {"no-update", MASK_NO_UPDATE}, \
- {"fused-madd", - MASK_NO_FUSED_MADD}, \
- {"no-fused-madd", MASK_NO_FUSED_MADD}, \
+ | MASK_MINIMAL_TOC), \
+ N_("Put everything in the regular TOC")}, \
+ {"fp-in-toc", - MASK_NO_FP_IN_TOC, \
+ N_("Place floating point constants in TOC")}, \
+ {"no-fp-in-toc", MASK_NO_FP_IN_TOC, \
+ N_("Don't place floating point constants in TOC")},\
+ {"sum-in-toc", - MASK_NO_SUM_IN_TOC, \
+ N_("Place symbol+offset constants in TOC")}, \
+ {"no-sum-in-toc", MASK_NO_SUM_IN_TOC, \
+ N_("Don't place symbol+offset constants in TOC")},\
+ {"minimal-toc", MASK_MINIMAL_TOC, \
+ "Use only one TOC entry per procedure"}, \
+ {"minimal-toc", - (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC), \
+ ""}, \
+ {"no-minimal-toc", - MASK_MINIMAL_TOC, \
+ N_("Place variable addresses in the regular TOC")},\
+ {"hard-float", - MASK_SOFT_FLOAT, \
+ N_("Use hardware fp")}, \
+ {"soft-float", MASK_SOFT_FLOAT, \
+ N_("Do not use hardware fp")}, \
+ {"multiple", MASK_MULTIPLE | MASK_MULTIPLE_SET, \
+ N_("Generate load/store multiple instructions")}, \
+ {"no-multiple", - MASK_MULTIPLE, \
+ N_("Do not generate load/store multiple instructions")},\
+ {"no-multiple", MASK_MULTIPLE_SET, \
+ ""}, \
+ {"string", MASK_STRING | MASK_STRING_SET, \
+ N_("Generate string instructions for block moves")},\
+ {"no-string", - MASK_STRING, \
+ N_("Do not generate string instructions for block moves")},\
+ {"no-string", MASK_STRING_SET, \
+ ""}, \
+ {"update", - MASK_NO_UPDATE, \
+ N_("Generate load/store with update instructions")},\
+ {"no-update", MASK_NO_UPDATE, \
+ N_("Do not generate load/store with update instructions")},\
+ {"fused-madd", - MASK_NO_FUSED_MADD, \
+ N_("Generate fused multiply/add instructions")},\
+ {"no-fused-madd", MASK_NO_FUSED_MADD, \
+ N_("Don't generate fused multiply/add instructions")},\
+ {"sched-prolog", MASK_SCHED_PROLOG, \
+ ""}, \
+ {"no-sched-prolog", -MASK_SCHED_PROLOG, \
+ N_("Don't schedule the start and end of the procedure")},\
+ {"sched-epilog", MASK_SCHED_PROLOG, \
+ ""}, \
+ {"no-sched-epilog", -MASK_SCHED_PROLOG, \
+ ""}, \
SUBTARGET_SWITCHES \
- {"", TARGET_DEFAULT}}
+ {"", TARGET_DEFAULT | MASK_SCHED_PROLOG, \
+ ""}}
#define TARGET_DEFAULT (MASK_POWER | MASK_MULTIPLE | MASK_STRING)
+/* This is meant to be redefined in the host dependent files */
+#define SUBTARGET_SWITCHES
+
/* Processor type. Order must match cpu attribute in MD file. */
enum processor_type
{
PROCESSOR_PPC604e,
PROCESSOR_PPC620,
PROCESSOR_PPC630,
- PROCESSOR_PPC750
+ PROCESSOR_PPC750,
+ PROCESSOR_PPC7400,
+ PROCESSOR_PPC7450
};
extern enum processor_type rs6000_cpu;
/* Specify the dialect of assembler to use. New mnemonics is dialect one
and the old mnemonics are dialect zero. */
-#define ASSEMBLER_DIALECT TARGET_NEW_MNEMONICS ? 1 : 0
+#define ASSEMBLER_DIALECT (TARGET_NEW_MNEMONICS ? 1 : 0)
/* This macro is similar to `TARGET_SWITCHES' but defines names of
command options that have values. Its definition is an
#define TARGET_OPTIONS { { "short-data-", &m88k_short_data } } */
/* This is meant to be overridden in target specific files. */
-#ifndef SUBTARGET_OPTIONS
#define SUBTARGET_OPTIONS
-#endif
-#define TARGET_OPTIONS \
-{ \
- {"cpu=", &rs6000_select[1].string}, \
- {"tune=", &rs6000_select[2].string}, \
- {"debug-", &rs6000_debug_name}, \
- {"debug=", &rs6000_debug_name}, \
- SUBTARGET_OPTIONS \
+#define TARGET_OPTIONS \
+{ \
+ {"cpu=", &rs6000_select[1].string, \
+ N_("Use features of and schedule code for given CPU") }, \
+ {"tune=", &rs6000_select[2].string, \
+ N_("Schedule code for given CPU") }, \
+ {"debug=", &rs6000_debug_name, N_("Enable debug output") }, \
+ {"abi=", &rs6000_abi_string, N_("Specify ABI to use") }, \
+ SUBTARGET_OPTIONS \
}
/* rs6000_select[0] is reserved for the default cpu defined via --with-cpu */
extern struct rs6000_cpu_select rs6000_select[];
/* Debug support */
-extern const char *rs6000_debug_name; /* Name for -mdebug-xxxx option */
+extern const char *rs6000_debug_name; /* Name for -mdebug-xxxx option */
+extern const char *rs6000_abi_string; /* for -mabi={sysv,darwin,solaris,eabi,aix,altivec} */
extern int rs6000_debug_stack; /* debug stack applications */
extern int rs6000_debug_arg; /* debug argument handling */
/* Define this to change the optimizations performed by default. */
#define OPTIMIZATION_OPTIONS(LEVEL,SIZE) optimization_options(LEVEL,SIZE)
-
/* Show we can debug even without a frame pointer. */
#define CAN_DEBUG_WITHOUT_FP
\f
#define UNITS_PER_WORD (! TARGET_POWERPC64 ? 4 : 8)
#define MIN_UNITS_PER_WORD 4
#define UNITS_PER_FP_WORD 8
+#define UNITS_PER_ALTIVEC_WORD 16
/* Type used for ptrdiff_t, as a string used in a declaration. */
#define PTRDIFF_TYPE "int"
+/* Type used for size_t, as a string used in a declaration. */
+#define SIZE_TYPE "long unsigned int"
+
/* Type used for wchar_t, as a string used in a declaration. */
#define WCHAR_TYPE "short unsigned int"
#define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
/* Boundary (in *bits*) on which stack pointer should be aligned. */
-#define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
+#define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
/* Allocation boundary (in *bits*) for the code of a function. */
#define FUNCTION_BOUNDARY 32
/* No data type wants to be aligned rounder than this. */
-#define BIGGEST_ALIGNMENT 64
+#define BIGGEST_ALIGNMENT 128
-/* 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))
+/* A C expression to compute the alignment for a variables in the
+ local store. TYPE is the data type, and ALIGN is the alignment
+ that the object would ordinarily have. */
+#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
+ ((TARGET_ALTIVEC \
+ && TREE_CODE (TYPE)) == VECTOR_TYPE ? 128 : ALIGN)
+
+/* Handle #pragma pack. */
+#define HANDLE_PRAGMA_PACK 1
/* Alignment of field after `int : 0' in a structure. */
#define EMPTY_FIELD_BOUNDARY 32
/* 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 \
&& (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
-/* Make arrays of chars word-aligned for the same reasons. */
+/* Make arrays of chars word-aligned for the same reasons.
+ Align vectors to 128 bits. */
#define DATA_ALIGNMENT(TYPE, ALIGN) \
- (TREE_CODE (TYPE) == ARRAY_TYPE \
+ (TREE_CODE (TYPE) == VECTOR_TYPE ? 128 \
+ : TREE_CODE (TYPE) == ARRAY_TYPE \
&& TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
&& (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
/* Non-zero if move instructions will actually fail to work
when given unaligned data. */
#define STRICT_ALIGNMENT 0
+
+/* Define this macro to be the value 1 if unaligned accesses have a cost
+ many times greater than aligned accesses, for example if they are
+ emulated in a trap handler. */
+#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) \
+ ((STRICT_ALIGNMENT \
+ || (((MODE) == SFmode || (MODE) == DFmode || (MODE) == DImode) \
+ && (ALIGN) < 32)) ? 1 : 0)
\f
/* Standard register usage. */
a register, in order to work around problems in allocating stack storage
in inline functions. */
-#define FIRST_PSEUDO_REGISTER 77
+#define FIRST_PSEUDO_REGISTER 110
+
+/* This must not decrease, for backwards compatibility. If
+ FIRST_PSEUDO_REGISTER increases, this should as well. */
+/* fixme: this needs to be defined to "TARGET_ALTIVEC_ABI ? 110 : 77"
+ and then fix usages of DWARF_FRAME_REGISTERS to work. */
+#define DWARF_FRAME_REGISTERS 77
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator.
- On RS/6000, r1 is used for the stack and r2 is used as the TOC pointer.
+ On RS/6000, r1 is used for the stack. On Darwin, r2 is available
+ as a local register; for all other OS's r2 is the TOC pointer.
cr5 is not supposed to be used.
On System V implementations, r13 is fixed and not available for use. */
-#ifndef FIXED_R13
-#define FIXED_R13 0
-#endif
-
#define FIXED_REGISTERS \
- {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FIXED_R13, 0, 0, \
+ {0, 1, FIXED_R2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FIXED_R13, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, \
+ /* AltiVec registers. */ \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1}
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0 \
+}
/* 1 for registers not available across function calls.
These must include the FIXED_REGISTERS and also any
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1}
+ 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, \
+ /* AltiVec registers. */ \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0 \
+}
+
+
+#define MQ_REGNO 64
+#define CR0_REGNO 68
+#define CR1_REGNO 69
+#define CR2_REGNO 70
+#define CR3_REGNO 71
+#define CR4_REGNO 72
+#define MAX_CR_REGNO 75
+#define XER_REGNO 76
+#define FIRST_ALTIVEC_REGNO 77
+#define LAST_ALTIVEC_REGNO 108
+#define VRSAVE_REGNO 109
/* List the order in which to allocate registers. Each register must be
listed once, even those in FIXED_REGISTERS.
mq (not saved; best to use it if we can)
ctr (not saved; when we have the choice ctr is better)
lr (saved)
- cr5, r1, r2, ap, fpmem (fixed) */
+ cr5, r1, r2, ap, xer, vrsave (fixed)
+
+ AltiVec registers:
+ v0 - v1 (not saved or used for anything)
+ v13 - v3 (not saved; incoming vector arg registers)
+ v2 (not saved; incoming vector arg reg; return value)
+ v19 - v14 (not saved or used for anything)
+ v31 - v20 (saved; order given to save least number)
+*/
+
#define REG_ALLOC_ORDER \
{32, \
31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, \
18, 17, 16, 15, 14, 13, 12, \
64, 66, 65, \
- 73, 1, 2, 67, 76}
+ 73, 1, 2, 67, 76, \
+ /* AltiVec registers. */ \
+ 77, 78, \
+ 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, \
+ 79, \
+ 96, 95, 94, 93, 92, 91, \
+ 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, \
+ 97, 109 \
+}
/* True if register is floating-point. */
#define FP_REGNO_P(N) ((N) >= 32 && (N) <= 63)
/* True if register is a condition register. */
#define CR_REGNO_P(N) ((N) >= 68 && (N) <= 75)
-/* True if register is condition register 0. */
-#define CR0_REGNO_P(N) ((N) == 68)
-
/* True if register is a condition register, but not cr0. */
#define CR_REGNO_NOT_CR0_P(N) ((N) >= 69 && (N) <= 75)
/* True if register is an integer register. */
-#define INT_REGNO_P(N) ((N) <= 31 || (N) == 67)
+#define INT_REGNO_P(N) ((N) <= 31 || (N) == ARG_POINTER_REGNUM)
-/* True if register is the temporary memory location used for int/float
- conversion. */
-#define FPMEM_REGNO_P(N) ((N) == FPMEM_REGNUM)
+/* True if register is the XER register. */
+#define XER_REGNO_P(N) ((N) == XER_REGNO)
+
+/* True if register is an AltiVec register. */
+#define ALTIVEC_REGNO_P(N) ((N) >= FIRST_ALTIVEC_REGNO && (N) <= LAST_ALTIVEC_REGNO)
/* Return number of consecutive hard regs needed starting at reg REGNO
to hold something of mode MODE.
PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
#define HARD_REGNO_NREGS(REGNO, MODE) \
- (FP_REGNO_P (REGNO) || FPMEM_REGNO_P (REGNO) \
+ (FP_REGNO_P (REGNO) \
? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
+ : ALTIVEC_REGNO_P (REGNO) \
+ ? ((GET_MODE_SIZE (MODE) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD) \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+#define ALTIVEC_VECTOR_MODE(MODE) \
+ ((MODE) == V16QImode \
+ || (MODE) == V8HImode \
+ || (MODE) == V4SFmode \
+ || (MODE) == V4SImode)
+
+/* Define this macro to be nonzero if the port is prepared to handle
+ insns involving vector mode MODE. At the very least, it must have
+ move patterns for this mode. */
+
+#define VECTOR_MODE_SUPPORTED_P(MODE) \
+ (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE))
+
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
For POWER and PowerPC, the GPRs can hold any mode, but the float
registers only can hold floating modes and DImode, and CR register only
(GET_MODE_CLASS (MODE) == MODE_FLOAT \
|| (GET_MODE_CLASS (MODE) == MODE_INT \
&& GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD)) \
+ : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE) \
: CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC \
- : FPMEM_REGNO_P (REGNO) ? ((MODE) == DImode || (MODE) == DFmode) \
+ : XER_REGNO_P (REGNO) ? (MODE) == PSImode \
: ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT \
&& GET_MODE_SIZE (MODE) <= UNITS_PER_WORD) \
: 1)
? GET_MODE_CLASS (MODE2) == MODE_CC \
: GET_MODE_CLASS (MODE2) == MODE_CC \
? GET_MODE_CLASS (MODE1) == MODE_CC \
+ : ALTIVEC_VECTOR_MODE (MODE1) \
+ ? ALTIVEC_VECTOR_MODE (MODE2) \
+ : ALTIVEC_VECTOR_MODE (MODE2) \
+ ? ALTIVEC_VECTOR_MODE (MODE1) \
: 1)
/* A C expression returning the cost of moving data from a register of class
On the RS/6000, copying between floating-point and fixed-point
registers is expensive. */
-#define REGISTER_MOVE_COST(CLASS1, CLASS2) \
- ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2 \
+#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
+ ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2 \
: (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10 \
: (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10 \
+ : (CLASS1) == ALTIVEC_REGS && (CLASS2) != ALTIVEC_REGS ? 20 \
+ : (CLASS1) != ALTIVEC_REGS && (CLASS2) == ALTIVEC_REGS ? 20 \
: (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS \
|| (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS \
|| (CLASS1) == LINK_OR_CTR_REGS) \
On the RS/6000, bump this up a bit. */
-#define MEMORY_MOVE_COST(MODE,CLASS,IN) \
- ((GET_MODE_CLASS (MODE) == MODE_FLOAT \
+#define MEMORY_MOVE_COST(MODE, CLASS, IN) \
+ ((GET_MODE_CLASS (MODE) == MODE_FLOAT \
&& (rs6000_cpu == PROCESSOR_RIOS1 || rs6000_cpu == PROCESSOR_PPC601) \
? 3 : 2) \
+ 4)
#define BRANCH_COST 3
-/* A C statement (sans semicolon) to update the integer variable COST
- based on the relationship between INSN that is dependent on
- DEP_INSN through the dependence LINK. The default is to make no
- adjustment to COST. On the RS/6000, ignore the cost of anti- and
- output-dependencies. In fact, output dependencies on the CR do have
- a cost, but it is probably not worthwhile to track it. */
-
-#define ADJUST_COST(INSN,LINK,DEP_INSN,COST) \
- (COST) = rs6000_adjust_cost (INSN,LINK,DEP_INSN,COST)
-
-/* A C statement (sans semicolon) to update the integer scheduling priority
- INSN_PRIORITY (INSN). Reduce the priority to execute the INSN earlier,
- increase the priority to execute INSN later. Do not define this macro if
- you do not need to adjust the scheduling priorities of insns. */
-
-#define ADJUST_PRIORITY(INSN) \
- INSN_PRIORITY (INSN) = rs6000_adjust_priority (INSN, INSN_PRIORITY (INSN))
-
/* Define this macro to change register usage conditional on target flags.
Set MQ register fixed (already call_used) if not POWER architecture
(RIOS1, RIOS2, RSC, and PPC601) so that it will not be allocated.
#define CONDITIONAL_REGISTER_USAGE \
{ \
+ int i; \
if (! TARGET_POWER) \
fixed_regs[64] = 1; \
if (TARGET_64BIT) \
&& flag_pic == 1) \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] \
= call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
+ if (DEFAULT_ABI == ABI_DARWIN && flag_pic) \
+ global_regs[PIC_OFFSET_TABLE_REGNUM] \
+ = fixed_regs[PIC_OFFSET_TABLE_REGNUM] \
+ = call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
+ if (TARGET_ALTIVEC_ABI) \
+ { \
+ fixed_regs[VRSAVE_REGNO] = call_used_regs[VRSAVE_REGNO] = 1; \
+ for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i) \
+ call_used_regs[i] = 1; \
+ } \
}
/* Specify the registers used for certain standard purposes.
/* Place to put static chain when calling a function that requires it. */
#define STATIC_CHAIN_REGNUM 11
-/* count register number for special purposes */
-#define COUNT_REGISTER_REGNUM 66
+/* Link register number. */
+#define LINK_REGISTER_REGNUM 65
-/* Special register that represents memory, used for float/int conversions. */
-#define FPMEM_REGNUM 76
+/* Count register number. */
+#define COUNT_REGISTER_REGNUM 66
/* Place that structure value return address is placed.
So make a class for registers valid as base registers.
Also, cr0 is the only condition code register that can be used in
- arithmetic insns, so make a separate class for it.
-
- There is a special 'register' (76), which is not a register, but a
- placeholder for memory allocated to convert between floating point and
- integral types. This works around a problem where if we allocate memory
- with allocate_stack_{local,temp} and the function is an inline function, the
- memory allocated will clobber memory in the caller. So we use a special
- register, and if that is used, we allocate stack space for it. */
+ arithmetic insns, so make a separate class for it. */
enum reg_class
{
BASE_REGS,
GENERAL_REGS,
FLOAT_REGS,
+ ALTIVEC_REGS,
+ VRSAVE_REGS,
NON_SPECIAL_REGS,
MQ_REGS,
LINK_REGS,
CR0_REGS,
CR_REGS,
NON_FLOAT_REGS,
- FPMEM_REGS,
- FLOAT_OR_FPMEM_REGS,
+ XER_REGS,
ALL_REGS,
LIM_REG_CLASSES
};
"BASE_REGS", \
"GENERAL_REGS", \
"FLOAT_REGS", \
+ "ALTIVEC_REGS", \
+ "VRSAVE_REGS", \
"NON_SPECIAL_REGS", \
"MQ_REGS", \
"LINK_REGS", \
"CR0_REGS", \
"CR_REGS", \
"NON_FLOAT_REGS", \
- "FPMEM_REGS", \
- "FLOAT_OR_FPMEM_REGS", \
+ "XER_REGS", \
"ALL_REGS" \
}
This is an initializer for a vector of HARD_REG_SET
of length N_REG_CLASSES. */
-#define REG_CLASS_CONTENTS \
-{ \
- { 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \
- { 0xfffffffe, 0x00000000, 0x00000008 }, /* BASE_REGS */ \
- { 0xffffffff, 0x00000000, 0x00000008 }, /* GENERAL_REGS */ \
- { 0x00000000, 0xffffffff, 0x00000000 }, /* FLOAT_REGS */ \
- { 0xffffffff, 0xffffffff, 0x00000008 }, /* NON_SPECIAL_REGS */ \
- { 0x00000000, 0x00000000, 0x00000001 }, /* MQ_REGS */ \
- { 0x00000000, 0x00000000, 0x00000002 }, /* LINK_REGS */ \
- { 0x00000000, 0x00000000, 0x00000004 }, /* CTR_REGS */ \
- { 0x00000000, 0x00000000, 0x00000006 }, /* LINK_OR_CTR_REGS */ \
- { 0x00000000, 0x00000000, 0x00000007 }, /* SPECIAL_REGS */ \
- { 0xffffffff, 0x00000000, 0x0000000f }, /* SPEC_OR_GEN_REGS */ \
- { 0x00000000, 0x00000000, 0x00000010 }, /* CR0_REGS */ \
- { 0x00000000, 0x00000000, 0x00000ff0 }, /* CR_REGS */ \
- { 0xffffffff, 0x00000000, 0x0000ffff }, /* NON_FLOAT_REGS */ \
- { 0x00000000, 0x00000000, 0x00010000 }, /* FPMEM_REGS */ \
- { 0x00000000, 0xffffffff, 0x00010000 }, /* FLOAT_OR_FPMEM_REGS */ \
- { 0xffffffff, 0xffffffff, 0x0001ffff } /* ALL_REGS */ \
+#define REG_CLASS_CONTENTS \
+{ \
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \
+ { 0xfffffffe, 0x00000000, 0x00000008, 0x00000000 }, /* BASE_REGS */ \
+ { 0xffffffff, 0x00000000, 0x00000008, 0x00000000 }, /* GENERAL_REGS */ \
+ { 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FLOAT_REGS */ \
+ { 0x00000000, 0x00000000, 0xffffe000, 0x0001ffff }, /* ALTIVEC_REGS */ \
+ { 0x00000000, 0x00000000, 0x00000000, 0x00020000 }, /* VRSAVE_REGS */ \
+ { 0xffffffff, 0xffffffff, 0x00000008, 0x00000000 }, /* NON_SPECIAL_REGS */ \
+ { 0x00000000, 0x00000000, 0x00000001, 0x00000000 }, /* MQ_REGS */ \
+ { 0x00000000, 0x00000000, 0x00000002, 0x00000000 }, /* LINK_REGS */ \
+ { 0x00000000, 0x00000000, 0x00000004, 0x00000000 }, /* CTR_REGS */ \
+ { 0x00000000, 0x00000000, 0x00000006, 0x00000000 }, /* LINK_OR_CTR_REGS */ \
+ { 0x00000000, 0x00000000, 0x00000007, 0x00000000 }, /* SPECIAL_REGS */ \
+ { 0xffffffff, 0x00000000, 0x0000000f, 0x00000000 }, /* SPEC_OR_GEN_REGS */ \
+ { 0x00000000, 0x00000000, 0x00000010, 0x00000000 }, /* CR0_REGS */ \
+ { 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */ \
+ { 0xffffffff, 0x00000000, 0x0000ffff, 0x00000000 }, /* NON_FLOAT_REGS */ \
+ { 0x00000000, 0x00000000, 0x00010000, 0x00000000 }, /* XER_REGS */ \
+ { 0xffffffff, 0xffffffff, 0xffffffff, 0x0001ffff } /* ALL_REGS */ \
}
/* The same information, inverted:
reg number REGNO. This could be a conditional expression
or could index an array. */
-#define REGNO_REG_CLASS(REGNO) \
- ((REGNO) == 0 ? GENERAL_REGS \
- : (REGNO) < 32 ? BASE_REGS \
- : FP_REGNO_P (REGNO) ? FLOAT_REGS \
- : (REGNO) == 68 ? CR0_REGS \
- : CR_REGNO_P (REGNO) ? CR_REGS \
- : (REGNO) == 64 ? MQ_REGS \
- : (REGNO) == 65 ? LINK_REGS \
- : (REGNO) == 66 ? CTR_REGS \
- : (REGNO) == 67 ? BASE_REGS \
- : (REGNO) == 76 ? FPMEM_REGS \
+#define REGNO_REG_CLASS(REGNO) \
+ ((REGNO) == 0 ? GENERAL_REGS \
+ : (REGNO) < 32 ? BASE_REGS \
+ : FP_REGNO_P (REGNO) ? FLOAT_REGS \
+ : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_REGS \
+ : (REGNO) == CR0_REGNO ? CR0_REGS \
+ : CR_REGNO_P (REGNO) ? CR_REGS \
+ : (REGNO) == MQ_REGNO ? MQ_REGS \
+ : (REGNO) == LINK_REGISTER_REGNUM ? LINK_REGS \
+ : (REGNO) == COUNT_REGISTER_REGNUM ? CTR_REGS \
+ : (REGNO) == ARG_POINTER_REGNUM ? BASE_REGS \
+ : (REGNO) == XER_REGNO ? XER_REGS \
+ : (REGNO) == VRSAVE_REGNO ? VRSAVE_REGS \
: NO_REGS)
/* The class value for index registers, and the one for base regs. */
: (C) == 'q' ? MQ_REGS \
: (C) == 'c' ? CTR_REGS \
: (C) == 'l' ? LINK_REGS \
+ : (C) == 'v' ? ALTIVEC_REGS \
: (C) == 'x' ? CR0_REGS \
: (C) == 'y' ? CR_REGS \
- : (C) == 'z' ? FPMEM_REGS \
+ : (C) == 'z' ? XER_REGS \
: NO_REGS)
/* The letters I, J, K, L, M, N, and P in a register constraint string
`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
+ `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 */
#define CONST_OK_FOR_LETTER_P(VALUE, C) \
( (C) == 'I' ? (unsigned HOST_WIDE_INT) ((VALUE) + 0x8000) < 0x10000 \
- : (C) == 'J' ? ((VALUE) & (~ (HOST_WIDE_INT) 0xffff0000)) == 0 \
+ : (C) == 'J' ? ((VALUE) & (~ (unsigned HOST_WIDE_INT) 0xffff0000)) == 0 \
: (C) == 'K' ? ((VALUE) & (~ (HOST_WIDE_INT) 0xffff)) == 0 \
: (C) == 'L' ? (((VALUE) & 0xffff) == 0 \
&& ((VALUE) >> 31 == -1 || (VALUE) >> 31 == 0)) \
: (C) == 'M' ? (VALUE) > 31 \
- : (C) == 'N' ? exact_log2 (VALUE) >= 0 \
+ : (C) == 'N' ? (VALUE) > 0 && exact_log2 (VALUE) >= 0 \
: (C) == 'O' ? (VALUE) == 0 \
: (C) == 'P' ? (unsigned HOST_WIDE_INT) ((- (VALUE)) + 0x8000) < 0x10000 \
: 0)
in some cases it is preferable to use a more restrictive class.
On the RS/6000, we have to return NO_REGS when we want to reload a
- floating-point CONST_DOUBLE to force it to be copied to memory. */
+ floating-point CONST_DOUBLE to force it to be copied to memory.
+
+ We also don't want to reload integer values into floating-point
+ registers if we can at all help it. In fact, this can
+ cause reload to abort, if it tries to generate a reload of CTR
+ into a FP register and discovers it doesn't have the memory location
+ required.
+
+ ??? Would it be a good idea to have reload do the converse, that is
+ try to reload floating modes into FP registers if possible?
+ */
#define PREFERRED_RELOAD_CLASS(X,CLASS) \
- ((GET_CODE (X) == CONST_DOUBLE \
- && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \
- ? NO_REGS : (CLASS))
+ (((GET_CODE (X) == CONST_DOUBLE \
+ && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \
+ ? NO_REGS \
+ : (GET_MODE_CLASS (GET_MODE (X)) == MODE_INT \
+ && (CLASS) == NON_SPECIAL_REGS) \
+ ? GENERAL_REGS \
+ : (CLASS)))
/* Return the register class of a scratch register needed to copy IN into
or out of a register in CLASS in MODE. If it can be done directly,
#define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
secondary_reload_class (CLASS, MODE, IN)
-/* If we are copying between FP registers and anything else, we need a memory
- location. */
+/* If we are copying between FP or AltiVec registers and anything
+ else, we need a memory location. */
-#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
- ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS || (CLASS2) == FLOAT_REGS))
+#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
+ ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS \
+ || (CLASS2) == FLOAT_REGS \
+ || (CLASS1) == ALTIVEC_REGS \
+ || (CLASS2) == ALTIVEC_REGS))
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS.
On RS/6000, this is the size of MODE in words,
except in the FP regs, where a single reg is enough for two words. */
#define CLASS_MAX_NREGS(CLASS, MODE) \
- (((CLASS) == FLOAT_REGS || (CLASS) == FPMEM_REGS \
- || (CLASS) == FLOAT_OR_FPMEM_REGS) \
+ (((CLASS) == FLOAT_REGS) \
? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
/* If defined, gives a class of registers that cannot be used as the
- operand of a SUBREG that changes the size of the object. */
+ operand of a SUBREG that changes the mode of the object illegally. */
+
+#define CLASS_CANNOT_CHANGE_MODE FLOAT_REGS
+
+/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
-#define CLASS_CANNOT_CHANGE_SIZE FLOAT_OR_FPMEM_REGS
+#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
+ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
\f
/* Stack layout; function entry, exit and calling. */
ABI_AIX, /* IBM's AIX */
ABI_AIX_NODESC, /* AIX calling sequence minus function descriptors */
ABI_V4, /* System V.4/eabi */
- ABI_NT, /* Windows/NT */
- ABI_SOLARIS /* Solaris */
+ ABI_SOLARIS, /* Solaris */
+ ABI_DARWIN /* Apple's Darwin (OS X kernel) */
};
extern enum rs6000_abi rs6000_current_abi; /* available for use by subtarget */
-/* Default ABI to compile code for */
-#ifndef DEFAULT_ABI
-#define DEFAULT_ABI ABI_AIX
-/* The prefix to add to user-visible assembler symbols. */
-#define USER_LABEL_PREFIX "."
-#endif
-
/* Structure used to define the rs6000 stack */
typedef struct rs6000_stack {
int first_gp_reg_save; /* first callee saved GP register used */
int toc_save_p; /* true if the TOC needs to be saved */
int push_p; /* true if we need to allocate stack space */
int calls_p; /* true if the function makes any calls */
- int main_p; /* true if this is main */
- int main_save_p; /* true if this is main and we need to save args */
- int fpmem_p; /* true if float/int conversion temp needed */
enum rs6000_abi abi; /* which ABI to use */
int gp_save_offset; /* offset to save GP regs from initial SP */
int fp_save_offset; /* offset to save FP regs from initial SP */
int cr_save_offset; /* offset to save CR from initial SP */
int toc_save_offset; /* offset to save the TOC pointer */
int varargs_save_offset; /* offset to save the varargs registers */
- int main_save_offset; /* offset to save main's args */
- int fpmem_offset; /* offset for float/int conversion temp */
+ int ehrd_offset; /* offset to EH return data */
int reg_size; /* register size (4 or 8) */
int varargs_size; /* size to hold V.4 args passed in regs */
int vars_size; /* variable save area size */
int parm_size; /* outgoing parameter size */
- int main_size; /* size to hold saving main's args */
int save_size; /* save area size */
int fixed_size; /* fixed size of stack frame */
int gp_size; /* size of saved GP registers */
int fp_size; /* size of saved FP registers */
int cr_size; /* size to hold CR if not in save_size */
int lr_size; /* size to hold LR if not in save_size */
- int fpmem_size; /* size to hold float/int conversion */
int toc_size; /* size to hold TOC if not in save_size */
int total_size; /* total bytes allocated for stack */
} rs6000_stack_t;
/* #define FRAME_GROWS_DOWNWARD */
/* Size of the outgoing register save area */
-#define RS6000_REG_SAVE (TARGET_32BIT ? 32 : 64)
+#define RS6000_REG_SAVE ((DEFAULT_ABI == ABI_AIX \
+ || DEFAULT_ABI == ABI_AIX_NODESC \
+ || DEFAULT_ABI == ABI_DARWIN) \
+ ? (TARGET_64BIT ? 64 : 32) \
+ : 0)
/* Size of the fixed area on the stack */
-#define RS6000_SAVE_AREA (TARGET_32BIT ? 24 : 48)
+#define RS6000_SAVE_AREA \
+ (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_DARWIN) ? 24 : 8) \
+ << (TARGET_64BIT ? 1 : 0))
/* MEM representing address to save the TOC register */
#define RS6000_SAVE_TOC gen_rtx_MEM (Pmode, \
plus_constant (stack_pointer_rtx, \
(TARGET_32BIT ? 20 : 40)))
-/* Offset & size for fpmem stack locations used for converting between
- float and integral types. */
-extern int rs6000_fpmem_offset;
-extern int rs6000_fpmem_size;
-
/* Size of the V.4 varargs area if needed */
#define RS6000_VARARGS_AREA 0
-/* Whether a V.4 varargs area is needed */
-extern int rs6000_sysv_varargs_p;
-
/* Align an address */
#define RS6000_ALIGN(n,a) (((n) + (a) - 1) & ~((a) - 1))
-/* Initialize data used by insn expanders. This is called from
- init_emit, once for each function, before code is generated. */
-#define INIT_EXPANDERS rs6000_init_expanders ()
-
/* Size of V.4 varargs area in bytes */
#define RS6000_VARARGS_SIZE \
((GP_ARG_NUM_REG * (TARGET_32BIT ? 4 : 8)) + (FP_ARG_NUM_REG * 8) + 8)
area. */
#define FIRST_PARM_OFFSET(FNDECL) RS6000_SAVE_AREA
+/* Offset from the argument pointer register value to the top of
+ stack. This is different from FIRST_PARM_OFFSET because of the
+ register save area. */
+#define ARG_POINTER_CFA_OFFSET(FNDECL) 0
+
/* Define this if stack space is still allocated for a parameter passed
in a register. The value is the number of bytes allocated to this
area. */
/* Define this if the maximum size of all the outgoing args is to be
accumulated and pushed during the prologue. The amount can be
found in the variable current_function_outgoing_args_size. */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
/* Value is the number of bytes of arguments automatically
popped when returning from a subroutine call.
&& TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \
|| POINTER_TYPE_P (VALTYPE) \
? word_mode : TYPE_MODE (VALTYPE), \
- TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT ? 33 : 3)
+ TREE_CODE (VALTYPE) == VECTOR_TYPE ? ALTIVEC_ARG_RETURN \
+ : TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT \
+ ? FP_ARG_RETURN : GP_ARG_RETURN)
/* Define how to find the value returned by a library function
assuming the value has mode MODE. */
-#define LIBCALL_VALUE(MODE) \
- gen_rtx_REG (MODE, (GET_MODE_CLASS (MODE) == MODE_FLOAT \
- && TARGET_HARD_FLOAT ? 33 : 3))
+#define LIBCALL_VALUE(MODE) \
+ gen_rtx_REG (MODE, ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_ARG_RETURN \
+ : GET_MODE_CLASS (MODE) == MODE_FLOAT \
+ && TARGET_HARD_FLOAT \
+ ? FP_ARG_RETURN : GP_ARG_RETURN)
/* The definition of this macro implies that there are cases where
a scalar value cannot be returned in registers.
#define FP_ARG_MIN_REG 33
#define FP_ARG_AIX_MAX_REG 45
#define FP_ARG_V4_MAX_REG 40
-#define FP_ARG_MAX_REG FP_ARG_AIX_MAX_REG
+#define FP_ARG_MAX_REG ((DEFAULT_ABI == ABI_AIX \
+ || DEFAULT_ABI == ABI_AIX_NODESC \
+ || DEFAULT_ABI == ABI_DARWIN) \
+ ? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG)
#define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1)
+/* Minimum and maximum AltiVec registers used to hold arguments. */
+#define ALTIVEC_ARG_MIN_REG (FIRST_ALTIVEC_REGNO + 2)
+#define ALTIVEC_ARG_MAX_REG (ALTIVEC_ARG_MIN_REG + 11)
+#define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG - ALTIVEC_ARG_MIN_REG + 1)
+
/* Return registers */
#define GP_ARG_RETURN GP_ARG_MIN_REG
#define FP_ARG_RETURN FP_ARG_MIN_REG
+#define ALTIVEC_ARG_RETURN (FIRST_ALTIVEC_REGNO + 2)
/* Flags for the call/call_value rtl operations set up by function_arg */
#define CALL_NORMAL 0x00000000 /* no special processing */
-#define CALL_NT_DLLIMPORT 0x00000001 /* NT, this is a DLL import call */
+/* Bits in 0x00000001 are unused. */
#define CALL_V4_CLEAR_FP_ARGS 0x00000002 /* V.4, no FP args passed */
#define CALL_V4_SET_FP_ARGS 0x00000004 /* V.4, FP args were passed */
#define CALL_LONG 0x00000008 /* always call indirect */
-/* Define cutoff for using external functions to save floating point */
-#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) == 62 || (FIRST_REG) == 63)
-
/* 1 if N is a possible register number for a function value
as seen by the caller.
- On RS/6000, this is r3 and fp1. */
-#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_ARG_RETURN || ((N) == FP_ARG_RETURN))
+ On RS/6000, this is r3, fp1, and v2 (for AltiVec). */
+#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_ARG_RETURN \
+ || ((N) == FP_ARG_RETURN) \
+ || (TARGET_ALTIVEC && \
+ (N) == ALTIVEC_ARG_RETURN))
/* 1 if N is a possible register number for function argument passing.
- On RS/6000, these are r3-r10 and fp1-fp13. */
+ On RS/6000, these are r3-r10 and fp1-fp13.
+ On AltiVec, v2 - v13 are used for passing vectors. */
#define FUNCTION_ARG_REGNO_P(N) \
- (((unsigned)((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG)) \
+ ((unsigned)(((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG)) \
+ || (TARGET_ALTIVEC && \
+ (unsigned)((N) - ALTIVEC_ARG_MIN_REG) < (unsigned)(ALTIVEC_ARG_MAX_REG)) \
|| ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))
\f
+/* A C structure for machine-specific, per-function data.
+ This is added to the cfun structure. */
+typedef struct machine_function
+{
+ /* Whether a System V.4 varargs area was created. */
+ int sysv_varargs_p;
+ /* Flags if __builtin_return_address (n) with n >= 1 was used. */
+ int ra_needs_full_frame;
+} machine_function;
+
/* Define a data type for recording info about an argument list
during the scan of that argument list. This data type should
hold all necessary information about the function itself
{
int words; /* # words used for passing GP registers */
int fregno; /* next available FP register */
+ int vregno; /* next available AltiVec register */
int nargs_prototype; /* # args left in the current prototype */
int orig_nargs; /* Original value of nargs_prototype */
int prototype; /* Whether a prototype was defined */
/* Define intermediate macro to compute the size (in registers) of an argument
for the RS/6000. */
-#define RS6000_ARG_SIZE(MODE, TYPE, NAMED) \
-(! (NAMED) ? 0 \
- : (MODE) != BLKmode \
- ? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD \
- : (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
+#define RS6000_ARG_SIZE(MODE, TYPE) \
+((MODE) != BLKmode \
+ ? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD \
+ : ((unsigned HOST_WIDE_INT) int_size_in_bytes (TYPE) \
+ + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
/* Initialize a variable CUM of type CUMULATIVE_ARGS
for a call to a function whose data type is FNTYPE.
&& (CUM).fregno <= FP_ARG_MAX_REG \
&& TARGET_HARD_FLOAT)
+/* Non-zero if we can use an AltiVec register to pass this arg. */
+#define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE) \
+ (ALTIVEC_VECTOR_MODE (MODE) \
+ && (CUM).vregno <= ALTIVEC_ARG_MAX_REG \
+ && TARGET_ALTIVEC_ABI)
+
/* Determine where to put an argument to a function.
Value is zero to push the argument on the stack,
or a hard register in which to store the argument.
the argument, `downward' to pad below, or `none' to inhibit
padding. */
-#define FUNCTION_ARG_PADDING(MODE, TYPE) \
- (enum direction) function_arg_padding (MODE, TYPE)
+#define FUNCTION_ARG_PADDING(MODE, TYPE) function_arg_padding (MODE, TYPE)
/* If defined, a C expression that gives the alignment boundary, in bits,
of an argument with the specified mode and type. If it is not defined,
#define EXPAND_BUILTIN_VA_ARG(valist, type) \
rs6000_va_arg (valist, type)
-/* 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)
+/* Define this macro to be a nonzero value if the location where a function
+ argument is passed depends on whether or not it is a named argument. */
+#define STRICT_ARGUMENT_NAMING 1
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. */
its backpointer, which we maintain. */
#define EXIT_IGNORE_STACK 1
-/* 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)
-
-/* A C compound statement that outputs the assembler code for a thunk function,
- used to implement C++ virtual function calls with multiple inheritance. The
- thunk acts as a wrapper around a virtual function, adjusting the implicit
- object parameter before handing control off to the real function.
-
- First, emit code to add the integer DELTA to the location that contains the
- incoming first argument. Assume that this argument contains a pointer, and
- is the one used to pass the `this' pointer in C++. This is the incoming
- argument *before* the function prologue, e.g. `%o0' on a sparc. The
- addition must preserve the values of all other incoming arguments.
-
- After the addition, emit code to jump to FUNCTION, which is a
- `FUNCTION_DECL'. This is a direct pure jump, not a call, and does not touch
- 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
- extracted from it.) It might possibly be useful on some targets, but
- probably not.
-
- If you do not define this macro, the target-independent code in the C++
- frontend will generate a less efficient heavyweight thunk that calls
- FUNCTION instead of jumping to it. The generic approach does not support
- varargs. */
-#if TARGET_ELF
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
- output_mi_thunk (FILE, THUNK_FNDECL, DELTA, FUNCTION)
-#endif
+/* Define this macro as a C expression that is nonzero for registers
+ that are used by the epilogue or the return' pattern. The stack
+ and frame pointer registers are already be assumed to be used as
+ needed. */
+
+#define EPILOGUE_USES(REGNO) \
+ ((reload_completed && (REGNO) == LINK_REGISTER_REGNUM) \
+ || (current_function_calls_eh_return \
+ && TARGET_AIX \
+ && (REGNO) == TOC_REGISTER))
+
\f
/* TRAMPOLINE_TEMPLATE deleted */
#define INITIALIZE_TRAMPOLINE(ADDR, FNADDR, CXT) \
rs6000_initialize_trampoline (ADDR, FNADDR, CXT)
\f
-/* If defined, a C expression whose value is nonzero if IDENTIFIER
- with arguments ARGS is a valid machine specific attribute for DECL.
- The attributes in ATTRIBUTES have previously been assigned to DECL. */
-
-#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, NAME, ARGS) \
- (rs6000_valid_decl_attribute_p (DECL, ATTRIBUTES, NAME, ARGS))
-
-/* If defined, a C expression whose value is nonzero if IDENTIFIER
- with arguments ARGS is a valid machine specific attribute for TYPE.
- The attributes in ATTRIBUTES have previously been assigned to TYPE. */
-
-#define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, NAME, ARGS) \
- (rs6000_valid_type_attribute_p (TYPE, ATTRIBUTES, NAME, ARGS))
-
-/* If defined, a C expression whose value is zero if the attributes on
- TYPE1 and TYPE2 are incompatible, one if they are compatible, and
- two if they are nearly compatible (which causes a warning to be
- generated). */
-
-#define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \
- (rs6000_comp_type_attributes (TYPE1, TYPE2))
-
-/* If defined, a C statement that assigns default attributes to newly
- defined TYPE. */
-
-#define SET_DEFAULT_TYPE_ATTRIBUTES(TYPE) \
- (rs6000_set_default_type_attributes (TYPE))
-
-\f
/* Definitions for __builtin_return_address and __builtin_frame_address.
__builtin_return_address (0) should give link register (65), enable
this. */
abi's store the return address. */
#define RETURN_ADDRESS_OFFSET \
((DEFAULT_ABI == ABI_AIX \
- || DEFAULT_ABI == ABI_AIX_NODESC) ? 8 : \
+ || DEFAULT_ABI == ABI_DARWIN \
+ || DEFAULT_ABI == ABI_AIX_NODESC) ? (TARGET_32BIT ? 8 : 16) : \
(DEFAULT_ABI == ABI_V4 \
|| DEFAULT_ABI == ABI_SOLARIS) ? (TARGET_32BIT ? 4 : 8) : \
- (DEFAULT_ABI == ABI_NT) ? -4 : \
- (fatal ("RETURN_ADDRESS_OFFSET not supported"), 0))
+ (internal_error ("RETURN_ADDRESS_OFFSET not supported"), 0))
/* The current return address is in link register (65). The return address
of anything farther back is accessed normally at an offset of 8 from the
frame pointer. */
-#define RETURN_ADDR_RTX(count, frame) \
- ((count == -1) \
- ? gen_rtx_REG (Pmode, 65) \
- : gen_rtx_MEM (Pmode, \
- memory_address \
- (Pmode, \
- plus_constant (copy_to_reg \
- (gen_rtx_MEM (Pmode, \
- memory_address (Pmode, \
- frame))), \
- RETURN_ADDRESS_OFFSET))))
+#define RETURN_ADDR_RTX(COUNT, FRAME) \
+ (rs6000_return_addr (COUNT, FRAME))
+
\f
/* Definitions for register eliminations.
After reload, it makes no difference, since pseudo regs have
been eliminated by then. */
-#ifndef REG_OK_STRICT
+#ifdef REG_OK_STRICT
+# define REG_OK_STRICT_FLAG 1
+#else
+# define REG_OK_STRICT_FLAG 0
+#endif
/* Nonzero if X is a hard reg that can be used as an index
- or if it is a pseudo reg. */
-#define REG_OK_FOR_INDEX_P(X) \
- (REGNO (X) <= 31 || REGNO (X) == 67 || REGNO (X) >= FIRST_PSEUDO_REGISTER)
+ or if it is a pseudo reg in the non-strict case. */
+#define INT_REG_OK_FOR_INDEX_P(X, STRICT) \
+ ((! (STRICT) \
+ && (REGNO (X) <= 31 \
+ || REGNO (X) == ARG_POINTER_REGNUM \
+ || REGNO (X) >= FIRST_PSEUDO_REGISTER)) \
+ || ((STRICT) && REGNO_OK_FOR_INDEX_P (REGNO (X))))
/* Nonzero if X is a hard reg that can be used as a base reg
- or if it is a pseudo reg. */
-#define REG_OK_FOR_BASE_P(X) \
- (REGNO (X) > 0 && REG_OK_FOR_INDEX_P (X))
-
-#else
-
-/* Nonzero if X is a hard reg that can be used as an index. */
-#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
-/* Nonzero if X is a hard reg that can be used as a base reg. */
-#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
+ or if it is a pseudo reg in the non-strict case. */
+#define INT_REG_OK_FOR_BASE_P(X, STRICT) \
+ (REGNO (X) > 0 && INT_REG_OK_FOR_INDEX_P (X, (STRICT)))
-#endif
+#define REG_OK_FOR_INDEX_P(X) INT_REG_OK_FOR_INDEX_P (X, REG_OK_STRICT_FLAG)
+#define REG_OK_FOR_BASE_P(X) INT_REG_OK_FOR_BASE_P (X, REG_OK_STRICT_FLAG)
\f
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
that is a valid memory address for an instruction.
adjacent memory cells are accessed by adding word-sized offsets
during assembly output. */
-#define LEGITIMATE_CONSTANT_POOL_BASE_P(X) \
- (TARGET_TOC && GET_CODE (X) == SYMBOL_REF \
- && CONSTANT_POOL_ADDRESS_P (X) \
- && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (X)))
+#define CONSTANT_POOL_EXPR_P(X) (constant_pool_expr_p (X))
+
+#define TOC_RELATIVE_EXPR_P(X) (toc_relative_expr_p (X))
-/* AIX64 guaranteed to have 64 bit TOC alignment. */
#define LEGITIMATE_CONSTANT_POOL_ADDRESS_P(X) \
- (LEGITIMATE_CONSTANT_POOL_BASE_P (X) \
- || (TARGET_TOC \
- && GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS \
- && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
- && LEGITIMATE_CONSTANT_POOL_BASE_P (XEXP (XEXP (X, 0), 0))))
+ (TARGET_TOC \
+ && GET_CODE (X) == PLUS \
+ && GET_CODE (XEXP (X, 0)) == REG \
+ && (TARGET_MINIMAL_TOC || REGNO (XEXP (X, 0)) == TOC_REGISTER) \
+ && CONSTANT_POOL_EXPR_P (XEXP (X, 1)))
#define LEGITIMATE_SMALL_DATA_P(MODE, X) \
((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) \
&& (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST) \
&& small_data_operand (X, MODE))
-#define LEGITIMATE_ADDRESS_INTEGER_P(X,OFFSET) \
+#define LEGITIMATE_ADDRESS_INTEGER_P(X, OFFSET) \
(GET_CODE (X) == CONST_INT \
&& (unsigned HOST_WIDE_INT) (INTVAL (X) + (OFFSET) + 0x8000) < 0x10000)
-#define LEGITIMATE_OFFSET_ADDRESS_P(MODE,X) \
- (GET_CODE (X) == PLUS \
- && GET_CODE (XEXP (X, 0)) == REG \
- && REG_OK_FOR_BASE_P (XEXP (X, 0)) \
- && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0) \
- && (((MODE) != DFmode && (MODE) != DImode) \
- || (TARGET_32BIT \
- ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) \
- : ! (INTVAL (XEXP (X, 1)) & 3))) \
- && ((MODE) != TImode \
- || (TARGET_32BIT \
- ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 12) \
- : (LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 8) \
+#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X, STRICT) \
+ (GET_CODE (X) == PLUS \
+ && GET_CODE (XEXP (X, 0)) == REG \
+ && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
+ && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0) \
+ && (! ALTIVEC_VECTOR_MODE (MODE) || INTVAL (X) == 0) \
+ && (((MODE) != DFmode && (MODE) != DImode) \
+ || (TARGET_32BIT \
+ ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) \
+ : ! (INTVAL (XEXP (X, 1)) & 3))) \
+ && ((MODE) != TImode \
+ || (TARGET_32BIT \
+ ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 12) \
+ : (LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 8) \
&& ! (INTVAL (XEXP (X, 1)) & 3)))))
-#define LEGITIMATE_INDEXED_ADDRESS_P(X) \
- (GET_CODE (X) == PLUS \
- && GET_CODE (XEXP (X, 0)) == REG \
- && GET_CODE (XEXP (X, 1)) == REG \
- && ((REG_OK_FOR_BASE_P (XEXP (X, 0)) \
- && REG_OK_FOR_INDEX_P (XEXP (X, 1))) \
- || (REG_OK_FOR_BASE_P (XEXP (X, 1)) \
- && REG_OK_FOR_INDEX_P (XEXP (X, 0)))))
-
-#define LEGITIMATE_INDIRECT_ADDRESS_P(X) \
- (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))
-
-#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X) \
- (TARGET_ELF \
- && ! flag_pic && ! TARGET_TOC \
- && (MODE) != DImode \
- && (MODE) != TImode \
- && (TARGET_HARD_FLOAT || (MODE) != DFmode) \
- && GET_CODE (X) == LO_SUM \
- && GET_CODE (XEXP (X, 0)) == REG \
- && REG_OK_FOR_BASE_P (XEXP (X, 0)) \
+#define LEGITIMATE_INDEXED_ADDRESS_P(X, STRICT) \
+ (GET_CODE (X) == PLUS \
+ && GET_CODE (XEXP (X, 0)) == REG \
+ && GET_CODE (XEXP (X, 1)) == REG \
+ && ((INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
+ && INT_REG_OK_FOR_INDEX_P (XEXP (X, 1), (STRICT))) \
+ || (INT_REG_OK_FOR_BASE_P (XEXP (X, 1), (STRICT)) \
+ && INT_REG_OK_FOR_INDEX_P (XEXP (X, 0), (STRICT)))))
+
+#define LEGITIMATE_INDIRECT_ADDRESS_P(X, STRICT) \
+ (GET_CODE (X) == REG && INT_REG_OK_FOR_BASE_P (X, (STRICT)))
+
+#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X, STRICT) \
+ (TARGET_ELF \
+ && ! flag_pic && ! TARGET_TOC \
+ && (MODE) != DImode \
+ && (MODE) != TImode \
+ && ! ALTIVEC_VECTOR_MODE (MODE) \
+ && (TARGET_HARD_FLOAT || (MODE) != DFmode) \
+ && GET_CODE (X) == LO_SUM \
+ && GET_CODE (XEXP (X, 0)) == REG \
+ && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
&& CONSTANT_P (XEXP (X, 1)))
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ if (LEGITIMATE_INDIRECT_ADDRESS_P (X)) \
- goto ADDR; \
- if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC) \
- && TARGET_UPDATE \
- && LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (X, 0))) \
- goto ADDR; \
- if (LEGITIMATE_SMALL_DATA_P (MODE, X)) \
- goto ADDR; \
- if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (X)) \
- goto ADDR; \
- if (LEGITIMATE_OFFSET_ADDRESS_P (MODE, X)) \
- goto ADDR; \
- if ((MODE) != TImode \
- && (TARGET_HARD_FLOAT || TARGET_POWERPC64 || (MODE) != DFmode) \
- && (TARGET_POWERPC64 || (MODE) != DImode) \
- && LEGITIMATE_INDEXED_ADDRESS_P (X)) \
- goto ADDR; \
- if (LEGITIMATE_LO_SUM_ADDRESS_P (MODE, X)) \
- goto ADDR; \
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
+{ if (rs6000_legitimate_address (MODE, X, REG_OK_STRICT_FLAG)) \
+ goto ADDR; \
}
\f
/* Try machine-dependent ways of modifying an illegitimate address
Then check for the sum of a register and something not constant, try to
load the other things into a register and return the sum. */
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
-{ if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG \
- && GET_CODE (XEXP (X, 1)) == CONST_INT \
- && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (X, 1)) + 0x8000) >= 0x10000) \
- { HOST_WIDE_INT high_int, low_int; \
- rtx sum; \
- high_int = INTVAL (XEXP (X, 1)) & (~ (HOST_WIDE_INT) 0xffff); \
- low_int = INTVAL (XEXP (X, 1)) & 0xffff; \
- if (low_int & 0x8000) \
- high_int += 0x10000, low_int |= ((HOST_WIDE_INT) -1) << 16; \
- sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (X, 0), \
- GEN_INT (high_int)), 0); \
- (X) = gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int)); \
- goto WIN; \
- } \
- else if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG \
- && GET_CODE (XEXP (X, 1)) != CONST_INT \
- && (TARGET_HARD_FLOAT || TARGET_POWERPC64 || (MODE) != DFmode) \
- && (TARGET_POWERPC64 || (MODE) != DImode) \
- && (MODE) != TImode) \
- { \
- (X) = gen_rtx_PLUS (Pmode, XEXP (X, 0), \
- force_reg (Pmode, force_operand (XEXP (X, 1), 0))); \
- goto WIN; \
- } \
- else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC \
- && !flag_pic \
- && GET_CODE (X) != CONST_INT \
- && GET_CODE (X) != CONST_DOUBLE && CONSTANT_P (X) \
- && (TARGET_HARD_FLOAT || (MODE) != DFmode) \
- && (MODE) != DImode && (MODE) != TImode) \
- { \
- rtx reg = gen_reg_rtx (Pmode); \
- emit_insn (gen_elf_high (reg, (X))); \
- (X) = gen_rtx_LO_SUM (Pmode, reg, (X)); \
- goto WIN; \
- } \
+#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
+{ rtx result = rs6000_legitimize_address (X, OLDX, MODE); \
+ if (result != NULL_RTX) \
+ { \
+ (X) = result; \
+ goto WIN; \
+ } \
}
/* Try a machine-dependent way of reloading an illegitimate address
register by splitting the addend across an addiu/addis and the mem insn.
This cuts number of extra insns needed from 3 to 1. */
-#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \
-do { \
- /* We must recognize output that we have already generated ourselves. */ \
- if (GET_CODE (X) == PLUS \
- && GET_CODE (XEXP (X, 0)) == PLUS \
- && GET_CODE (XEXP (XEXP (X, 0), 0)) == REG \
- && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
- && GET_CODE (XEXP (X, 1)) == CONST_INT) \
- { \
- push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL_PTR, \
- BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0, \
- OPNUM, TYPE); \
- goto WIN; \
- } \
- if (GET_CODE (X) == PLUS \
- && GET_CODE (XEXP (X, 0)) == REG \
- && REGNO (XEXP (X, 0)) < FIRST_PSEUDO_REGISTER \
- && REG_MODE_OK_FOR_BASE_P (XEXP (X, 0), MODE) \
- && GET_CODE (XEXP (X, 1)) == CONST_INT) \
- { \
- HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \
- HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; \
- HOST_WIDE_INT high \
- = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000; \
- \
- /* Check for 32-bit overflow. */ \
- if (high + low != val) \
- break; \
- \
- /* Reload the high part into a base reg; leave the low part \
- in the mem directly. */ \
- \
- X = gen_rtx_PLUS (GET_MODE (X), \
- gen_rtx_PLUS (GET_MODE (X), XEXP (X, 0), \
- GEN_INT (high)), \
- GEN_INT (low)); \
- \
- push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL_PTR, \
- BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0, \
- OPNUM, TYPE); \
- goto WIN; \
- } \
+#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \
+do { \
+ /* We must recognize output that we have already generated ourselves. */ \
+ if (GET_CODE (X) == PLUS \
+ && GET_CODE (XEXP (X, 0)) == PLUS \
+ && GET_CODE (XEXP (XEXP (X, 0), 0)) == REG \
+ && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
+ && GET_CODE (XEXP (X, 1)) == CONST_INT) \
+ { \
+ push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL, \
+ BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0, \
+ OPNUM, TYPE); \
+ goto WIN; \
+ } \
+ if (GET_CODE (X) == PLUS \
+ && GET_CODE (XEXP (X, 0)) == REG \
+ && REGNO (XEXP (X, 0)) < FIRST_PSEUDO_REGISTER \
+ && REG_MODE_OK_FOR_BASE_P (XEXP (X, 0), MODE) \
+ && GET_CODE (XEXP (X, 1)) == CONST_INT) \
+ { \
+ HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \
+ HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; \
+ HOST_WIDE_INT high \
+ = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000; \
+ \
+ /* Check for 32-bit overflow. */ \
+ if (high + low != val) \
+ break; \
+ \
+ /* Reload the high part into a base reg; leave the low part \
+ in the mem directly. */ \
+ \
+ X = gen_rtx_PLUS (GET_MODE (X), \
+ gen_rtx_PLUS (GET_MODE (X), XEXP (X, 0), \
+ GEN_INT (high)), \
+ GEN_INT (low)); \
+ \
+ push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL, \
+ BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0, \
+ OPNUM, TYPE); \
+ goto WIN; \
+ } \
+ else if (TARGET_TOC \
+ && CONSTANT_POOL_EXPR_P (X) \
+ && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (X), MODE)) \
+ { \
+ (X) = create_TOC_reference (X); \
+ goto WIN; \
+ } \
} while (0)
/* Go to LABEL if ADDR (a legitimate address expression)
#define PIC_OFFSET_TABLE_REGNUM 30
+#define TOC_REGISTER (TARGET_MINIMAL_TOC ? 30 : 2)
+
/* Define this macro if the register defined by
`PIC_OFFSET_TABLE_REGNUM' is clobbered by calls. Do not define
this macro if `PPIC_OFFSET_TABLE_REGNUM' is not defined. */
/* In rare cases, correct code generation requires extra machine
dependent processing between the second jump optimization pass and
delayed branch scheduling. On those machines, define this macro
- as a C statement to act on the code starting at INSN.
+ as a C statement to act on the code starting at INSN. */
- On the RS/6000, we use it to make sure the GOT_TOC register marker
- that FINALIZE_PIC is supposed to remove actually got removed. */
-
-#define MACHINE_DEPENDENT_REORG(INSN) rs6000_reorg (INSN)
+/* #define MACHINE_DEPENDENT_REORG(INSN) */
\f
/* Define this if some processing needs to be done immediately before
/* Specify the machine mode that this machine uses
for the index in the tablejump instruction. */
-#define CASE_VECTOR_MODE (TARGET_32BIT ? SImode : DImode)
+#define CASE_VECTOR_MODE SImode
/* Define as C expression which evaluates to nonzero if the tablejump
instruction expects the table to contain offsets from the address of the
/* Define if loading short immediate values into registers sign extends. */
#define SHORT_IMMEDIATES_SIGN_EXTEND
\f
-/* 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, 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) == 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
-
-/* 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) */
-
/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
is done just by pretending it is already truncated. */
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
#define SHIFT_COUNT_TRUNCATED (TARGET_POWER ? 1 : 0)
-/* Use atexit for static constructors/destructors, instead of defining
- our own exit function. */
-#define HAVE_ATEXIT
-
/* Compute the cost of computing a constant rtl expression RTX
whose rtx-code is CODE. The body of this macro is a portion
of a switch statement. If the code is computed here,
return COSTS_N_INSNS (2); \
case PROCESSOR_PPC601: \
return COSTS_N_INSNS (5); \
+ case PROCESSOR_PPC7400: \
+ case PROCESSOR_PPC7450: \
case PROCESSOR_PPC603: \
case PROCESSOR_PPC750: \
return (GET_CODE (XEXP (X, 1)) != CONST_INT \
? COSTS_N_INSNS (21) \
: COSTS_N_INSNS (37)); \
case PROCESSOR_PPC750: \
+ case PROCESSOR_PPC7400: \
return COSTS_N_INSNS (19); \
+ case PROCESSOR_PPC7450: \
+ return COSTS_N_INSNS (23); \
} \
case FFS: \
return COSTS_N_INSNS (4); \
For the RS/6000, we need separate modes when unsigned (logical) comparisons
are being done and we need a separate mode for floating-point. We also
use a mode for the case when we are comparing the results of two
- comparisons. */
+ comparisons, as then only the EQ bit is valid in the register. */
#define EXTRA_CC_MODES \
CC(CCUNSmode, "CCUNS") \
CC(CCFPmode, "CCFP") \
CC(CCEQmode, "CCEQ")
-/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
- return the mode to be used for the comparison. For floating-point, CCFPmode
- should be used. CCUNSmode should be used for unsigned comparisons.
- CCEQmode should be used when we are doing an inequality comparison on
- the result of a comparison. CCmode should be used in all other cases. */
+/* Given a comparison code (EQ, NE, etc.) and the first operand of a
+ COMPARE, return the mode to be used for the comparison. For
+ floating-point, CCFPmode should be used. CCUNSmode should be used
+ for unsigned comparisons. CCEQmode should be used when we are
+ doing an inequality comparison on the result of a
+ comparison. CCmode should be used in all other cases. */
#define SELECT_CC_MODE(OP,X,Y) \
(GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT ? CCFPmode \
extern struct rtx_def *rs6000_compare_op0, *rs6000_compare_op1;
extern int rs6000_compare_fp_p;
-
-/* Set to non-zero by "fix" operation to indicate that itrunc and
- uitrunc must be defined. */
-
-extern int rs6000_trunc_used;
-
-/* Function names to call to do floating point truncation. */
-
-#define RS6000_ITRUNC "__itrunc"
-#define RS6000_UITRUNC "__uitrunc"
-
-/* Prefix and suffix to use to saving floating point */
-#ifndef SAVE_FP_PREFIX
-#define SAVE_FP_PREFIX "._savef"
-#define SAVE_FP_SUFFIX ""
-#endif
-
-/* Prefix and suffix to use to restoring floating point */
-#ifndef RESTORE_FP_PREFIX
-#define RESTORE_FP_PREFIX "._restf"
-#define RESTORE_FP_SUFFIX ""
-#endif
-
-/* Function name to call to do profiling. */
-#define RS6000_MCOUNT ".__mcount"
-
\f
/* Control the assembler format that we output. */
the end of the line. */
#define ASM_COMMENT_START " #"
-/* 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.
-
- We then switch back to text to force the gcc2_compiled. label and the space
- allocated after it (when profiling) into the text section.
-
- 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 ("\t.long _section_.text\n", FILE); \
-}
-
-/* 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
-
/* Implicit library calls should use memcpy, not bcopy, etc. */
#define TARGET_MEM_FUNCTIONS
-/* 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 name of our readonly data section. */
-
-#define READONLY_DATA_SECTION read_only_data_section
-
-
-/* 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
-
-/* 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. */
-
-#define JUMP_TABLES_IN_TEXT_SECTION 1
-
-/* 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, ".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, ".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, ".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 (".toc\nLCTOC..0:\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, ".csect toc_table[RW]%s\n", \
- (TARGET_32BIT ? "" : ",3")); \
- } \
- else \
- { \
- if (in_section != toc) \
- fputs (".toc\n", asm_out_file); \
- } \
- in_section = toc; \
-}
-
/* Flag to say the TOC is initialized */
extern int toc_initialized;
-/* 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. */
-
-/* ??? What do the 16 and 044 in the .function line really mean? */
-
-#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 (".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); \
- fputs (".csect .text[PR]\n.", FILE); \
- RS6000_OUTPUT_BASENAME (FILE, NAME); \
- fputs (":\n", FILE); \
- if (write_symbols == XCOFF_DEBUG) \
- xcoffout_declare_function (FILE, DECL, NAME); \
-}
-
-/* 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. */
-
-#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X) \
- (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 \
- || (! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC) \
- && GET_CODE (X) == CONST_DOUBLE \
- && (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
- || (TARGET_POWERPC64 && GET_MODE (X) == DImode)))))
-#if 0
- && BITS_PER_WORD == HOST_BITS_PER_INT)))
-#endif
-
-/* 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)) \
- toc_section (); \
- else \
- read_only_private_data_section (); \
-}
-
/* Macro to output a special constant pool entry. Go to WIN if we output
it. Otherwise, it is written the usual way.
On the RS/6000, toc entries are handled this way. */
-#define ASM_OUTPUT_SPECIAL_POOL_ENTRY(FILE, X, MODE, ALIGN, LABELNO, WIN) \
-{ if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (X)) \
- { \
- output_toc (FILE, X, LABELNO); \
- goto WIN; \
- } \
+#define ASM_OUTPUT_SPECIAL_POOL_ENTRY(FILE, X, MODE, ALIGN, LABELNO, WIN) \
+{ if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (X, MODE)) \
+ { \
+ output_toc (FILE, X, LABELNO, MODE); \
+ goto WIN; \
+ } \
}
-/* 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 \
+/* This implementes the `alias' attribute. */
+
+#define ASM_OUTPUT_DEF_FROM_DECLS(FILE,decl,target) \
+do { \
+ const char * alias = XSTR (XEXP (DECL_RTL (decl), 0), 0); \
+ char * name = IDENTIFIER_POINTER (target); \
+ if (TREE_CODE (decl) == FUNCTION_DECL \
+ && DEFAULT_ABI == ABI_AIX) \
{ \
- if (TREE_PUBLIC (EXP)) \
- data_section (); \
+ if (TREE_PUBLIC (decl)) \
+ { \
+ fputs ("\t.globl .", FILE); \
+ assemble_name (FILE, alias); \
+ putc ('\n', FILE); \
+ } \
else \
- private_data_section (); \
+ { \
+ fputs ("\t.lglobl .", FILE); \
+ assemble_name (FILE, alias); \
+ putc ('\n', FILE); \
+ } \
+ fputs ("\t.set .", FILE); \
+ assemble_name (FILE, alias); \
+ fputs (",.", FILE); \
+ assemble_name (FILE, name); \
+ fputc ('\n', FILE); \
} \
-}
-
-/* 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); \
- }
-
-/* Remove any trailing [DS] or the like from the symbol name. */
-
-#define STRIP_NAME_ENCODING(VAR,NAME) \
- do \
- { \
- const char *_name = (NAME); \
- int _len; \
- if (_name[0] == '*') \
- _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 something to declare an external symbol to the assembler. Most
- assemblers don't need this.
-
- If we haven't already, add "[RW]" (or "[DS]" for a function) to the
- name. Normally we write this out along with the name. In the few cases
- where we can't, it gets stripped off. */
-
-#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; \
- } \
- fputs ("\t.extern ", FILE); \
- assemble_name (FILE, XSTR (_symref, 0)); \
- if (TREE_CODE (DECL) == FUNCTION_DECL) \
- { \
- fputs ("\n\t.extern .", FILE); \
- RS6000_OUTPUT_BASENAME (FILE, XSTR (_symref, 0)); \
- } \
- putc ('\n', FILE); \
-}
-
-/* Similar, but for libcall. We only have to worry about the function name,
- not that of the descriptor. */
-
-#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
-{ fputs ("\t.extern .", FILE); \
- assemble_name (FILE, XSTR (FUN, 0)); \
- putc ('\n', FILE); \
-}
+ ASM_OUTPUT_DEF (FILE, alias, name); \
+} while (0)
/* Output to assembler file text saying following lines
may contain character constants, extra white space, comments, etc. */
#define ASM_APP_OFF ""
-/* Output before instructions.
- Text section for 64-bit target may contain 64-bit address jump table. */
-
-#define TEXT_SECTION_ASM_OP (TARGET_32BIT \
- ? ".csect .text[PR]" : ".csect .text[PR],3")
-
-/* Output before writable data.
- Align entire section to BIGGEST_ALIGNMENT. */
-
-#define DATA_SECTION_ASM_OP ".csect .data[RW],3"
-
/* How to refer to registers in assembler output.
This sequence is indexed by compiler's hard-register-number (see above). */
&rs6000_reg_names[74][0], /* cr6 */ \
&rs6000_reg_names[75][0], /* cr7 */ \
\
- &rs6000_reg_names[76][0], /* fpmem */ \
+ &rs6000_reg_names[76][0], /* xer */ \
+ \
+ &rs6000_reg_names[77][0], /* v0 */ \
+ &rs6000_reg_names[78][0], /* v1 */ \
+ &rs6000_reg_names[79][0], /* v2 */ \
+ &rs6000_reg_names[80][0], /* v3 */ \
+ &rs6000_reg_names[81][0], /* v4 */ \
+ &rs6000_reg_names[82][0], /* v5 */ \
+ &rs6000_reg_names[83][0], /* v6 */ \
+ &rs6000_reg_names[84][0], /* v7 */ \
+ &rs6000_reg_names[85][0], /* v8 */ \
+ &rs6000_reg_names[86][0], /* v9 */ \
+ &rs6000_reg_names[87][0], /* v10 */ \
+ &rs6000_reg_names[88][0], /* v11 */ \
+ &rs6000_reg_names[89][0], /* v12 */ \
+ &rs6000_reg_names[90][0], /* v13 */ \
+ &rs6000_reg_names[91][0], /* v14 */ \
+ &rs6000_reg_names[92][0], /* v15 */ \
+ &rs6000_reg_names[93][0], /* v16 */ \
+ &rs6000_reg_names[94][0], /* v17 */ \
+ &rs6000_reg_names[95][0], /* v18 */ \
+ &rs6000_reg_names[96][0], /* v19 */ \
+ &rs6000_reg_names[97][0], /* v20 */ \
+ &rs6000_reg_names[98][0], /* v21 */ \
+ &rs6000_reg_names[99][0], /* v22 */ \
+ &rs6000_reg_names[100][0], /* v23 */ \
+ &rs6000_reg_names[101][0], /* v24 */ \
+ &rs6000_reg_names[102][0], /* v25 */ \
+ &rs6000_reg_names[103][0], /* v26 */ \
+ &rs6000_reg_names[104][0], /* v27 */ \
+ &rs6000_reg_names[105][0], /* v28 */ \
+ &rs6000_reg_names[106][0], /* v29 */ \
+ &rs6000_reg_names[107][0], /* v30 */ \
+ &rs6000_reg_names[108][0], /* v31 */ \
+ &rs6000_reg_names[109][0], /* vrsave */ \
}
/* print-rtl can't handle the above REGISTER_NAMES, so define the
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
"mq", "lr", "ctr", "ap", \
"cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
- "fpmem" \
+ "xer", \
+ "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", \
+ "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", \
+ "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", \
+ "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", \
+ "vrsave" \
}
/* Table of additional register names to use in user input. */
{"fr20", 52}, {"fr21", 53}, {"fr22", 54}, {"fr23", 55}, \
{"fr24", 56}, {"fr25", 57}, {"fr26", 58}, {"fr27", 59}, \
{"fr28", 60}, {"fr29", 61}, {"fr30", 62}, {"fr31", 63}, \
+ {"v0", 77}, {"v1", 78}, {"v2", 79}, {"v3", 80}, \
+ {"v4", 81}, {"v5", 82}, {"v6", 83}, {"v7", 84}, \
+ {"v8", 85}, {"v9", 86}, {"v10", 87}, {"v11", 88}, \
+ {"v12", 89}, {"v13", 90}, {"v14", 91}, {"v15", 92}, \
+ {"v16", 93}, {"v17", 94}, {"v18", 95}, {"v19", 96}, \
+ {"v20", 97}, {"v21", 98}, {"v22", 99}, {"v23", 100}, \
+ {"v24", 101},{"v25", 102},{"v26", 103},{"v27", 104}, \
+ {"v28", 105},{"v29", 106},{"v30", 107},{"v31", 108}, \
+ {"vrsave", 109}, \
/* no additional names for: mq, lr, ctr, ap */ \
{"cr0", 68}, {"cr1", 69}, {"cr2", 70}, {"cr3", 71}, \
{"cr4", 72}, {"cr5", 73}, {"cr6", 74}, {"cr7", 75}, \
the loader. This depends on the AIX version. */
#define RS6000_CALL_GLUE "cror 31,31,31"
-/* 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)
-
-/* This is how to output a reference to a user-level label named NAME.
- `assemble_name' uses this. */
-
-#define ASM_OUTPUT_LABELREF(FILE,NAME) \
- fputs (NAME, FILE)
-
-/* 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..%d", PREFIX, NUM)
-
/* This is how to output an assembler line defining a `double' constant. */
#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \
if (TARGET_32BIT) \
{ \
assemble_integer (operand_subword ((VALUE), 0, 0, DImode), \
- UNITS_PER_WORD, 1); \
+ UNITS_PER_WORD, BITS_PER_WORD, 1); \
assemble_integer (operand_subword ((VALUE), 1, 0, DImode), \
- UNITS_PER_WORD, 1); \
+ UNITS_PER_WORD, BITS_PER_WORD, 1); \
} \
else \
{ \
- fputs ("\t.llong ", FILE); \
+ fprintf (FILE, "%s", DOUBLE_INT_ASM_OP); \
output_addr_const (FILE, (VALUE)); \
putc ('\n', FILE); \
} \
/* This is how to output an assembler line for a numeric constant byte. */
#define ASM_OUTPUT_BYTE(FILE,VALUE) \
- fprintf (FILE, "\t.byte 0x%x\n", (VALUE))
-
-/* This is how to output an assembler line to define N characters starting
- at P to FILE. */
+ fprintf (FILE, "\t.byte 0x%x\n", (int)(VALUE))
-#define ASM_OUTPUT_ASCII(FILE, P, N) output_ascii ((FILE), (P), (N))
-
-/* This is how to output an element of a case-vector that is absolute.
- (RS/6000 does not use such vectors, but we must define this macro
- anyway.) */
-
-#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
- do { char buf[100]; \
- fputs (TARGET_32BIT ? "\t.long " : "\t.llong ", FILE); \
- ASM_GENERATE_INTERNAL_LABEL (buf, "L", VALUE); \
- assemble_name (FILE, buf); \
- putc ('\n', FILE); \
- } while (0)
+/* 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. */
-#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
do { char buf[100]; \
- fputs (TARGET_32BIT ? "\t.long " : "\t.llong ", FILE); \
+ fputs ("\t.long ", FILE); \
ASM_GENERATE_INTERNAL_LABEL (buf, "L", VALUE); \
assemble_name (FILE, buf); \
putc ('-', FILE); \
if ((LOG) != 0) \
fprintf (FILE, "\t.align %d\n", (LOG))
-#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)
-
-/* 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. */
( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
-/* Define the parentheses used to group arithmetic operations
- in assembler code. */
+/* Pick up the return address upon entry to a procedure. Used for
+ dwarf2 unwind information. This also enables the table driven
+ mechanism. */
-#define ASM_OPEN_PAREN "("
-#define ASM_CLOSE_PAREN ")"
+#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LINK_REGISTER_REGNUM)
-/* Define results of standard character escape sequences. */
-#define TARGET_BELL 007
-#define TARGET_BS 010
-#define TARGET_TAB 011
-#define TARGET_NEWLINE 012
-#define TARGET_VT 013
-#define TARGET_FF 014
-#define TARGET_CR 015
+/* Describe how we implement __builtin_eh_return. */
+#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 3 : INVALID_REGNUM)
+#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 10)
/* Print operand X (an rtx) in assembler syntax to file FILE.
CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
/* Define the codes that are matched by predicates in rs6000.c. */
-#define PREDICATE_CODES \
- {"short_cint_operand", {CONST_INT}}, \
- {"u_short_cint_operand", {CONST_INT}}, \
- {"non_short_cint_operand", {CONST_INT}}, \
- {"gpc_reg_operand", {SUBREG, REG}}, \
- {"cc_reg_operand", {SUBREG, REG}}, \
- {"cc_reg_not_cr0_operand", {SUBREG, REG}}, \
- {"reg_or_short_operand", {SUBREG, REG, CONST_INT}}, \
- {"reg_or_neg_short_operand", {SUBREG, REG, CONST_INT}}, \
- {"reg_or_u_short_operand", {SUBREG, REG, CONST_INT}}, \
- {"reg_or_cint_operand", {SUBREG, REG, CONST_INT}}, \
- {"got_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
- {"got_no_const_operand", {SYMBOL_REF, LABEL_REF}}, \
- {"easy_fp_constant", {CONST_DOUBLE}}, \
- {"reg_or_mem_operand", {SUBREG, MEM, REG}}, \
- {"lwa_operand", {SUBREG, MEM, REG}}, \
- {"volatile_mem_operand", {MEM}}, \
- {"offsettable_mem_operand", {MEM}}, \
- {"mem_or_easy_const_operand", {SUBREG, MEM, CONST_DOUBLE}}, \
- {"add_operand", {SUBREG, REG, CONST_INT}}, \
- {"non_add_cint_operand", {CONST_INT}}, \
- {"and_operand", {SUBREG, REG, CONST_INT}}, \
- {"and64_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
- {"logical_operand", {SUBREG, REG, CONST_INT}}, \
- {"non_logical_cint_operand", {CONST_INT}}, \
- {"mask_operand", {CONST_INT}}, \
- {"mask64_operand", {CONST_INT, CONST_DOUBLE}}, \
- {"count_register_operand", {REG}}, \
- {"fpmem_operand", {REG}}, \
- {"call_operand", {SYMBOL_REF, REG}}, \
- {"current_file_function_operand", {SYMBOL_REF}}, \
- {"input_operand", {SUBREG, MEM, REG, CONST_INT, \
- CONST_DOUBLE, SYMBOL_REF}}, \
- {"load_multiple_operation", {PARALLEL}}, \
- {"store_multiple_operation", {PARALLEL}}, \
- {"branch_comparison_operator", {EQ, NE, LE, LT, GE, \
- GT, LEU, LTU, GEU, GTU}}, \
- {"scc_comparison_operator", {EQ, NE, LE, LT, GE, \
- GT, LEU, LTU, GEU, GTU}}, \
- {"trap_comparison_operator", {EQ, NE, LE, LT, GE, \
- GT, LEU, LTU, GEU, GTU}},
+#define PREDICATE_CODES \
+ {"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}}, \
+ {"reg_or_short_operand", {SUBREG, REG, CONST_INT}}, \
+ {"reg_or_neg_short_operand", {SUBREG, REG, CONST_INT}}, \
+ {"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}}, \
+ {"easy_fp_constant", {CONST_DOUBLE}}, \
+ {"zero_fp_constant", {CONST_DOUBLE}}, \
+ {"reg_or_mem_operand", {SUBREG, MEM, REG}}, \
+ {"lwa_operand", {SUBREG, MEM, REG}}, \
+ {"volatile_mem_operand", {MEM}}, \
+ {"offsettable_mem_operand", {MEM}}, \
+ {"mem_or_easy_const_operand", {SUBREG, MEM, CONST_DOUBLE}}, \
+ {"add_operand", {SUBREG, REG, CONST_INT}}, \
+ {"non_add_cint_operand", {CONST_INT}}, \
+ {"and_operand", {SUBREG, REG, CONST_INT}}, \
+ {"and64_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
+ {"logical_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
+ {"non_logical_cint_operand", {CONST_INT, CONST_DOUBLE}}, \
+ {"mask_operand", {CONST_INT}}, \
+ {"mask64_operand", {CONST_INT, CONST_DOUBLE}}, \
+ {"count_register_operand", {REG}}, \
+ {"xer_operand", {REG}}, \
+ {"call_operand", {SYMBOL_REF, REG}}, \
+ {"current_file_function_operand", {SYMBOL_REF}}, \
+ {"input_operand", {SUBREG, MEM, REG, CONST_INT, \
+ CONST_DOUBLE, SYMBOL_REF}}, \
+ {"load_multiple_operation", {PARALLEL}}, \
+ {"store_multiple_operation", {PARALLEL}}, \
+ {"branch_comparison_operator", {EQ, NE, LE, LT, GE, \
+ GT, LEU, LTU, GEU, GTU, \
+ UNORDERED, ORDERED, \
+ UNGE, UNLE }}, \
+ {"branch_positive_comparison_operator", {EQ, LT, GT, LTU, GTU, \
+ UNORDERED }}, \
+ {"scc_comparison_operator", {EQ, NE, LE, LT, GE, \
+ GT, LEU, LTU, GEU, GTU, \
+ UNORDERED, ORDERED, \
+ UNGE, UNLE }}, \
+ {"trap_comparison_operator", {EQ, NE, LE, LT, GE, \
+ GT, LEU, LTU, GEU, GTU}}, \
+ {"boolean_operator", {AND, IOR, XOR}}, \
+ {"boolean_or_operator", {IOR, XOR}}, \
+ {"min_max_operator", {SMIN, SMAX, UMIN, UMAX}},
/* uncomment for disabling the corresponding default options */
/* #define MACHINE_no_sched_interblock */
/* #define MACHINE_no_sched_speculative */
/* #define MACHINE_no_sched_speculative_load */
-/* indicate that issue rate is defined for this machine
- (no need to use the default) */
-#define ISSUE_RATE get_issue_rate ()
-
/* General flags. */
extern int flag_pic;
extern int optimize;
extern int flag_expensive_optimizations;
extern int frame_pointer_needed;
-/* Declare functions in rs6000.c */
-extern void optimization_options ();
-extern void output_options ();
-extern void rs6000_override_options ();
-extern void rs6000_file_start ();
-extern struct rtx_def *rs6000_float_const ();
-extern struct rtx_def *rs6000_got_register ();
-extern struct rtx_def *find_addr_reg();
-extern int direct_return ();
-extern int get_issue_rate ();
-extern int any_operand ();
-extern int short_cint_operand ();
-extern int u_short_cint_operand ();
-extern int non_short_cint_operand ();
-extern int gpc_reg_operand ();
-extern int cc_reg_operand ();
-extern int cc_reg_not_cr0_operand ();
-extern int reg_or_short_operand ();
-extern int reg_or_neg_short_operand ();
-extern int reg_or_u_short_operand ();
-extern int reg_or_cint_operand ();
-extern int got_operand ();
-extern int got_no_const_operand ();
-extern int num_insns_constant ();
-extern int easy_fp_constant ();
-extern int volatile_mem_operand ();
-extern int offsettable_mem_operand ();
-extern int mem_or_easy_const_operand ();
-extern int add_operand ();
-extern int non_add_cint_operand ();
-extern int non_logical_cint_operand ();
-extern int logical_operand ();
-extern int mask_operand ();
-extern int mask64_operand ();
-extern int and64_operand ();
-extern int and_operand ();
-extern int count_register_operand ();
-extern int fpmem_operand ();
-extern int reg_or_mem_operand ();
-extern int lwa_operand ();
-extern int call_operand ();
-extern int current_file_function_operand ();
-extern int input_operand ();
-extern int small_data_operand ();
-extern void init_cumulative_args ();
-extern void function_arg_advance ();
-extern int function_arg_boundary ();
-extern struct rtx_def *function_arg ();
-extern int function_arg_partial_nregs ();
-extern int function_arg_pass_by_reference ();
-extern void setup_incoming_varargs ();
-extern union tree_node *rs6000_va_list ();
-extern void rs6000_va_start ();
-extern struct rtx_def *rs6000_va_arg ();
-extern struct rtx_def *rs6000_stack_temp ();
-extern int expand_block_move ();
-extern int load_multiple_operation ();
-extern int store_multiple_operation ();
-extern int branch_comparison_operator ();
-extern int scc_comparison_operator ();
-extern int trap_comparison_operator ();
-extern int includes_lshift_p ();
-extern int includes_rshift_p ();
-extern int registers_ok_for_quad_peep ();
-extern int addrs_ok_for_quad_peep ();
-extern enum reg_class secondary_reload_class ();
-extern int ccr_bit ();
-extern void rs6000_finalize_pic ();
-extern void rs6000_reorg ();
-extern void rs6000_save_machine_status ();
-extern void rs6000_restore_machine_status ();
-extern void rs6000_init_expanders ();
-extern void print_operand ();
-extern void print_operand_address ();
-extern int first_reg_to_save ();
-extern int first_fp_reg_to_save ();
-extern int rs6000_makes_calls ();
-extern rs6000_stack_t *rs6000_stack_info ();
-extern void output_prolog ();
-extern void output_epilog ();
-extern void output_mi_thunk ();
-extern void output_toc ();
-extern void output_ascii ();
-extern void rs6000_gen_section_name ();
-extern void output_function_profiler ();
-extern int rs6000_adjust_cost ();
-extern int rs6000_adjust_priority ();
-extern void rs6000_trampoline_template ();
-extern int rs6000_trampoline_size ();
-extern void rs6000_initialize_trampoline ();
-extern void rs6000_output_load_toc_table ();
-extern int rs6000_comp_type_attributes ();
-extern int rs6000_valid_decl_attribute_p ();
-extern int rs6000_valid_type_attribute_p ();
-extern void rs6000_set_default_type_attributes ();
-extern struct rtx_def *rs6000_dll_import_ref ();
-extern struct rtx_def *rs6000_longcall_ref ();
-extern int function_arg_padding ();
-extern void toc_section ();
-extern void private_data_section ();
-extern void rs6000_fatal_bad_address ();
-
-/* See nonlocal_goto_receiver for when this must be set. */
-
-#define DONT_ACCESS_GBLS_AFTER_EPILOGUE (TARGET_TOC && TARGET_MINIMAL_TOC)
+enum rs6000_builtins
+{
+ /* AltiVec builtins. */
+ ALTIVEC_BUILTIN_ST_INTERNAL,
+ ALTIVEC_BUILTIN_LD_INTERNAL,
+ ALTIVEC_BUILTIN_VADDUBM,
+ ALTIVEC_BUILTIN_VADDUHM,
+ ALTIVEC_BUILTIN_VADDUWM,
+ ALTIVEC_BUILTIN_VADDFP,
+ ALTIVEC_BUILTIN_VADDCUW,
+ ALTIVEC_BUILTIN_VADDUBS,
+ ALTIVEC_BUILTIN_VADDSBS,
+ ALTIVEC_BUILTIN_VADDUHS,
+ ALTIVEC_BUILTIN_VADDSHS,
+ ALTIVEC_BUILTIN_VADDUWS,
+ ALTIVEC_BUILTIN_VADDSWS,
+ ALTIVEC_BUILTIN_VAND,
+ ALTIVEC_BUILTIN_VANDC,
+ ALTIVEC_BUILTIN_VAVGUB,
+ ALTIVEC_BUILTIN_VAVGSB,
+ ALTIVEC_BUILTIN_VAVGUH,
+ ALTIVEC_BUILTIN_VAVGSH,
+ ALTIVEC_BUILTIN_VAVGUW,
+ ALTIVEC_BUILTIN_VAVGSW,
+ ALTIVEC_BUILTIN_VCMPBFP,
+ ALTIVEC_BUILTIN_VCMPEQUB,
+ ALTIVEC_BUILTIN_VCMPEQUH,
+ ALTIVEC_BUILTIN_VCMPEQUW,
+ ALTIVEC_BUILTIN_VCMPEQFP,
+ ALTIVEC_BUILTIN_VCMPGEFP,
+ ALTIVEC_BUILTIN_VCMPGTUB,
+ ALTIVEC_BUILTIN_VCMPGTSB,
+ ALTIVEC_BUILTIN_VCMPGTUH,
+ ALTIVEC_BUILTIN_VCMPGTSH,
+ ALTIVEC_BUILTIN_VCMPGTUW,
+ ALTIVEC_BUILTIN_VCMPGTSW,
+ ALTIVEC_BUILTIN_VCMPGTFP,
+ ALTIVEC_BUILTIN_VMAXUB,
+ ALTIVEC_BUILTIN_VMAXSB,
+ ALTIVEC_BUILTIN_VMAXUH,
+ ALTIVEC_BUILTIN_VMAXSH,
+ ALTIVEC_BUILTIN_VMAXUW,
+ ALTIVEC_BUILTIN_VMAXSW,
+ ALTIVEC_BUILTIN_VMAXFP,
+ ALTIVEC_BUILTIN_VMRGHB,
+ ALTIVEC_BUILTIN_VMRGHH,
+ ALTIVEC_BUILTIN_VMRGHW,
+ ALTIVEC_BUILTIN_VMRGLB,
+ ALTIVEC_BUILTIN_VMRGLH,
+ ALTIVEC_BUILTIN_VMRGLW,
+ ALTIVEC_BUILTIN_VMINUB,
+ ALTIVEC_BUILTIN_VMINSB,
+ ALTIVEC_BUILTIN_VMINUH,
+ ALTIVEC_BUILTIN_VMINSH,
+ ALTIVEC_BUILTIN_VMINUW,
+ ALTIVEC_BUILTIN_VMINSW,
+ ALTIVEC_BUILTIN_VMINFP,
+ ALTIVEC_BUILTIN_VMULEUB,
+ ALTIVEC_BUILTIN_VMULESB,
+ ALTIVEC_BUILTIN_VMULEUH,
+ ALTIVEC_BUILTIN_VMULESH,
+ ALTIVEC_BUILTIN_VMULOUB,
+ ALTIVEC_BUILTIN_VMULOSB,
+ ALTIVEC_BUILTIN_VMULOUH,
+ ALTIVEC_BUILTIN_VMULOSH,
+ ALTIVEC_BUILTIN_VNOR,
+ ALTIVEC_BUILTIN_VOR,
+ ALTIVEC_BUILTIN_VPKUHUM,
+ ALTIVEC_BUILTIN_VPKUWUM,
+ ALTIVEC_BUILTIN_VPKPX,
+ ALTIVEC_BUILTIN_VPKUHSS,
+ ALTIVEC_BUILTIN_VPKSHSS,
+ ALTIVEC_BUILTIN_VPKUWSS,
+ ALTIVEC_BUILTIN_VPKSWSS,
+ ALTIVEC_BUILTIN_VPKUHUS,
+ ALTIVEC_BUILTIN_VPKSHUS,
+ ALTIVEC_BUILTIN_VPKUWUS,
+ ALTIVEC_BUILTIN_VPKSWUS,
+ ALTIVEC_BUILTIN_VRLB,
+ ALTIVEC_BUILTIN_VRLH,
+ ALTIVEC_BUILTIN_VRLW,
+ ALTIVEC_BUILTIN_VSLB,
+ ALTIVEC_BUILTIN_VSLH,
+ ALTIVEC_BUILTIN_VSLW,
+ ALTIVEC_BUILTIN_VSL,
+ ALTIVEC_BUILTIN_VSLO,
+ ALTIVEC_BUILTIN_VSRB,
+ ALTIVEC_BUILTIN_VRSH,
+ ALTIVEC_BUILTIN_VRSW,
+ ALTIVEC_BUILTIN_VSRAB,
+ ALTIVEC_BUILTIN_VSRAH,
+ ALTIVEC_BUILTIN_VSRAW,
+ ALTIVEC_BUILTIN_VSR,
+ ALTIVEC_BUILTIN_VSRO,
+ ALTIVEC_BUILTIN_VSUBUBM,
+ ALTIVEC_BUILTIN_VSUBUHM,
+ ALTIVEC_BUILTIN_VSUBUWM,
+ ALTIVEC_BUILTIN_VSUBFP,
+ ALTIVEC_BUILTIN_VSUBCUW,
+ ALTIVEC_BUILTIN_VSUBUBS,
+ ALTIVEC_BUILTIN_VSUBSBS,
+ ALTIVEC_BUILTIN_VSUBUHS,
+ ALTIVEC_BUILTIN_VSUBSHS,
+ ALTIVEC_BUILTIN_VSUBUWS,
+ ALTIVEC_BUILTIN_VSUBSWS,
+ ALTIVEC_BUILTIN_VSUM4UBS,
+ ALTIVEC_BUILTIN_VSUM4SBS,
+ ALTIVEC_BUILTIN_VSUM4SHS,
+ ALTIVEC_BUILTIN_VSUM2SWS,
+ ALTIVEC_BUILTIN_VSUMSWS,
+ ALTIVEC_BUILTIN_VXOR
+};