1 /* Definitions for 64-bit PowerPC running FreeBSD using the ELF format
2    Copyright (C) 2012-2021 Free Software Foundation, Inc.
3 
4    This file is part of GCC.
5 
6    GCC is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published
8    by the Free Software Foundation; either version 3, or (at your
9    option) any later version.
10 
11    GCC is distributed in the hope that it will be useful, but WITHOUT
12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14    License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with GCC; see the file COPYING3.  If not see
18    <http://www.gnu.org/licenses/>.  */
19 
20 /* Undef gnu-user.h macros we don't want.  */
21 #undef CPLUSPLUS_CPP_SPEC
22 #undef LINK_GCC_C_SEQUENCE_SPEC
23 
24 /* Override the defaults, which exist to force the proper definition.  */
25 
26 #ifdef IN_LIBGCC2
27 #undef TARGET_64BIT
28 #ifdef __powerpc64__
29 #define TARGET_64BIT 1
30 #else
31 #define TARGET_64BIT 0
32 #endif
33 #endif
34 
35 #undef	TARGET_AIX
36 #define	TARGET_AIX TARGET_64BIT
37 
38 #ifdef HAVE_LD_NO_DOT_SYMS
39 /* New ABI uses a local sym for the function entry point.  */
40 extern int dot_symbols;
41 #undef DOT_SYMBOLS
42 #define DOT_SYMBOLS dot_symbols
43 #endif
44 
45 #define TARGET_USES_LINUX64_OPT 1
46 #ifdef HAVE_LD_LARGE_TOC
47 #undef TARGET_CMODEL
48 #define TARGET_CMODEL rs6000_current_cmodel
49 #define SET_CMODEL(opt) rs6000_current_cmodel = opt
50 #else
51 #define SET_CMODEL(opt) do {} while (0)
52 #endif
53 
54 #undef  PROCESSOR_DEFAULT
55 #define PROCESSOR_DEFAULT PROCESSOR_PPC7450
56 #undef  PROCESSOR_DEFAULT64
57 #define PROCESSOR_DEFAULT64 PROCESSOR_POWER8
58 
59 /* We don't need to generate entries in .fixup, except when
60    -mrelocatable or -mrelocatable-lib is given.  */
61 #undef RELOCATABLE_NEEDS_FIXUP
62 #define RELOCATABLE_NEEDS_FIXUP \
63   (rs6000_isa_flags & rs6000_isa_flags_explicit & OPTION_MASK_RELOCATABLE)
64 
65 #undef  RS6000_ABI_NAME
66 #define RS6000_ABI_NAME "freebsd"
67 
68 #define INVALID_64BIT "-m%s not supported in this configuration"
69 #define INVALID_32BIT INVALID_64BIT
70 
71 /* Use LINUX64 instead of FREEBSD64 for compat with e.g. sysv4le.h */
72 #ifdef LINUX64_DEFAULT_ABI_ELFv2
73 #define ELFv2_ABI_CHECK (rs6000_elf_abi != 1)
74 #else
75 #define ELFv2_ABI_CHECK (rs6000_elf_abi == 2)
76 #endif
77 
78 #undef  SUBSUBTARGET_OVERRIDE_OPTIONS
79 #define SUBSUBTARGET_OVERRIDE_OPTIONS				\
80   do rs6000_linux64_override_options (); while (0)
81 
82 #undef	ASM_SPEC
83 #undef	LINK_OS_FREEBSD_SPEC
84 
85 #define	ASM_SPEC	 "%{m32:%(asm_spec32)}%{!m32:%(asm_spec64)} %(asm_spec_common)"
86 #define	LINK_OS_FREEBSD_SPEC "%{m32:%(link_os_freebsd_spec32)}%{!m32:%(link_os_freebsd_spec64)}"
87 
88 #define ASM_SPEC32 "-a32 \
89 %{mrelocatable} %{mrelocatable-lib} %{" FPIE_OR_FPIC_SPEC ":-K PIC} \
90 %{memb} %{!memb: %{msdata=eabi: -memb}} \
91 %{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
92     %{mcall-freebsd: -mbig} \
93     %{mcall-i960-old: -mlittle} \
94     %{mcall-linux: -mbig} \
95     %{mcall-gnu: -mbig} \
96     %{mcall-netbsd: -mbig} \
97 }}}}"
98 
99 #define ASM_SPEC64 "-a64"
100 
101 #define ASM_SPEC_COMMON "%(asm_cpu) \
102 %{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}}" \
103   ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN)
104 
105 #undef	SUBSUBTARGET_EXTRA_SPECS
106 #define SUBSUBTARGET_EXTRA_SPECS					\
107   { "asm_spec_common",		ASM_SPEC_COMMON },			\
108   { "asm_spec32",		ASM_SPEC32 },				\
109   { "asm_spec64",		ASM_SPEC64 },				\
110   { "link_os_freebsd_spec32",	LINK_OS_FREEBSD_SPEC32 },     		\
111   { "link_os_freebsd_spec64",	LINK_OS_FREEBSD_SPEC64 },
112 
113 #define LINK_OS_FREEBSD_SPEC_DEF "\
114   %{p:%nconsider using `-pg' instead of `-p' with gprof(1)} \
115   %{v:-V} \
116   %{assert*} %{R*} %{rpath*} %{defsym*} \
117   %{shared:-Bshareable %{h*} %{soname*}} \
118   %{!shared: \
119     %{!static: \
120       %{rdynamic: -export-dynamic} \
121       %{!dynamic-linker:-dynamic-linker " FBSD_DYNAMIC_LINKER "}} \
122     %{static:-Bstatic}} \
123   %{symbolic:-Bsymbolic}"
124 
125 #undef  DEFAULT_ASM_ENDIAN
126 #define LINK_OS_FREEBSD_SPEC32 "-melf32ppc_fbsd " LINK_OS_FREEBSD_SPEC_DEF
127 #if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN)
128 #define DEFAULT_ASM_ENDIAN " -mlittle"
129 #define LINK_OS_FREEBSD_SPEC64 "-melf64lppc_fbsd " LINK_OS_FREEBSD_SPEC_DEF
130 #else
131 #define DEFAULT_ASM_ENDIAN " -mbig"
132 #define LINK_OS_FREEBSD_SPEC64 "-melf64ppc_fbsd " LINK_OS_FREEBSD_SPEC_DEF
133 #endif
134 
135 #undef	MULTILIB_DEFAULTS
136 #define MULTILIB_DEFAULTS { "m64" }
137 
138 /* PowerPC-64 FreeBSD increases natural record alignment to doubleword if
139    the first field is an FP double, only if in power alignment mode.  */
140 #undef  ROUND_TYPE_ALIGN
141 #define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED)			\
142   ((TARGET_64BIT							\
143     && (TREE_CODE (STRUCT) == RECORD_TYPE				\
144 	|| TREE_CODE (STRUCT) == UNION_TYPE				\
145 	|| TREE_CODE (STRUCT) == QUAL_UNION_TYPE)			\
146     && TARGET_ALIGN_NATURAL == 0)					\
147    ? rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED)	\
148    : MAX ((COMPUTED), (SPECIFIED)))
149 
150 /* Use the default for compiling target libs.  */
151 #ifdef IN_TARGET_LIBS
152 #undef TARGET_ALIGN_NATURAL
153 #define TARGET_ALIGN_NATURAL 1
154 #endif
155 
156 /* Indicate that jump tables go in the text section.  */
157 #undef  JUMP_TABLES_IN_TEXT_SECTION
158 #define JUMP_TABLES_IN_TEXT_SECTION TARGET_64BIT
159 
160 /* The linux ppc64 ABI isn't explicit on whether aggregates smaller
161    than a doubleword should be padded upward or downward.  You could
162    reasonably assume that they follow the normal rules for structure
163    layout treating the parameter area as any other block of memory,
164    then map the reg param area to registers.  i.e. pad upward.
165    Setting both of the following defines results in this behavior.
166    Setting just the first one will result in aggregates that fit in a
167    doubleword being padded downward, and others being padded upward.
168    Not a bad idea as this results in struct { int x; } being passed
169    the same way as an int.  */
170 #define AGGREGATE_PADDING_FIXED TARGET_64BIT
171 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
172 
173 /* Specify padding for the last element of a block move between
174    registers and memory.  FIRST is nonzero if this is the only
175    element.  */
176 #define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
177   (!(FIRST) ? PAD_UPWARD : targetm.calls.function_arg_padding (MODE, TYPE))
178 
179 /* FreeBSD doesn't support saving and restoring 64-bit regs with a 32-bit
180    kernel. This is supported when running on a 64-bit kernel with
181    COMPAT_FREEBSD32, but tell GCC it isn't so that our 32-bit binaries
182    are compatible. */
183 #define OS_MISSING_POWERPC64 !TARGET_64BIT
184 
185 #undef  FBSD_TARGET_CPU_CPP_BUILTINS
186 #define FBSD_TARGET_CPU_CPP_BUILTINS()			\
187   do							\
188     {							\
189       builtin_define ("__PPC__");			\
190       builtin_define ("__ppc__");			\
191       builtin_define ("__powerpc__");			\
192       if (TARGET_64BIT)					\
193 	{						\
194 	  builtin_define ("__arch64__");		\
195 	  builtin_define ("__LP64__");			\
196 	  builtin_define ("__PPC64__");			\
197 	  builtin_define ("__powerpc64__");		\
198 	  builtin_assert ("cpu=powerpc64");		\
199 	  builtin_assert ("machine=powerpc64");		\
200 	}						\
201       else						\
202 	{						\
203 	  builtin_define_std ("PPC");			\
204 	  builtin_define_std ("powerpc");		\
205 	  builtin_assert ("cpu=powerpc");		\
206 	  builtin_assert ("machine=powerpc");		\
207 	  TARGET_OS_SYSV_CPP_BUILTINS ();		\
208 	}						\
209     }							\
210   while (0)
211 
212 #undef	CPP_OS_DEFAULT_SPEC
213 #define CPP_OS_DEFAULT_SPEC "%(cpp_os_freebsd)"
214 
215 #undef CPP_OS_FREEBSD_SPEC
216 #define CPP_OS_FREEBSD_SPEC ""
217 
218 #undef	STARTFILE_DEFAULT_SPEC
219 #define STARTFILE_DEFAULT_SPEC "%(startfile_freebsd)"
220 
221 #undef	ENDFILE_DEFAULT_SPEC
222 #define ENDFILE_DEFAULT_SPEC "%(endfile_freebsd)"
223 
224 #undef	LIB_DEFAULT_SPEC
225 #define LIB_DEFAULT_SPEC "%(lib_freebsd)"
226 
227 #undef	LINK_START_DEFAULT_SPEC
228 #define LINK_START_DEFAULT_SPEC "%(link_start_freebsd)"
229 
230 #undef	LINK_OS_DEFAULT_SPEC
231 #define	LINK_OS_DEFAULT_SPEC "%(link_os_freebsd)"
232 
233 /* XXX: This is wrong for many platforms in sysv4.h.
234    We should work on getting that definition fixed.  */
235 #undef  LINK_SHLIB_SPEC
236 #define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}}"
237 
238 
239 /************************[  Target stuff  ]***********************************/
240 
241 /* Define the actual types of some ANSI-mandated types.
242    Needs to agree with <machine/ansi.h>.  GCC defaults come from c-decl.c,
243    c-common.c, and config/<arch>/<arch>.h.  */
244 
245 
246 #undef  SIZE_TYPE
247 #define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int")
248 
249 #undef  PTRDIFF_TYPE
250 #define PTRDIFF_TYPE	(TARGET_64BIT ? "long int" : "int")
251 
252 /* rs6000.h gets this wrong for FreeBSD.  We use the GCC defaults instead.  */
253 #undef WCHAR_TYPE
254 
255 #undef  WCHAR_TYPE_SIZE
256 #define WCHAR_TYPE_SIZE 32
257 
258 /* Function profiling bits */
259 #undef  RS6000_MCOUNT
260 #define RS6000_MCOUNT "_mcount"
261 
262 #define PROFILE_HOOK(LABEL) \
263   do { if (TARGET_64BIT) output_profile_hook (LABEL); } while (0)
264 
265 /* _init and _fini functions are built from bits spread across many
266    object files, each potentially with a different TOC pointer.  For
267    that reason, place a nop after the call so that the linker can
268    restore the TOC pointer if a TOC adjusting call stub is needed.  */
269 #ifdef __powerpc64__
270 #define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC)	\
271   asm (SECTION_OP "\n"					\
272 "	bl " #FUNC "\n"					\
273 "	nop\n"						\
274 "	.previous");
275 #endif
276 
277 /* FP save and restore routines.  */
278 #undef  SAVE_FP_PREFIX
279 #define SAVE_FP_PREFIX (TARGET_64BIT ? "._savef" : "_savefpr_")
280 #undef  SAVE_FP_SUFFIX
281 #define SAVE_FP_SUFFIX ""
282 #undef  RESTORE_FP_PREFIX
283 #define RESTORE_FP_PREFIX (TARGET_64BIT ? "._restf" : "_restfpr_")
284 #undef  RESTORE_FP_SUFFIX
285 #define RESTORE_FP_SUFFIX ""
286 
287 /* Select a format to encode pointers in exception handling data.  CODE
288    is 0 for data, 1 for code labels, 2 for function pointers.  GLOBAL is
289    true if the symbol may be affected by dynamic relocations.  */
290 #undef	ASM_PREFERRED_EH_DATA_FORMAT
291 #define	ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
292   (TARGET_64BIT || flag_pic						\
293    ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel		\
294       | (TARGET_64BIT ? DW_EH_PE_udata8 : DW_EH_PE_sdata4))		\
295    : DW_EH_PE_absptr)
296 
297 /* Static stack checking is supported by means of probes.  */
298 #define STACK_CHECK_STATIC_BUILTIN 1
299 
300 /* The default value isn't sufficient in 64-bit mode.  */
301 #define STACK_CHECK_PROTECT (TARGET_64BIT ? 16 * 1024 : 12 * 1024)
302 
303 /* Use standard DWARF numbering for DWARF debugging information.  */
304 #define RS6000_USE_DWARF_NUMBERING
305 
306 /* PowerPC64 Linux word-aligns FP doubles when -malign-power is given.  */
307 #undef  ADJUST_FIELD_ALIGN
308 #define ADJUST_FIELD_ALIGN(FIELD, TYPE, COMPUTED) \
309   (rs6000_special_adjust_field_align_p ((TYPE), (COMPUTED))		\
310    ? 128                                                                \
311    : (TARGET_64BIT                                                      \
312       && TARGET_ALIGN_NATURAL == 0                                      \
313       && TYPE_MODE (strip_array_types (TYPE)) == DFmode)   		\
314    ? MIN ((COMPUTED), 32)                                               \
315    : (COMPUTED))
316 
317 #undef  TOC_SECTION_ASM_OP
318 #define TOC_SECTION_ASM_OP \
319   (TARGET_64BIT                                         \
320    ? "\t.section\t\".toc\",\"aw\""                      \
321    : "\t.section\t\".got\",\"aw\"")
322 
323 #undef  MINIMAL_TOC_SECTION_ASM_OP
324 #define MINIMAL_TOC_SECTION_ASM_OP \
325   (TARGET_64BIT                                         \
326    ? "\t.section\t\".toc1\",\"aw\""                     \
327    : (flag_pic						\
328       ? "\t.section\t\".got2\",\"aw\""                  \
329       : "\t.section\t\".got1\",\"aw\""))
330 
331 /* This is how to declare the size of a function.  */
332 #undef  ASM_DECLARE_FUNCTION_SIZE
333 #define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)                    \
334   do                                                                    \
335     {                                                                   \
336       if (!flag_inhibit_size_directive)                                 \
337         {                                                               \
338           fputs ("\t.size\t", (FILE));                                  \
339           if (TARGET_64BIT && DOT_SYMBOLS)                              \
340             putc ('.', (FILE));                                         \
341           assemble_name ((FILE), (FNAME));                              \
342           fputs (",.-", (FILE));                                        \
343           rs6000_output_function_entry (FILE, FNAME);                   \
344           putc ('\n', (FILE));                                          \
345         }                                                               \
346     }                                                                   \
347   while (0)
348 
349 #undef  ASM_OUTPUT_SPECIAL_POOL_ENTRY_P
350 #define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X, MODE)                        \
351   (TARGET_TOC                                                           \
352    && (SYMBOL_REF_P (X)							\
353        || (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS      \
354            && SYMBOL_REF_P (XEXP (XEXP (X, 0), 0)))			\
355        || GET_CODE (X) == LABEL_REF                                     \
356        || (CONST_INT_P (X)						\
357            && GET_MODE_BITSIZE (MODE) <= GET_MODE_BITSIZE (Pmode))      \
358        || (CONST_DOUBLE_P (X)						\
359            && ((TARGET_64BIT                                            \
360                 && (TARGET_MINIMAL_TOC                                  \
361                     || (SCALAR_FLOAT_MODE_P (GET_MODE (X))              \
362                         && ! TARGET_NO_FP_IN_TOC)))                     \
363                || (!TARGET_64BIT                                        \
364                    && !TARGET_NO_FP_IN_TOC                              \
365                    && SCALAR_FLOAT_MODE_P (GET_MODE (X))                \
366                    && BITS_PER_WORD == HOST_BITS_PER_INT)))))
367 
368 /* Use --as-needed -lgcc_s for eh support.  */
369 #ifdef HAVE_LD_AS_NEEDED
370 #define USE_LD_AS_NEEDED 1
371 #endif
372 
373 #define POWERPC_FREEBSD
374