summaryrefslogtreecommitdiffstats
path: root/gcc/config/rs6000/linux64.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/rs6000/linux64.h')
-rw-r--r--gcc/config/rs6000/linux64.h571
1 files changed, 406 insertions, 165 deletions
diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
index 5a31366dbf2..f63b7d41923 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -19,43 +19,163 @@
Free Software Foundation, 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */
-/* Yes! We are AIX! Err. Wait. We're Linux!. No, wait, we're a
- combo of both!*/
-#undef DEFAULT_ABI
-#define DEFAULT_ABI ABI_AIX
+#ifndef RS6000_BI_ARCH
-#undef TARGET_AIX
-#define TARGET_AIX 1
+#undef DEFAULT_ABI
+#define DEFAULT_ABI ABI_AIX
-#undef TARGET_DEFAULT
-#define TARGET_DEFAULT \
- (MASK_POWERPC | MASK_POWERPC64 | MASK_64BIT | MASK_NEW_MNEMONICS)
+#undef TARGET_64BIT
+#define TARGET_64BIT 1
+
+#define DEFAULT_ARCH64_P 1
+#define RS6000_BI_ARCH_P 0
+
+#else
+
+#define DEFAULT_ARCH64_P (TARGET_DEFAULT & MASK_64BIT)
+#define RS6000_BI_ARCH_P 1
+
+#endif
+
+#ifdef IN_LIBGCC2
+#undef TARGET_64BIT
+#ifdef __powerpc64__
+#define TARGET_64BIT 1
+#else
+#define TARGET_64BIT 0
+#endif
+#endif
+
+#undef TARGET_AIX
+#define TARGET_AIX TARGET_64BIT
-#undef PROCESSOR_DEFAULT
-#define PROCESSOR_DEFAULT PROCESSOR_PPC630
-#undef PROCESSOR_DEFAULT64
+#undef PROCESSOR_DEFAULT64
#define PROCESSOR_DEFAULT64 PROCESSOR_PPC630
-#undef ASM_DEFAULT_SPEC
-#define ASM_DEFAULT_SPEC "-mppc64"
+#undef TARGET_RELOCATABLE
+#define TARGET_RELOCATABLE (!TARGET_64BIT && (target_flags & MASK_RELOCATABLE))
+
+#undef RS6000_ABI_NAME
+#define RS6000_ABI_NAME (TARGET_64BIT ? "aixdesc" : "sysv")
+
+#define INVALID_64BIT "-m%s not supported in this configuration"
+#define INVALID_32BIT INVALID_64BIT
+
+#undef SUBSUBTARGET_OVERRIDE_OPTIONS
+#define SUBSUBTARGET_OVERRIDE_OPTIONS \
+ do \
+ { \
+ if (TARGET_64BIT) \
+ { \
+ if (DEFAULT_ABI != ABI_AIX) \
+ { \
+ DEFAULT_ABI = ABI_AIX; \
+ error (INVALID_64BIT, "call"); \
+ } \
+ if (TARGET_RELOCATABLE) \
+ { \
+ target_flags &= ~MASK_RELOCATABLE; \
+ error (INVALID_64BIT, "relocatable"); \
+ } \
+ if (TARGET_EABI) \
+ { \
+ target_flags &= ~MASK_EABI; \
+ error (INVALID_64BIT, "eabi"); \
+ } \
+ if (TARGET_PROTOTYPE) \
+ { \
+ target_flags &= ~MASK_PROTOTYPE; \
+ error (INVALID_64BIT, "prototype"); \
+ } \
+ } \
+ else \
+ { \
+ if (!RS6000_BI_ARCH_P) \
+ error (INVALID_32BIT, "32"); \
+ } \
+ } \
+ while (0)
+
+#ifdef RS6000_BI_ARCH
+
+#undef OVERRIDE_OPTIONS
+#define OVERRIDE_OPTIONS \
+ rs6000_override_options (((TARGET_DEFAULT ^ target_flags) & MASK_64BIT) \
+ ? (char *) 0 : TARGET_CPU_DEFAULT)
+
+#undef ASM_FILE_START
+#define ASM_FILE_START(FILE) \
+ do \
+ { \
+ output_file_directive ((FILE), main_input_filename); \
+ rs6000_file_start (FILE, (((TARGET_DEFAULT ^ target_flags) \
+ & MASK_64BIT) \
+ ? (char *) 0 : TARGET_CPU_DEFAULT)); \
+ } \
+ while (0)
+
+#endif
+#undef ASM_DEFAULT_SPEC
#undef ASM_SPEC
-#define ASM_SPEC "%{.s: %{mregnames} %{mno-regnames}} \
-%{.S: %{mregnames} %{mno-regnames}} \
-%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian} \
-%{v:-V} %{Qy:} %{!Qn:-Qy} -a64 %(asm_cpu) %{Wa,*:%*}"
+#undef LINK_OS_LINUX_SPEC
-/* This is always a 64 bit compiler. */
-#undef TARGET_64BIT
-#define TARGET_64BIT 1
+#ifndef RS6000_BI_ARCH
+#define ASM_DEFAULT_SPEC "-mppc64"
+#define ASM_SPEC "%(asm_spec64) %(asm_spec_common)"
+#define LINK_OS_LINUX_SPEC "%(link_os_linux_spec64)"
+#else
+#if DEFAULT_ARCH64_P
+#define ASM_DEFAULT_SPEC "-mppc%{!m32:64}"
+#define ASM_SPEC "%{m32:%(asm_spec32)}%{!m32:%(asm_spec64)} %(asm_spec_common)"
+#define LINK_OS_LINUX_SPEC "%{m32:%(link_os_linux_spec32)}%{!m32:%(link_os_linux_spec64)}"
+#else
+#define ASM_DEFAULT_SPEC "-mppc%{m64:64}"
+#define ASM_SPEC "%{!m64:%(asm_spec32)}%{m64:%(asm_spec64)} %(asm_spec_common)"
+#define LINK_OS_LINUX_SPEC "%{!m64:%(link_os_linux_spec32)}%{m64:%(link_os_linux_spec64)}"
+#endif
+#endif
+
+#define ASM_SPEC32 "-a32 %{n} %{T} %{Ym,*} %{Yd,*} \
+%{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} \
+%{memb} %{!memb: %{msdata: -memb} %{msdata=eabi: -memb}} \
+%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
+ %{mcall-freebsd: -mbig} \
+ %{mcall-i960-old: -mlittle} \
+ %{mcall-linux: -mbig} \
+ %{mcall-gnu: -mbig} \
+ %{mcall-netbsd: -mbig} \
+}}}}"
+
+#define ASM_SPEC64 "-a64"
+
+#define ASM_SPEC_COMMON "%(asm_cpu) \
+%{.s: %{mregnames} %{mno-regnames}} %{.S: %{mregnames} %{mno-regnames}} \
+%{v:-V} %{Qy:} %{!Qn:-Qy} %{Wa,*:%*} \
+%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian}"
+
+#undef SUBSUBTARGET_EXTRA_SPECS
+#define SUBSUBTARGET_EXTRA_SPECS \
+ { "asm_spec_common", ASM_SPEC_COMMON }, \
+ { "asm_spec32", ASM_SPEC32 }, \
+ { "asm_spec64", ASM_SPEC64 }, \
+ { "link_os_linux_spec32", LINK_OS_LINUX_SPEC32 }, \
+ { "link_os_linux_spec64", LINK_OS_LINUX_SPEC64 },
+
+#undef MULTILIB_DEFAULTS
+#if DEFAULT_ARCH64_P
+#define MULTILIB_DEFAULTS { "m64" }
+#else
+#define MULTILIB_DEFAULTS { "m32" }
+#endif
+
+#ifndef RS6000_BI_ARCH
/* 64-bit PowerPC Linux always has a TOC. */
-#undef TARGET_NO_TOC
-#define TARGET_NO_TOC 0
#undef TARGET_TOC
#define TARGET_TOC 1
-/* Some things from sysv4.h we don't do. */
+/* Some things from sysv4.h we don't do when 64 bit. */
#undef TARGET_RELOCATABLE
#define TARGET_RELOCATABLE 0
#undef TARGET_EABI
@@ -63,8 +183,9 @@
#undef TARGET_PROTOTYPE
#define TARGET_PROTOTYPE 0
-/* Reuse sysv4 mask bits we made available above. */
-#define MASK_PROFILE_KERNEL 0x08000000
+#endif
+
+#define MASK_PROFILE_KERNEL 0x00080000
/* Non-standard profiling for kernels, which just saves LR then calls
_mcount without worrying about arg saves. The idea is to change
@@ -73,88 +194,62 @@
#define TARGET_PROFILE_KERNEL (target_flags & MASK_PROFILE_KERNEL)
/* Override sysv4.h. */
-#undef SUBTARGET_SWITCHES
-#define SUBTARGET_SWITCHES \
- {"bit-align", -MASK_NO_BITFIELD_TYPE, \
- N_("Align to the base type of the bit-field") }, \
- {"no-bit-align", MASK_NO_BITFIELD_TYPE, \
- N_("Don't align to the base type of the bit-field") }, \
- {"strict-align", MASK_STRICT_ALIGN, \
- N_("Don't assume that unaligned accesses are handled by the system") }, \
- {"no-strict-align", -MASK_STRICT_ALIGN, \
- N_("Assume that unaligned accesses are handled by the system") }, \
- {"little-endian", MASK_LITTLE_ENDIAN, \
- N_("Produce little endian code") }, \
- {"little", MASK_LITTLE_ENDIAN, \
- N_("Produce little endian code") }, \
- {"big-endian", -MASK_LITTLE_ENDIAN, \
- N_("Produce big endian code") }, \
- {"big", -MASK_LITTLE_ENDIAN, \
- N_("Produce big endian code") }, \
- {"bit-word", -MASK_NO_BITFIELD_WORD, \
- N_("Allow bit-fields to cross word boundaries") }, \
- {"no-bit-word", MASK_NO_BITFIELD_WORD, \
- N_("Do not allow bit-fields to cross word boundaries") }, \
- {"regnames", MASK_REGNAMES, \
- N_("Use alternate register names") }, \
- {"no-regnames", -MASK_REGNAMES, \
- N_("Don't use alternate register names") }, \
+#undef EXTRA_SUBTARGET_SWITCHES
+#define EXTRA_SUBTARGET_SWITCHES \
{"profile-kernel", MASK_PROFILE_KERNEL, \
N_("Call mcount for profiling before a function prologue") }, \
{"no-profile-kernel", -MASK_PROFILE_KERNEL, \
N_("Call mcount for profiling after a function prologue") },
-#undef SUBTARGET_OPTIONS
-#define SUBTARGET_OPTIONS
-
-#undef SUBTARGET_OVERRIDE_OPTIONS
-#define SUBTARGET_OVERRIDE_OPTIONS {}
-
/* We use glibc _mcount for profiling. */
-#define NO_PROFILE_COUNTERS 1
-#define PROFILE_HOOK(LABEL) output_profile_hook (LABEL)
+#define NO_PROFILE_COUNTERS TARGET_64BIT
+#define PROFILE_HOOK(LABEL) \
+ do { if (TARGET_64BIT) output_profile_hook (LABEL); } while (0)
/* We don't need to generate entries in .fixup. */
#undef RELOCATABLE_NEEDS_FIXUP
-#define USER_LABEL_PREFIX ""
-
/* This now supports a natural alignment mode. */
/* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints. */
#undef ADJUST_FIELD_ALIGN
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
- (TARGET_ALIGN_NATURAL ? (COMPUTED) : \
- (TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
- ? get_inner_array_type (FIELD) \
- : TREE_TYPE (FIELD)) == DFmode \
- ? MIN ((COMPUTED), 32) : (COMPUTED)))
+ ((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
+ ? 128 \
+ : (TARGET_64BIT \
+ && TARGET_ALIGN_NATURAL == 0 \
+ && TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
+ ? get_inner_array_type (FIELD) \
+ : TREE_TYPE (FIELD)) == DFmode) \
+ ? MIN ((COMPUTED), 32) \
+ : (COMPUTED))
/* AIX increases natural record alignment to doubleword if the first
field is an FP double while the FP fields remain word aligned. */
#undef ROUND_TYPE_ALIGN
-#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 \
- && TARGET_ALIGN_NATURAL == 0 \
- && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode \
- ? MAX (MAX ((COMPUTED), (SPECIFIED)), 64) \
+#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \
+ ((TARGET_ALTIVEC && TREE_CODE (STRUCT) == VECTOR_TYPE) \
+ ? MAX (MAX ((COMPUTED), (SPECIFIED)), 128) \
+ : (TARGET_64BIT \
+ && (TREE_CODE (STRUCT) == RECORD_TYPE \
+ || TREE_CODE (STRUCT) == UNION_TYPE \
+ || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
+ && TYPE_FIELDS (STRUCT) != 0 \
+ && TARGET_ALIGN_NATURAL == 0 \
+ && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode) \
+ ? MAX (MAX ((COMPUTED), (SPECIFIED)), 64) \
: MAX ((COMPUTED), (SPECIFIED)))
/* Indicate that jump tables go in the text section. */
#undef JUMP_TABLES_IN_TEXT_SECTION
-#define JUMP_TABLES_IN_TEXT_SECTION 1
-
-/* 64-bit PowerPC Linux always has GPR13 fixed. */
-#define FIXED_R13 1
+#define JUMP_TABLES_IN_TEXT_SECTION TARGET_64BIT
/* __throw will restore its own return address to be the same as the
return address of the function that the throw is being made to.
This is unfortunate, because we want to check the original
return address to see if we need to restore the TOC.
So we have to squirrel it away with this. */
-#define SETUP_FRAME_ADDRESSES() rs6000_aix_emit_builtin_unwind_init ()
+#define SETUP_FRAME_ADDRESSES() \
+ do { if (TARGET_64BIT) rs6000_aix_emit_builtin_unwind_init (); } while (0)
/* Override svr4.h */
#undef MD_EXEC_PREFIX
@@ -165,17 +260,28 @@
#define CPP_SYSV_SPEC ""
#undef TARGET_OS_CPP_BUILTINS
-#define TARGET_OS_CPP_BUILTINS() \
- do \
- { \
- builtin_define ("__PPC__"); \
- builtin_define ("__PPC64__"); \
- builtin_define ("__powerpc__"); \
- builtin_define ("__powerpc64__"); \
- builtin_define ("__PIC__"); \
- builtin_assert ("cpu=powerpc64"); \
- builtin_assert ("machine=powerpc64"); \
- } \
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ if (TARGET_64BIT) \
+ { \
+ builtin_define ("__PPC__"); \
+ builtin_define ("__PPC64__"); \
+ builtin_define ("__powerpc__"); \
+ builtin_define ("__powerpc64__"); \
+ builtin_define ("__PIC__"); \
+ builtin_assert ("cpu=powerpc64"); \
+ builtin_assert ("machine=powerpc64"); \
+ } \
+ else \
+ { \
+ builtin_define_std ("PPC"); \
+ builtin_define_std ("powerpc"); \
+ builtin_assert ("cpu=powerpc"); \
+ builtin_assert ("machine=powerpc"); \
+ TARGET_OS_SYSV_CPP_BUILTINS (); \
+ } \
+ } \
while (0)
#undef CPP_OS_DEFAULT_SPEC
@@ -205,48 +311,40 @@
#undef LINK_OS_DEFAULT_SPEC
#define LINK_OS_DEFAULT_SPEC "%(link_os_linux)"
-#undef LINK_OS_LINUX_SPEC
-#define LINK_OS_LINUX_SPEC "-m elf64ppc %{!shared: %{!static: \
+#define LINK_OS_LINUX_SPEC32 "-m elf32ppclinux %{!shared: %{!static: \
%{rdynamic:-export-dynamic} \
- %{!dynamic-linker:-dynamic-linker /lib64/ld64.so.1}}}"
-
-#ifdef NATIVE_CROSS
-#define STARTFILE_PREFIX_SPEC "/usr/local/lib64/ /lib64/ /usr/lib64/"
-#endif
+ %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}}}"
-#undef STARTFILE_LINUX_SPEC
-#ifdef HAVE_LD_PIE
-#define STARTFILE_LINUX_SPEC "\
-%{!shared: %{pg|p:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}} crti.o%s \
-%{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
-#else
-#define STARTFILE_LINUX_SPEC "\
-%{!shared: %{pg|p:gcrt1.o%s;:crt1.o%s}} crti.o%s \
-%{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
-#endif
-
-#undef ENDFILE_LINUX_SPEC
-#define ENDFILE_LINUX_SPEC "\
-%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
+#define LINK_OS_LINUX_SPEC64 "-m elf64ppc %{!shared: %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /lib64/ld64.so.1}}}"
#undef TOC_SECTION_ASM_OP
-#define TOC_SECTION_ASM_OP "\t.section\t\".toc\",\"aw\""
+#define TOC_SECTION_ASM_OP \
+ (TARGET_64BIT \
+ ? "\t.section\t\".toc\",\"aw\"" \
+ : "\t.section\t\".got\",\"aw\"")
#undef MINIMAL_TOC_SECTION_ASM_OP
-#define MINIMAL_TOC_SECTION_ASM_OP "\t.section\t\".toc1\",\"aw\""
+#define MINIMAL_TOC_SECTION_ASM_OP \
+ (TARGET_64BIT \
+ ? "\t.section\t\".toc1\",\"aw\"" \
+ : ((TARGET_RELOCATABLE || flag_pic) \
+ ? "\t.section\t\".got2\",\"aw\"" \
+ : "\t.section\t\".got1\",\"aw\""))
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC64 GNU/Linux)");
/* Must be at least as big as our pointer type. */
-#undef SIZE_TYPE
-#define SIZE_TYPE "long unsigned int"
+#undef SIZE_TYPE
+#define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int")
-#undef PTRDIFF_TYPE
-#define PTRDIFF_TYPE "long int"
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
-#undef WCHAR_TYPE
-#define WCHAR_TYPE "int"
+#undef WCHAR_TYPE
+#define WCHAR_TYPE (TARGET_64BIT ? "int" : "long int")
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32
@@ -260,51 +358,25 @@
/* PowerPC no-op instruction. */
#undef RS6000_CALL_GLUE
-#define RS6000_CALL_GLUE "nop"
+#define RS6000_CALL_GLUE (TARGET_64BIT ? "nop" : "cror 31,31,31")
#undef RS6000_MCOUNT
#define RS6000_MCOUNT "_mcount"
/* FP save and restore routines. */
#undef SAVE_FP_PREFIX
-#define SAVE_FP_PREFIX "._savef"
+#define SAVE_FP_PREFIX (TARGET_64BIT ? "._savef" : "_savefpr_")
#undef SAVE_FP_SUFFIX
-#define SAVE_FP_SUFFIX ""
+#define SAVE_FP_SUFFIX (TARGET_64BIT ? "" : "_l")
#undef RESTORE_FP_PREFIX
-#define RESTORE_FP_PREFIX "._restf"
+#define RESTORE_FP_PREFIX (TARGET_64BIT ? "._restf" : "_restfpr_")
#undef RESTORE_FP_SUFFIX
-#define RESTORE_FP_SUFFIX ""
+#define RESTORE_FP_SUFFIX (TARGET_64BIT ? "" : "_l")
/* Dwarf2 debugging. */
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
-#undef ASM_DECLARE_FUNCTION_NAME
-#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
- do \
- { \
- fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", (FILE)); \
- ASM_OUTPUT_LABEL ((FILE), (NAME)); \
- fputs (DOUBLE_INT_ASM_OP, (FILE)); \
- putc ('.', (FILE)); \
- assemble_name ((FILE), (NAME)); \
- fputs (",.TOC.@tocbase,0\n\t.previous\n\t.size\t", (FILE)); \
- assemble_name ((FILE), (NAME)); \
- fputs (",24\n\t.type\t.", (FILE)); \
- assemble_name ((FILE), (NAME)); \
- fputs (",@function\n", (FILE)); \
- if (TREE_PUBLIC (DECL) && ! DECL_WEAK (DECL)) \
- { \
- fputs ("\t.globl\t.", (FILE)); \
- assemble_name ((FILE), (NAME)); \
- putc ('\n', (FILE)); \
- } \
- ASM_DECLARE_RESULT ((FILE), DECL_RESULT (DECL)); \
- putc ('.', (FILE)); \
- ASM_OUTPUT_LABEL ((FILE), (NAME)); \
- } \
- while (0)
-
/* This is how to declare the size of a function. */
#undef ASM_DECLARE_FUNCTION_SIZE
#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
@@ -312,9 +384,13 @@
{ \
if (!flag_inhibit_size_directive) \
{ \
- fputs ("\t.size\t.", (FILE)); \
+ fputs ("\t.size\t", (FILE)); \
+ if (TARGET_64BIT) \
+ putc ('.', (FILE)); \
assemble_name ((FILE), (FNAME)); \
- fputs (",.-.", (FILE)); \
+ fputs (",.-", (FILE)); \
+ if (TARGET_64BIT) \
+ putc ('.', (FILE)); \
assemble_name ((FILE), (FNAME)); \
putc ('\n', (FILE)); \
} \
@@ -341,10 +417,16 @@
|| (GET_CODE (X) == CONST_INT \
&& GET_MODE_BITSIZE (MODE) <= GET_MODE_BITSIZE (Pmode)) \
|| (GET_CODE (X) == CONST_DOUBLE \
- && (TARGET_POWERPC64 \
- || TARGET_MINIMAL_TOC \
- || (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
- && ! TARGET_NO_FP_IN_TOC)))))
+ && ((TARGET_64BIT \
+ && (TARGET_POWERPC64 \
+ || TARGET_MINIMAL_TOC \
+ || (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
+ && ! TARGET_NO_FP_IN_TOC))) \
+ || (!TARGET_64BIT \
+ && !TARGET_NO_FP_IN_TOC \
+ && !TARGET_RELOCATABLE \
+ && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
+ && BITS_PER_WORD == HOST_BITS_PER_INT)))))
/* This is the same as the dbxelf.h version, except that we need to
use the function code label, not the function descriptor. */
@@ -357,7 +439,9 @@ do \
ASM_GENERATE_INTERNAL_LABEL (temp, "LM", sym_lineno); \
fprintf (FILE, "\t.stabn 68,0,%d,", LINE); \
assemble_name (FILE, temp); \
- fputs ("-.", FILE); \
+ putc ('-', FILE); \
+ if (TARGET_64BIT) \
+ putc ('.', FILE); \
assemble_name (FILE, \
XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\
putc ('\n', FILE); \
@@ -378,7 +462,8 @@ while (0)
flab = IDENTIFIER_POINTER (current_function_func_begin_label); \
else \
{ \
- putc ('.', FILE); \
+ if (TARGET_64BIT) \
+ putc ('.', FILE); \
flab = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); \
} \
assemble_name (FILE, flab); \
@@ -395,19 +480,175 @@ while (0)
{ \
fprintf (FILE, "%s\"\",%d,0,0,", ASM_STABS_OP, N_FUN); \
assemble_name (FILE, LSCOPE); \
- fputs ("-.", FILE); \
+ putc ('-', FILE); \
+ if (TARGET_64BIT) \
+ putc ('.', FILE); \
assemble_name (FILE, XSTR (XEXP (DECL_RTL (DECL), 0), 0)); \
putc ('\n', FILE); \
} \
while (0)
-/* Override sysv4.h as these are ABI_V4 only. */
-#undef ASM_OUTPUT_REG_PUSH
-#undef ASM_OUTPUT_REG_POP
-
/* Select a format to encode pointers in exception handling data. CODE
is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
true if the symbol may be affected by dynamic relocations. */
#undef ASM_PREFERRED_EH_DATA_FORMAT
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
- (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_udata8)
+ ((TARGET_64BIT || flag_pic || TARGET_RELOCATABLE) \
+ ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel \
+ | (TARGET_64BIT ? DW_EH_PE_udata8 : DW_EH_PE_sdata4)) \
+ : DW_EH_PE_absptr)
+
+/* For backward compatibility, we must continue to use the AIX
+ structure return convention. */
+#undef DRAFT_V4_STRUCT_RET
+#define DRAFT_V4_STRUCT_RET (!TARGET_64BIT)
+
+/* Do code reading to identify a signal frame, and set the frame
+ state data appropriately. See unwind-dw2.c for the structs. */
+
+#ifdef IN_LIBGCC2
+#include <signal.h>
+#include <sys/ucontext.h>
+
+#ifdef __powerpc64__
+enum { SIGNAL_FRAMESIZE = 128 };
+#else
+enum { SIGNAL_FRAMESIZE = 64 };
+#endif
+#endif
+
+#ifdef __powerpc64__
+
+#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
+ do { \
+ unsigned char *pc_ = (CONTEXT)->ra; \
+ struct sigcontext *sc_; \
+ long new_cfa_; \
+ int i_; \
+ \
+ /* addi r1, r1, 128; li r0, 0x0077; sc (sigreturn) */ \
+ /* addi r1, r1, 128; li r0, 0x00AC; sc (rt_sigreturn) */ \
+ if (*(unsigned int *) (pc_+0) != 0x38210000 + SIGNAL_FRAMESIZE \
+ || *(unsigned int *) (pc_+8) != 0x44000002) \
+ break; \
+ if (*(unsigned int *) (pc_+4) == 0x38000077) \
+ { \
+ struct sigframe { \
+ char gap[SIGNAL_FRAMESIZE]; \
+ struct sigcontext sigctx; \
+ } *rt_ = (CONTEXT)->cfa; \
+ sc_ = &rt_->sigctx; \
+ } \
+ else if (*(unsigned int *) (pc_+4) == 0x380000AC) \
+ { \
+ struct rt_sigframe { \
+ int tramp[6]; \
+ struct siginfo *pinfo; \
+ struct ucontext *puc; \
+ } *rt_ = (struct rt_sigframe *) pc_; \
+ sc_ = &rt_->puc->uc_mcontext; \
+ } \
+ else \
+ break; \
+ \
+ new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM]; \
+ (FS)->cfa_how = CFA_REG_OFFSET; \
+ (FS)->cfa_reg = STACK_POINTER_REGNUM; \
+ (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
+ \
+ for (i_ = 0; i_ < 32; i_++) \
+ if (i_ != STACK_POINTER_REGNUM) \
+ { \
+ (FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[i_].loc.offset \
+ = (long)&(sc_->regs->gpr[i_]) - new_cfa_; \
+ } \
+ \
+ (FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset \
+ = (long)&(sc_->regs->link) - new_cfa_; \
+ \
+ /* The unwinder expects the IP to point to the following insn, \
+ whereas the kernel returns the address of the actual \
+ faulting insn. We store NIP+4 in an unused register slot to \
+ get the same result for multiple evaluation of the same signal \
+ frame. */ \
+ sc_->regs->gpr[47] = sc_->regs->nip + 4; \
+ (FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[CR0_REGNO].loc.offset \
+ = (long)&(sc_->regs->gpr[47]) - new_cfa_; \
+ (FS)->retaddr_column = CR0_REGNO; \
+ goto SUCCESS; \
+ } while (0)
+
+#else
+
+#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
+ do { \
+ unsigned char *pc_ = (CONTEXT)->ra; \
+ struct sigcontext *sc_; \
+ long new_cfa_; \
+ int i_; \
+ \
+ /* li r0, 0x7777; sc (sigreturn old) */ \
+ /* li r0, 0x0077; sc (sigreturn new) */ \
+ /* li r0, 0x6666; sc (rt_sigreturn old) */ \
+ /* li r0, 0x00AC; sc (rt_sigreturn new) */ \
+ if (*(unsigned int *) (pc_+4) != 0x44000002) \
+ break; \
+ if (*(unsigned int *) (pc_+0) == 0x38007777 \
+ || *(unsigned int *) (pc_+0) == 0x38000077) \
+ { \
+ struct sigframe { \
+ char gap[SIGNAL_FRAMESIZE]; \
+ struct sigcontext sigctx; \
+ } *rt_ = (CONTEXT)->cfa; \
+ sc_ = &rt_->sigctx; \
+ } \
+ else if (*(unsigned int *) (pc_+0) == 0x38006666 \
+ || *(unsigned int *) (pc_+0) == 0x380000AC) \
+ { \
+ struct rt_sigframe { \
+ char gap[SIGNAL_FRAMESIZE]; \
+ unsigned long _unused[2]; \
+ struct siginfo *pinfo; \
+ void *puc; \
+ struct siginfo info; \
+ struct ucontext uc; \
+ } *rt_ = (CONTEXT)->cfa; \
+ sc_ = &rt_->uc.uc_mcontext; \
+ } \
+ else \
+ break; \
+ \
+ new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM]; \
+ (FS)->cfa_how = CFA_REG_OFFSET; \
+ (FS)->cfa_reg = STACK_POINTER_REGNUM; \
+ (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
+ \
+ for (i_ = 0; i_ < 32; i_++) \
+ if (i_ != STACK_POINTER_REGNUM) \
+ { \
+ (FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[i_].loc.offset \
+ = (long)&(sc_->regs->gpr[i_]) - new_cfa_; \
+ } \
+ \
+ (FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset \
+ = (long)&(sc_->regs->link) - new_cfa_; \
+ \
+ /* The unwinder expects the IP to point to the following insn, \
+ whereas the kernel returns the address of the actual \
+ faulting insn. We store NIP+4 in an unused register slot to \
+ get the same result for multiple evaluation of the same signal \
+ frame. */ \
+ sc_->regs->gpr[47] = sc_->regs->nip + 4; \
+ (FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[CR0_REGNO].loc.offset \
+ = (long)&(sc_->regs->gpr[47]) - new_cfa_; \
+ (FS)->retaddr_column = CR0_REGNO; \
+ goto SUCCESS; \
+ } while (0)
+
+#endif
OpenPOWER on IntegriCloud