1 /* Definitions for rtems targeting a PowerPC using elf.
2    Copyright (C) 1996-2022 Free Software Foundation, Inc.
3    Contributed by Joel Sherrill (joel@OARcorp.com).
4 
5    This file is part of GCC.
6 
7    GCC is free software; you can redistribute it and/or modify it
8    under the terms of the GNU General Public License as published
9    by the Free Software Foundation; either version 3, or (at your
10    option) any later version.
11 
12    GCC is distributed in the hope that it will be useful, but WITHOUT
13    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15    License for more details.
16 
17    Under Section 7 of GPL version 3, you are granted additional
18    permissions described in the GCC Runtime Library Exception, version
19    3.1, as published by the Free Software Foundation.
20 
21    You should have received a copy of the GNU General Public License and
22    a copy of the GCC Runtime Library Exception along with this program;
23    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24    <http://www.gnu.org/licenses/>.  */
25 
26 /* Undef gnu-user.h macro we don't want.  */
27 #undef CPLUSPLUS_CPP_SPEC
28 
29 /* Copy and paste from linux64.h and freebsd64.h */
30 #ifdef IN_LIBGCC2
31 #undef TARGET_64BIT
32 #ifdef __powerpc64__
33 #define TARGET_64BIT 1
34 #else
35 #define TARGET_64BIT 0
36 #endif
37 #endif
38 
39 /* Copy and paste from linux64.h and freebsd64.h */
40 #undef    TARGET_AIX
41 #define   TARGET_AIX TARGET_64BIT
42 
43 /* Simplified copy and paste from linux64.h and freebsd64.h */
44 #undef DOT_SYMBOLS
45 #define DOT_SYMBOLS 0
46 
47 /* Copy and paste from linux64.h and freebsd64.h */
48 #undef TARGET_CMODEL
49 #define TARGET_CMODEL rs6000_current_cmodel
50 #define SET_CMODEL(opt) rs6000_current_cmodel = opt
51 
52 #undef TARGET_OS_CPP_BUILTINS
53 #define TARGET_OS_CPP_BUILTINS()                            \
54   do                                                                  \
55     {                                                                 \
56       builtin_define ("__rtems__");                         \
57       builtin_define ("__USE_INIT_FINI__");                 \
58       builtin_assert ("system=rtems");                      \
59       if (TARGET_64BIT)                                               \
60           {                                                           \
61             builtin_define ("__PPC__");                     \
62             builtin_define ("__PPC64__");                             \
63             builtin_define ("__powerpc64__");               \
64             builtin_assert ("cpu=powerpc64");               \
65             builtin_assert ("machine=powerpc64");           \
66           }                                                           \
67       else                                                            \
68           {                                                           \
69             builtin_define_std ("PPC");                     \
70             builtin_define_std ("powerpc");                 \
71             builtin_assert ("cpu=powerpc");                 \
72             builtin_assert ("machine=powerpc");             \
73             TARGET_OS_SYSV_CPP_BUILTINS ();                 \
74           }                                                           \
75     }                                                                 \
76   while (0)
77 
78 /* Copy and paste from linux64.h and freebsd64.h */
79 #undef RELOCATABLE_NEEDS_FIXUP
80 #define RELOCATABLE_NEEDS_FIXUP \
81   (rs6000_isa_flags & rs6000_isa_flags_explicit & OPTION_MASK_RELOCATABLE)
82 
83 /* Copy and paste from linux64.h */
84 #undef    RS6000_ABI_NAME
85 #define   RS6000_ABI_NAME "linux"
86 
87 /* Copy and paste from linux64.h and freebsd64.h */
88 #define INVALID_64BIT "%<-m%s%> not supported in this configuration"
89 
90 /* A lot of copy and paste from linux64.h and freebsd64.h */
91 #undef    SUBSUBTARGET_OVERRIDE_OPTIONS
92 #define   SUBSUBTARGET_OVERRIDE_OPTIONS                               \
93   do                                                                            \
94     {                                                                           \
95       if (rs6000_isa_flags & OPTION_MASK_64BIT)                       \
96           {                                                                     \
97             rs6000_elf_abi = 2;                                                 \
98             rs6000_current_abi = ABI_ELFv2;                           \
99             if (rs6000_isa_flags & OPTION_MASK_RELOCATABLE) \
100               {                                                                 \
101                 rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE;         \
102                 error (INVALID_64BIT, "relocatable");                 \
103               }                                                                 \
104             if (rs6000_isa_flags & OPTION_MASK_EABI)                  \
105               {                                                                 \
106                 rs6000_isa_flags &= ~OPTION_MASK_EABI;                \
107                 error (INVALID_64BIT, "eabi");                        \
108               }                                                                 \
109             if (TARGET_PROTOTYPE)                                               \
110               {                                                                 \
111                 target_prototype = 0;                                 \
112                 error (INVALID_64BIT, "prototype");                   \
113               }                                                                 \
114             if ((rs6000_isa_flags & OPTION_MASK_POWERPC64) == 0)      \
115               {                                                                 \
116                 rs6000_isa_flags |= OPTION_MASK_POWERPC64;  \
117                 error ("%<-m64%> requires a PowerPC64 cpu");                    \
118               }                                                                 \
119             if ((rs6000_isa_flags_explicit                            \
120                     & OPTION_MASK_MINIMAL_TOC) != 0)                  \
121               {                                                                 \
122                 if (OPTION_SET_P (rs6000_current_cmodel)    \
123                       && rs6000_current_cmodel != CMODEL_SMALL)       \
124                     error ("%<-mcmodel%> incompatible with other toc options"); \
125                 SET_CMODEL (CMODEL_SMALL);                            \
126               }                                                                 \
127             else                                                                \
128               {                                                                 \
129                 if (!OPTION_SET_P (rs6000_current_cmodel))  \
130                     SET_CMODEL (CMODEL_MEDIUM);                       \
131                 if (rs6000_current_cmodel != CMODEL_SMALL)  \
132                     {                                                           \
133                       TARGET_NO_FP_IN_TOC = 0;                        \
134                       TARGET_NO_SUM_IN_TOC = 0;                       \
135                     }                                                           \
136               }                                                                 \
137           }                                                                     \
138     }                                                                           \
139   while (0)
140 
141 #undef TARGET_LIBGCC_SDATA_SECTION
142 #define TARGET_LIBGCC_SDATA_SECTION ".sdata"
143 
144 /* Copy and paste from linux64.h and freebsd64.h */
145 #undef    SIZE_TYPE
146 #define   SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int")
147 
148 /* Copy and paste from linux64.h and freebsd64.h */
149 #undef    PTRDIFF_TYPE
150 #define   PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
151 
152 /* Copy and paste from freebsd64.h */
153 #undef WCHAR_TYPE
154 
155 /* Copy and paste from freebsd64.h */
156 #undef  WCHAR_TYPE_SIZE
157 #define WCHAR_TYPE_SIZE 32
158 
159 /* Copy and paste from linux64.h and freebsd64.h */
160 #ifdef __powerpc64__
161 #define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC)          \
162   asm (SECTION_OP "\n"                                                \
163 "         bl " #FUNC "\n"                                             \
164 "         nop\n"                                                      \
165 "         .previous");
166 #endif
167 
168 /* This could be also POWERPC_FREEBSD.  It is related to the save/restore
169    defines below.  */
170 #define POWERPC_LINUX
171 
172 /* Copy and paste from linux64.h and freebsd64.h */
173 #undef  SAVE_FP_PREFIX
174 #define SAVE_FP_PREFIX (TARGET_64BIT ? "._savef" : "_savefpr_")
175 #undef  SAVE_FP_SUFFIX
176 #define SAVE_FP_SUFFIX ""
177 #undef  RESTORE_FP_PREFIX
178 #define RESTORE_FP_PREFIX (TARGET_64BIT ? "._restf" : "_restfpr_")
179 #undef  RESTORE_FP_SUFFIX
180 #define RESTORE_FP_SUFFIX ""
181 
182 /* Copy and paste from linux64.h and freebsd64.h */
183 #undef    ASM_PREFERRED_EH_DATA_FORMAT
184 #define   ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
185   (TARGET_64BIT || flag_pic                                                     \
186    ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel             \
187       | (TARGET_64BIT ? DW_EH_PE_udata8 : DW_EH_PE_sdata4))           \
188    : DW_EH_PE_absptr)
189 
190 /* Copy and paste from linux64.h and freebsd64.h */
191 #undef  TOC_SECTION_ASM_OP
192 #define TOC_SECTION_ASM_OP \
193   (TARGET_64BIT                                                       \
194    ? "\t.section\t\".toc\",\"aw\""                          \
195    : "\t.section\t\".got\",\"aw\"")
196 
197 /* Copy and paste from linux64.h and freebsd64.h */
198 #undef  MINIMAL_TOC_SECTION_ASM_OP
199 #define MINIMAL_TOC_SECTION_ASM_OP \
200   (TARGET_64BIT                                                       \
201    ? "\t.section\t\".toc1\",\"aw\""                         \
202    : (flag_pic                                                        \
203       ? "\t.section\t\".got2\",\"aw\""                      \
204       : "\t.section\t\".got1\",\"aw\""))
205 
206 /* Copy and paste from linux64.h and freebsd64.h */
207 #undef    ASM_DECLARE_FUNCTION_SIZE
208 #define   ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)                          \
209   do                                                                                      \
210     {                                                                                     \
211       if (!flag_inhibit_size_directive)                                         \
212           {                                                                               \
213             fputs ("\t.size\t", (FILE));                                                  \
214             if (TARGET_64BIT && DOT_SYMBOLS)                                    \
215               putc ('.', (FILE));                                                         \
216             assemble_name ((FILE), (FNAME));                                    \
217             fputs (",.-", (FILE));                                              \
218             rs6000_output_function_entry (FILE, FNAME);                         \
219             putc ('\n', (FILE));                                                          \
220           }                                                                               \
221     }                                                                                     \
222   while (0)
223 
224 /* Copy and paste from linux64.h and freebsd64.h */
225 #undef  ASM_OUTPUT_SPECIAL_POOL_ENTRY_P
226 #define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X, MODE)                      \
227   (TARGET_TOC                                                                             \
228    && (SYMBOL_REF_P (X)                                                                   \
229        || (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS    \
230              && SYMBOL_REF_P (XEXP (XEXP (X, 0), 0)))                           \
231        || GET_CODE (X) == LABEL_REF                                             \
232        || (CONST_INT_P (X)                                                      \
233              && GET_MODE_BITSIZE (MODE) <= GET_MODE_BITSIZE (Pmode))  \
234        || (CONST_DOUBLE_P (X)                                                   \
235              && ((TARGET_64BIT                                                            \
236                     && (TARGET_MINIMAL_TOC                                                \
237                         || (SCALAR_FLOAT_MODE_P (GET_MODE (X))                  \
238                               && ! TARGET_NO_FP_IN_TOC)))                       \
239                  || (!TARGET_64BIT                                              \
240                        && !TARGET_NO_FP_IN_TOC                                  \
241                        && SCALAR_FLOAT_MODE_P (GET_MODE (X))                    \
242                        && BITS_PER_WORD == HOST_BITS_PER_INT)))))
243 
244 #undef CPP_OS_DEFAULT_SPEC
245 #define CPP_OS_DEFAULT_SPEC "\
246 %{!mcpu*:  %{!Dppc*: %{!Dmpc*: -Dmpc750} } }\
247 %{mcpu=403:  %{!Dppc*: %{!Dmpc*: -Dppc403}  } } \
248 %{mcpu=505:  %{!Dppc*: %{!Dmpc*: -Dmpc505}  } } \
249 %{mcpu=601:  %{!Dppc*: %{!Dmpc*: -Dppc601}  } } \
250 %{mcpu=602:  %{!Dppc*: %{!Dmpc*: -Dppc602}  } } \
251 %{mcpu=603:  %{!Dppc*: %{!Dmpc*: -Dppc603}  } } \
252 %{mcpu=603e: %{!Dppc*: %{!Dmpc*: -Dppc603e} } } \
253 %{mcpu=604:  %{!Dppc*: %{!Dmpc*: -Dmpc604}  } } \
254 %{mcpu=750:  %{!Dppc*: %{!Dmpc*: -Dmpc750}  } } \
255 %{mcpu=821:  %{!Dppc*: %{!Dmpc*: -Dmpc821}  } } \
256 %{mcpu=860:  %{!Dppc*: %{!Dmpc*: -Dmpc860}  } } \
257 %{mcpu=8540: %{!Dppc*: %{!Dmpc*: -Dppc8540}  } } \
258 %{mcpu=e6500: -D__PPC_CPU_E6500__} \
259 %{mvrsave: -D__PPC_VRSAVE__}"
260 
261 #undef    ASM_SPEC
262 #define   ASM_SPEC "%{!m64:%(asm_spec32)}%{m64:%(asm_spec64)} %(asm_spec_common)"
263 
264 #define ASM_SPEC32 "-a32 \
265 %{mrelocatable} %{mrelocatable-lib} %{" FPIE_OR_FPIC_SPEC ":-K PIC} \
266 %{memb|msdata=eabi: -memb}"
267 
268 #define ASM_SPEC64 "-a64"
269 
270 #define ASM_SPEC_COMMON "%(asm_cpu) \
271 %{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}}" \
272   ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN)
273 
274 #undef  LINK_OS_DEFAULT_SPEC
275 #define LINK_OS_DEFAULT_SPEC \
276 "%{!m64:%(link_os_spec32)}%{m64:%(link_os_spec64)}"
277 
278 #define LINK_OS_SPEC32 ENDIAN_SELECT(" -m elf32ppc",                  \
279                                              " -m elf32lppc",                   \
280                                              " -m elf32ppc")
281 #define LINK_OS_SPEC64 ENDIAN_SELECT(" -m elf64ppc",                  \
282                                              " -m elf64lppc",                   \
283                                              " -m elf64ppc")
284 
285 #undef  SUBSUBTARGET_EXTRA_SPECS
286 #define SUBSUBTARGET_EXTRA_SPECS \
287   { "asm_spec_common",                  ASM_SPEC_COMMON },                      \
288   { "asm_spec32",             ASM_SPEC32 },                                     \
289   { "asm_spec64",             ASM_SPEC64 },                                     \
290   { "link_os_spec32",                   LINK_OS_SPEC32 },                       \
291   { "link_os_spec64",                   LINK_OS_SPEC64 },
292 
293 /* Use gnu-user.h LINK_GCC_SEQUENCE_SPEC for rtems.  */
294 #undef LINK_GCC_C_SEQUENCE_SPEC
295 #define   LINK_GCC_C_SEQUENCE_SPEC \
296   "%{mads|myellowknife|mmvme|msim:%G %L %G;" \
297   "!mcall-*|mcall-linux:" GNU_USER_TARGET_LINK_GCC_C_SEQUENCE_SPEC ";" \
298   ":%G %L %G}"
299 
300 #define RTEMS_STARTFILE_SPEC "ecrti%O%s rtems_crti%O%s crtbegin%O%s"
301 #define RTEMS_ENDFILE_SPEC "crtend%O%s rtems_crtn%O%s ecrtn%O%s"
302