190075Sobrien/* Definitions for PowerPC running FreeBSD using the ELF format
2132718Skan   Copyright (C) 2001, 2003 Free Software Foundation, Inc.
390075Sobrien   Contributed by David E. O'Brien <obrien@FreeBSD.org> and BSDi.
490075Sobrien
5132718Skan   This file is part of GCC.
690075Sobrien
7132718Skan   GCC is free software; you can redistribute it and/or modify it
8132718Skan   under the terms of the GNU General Public License as published
9132718Skan   by the Free Software Foundation; either version 2, or (at your
10132718Skan   option) any later version.
1190075Sobrien
12132718Skan   GCC is distributed in the hope that it will be useful, but WITHOUT
13132718Skan   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14132718Skan   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15132718Skan   License for more details.
1690075Sobrien
17132718Skan   You should have received a copy of the GNU General Public License
18132718Skan   along with GCC; see the file COPYING.  If not, write to the
19169706Skan   Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
20169706Skan   MA 02110-1301, USA.  */
2190075Sobrien
2290075Sobrien/* Override the defaults, which exist to force the proper definition.  */
2390075Sobrien
24209867Snwhitehorn#ifdef IN_LIBGCC2
25209867Snwhitehorn#undef TARGET_64BIT
26209867Snwhitehorn#ifdef __powerpc64__
27209867Snwhitehorn#define TARGET_64BIT 1
28209867Snwhitehorn#else
29209867Snwhitehorn#define TARGET_64BIT 0
30209867Snwhitehorn#endif
31209867Snwhitehorn#endif
3290075Sobrien
33209867Snwhitehorn/* On 64-bit systems, use the AIX ABI like Linux and NetBSD */
34147823Sscottl
35209867Snwhitehorn#undef	DEFAULT_ABI
36209867Snwhitehorn#define	DEFAULT_ABI (TARGET_64BIT ? ABI_AIX : ABI_V4)
37209867Snwhitehorn#undef	TARGET_AIX
38209867Snwhitehorn#define	TARGET_AIX TARGET_64BIT
39209867Snwhitehorn
40218824Snwhitehorn#ifdef HAVE_LD_NO_DOT_SYMS
41218824Snwhitehorn/* New ABI uses a local sym for the function entry point.  */
42218824Snwhitehornextern int dot_symbols;
43218824Snwhitehorn#undef DOT_SYMBOLS
44218824Snwhitehorn#define DOT_SYMBOLS dot_symbols
45218824Snwhitehorn#endif
46218824Snwhitehorn
47209867Snwhitehorn#undef  FBSD_TARGET_CPU_CPP_BUILTINS
48209867Snwhitehorn#define FBSD_TARGET_CPU_CPP_BUILTINS()		\
49209867Snwhitehorn  do						\
50209867Snwhitehorn    {						\
51209867Snwhitehorn      builtin_define ("__PPC__");		\
52209867Snwhitehorn      builtin_define ("__ppc__");		\
53209867Snwhitehorn      builtin_define ("__PowerPC__");		\
54209867Snwhitehorn      builtin_define ("__powerpc__");		\
55209867Snwhitehorn      if (TARGET_64BIT)				\
56209867Snwhitehorn	{					\
57209867Snwhitehorn	  builtin_define ("__LP64__");		\
58209867Snwhitehorn	  builtin_define ("__ppc64__");		\
59209867Snwhitehorn	  builtin_define ("__powerpc64__");	\
60209867Snwhitehorn	  builtin_define ("__arch64__");	\
61209867Snwhitehorn	  builtin_assert ("cpu=powerpc64");	\
62209867Snwhitehorn	  builtin_assert ("machine=powerpc64");	\
63209867Snwhitehorn	} else {				\
64209867Snwhitehorn	  builtin_assert ("cpu=powerpc");	\
65209867Snwhitehorn	  builtin_assert ("machine=powerpc");	\
66209867Snwhitehorn	}					\
67209867Snwhitehorn    }						\
68209867Snwhitehorn  while (0)
69209867Snwhitehorn
70209867Snwhitehorn#define INVALID_64BIT "-m%s not supported in this configuration"
71209867Snwhitehorn#define INVALID_32BIT INVALID_64BIT
72209867Snwhitehorn
73209867Snwhitehorn#undef	SUBSUBTARGET_OVERRIDE_OPTIONS
74209867Snwhitehorn#define	SUBSUBTARGET_OVERRIDE_OPTIONS				\
75209867Snwhitehorn  do								\
76209867Snwhitehorn    {								\
77209867Snwhitehorn      if (!rs6000_explicit_options.alignment)			\
78209867Snwhitehorn	rs6000_alignment_flags = MASK_ALIGN_NATURAL;		\
79209867Snwhitehorn      if (TARGET_64BIT)						\
80209867Snwhitehorn	{							\
81209867Snwhitehorn	  if (DEFAULT_ABI != ABI_AIX)				\
82209867Snwhitehorn	    {							\
83209867Snwhitehorn	      rs6000_current_abi = ABI_AIX;			\
84209867Snwhitehorn	      error (INVALID_64BIT, "call");			\
85209867Snwhitehorn	    }							\
86209867Snwhitehorn	  dot_symbols = !strcmp (rs6000_abi_name, "aixdesc");	\
87209867Snwhitehorn	  if (target_flags & MASK_RELOCATABLE)			\
88209867Snwhitehorn	    {							\
89209867Snwhitehorn	      target_flags &= ~MASK_RELOCATABLE;		\
90209867Snwhitehorn	      error (INVALID_64BIT, "relocatable");		\
91209867Snwhitehorn	    }							\
92209867Snwhitehorn	  if (target_flags & MASK_EABI)				\
93209867Snwhitehorn	    {							\
94209867Snwhitehorn	      target_flags &= ~MASK_EABI;			\
95209867Snwhitehorn	      error (INVALID_64BIT, "eabi");			\
96209867Snwhitehorn	    }							\
97209867Snwhitehorn	  if (target_flags & MASK_PROTOTYPE)			\
98209867Snwhitehorn	    {							\
99209867Snwhitehorn	      target_flags &= ~MASK_PROTOTYPE;			\
100209867Snwhitehorn	      error (INVALID_64BIT, "prototype");		\
101209867Snwhitehorn	    }							\
102209867Snwhitehorn	  if ((target_flags & MASK_POWERPC64) == 0)		\
103209867Snwhitehorn	    {							\
104209867Snwhitehorn	      target_flags |= MASK_POWERPC64;			\
105209867Snwhitehorn	      error ("64 bit CPU required");			\
106209867Snwhitehorn	    }							\
107209867Snwhitehorn	}							\
108209867Snwhitehorn    }								\
109209867Snwhitehorn  while (0)
110209867Snwhitehorn
111209867Snwhitehorn
11290075Sobrien#undef	STARTFILE_DEFAULT_SPEC
11390075Sobrien#define STARTFILE_DEFAULT_SPEC "%(startfile_freebsd)"
11490075Sobrien
11590075Sobrien#undef	ENDFILE_DEFAULT_SPEC
11690075Sobrien#define ENDFILE_DEFAULT_SPEC "%(endfile_freebsd)"
11790075Sobrien
11890075Sobrien#undef	LIB_DEFAULT_SPEC
11990075Sobrien#define LIB_DEFAULT_SPEC "%(lib_freebsd)"
12090075Sobrien
12190075Sobrien#undef	LINK_START_DEFAULT_SPEC
12290075Sobrien#define LINK_START_DEFAULT_SPEC "%(link_start_freebsd)"
12390075Sobrien
12490075Sobrien#undef	LINK_OS_DEFAULT_SPEC
12590075Sobrien#define	LINK_OS_DEFAULT_SPEC "%(link_os_freebsd)"
12690075Sobrien
127117395Skan/* XXX: This is wrong for many platforms in sysv4.h.
128132718Skan   We should work on getting that definition fixed.  */
129117395Skan#undef  LINK_SHLIB_SPEC
130117395Skan#define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}}"
13190075Sobrien
132117395Skan
13390075Sobrien/************************[  Target stuff  ]***********************************/
13490075Sobrien
13590075Sobrien/* Define the actual types of some ANSI-mandated types.
13690075Sobrien   Needs to agree with <machine/ansi.h>.  GCC defaults come from c-decl.c,
13790075Sobrien   c-common.c, and config/<arch>/<arch>.h.  */
13890075Sobrien
139117395Skan#undef  SIZE_TYPE
140209867Snwhitehorn#define SIZE_TYPE	(TARGET_64BIT ? "long unsigned int" : "unsigned int")
141117395Skan
142209867Snwhitehorn#undef  PTRDIFF_TYPE
143209867Snwhitehorn#define PTRDIFF_TYPE	(TARGET_64BIT ? "long int" : "int")
144209867Snwhitehorn
14590075Sobrien/* rs6000.h gets this wrong for FreeBSD.  We use the GCC defaults instead.  */
14690075Sobrien#undef WCHAR_TYPE
14790075Sobrien
14890075Sobrien#undef  WCHAR_TYPE_SIZE
14990075Sobrien#define WCHAR_TYPE_SIZE 32
15090075Sobrien
15190075Sobrien#undef  TARGET_VERSION
15290075Sobrien#define TARGET_VERSION fprintf (stderr, " (FreeBSD/PowerPC ELF)");
15390075Sobrien
15490075Sobrien/* Override rs6000.h definition.  */
15590075Sobrien#undef  ASM_APP_ON
15690075Sobrien#define ASM_APP_ON "#APP\n"
15790075Sobrien
15890075Sobrien/* Override rs6000.h definition.  */
15990075Sobrien#undef  ASM_APP_OFF
16090075Sobrien#define ASM_APP_OFF "#NO_APP\n"
161209867Snwhitehorn
162209867Snwhitehorn/* Tell the assembler we want 32/64-bit binaries if -m32 or -m64 is passed */
163209867Snwhitehorn#if (TARGET_DEFAULT & MASK_64BIT)
164209867Snwhitehorn#define	SVR4_ASM_SPEC "%(asm_cpu) \
165209867Snwhitehorn%{.s: %{mregnames} %{mno-regnames}} %{.S: %{mregnames} %{mno-regnames}} \
166209867Snwhitehorn%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \
167209867Snwhitehorn%{mrelocatable} %{mrelocatable-lib} %{fpic|fpie|fPIC|fPIE:-K PIC} \
168209867Snwhitehorn%{memb|msdata|msdata=eabi: -memb} \
169209867Snwhitehorn%{mlittle|mlittle-endian:-mlittle; \
170209867Snwhitehorn  mbig|mbig-endian      :-mbig;    \
171209867Snwhitehorn  mcall-aixdesc |		   \
172209867Snwhitehorn  mcall-freebsd |		   \
173209867Snwhitehorn  mcall-netbsd  |		   \
174209867Snwhitehorn  mcall-openbsd |		   \
175209867Snwhitehorn  mcall-linux   |		   \
176209867Snwhitehorn  mcall-gnu             :-mbig;    \
177209867Snwhitehorn  mcall-i960-old        :-mlittle}"
178209867Snwhitehorn#define LINK_OS_FREEBSD_SPEC_DEF "\
179209867Snwhitehorn  %{p:%nconsider using `-pg' instead of `-p' with gprof(1)} \
180209867Snwhitehorn  %{v:-V} \
181209867Snwhitehorn  %{assert*} %{R*} %{rpath*} %{defsym*} \
182209867Snwhitehorn  %{shared:-Bshareable %{h*} %{soname*}} \
183238472Skib  %{!static:--enable-new-dtags}	\
184209867Snwhitehorn  %{!shared: \
185209867Snwhitehorn    %{!static: \
186209867Snwhitehorn      %{rdynamic: -export-dynamic} \
187209867Snwhitehorn      %{!dynamic-linker:-dynamic-linker %(fbsd_dynamic_linker) }} \
188209867Snwhitehorn    %{static:-Bstatic}} \
189209867Snwhitehorn  %{symbolic:-Bsymbolic}"
190209867Snwhitehorn
191209867Snwhitehorn
192209867Snwhitehorn#undef	ASM_DEFAULT_SPEC
193209867Snwhitehorn#undef	ASM_SPEC
194209867Snwhitehorn#undef	LINK_OS_FREEBSD_SPEC
195209867Snwhitehorn#define	ASM_DEFAULT_SPEC	"-mppc%{!m32:64}"
196209867Snwhitehorn#define	ASM_SPEC		"%{m32:-a32}%{!m32:-a64} " SVR4_ASM_SPEC
197227739Sandreast#define	LINK_OS_FREEBSD_SPEC	"%{m32:-melf32ppc_fbsd}%{!m32:-melf64ppc_fbsd} " LINK_OS_FREEBSD_SPEC_DEF
198209867Snwhitehorn#endif
199209867Snwhitehorn
200209867Snwhitehorn/* _init and _fini functions are built from bits spread across many
201209867Snwhitehorn   object files, each potentially with a different TOC pointer.  For
202209867Snwhitehorn   that reason, place a nop after the call so that the linker can
203209867Snwhitehorn   restore the TOC pointer if a TOC adjusting call stub is needed.  */
204209867Snwhitehorn#ifdef __powerpc64__
205209867Snwhitehorn#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC)	\
206209867Snwhitehorn  asm (SECTION_OP "\n"					\
207218824Snwhitehorn"	bl " #FUNC "\n"					\
208209867Snwhitehorn"	nop\n"						\
209209867Snwhitehorn"	.previous");
210209867Snwhitehorn#endif
211209867Snwhitehorn
212209867Snwhitehorn/* __throw will restore its own return address to be the same as the
213209867Snwhitehorn   return address of the function that the throw is being made to.
214209867Snwhitehorn   This is unfortunate, because we want to check the original
215209867Snwhitehorn   return address to see if we need to restore the TOC.
216209867Snwhitehorn   So we have to squirrel it away with this.  */
217209867Snwhitehorn#define SETUP_FRAME_ADDRESSES() \
218209867Snwhitehorn  do { if (TARGET_64BIT) rs6000_aix_emit_builtin_unwind_init (); } while (0)
219209867Snwhitehorn
220209867Snwhitehorn/* Select a format to encode pointers in exception handling data.  CODE
221209867Snwhitehorn   is 0 for data, 1 for code labels, 2 for function pointers.  GLOBAL is
222209867Snwhitehorn   true if the symbol may be affected by dynamic relocations.  */
223209867Snwhitehorn#undef	ASM_PREFERRED_EH_DATA_FORMAT
224209867Snwhitehorn#define	ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
225209867Snwhitehorn  ((TARGET_64BIT || flag_pic || TARGET_RELOCATABLE)			\
226209867Snwhitehorn   ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel		\
227209867Snwhitehorn      | (TARGET_64BIT ? DW_EH_PE_udata8 : DW_EH_PE_sdata4))		\
228209867Snwhitehorn   : DW_EH_PE_absptr)
229209867Snwhitehorn
230213185Snwhitehorn#ifdef __powerpc64__
231209867Snwhitehorn#define MD_FROB_UPDATE_CONTEXT(CTX, FS)					\
232209867Snwhitehorn    if ((FS)->regs.reg[2].how == REG_UNSAVED)				\
233209867Snwhitehorn      {									\
234213185Snwhitehorn	unsigned int *insn = (unsigned int *)				\
235209867Snwhitehorn	    _Unwind_GetGR ((CTX), LINK_REGISTER_REGNUM);		\
236213185Snwhitehorn	if (insn != NULL && *insn == 0xE8410028)			\
237209867Snwhitehorn	  _Unwind_SetGRPtr ((CTX), 2, (CTX)->cfa + 40);			\
238213185Snwhitehorn      }
239213185Snwhitehorn#endif
240209867Snwhitehorn
241217396Skib#define TARGET_ASM_FILE_END rs6000_elf_end_indicate_exec_stack
242217396Skib
243209867Snwhitehorn/* FreeBSD doesn't support saving and restoring 64-bit regs with a 32-bit
244209867Snwhitehorn   kernel. This is supported when running on a 64-bit kernel with
245209867Snwhitehorn   COMPAT_FREEBSD32, but tell GCC it isn't so that our 32-bit binaries
246209867Snwhitehorn   are compatible. */
247209867Snwhitehorn#define OS_MISSING_POWERPC64 !TARGET_64BIT
248209867Snwhitehorn
249209867Snwhitehorn/* Function profiling bits */
250209867Snwhitehorn#undef  RS6000_MCOUNT
251209867Snwhitehorn#define RS6000_MCOUNT ((TARGET_64BIT) ? "._mcount" : "_mcount")
252209867Snwhitehorn#define PROFILE_HOOK(LABEL) \
253209867Snwhitehorn  do { if (TARGET_64BIT) output_profile_hook (LABEL); } while (0)
254209867Snwhitehorn
255217396Skib#undef NEED_INDICATE_EXEC_STACK
256217396Skib#define NEED_INDICATE_EXEC_STACK 1
257227586Sandreast
258227586Sandreast/* This is how to declare the size of a function.  */
259227586Sandreast#undef  ASM_DECLARE_FUNCTION_SIZE
260227586Sandreast#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)                    \
261227586Sandreast  do                                                                    \
262227586Sandreast    {                                                                   \
263227586Sandreast      if (!flag_inhibit_size_directive)                                 \
264227586Sandreast        {                                                               \
265227586Sandreast          fputs ("\t.size\t", (FILE));                                  \
266227586Sandreast          if (TARGET_64BIT && DOT_SYMBOLS)                              \
267227586Sandreast            putc ('.', (FILE));                                         \
268227586Sandreast          assemble_name ((FILE), (FNAME));                              \
269227586Sandreast          fputs (",.-", (FILE));                                        \
270227586Sandreast          rs6000_output_function_entry (FILE, FNAME);                   \
271227586Sandreast          putc ('\n', (FILE));                                          \
272227586Sandreast        }                                                               \
273227586Sandreast    }                                                                   \
274227586Sandreast  while (0)
275227586Sandreast
276