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