OSDN Git Service

* config/s390/s390.c (addr_generation_dependency_p): Handle SUBREG
[pf3gnuchains/gcc-fork.git] / gcc / config / s390 / linux.h
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).
5
6 This file is part of GNU CC.
7
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)
11 any later version.
12
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.
17
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.  */
22
23 #ifndef _LINUX_H
24 #define _LINUX_H
25
26 /* Target specific version string.  */
27
28 #ifdef DEFAULT_TARGET_64BIT
29 #undef  TARGET_VERSION
30 #define TARGET_VERSION fprintf (stderr, " (Linux for zSeries)");
31 #else
32 #undef  TARGET_VERSION
33 #define TARGET_VERSION fprintf (stderr, " (Linux for S/390)");
34 #endif
35
36
37 /* Target specific type definitions.  */
38
39 /* ??? Do we really want long as size_t on 31-bit?  */
40 #undef  SIZE_TYPE
41 #define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "long unsigned int")
42 #undef  PTRDIFF_TYPE
43 #define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
44
45 #undef  WCHAR_TYPE
46 #define WCHAR_TYPE "int"
47 #undef  WCHAR_TYPE_SIZE
48 #define WCHAR_TYPE_SIZE 32
49
50
51 /* Target specific preprocessor settings.  */
52
53 #define TARGET_OS_CPP_BUILTINS()                \
54   do                                            \
55     {                                           \
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__");         \
62       if (flag_pic)                             \
63         {                                       \
64           builtin_define ("__PIC__");           \
65           builtin_define ("__pic__");           \
66         }                                       \
67     }                                           \
68   while (0)
69
70
71 /* Target specific compiler settings.  */
72
73 /* ??? -fcaller-saves sometimes doesn't work.  Fix this! */
74 #undef  CC1_SPEC
75 #define CC1_SPEC "-fno-caller-saves"
76 #undef  CC1PLUS_SPEC
77 #define CC1PLUS_SPEC "-fno-caller-saves"
78
79
80 /* Target specific assembler settings.  */
81
82 #ifdef DEFAULT_TARGET_64BIT
83 #undef  ASM_SPEC
84 #define ASM_SPEC "%{m31:-m31 -Aesa}"
85 #else
86 #undef  ASM_SPEC
87 #define ASM_SPEC "%{m64:-m64 -Aesame}"
88 #endif
89
90
91 /* Target specific linker settings.  */
92
93 #define LINK_ARCH31_SPEC \
94   "-m elf_s390 \
95    %{shared:-shared} \
96    %{!shared: \
97       %{static:-static} \
98       %{!static: \
99         %{rdynamic:-export-dynamic} \
100         %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}}}"
101
102 #define LINK_ARCH64_SPEC \
103   "-m elf64_s390 \
104    %{shared:-shared} \
105    %{!shared: \
106       %{static:-static} \
107       %{!static: \
108         %{rdynamic:-export-dynamic} \
109         %{!dynamic-linker:-dynamic-linker /lib/ld64.so.1}}}"
110
111 #ifdef DEFAULT_TARGET_64BIT
112 #undef  LINK_SPEC
113 #define LINK_SPEC "%{m31:%(link_arch31)} %{!m31:%(link_arch64)}"
114 #else
115 #undef  LINK_SPEC
116 #define LINK_SPEC "%{m64:%(link_arch64)} %{!m64:%(link_arch31)}"
117 #endif
118
119
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.  */
123
124 #define EXTRA_SPECS \
125   { "link_arch31",      LINK_ARCH31_SPEC },     \
126   { "link_arch64",      LINK_ARCH64_SPEC },     \
127
128
129 /* Character to start a comment.  */
130
131 #define ASM_COMMENT_START "#"
132
133
134 /* Assembler pseudos to introduce constants of various size.  */
135
136 #define ASM_DOUBLE "\t.double"
137
138 /* The LOCAL_LABEL_PREFIX variable is used by dbxelf.h.  */
139 #define LOCAL_LABEL_PREFIX "."
140
141 /* Prefix for internally generated assembler labels.  */
142 #define LPREFIX ".L"
143
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.  */
147
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)))
152
153
154      /* internal macro to output long */
155 #define _ASM_OUTPUT_LONG(FILE, VALUE)                                   \
156       fprintf (FILE, "\t.long\t0x%lX\n", VALUE);
157
158
159 /* This is how to output an element of a case-vector that is absolute.  */
160
161 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)                    \
162   fprintf (FILE, "%s%s%d\n", integer_asm_op (UNITS_PER_WORD, TRUE), \
163            LPREFIX, VALUE)
164
165 /* This is how to output an element of a case-vector that is relative.  */
166
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)
170
171
172
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.  */
176
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))
180
181 /* This is how to output an assembler line
182    that says to advance the location counter by SIZE bytes.  */
183
184 #undef ASM_OUTPUT_SKIP
185 #define ASM_OUTPUT_SKIP(FILE, SIZE)  \
186   fprintf ((FILE), "\t.set\t.,.+%u\n", (SIZE))
187
188 /* This is how to output assembler code to declare an
189    uninitialized external linkage data object.  */
190
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)
194
195 /* Output before read-only data.  */
196
197 #define TEXT_SECTION_ASM_OP ".text"
198
199 /* Output before writable (initialized) data.  */
200
201 #define DATA_SECTION_ASM_OP ".data"
202
203 /* Output before writable (uninitialized) data.  */
204
205 #define BSS_SECTION_ASM_OP ".bss"
206
207 /* This is how to output a command to make the user-level label named NAME
208    defined for reference from other files.  */
209
210 /* Globalizing directive for a label.  */
211 #define GLOBAL_ASM_OP ".globl "
212 \f
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)              \
216 do {                                                                          \
217   if (TARGET_64BIT)                                                           \
218     {                                                                         \
219       if (flag_pic)                                                           \
220         {                                                                     \
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");                                               \
233         }                                                                     \
234       else                                                                    \
235         {                                                                     \
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");                                               \
246         }                                                                     \
247     }                                                                         \
248   else                                                                        \
249     {                                                                         \
250       if (flag_pic)                                                           \
251         {                                                                     \
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");                                      \
268         } else {                                                              \
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");                                      \
281        }                                                                      \
282     }                                                                         \
283 } while (0)
284
285 /* Do code reading to identify a signal frame, and set the frame
286    state data appropriately.  See unwind-dw2.c for the structs.  */
287
288 #define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)               \
289   do {                                                                  \
290     unsigned char *pc_ = (CONTEXT)->ra;                                 \
291     long new_cfa_;                                                      \
292     int i_;                                                             \
293                                                                         \
294     typedef struct                                                      \
295       {                                                                 \
296         unsigned long psw_mask;                                         \
297         unsigned long psw_addr;                                         \
298         unsigned long gprs[16];                                         \
299         unsigned int  acrs[16];                                         \
300         unsigned int  fpc;                                              \
301         unsigned int  __pad;                                            \
302         double        fprs[16];                                         \
303       } __attribute__ ((__aligned__ (8))) sigregs_;                     \
304                                                                         \
305     sigregs_ *regs_;                                                    \
306                                                                         \
307     /* svc $__NR_sigreturn or svc $__NR_rt_sigreturn  */                \
308     if (pc_[0] != 0x0a || (pc_[1] != 119 && pc_[1] != 173))             \
309       break;                                                            \
310                                                                         \
311     /* New-style RT frame:                                              \
312         retcode + alignment (8 bytes)                                   \
313         siginfo (128 bytes)                                             \
314         ucontext (contains sigregs)  */                                 \
315     if ((CONTEXT)->ra == (CONTEXT)->cfa)                                \
316       {                                                                 \
317         struct ucontext_                                                \
318           {                                                             \
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;                            \
324                                                                         \
325         regs_ = &uc_->uc_mcontext;                                      \
326       }                                                                 \
327                                                                         \
328     /* Old-style RT frame and all non-RT frames:                        \
329         old signal mask (8 bytes)                                       \
330         pointer to sigregs  */                                          \
331     else                                                                \
332       {                                                                 \
333         regs_ = *(sigregs_ **)((CONTEXT)->cfa + 8);                     \
334       }                                                                 \
335                                                                         \
336     new_cfa_ = regs_->gprs[15] + 16*sizeof(long) + 32;                  \
337     (FS)->cfa_how = CFA_REG_OFFSET;                                     \
338     (FS)->cfa_reg = 15;                                                 \
339     (FS)->cfa_offset =                                                  \
340       new_cfa_ - (long) (CONTEXT)->cfa + 16*sizeof(long) + 32;          \
341                                                                         \
342     for (i_ = 0; i_ < 16; i_++)                                         \
343       {                                                                 \
344         (FS)->regs.reg[i_].how = REG_SAVED_OFFSET;                      \
345         (FS)->regs.reg[i_].loc.offset =                                 \
346           (long)&regs_->gprs[i_] - new_cfa_;                            \
347       }                                                                 \
348     for (i_ = 0; i_ < 16; i_++)                                         \
349       {                                                                 \
350         (FS)->regs.reg[16+i_].how = REG_SAVED_OFFSET;                   \
351         (FS)->regs.reg[16+i_].loc.offset =                              \
352           (long)&regs_->fprs[i_] - new_cfa_;                            \
353       }                                                                 \
354                                                                         \
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)&regs_->psw_addr - new_cfa_;  \
358     (FS)->retaddr_column = 32;                                          \
359                                                                         \
360     goto SUCCESS;                                                       \
361   } while (0)
362
363 #endif