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. */
144 /* Store in OUTPUT a string (made with alloca) containing
145 an assembler-name for a local static variable named NAME.
146 LABELNO is an integer which is different for each call. */
148 #undef ASM_FORMAT_PRIVATE_NAME
149 #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
150 ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
151 sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
154 /* internal macro to output long */
155 #define _ASM_OUTPUT_LONG(FILE, VALUE) \
156 fprintf (FILE, "\t.long\t0x%lX\n", VALUE);
159 /* This is how to output an element of a case-vector that is absolute. */
161 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
162 fprintf (FILE, "%s%s%d\n", integer_asm_op (UNITS_PER_WORD, TRUE), \
165 /* This is how to output an element of a case-vector that is relative. */
167 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
168 fprintf (FILE, "%s%s%d-%s%d\n", integer_asm_op (UNITS_PER_WORD, TRUE), \
169 LPREFIX, VALUE, LPREFIX, REL)
173 /* This is how to output an assembler line
174 that says to advance the location counter
175 to a multiple of 2**LOG bytes. */
177 #undef ASM_OUTPUT_ALIGN
178 #define ASM_OUTPUT_ALIGN(FILE, LOG) \
179 if ((LOG)!=0) fprintf ((FILE), "\t.align\t%d\n", 1<<(LOG))
181 /* This is how to output an assembler line
182 that says to advance the location counter by SIZE bytes. */
184 #undef ASM_OUTPUT_SKIP
185 #define ASM_OUTPUT_SKIP(FILE, SIZE) \
186 fprintf ((FILE), "\t.set\t.,.+%u\n", (SIZE))
188 /* This is how to output assembler code to declare an
189 uninitialized external linkage data object. */
191 #undef ASM_OUTPUT_ALIGNED_BSS
192 #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
193 asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
195 /* Output before read-only data. */
197 #define TEXT_SECTION_ASM_OP ".text"
199 /* Output before writable (initialized) data. */
201 #define DATA_SECTION_ASM_OP ".data"
203 /* Output before writable (uninitialized) data. */
205 #define BSS_SECTION_ASM_OP ".bss"
207 /* This is how to output a command to make the user-level label named NAME
208 defined for reference from other files. */
210 /* Globalizing directive for a label. */
211 #define GLOBAL_ASM_OP ".globl "
213 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
214 Used for C++ multiple inheritance. */
215 #define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
221 fprintf (FILE, "\tlarl 1,0f\n"); \
222 fprintf (FILE, "\tagf %d,0(1)\n", \
223 aggregate_value_p (TREE_TYPE \
224 (TREE_TYPE (FUNCTION))) ? 3 :2 ); \
225 fprintf (FILE, "\tlarl 1,"); \
226 assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \
227 fprintf (FILE, "@GOTENT\n"); \
228 fprintf (FILE, "\tlg 1,0(1)\n"); \
229 fprintf (FILE, "\tbr 1\n"); \
230 fprintf (FILE, "0:\t.long "); \
231 fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, (DELTA)); \
232 fprintf (FILE, "\n"); \
236 fprintf (FILE, "\tlarl 1,0f\n"); \
237 fprintf (FILE, "\tagf %d,0(1)\n", \
238 aggregate_value_p (TREE_TYPE \
239 (TREE_TYPE (FUNCTION))) ? 3 :2 ); \
240 fprintf (FILE, "\tjg "); \
241 assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \
242 fprintf (FILE, "\n"); \
243 fprintf (FILE, "0:\t.long "); \
244 fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, (DELTA)); \
245 fprintf (FILE, "\n"); \
252 fprintf (FILE, "\tbras 1,0f\n"); \
253 fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_-.\n"); \
254 fprintf (FILE, "\t.long "); \
255 assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \
256 fprintf (FILE, "@GOT\n"); \
257 fprintf (FILE, "\t.long "); \
258 fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, (DELTA)); \
259 fprintf (FILE, "\n"); \
260 fprintf (FILE, "0:\tal %d,8(1)\n", \
261 aggregate_value_p (TREE_TYPE \
262 (TREE_TYPE (FUNCTION))) ? 3 : 2 ); \
263 fprintf (FILE, "\tl 0,4(1)\n"); \
264 fprintf (FILE, "\tal 1,0(1)\n"); \
265 fprintf (FILE, "\talr 1,0\n"); \
266 fprintf (FILE, "\tl 1,0(1)\n"); \
267 fprintf (FILE, "\tbr 1\n"); \
269 fprintf (FILE, "\tbras 1,0f\n"); \
270 fprintf (FILE, "\t.long "); \
271 assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \
272 fprintf (FILE, "-.\n"); \
273 fprintf (FILE, "\t.long "); \
274 fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, (DELTA)); \
275 fprintf (FILE, "\n"); \
276 fprintf (FILE, "0:\tal %d,4(1)\n", \
277 aggregate_value_p (TREE_TYPE \
278 (TREE_TYPE (FUNCTION))) ? 3 : 2 ); \
279 fprintf (FILE, "\tal 1,0(1)\n"); \
280 fprintf (FILE, "\tbr 1\n"); \
285 /* Do code reading to identify a signal frame, and set the frame
286 state data appropriately. See unwind-dw2.c for the structs. */
288 #define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
290 unsigned char *pc_ = (CONTEXT)->ra; \
296 unsigned long psw_mask; \
297 unsigned long psw_addr; \
298 unsigned long gprs[16]; \
299 unsigned int acrs[16]; \
301 unsigned int __pad; \
303 } __attribute__ ((__aligned__ (8))) sigregs_; \
307 /* svc $__NR_sigreturn or svc $__NR_rt_sigreturn */ \
308 if (pc_[0] != 0x0a || (pc_[1] != 119 && pc_[1] != 173)) \
311 /* New-style RT frame: \
312 retcode + alignment (8 bytes) \
313 siginfo (128 bytes) \
314 ucontext (contains sigregs) */ \
315 if ((CONTEXT)->ra == (CONTEXT)->cfa) \
319 unsigned long uc_flags; \
320 struct ucontext_ *uc_link; \
321 unsigned long uc_stack[3]; \
322 sigregs_ uc_mcontext; \
323 } *uc_ = (CONTEXT)->cfa + 8 + 128; \
325 regs_ = &uc_->uc_mcontext; \
328 /* Old-style RT frame and all non-RT frames: \
329 old signal mask (8 bytes) \
330 pointer to sigregs */ \
333 regs_ = *(sigregs_ **)((CONTEXT)->cfa + 8); \
336 new_cfa_ = regs_->gprs[15] + 16*sizeof(long) + 32; \
337 (FS)->cfa_how = CFA_REG_OFFSET; \
338 (FS)->cfa_reg = 15; \
340 new_cfa_ - (long) (CONTEXT)->cfa + 16*sizeof(long) + 32; \
342 for (i_ = 0; i_ < 16; i_++) \
344 (FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
345 (FS)->regs.reg[i_].loc.offset = \
346 (long)®s_->gprs[i_] - new_cfa_; \
348 for (i_ = 0; i_ < 16; i_++) \
350 (FS)->regs.reg[16+i_].how = REG_SAVED_OFFSET; \
351 (FS)->regs.reg[16+i_].loc.offset = \
352 (long)®s_->fprs[i_] - new_cfa_; \
355 /* Load return addr from PSW into dummy register 32. */ \
356 (FS)->regs.reg[32].how = REG_SAVED_OFFSET; \
357 (FS)->regs.reg[32].loc.offset = (long)®s_->psw_addr - new_cfa_; \
358 (FS)->retaddr_column = 32; \