1 /* Definitions for Linux for S/390.
2 Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3 Contributed by Hartmut Penner (hpenner@de.ibm.com) and
4 Ulrich Weigand (uweigand@de.ibm.com).
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
26 /* Target specific version string. */
28 #ifdef DEFAULT_TARGET_64BIT
30 #define TARGET_VERSION fprintf (stderr, " (Linux for zSeries)");
33 #define TARGET_VERSION fprintf (stderr, " (Linux for S/390)");
37 /* Target specific type definitions. */
39 /* ??? Do we really want long as size_t on 31-bit? */
41 #define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "long unsigned int")
43 #define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
46 #define WCHAR_TYPE "int"
47 #undef WCHAR_TYPE_SIZE
48 #define WCHAR_TYPE_SIZE 32
51 /* Target specific preprocessor settings. */
53 #define TARGET_OS_CPP_BUILTINS() \
56 builtin_define_std ("linux"); \
57 builtin_define_std ("unix"); \
58 builtin_assert ("system=linux"); \
59 builtin_assert ("system=unix"); \
60 builtin_define ("__ELF__"); \
61 builtin_define ("__gnu_linux__"); \
64 builtin_define ("__PIC__"); \
65 builtin_define ("__pic__"); \
71 /* Target specific compiler settings. */
73 /* ??? -fcaller-saves sometimes doesn't work. Fix this! */
75 #define CC1_SPEC "-fno-caller-saves"
77 #define CC1PLUS_SPEC "-fno-caller-saves"
80 /* Target specific assembler settings. */
82 #ifdef DEFAULT_TARGET_64BIT
84 #define ASM_SPEC "%{m31:-m31 -Aesa}"
87 #define ASM_SPEC "%{m64:-m64 -Aesame}"
91 /* Target specific linker settings. */
93 #define LINK_ARCH31_SPEC \
99 %{rdynamic:-export-dynamic} \
100 %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}}}"
102 #define LINK_ARCH64_SPEC \
108 %{rdynamic:-export-dynamic} \
109 %{!dynamic-linker:-dynamic-linker /lib/ld64.so.1}}}"
111 #ifdef DEFAULT_TARGET_64BIT
113 #define LINK_SPEC "%{m31:%(link_arch31)} %{!m31:%(link_arch64)}"
116 #define LINK_SPEC "%{m64:%(link_arch64)} %{!m64:%(link_arch31)}"
120 /* This macro defines names of additional specifications to put in the specs
121 that can be used in various specifications like CC1_SPEC. Its definition
122 is an initializer with a subgrouping for each command option. */
124 #define EXTRA_SPECS \
125 { "link_arch31", LINK_ARCH31_SPEC }, \
126 { "link_arch64", LINK_ARCH64_SPEC }, \
129 /* Character to start a comment. */
131 #define ASM_COMMENT_START "#"
134 /* Assembler pseudos to introduce constants of various size. */
136 #define ASM_DOUBLE "\t.double"
138 /* The LOCAL_LABEL_PREFIX variable is used by dbxelf.h. */
139 #define LOCAL_LABEL_PREFIX "."
141 /* Prefix for internally generated assembler labels. */
145 /* This is how to output the definition of a user-level label named NAME,
146 such as the label on a static function or variable NAME. */
148 #undef ASM_OUTPUT_LABEL
149 #define ASM_OUTPUT_LABEL(FILE, NAME) \
150 (assemble_name (FILE, NAME), fputs (":\n", FILE))
152 /* Store in OUTPUT a string (made with alloca) containing
153 an assembler-name for a local static variable named NAME.
154 LABELNO is an integer which is different for each call. */
156 #undef ASM_FORMAT_PRIVATE_NAME
157 #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
158 ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
159 sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
162 /* internal macro to output long */
163 #define _ASM_OUTPUT_LONG(FILE, VALUE) \
164 fprintf (FILE, "\t.long\t0x%lX\n", VALUE);
167 /* This is how to output an element of a case-vector that is absolute. */
169 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
170 fprintf (FILE, "%s%s%d\n", integer_asm_op (UNITS_PER_WORD, TRUE), \
173 /* This is how to output an element of a case-vector that is relative. */
175 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
176 fprintf (FILE, "%s%s%d-%s%d\n", integer_asm_op (UNITS_PER_WORD, TRUE), \
177 LPREFIX, VALUE, LPREFIX, REL)
181 /* This is how to output an assembler line
182 that says to advance the location counter
183 to a multiple of 2**LOG bytes. */
185 #undef ASM_OUTPUT_ALIGN
186 #define ASM_OUTPUT_ALIGN(FILE, LOG) \
187 if ((LOG)!=0) fprintf ((FILE), "\t.align\t%d\n", 1<<(LOG))
189 /* This is how to output an assembler line
190 that says to advance the location counter by SIZE bytes. */
192 #undef ASM_OUTPUT_SKIP
193 #define ASM_OUTPUT_SKIP(FILE, SIZE) \
194 fprintf ((FILE), "\t.set\t.,.+%u\n", (SIZE))
196 /* This is how to output assembler code to declare an
197 uninitialized external linkage data object. */
199 #undef ASM_OUTPUT_ALIGNED_BSS
200 #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
201 asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
203 /* Output before read-only data. */
205 #define TEXT_SECTION_ASM_OP ".text"
207 /* Output before writable (initialized) data. */
209 #define DATA_SECTION_ASM_OP ".data"
211 /* Output before writable (uninitialized) data. */
213 #define BSS_SECTION_ASM_OP ".bss"
215 /* This is how to output a command to make the user-level label named NAME
216 defined for reference from other files. */
218 #define ASM_GLOBALIZE_LABEL(FILE, NAME) \
219 (fputs (".globl ", FILE), assemble_name (FILE, NAME), fputs ("\n", FILE))
221 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
222 Used for C++ multiple inheritance. */
223 #define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
229 fprintf (FILE, "\tlarl 1,0f\n"); \
230 fprintf (FILE, "\tagf %d,0(1)\n", \
231 aggregate_value_p (TREE_TYPE \
232 (TREE_TYPE (FUNCTION))) ? 3 :2 ); \
233 fprintf (FILE, "\tlarl 1,"); \
234 assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \
235 fprintf (FILE, "@GOTENT\n"); \
236 fprintf (FILE, "\tlg 1,0(1)\n"); \
237 fprintf (FILE, "\tbr 1\n"); \
238 fprintf (FILE, "0:\t.long "); \
239 fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, (DELTA)); \
240 fprintf (FILE, "\n"); \
244 fprintf (FILE, "\tlarl 1,0f\n"); \
245 fprintf (FILE, "\tagf %d,0(1)\n", \
246 aggregate_value_p (TREE_TYPE \
247 (TREE_TYPE (FUNCTION))) ? 3 :2 ); \
248 fprintf (FILE, "\tjg "); \
249 assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \
250 fprintf (FILE, "\n"); \
251 fprintf (FILE, "0:\t.long "); \
252 fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, (DELTA)); \
253 fprintf (FILE, "\n"); \
260 fprintf (FILE, "\tbras 1,0f\n"); \
261 fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_-.\n"); \
262 fprintf (FILE, "\t.long "); \
263 assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \
264 fprintf (FILE, "@GOT\n"); \
265 fprintf (FILE, "\t.long "); \
266 fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, (DELTA)); \
267 fprintf (FILE, "\n"); \
268 fprintf (FILE, "0:\tal %d,8(1)\n", \
269 aggregate_value_p (TREE_TYPE \
270 (TREE_TYPE (FUNCTION))) ? 3 : 2 ); \
271 fprintf (FILE, "\tl 0,4(1)\n"); \
272 fprintf (FILE, "\tal 1,0(1)\n"); \
273 fprintf (FILE, "\talr 1,0\n"); \
274 fprintf (FILE, "\tl 1,0(1)\n"); \
275 fprintf (FILE, "\tbr 1\n"); \
277 fprintf (FILE, "\tbras 1,0f\n"); \
278 fprintf (FILE, "\t.long "); \
279 assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \
280 fprintf (FILE, "-.\n"); \
281 fprintf (FILE, "\t.long "); \
282 fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, (DELTA)); \
283 fprintf (FILE, "\n"); \
284 fprintf (FILE, "0:\tal %d,4(1)\n", \
285 aggregate_value_p (TREE_TYPE \
286 (TREE_TYPE (FUNCTION))) ? 3 : 2 ); \
287 fprintf (FILE, "\tal 1,0(1)\n"); \
288 fprintf (FILE, "\tbr 1\n"); \
293 /* Do code reading to identify a signal frame, and set the frame
294 state data appropriately. See unwind-dw2.c for the structs. */
296 #define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
298 unsigned char *pc_ = (CONTEXT)->ra; \
304 unsigned long psw_mask; \
305 unsigned long psw_addr; \
306 unsigned long gprs[16]; \
307 unsigned int acrs[16]; \
309 unsigned int __pad; \
311 } __attribute__ ((__aligned__ (8))) sigregs_; \
315 /* svc $__NR_sigreturn or svc $__NR_rt_sigreturn */ \
316 if (pc_[0] != 0x0a || (pc_[1] != 119 && pc_[1] != 173)) \
319 /* New-style RT frame: \
320 retcode + alignment (8 bytes) \
321 siginfo (128 bytes) \
322 ucontext (contains sigregs) */ \
323 if ((CONTEXT)->ra == (CONTEXT)->cfa) \
327 unsigned long uc_flags; \
328 struct ucontext_ *uc_link; \
329 unsigned long uc_stack[3]; \
330 sigregs_ uc_mcontext; \
331 } *uc_ = (CONTEXT)->cfa + 8 + 128; \
333 regs_ = &uc_->uc_mcontext; \
336 /* Old-style RT frame and all non-RT frames: \
337 old signal mask (8 bytes) \
338 pointer to sigregs */ \
341 regs_ = *(sigregs_ **)((CONTEXT)->cfa + 8); \
344 new_cfa_ = regs_->gprs[15] + 16*sizeof(long) + 32; \
345 (FS)->cfa_how = CFA_REG_OFFSET; \
346 (FS)->cfa_reg = 15; \
348 new_cfa_ - (long) (CONTEXT)->cfa + 16*sizeof(long) + 32; \
350 for (i_ = 0; i_ < 16; i_++) \
352 (FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
353 (FS)->regs.reg[i_].loc.offset = \
354 (long)®s_->gprs[i_] - new_cfa_; \
356 for (i_ = 0; i_ < 16; i_++) \
358 (FS)->regs.reg[16+i_].how = REG_SAVED_OFFSET; \
359 (FS)->regs.reg[16+i_].loc.offset = \
360 (long)®s_->fprs[i_] - new_cfa_; \
363 /* Load return addr from PSW into dummy register 32. */ \
364 (FS)->regs.reg[32].how = REG_SAVED_OFFSET; \
365 (FS)->regs.reg[32].loc.offset = (long)®s_->psw_addr - new_cfa_; \
366 (FS)->retaddr_column = 32; \