OSDN Git Service

* config.gcc (s390-*-linux-*, s390x-*-linux*): Switch to
[pf3gnuchains/gcc-fork.git] / gcc / config / s390 / linux.h
1 /* Definitions for Linux for S/390.
2    Copyright (C) 1999, 2000, 2001 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 #undef SIZE_TYPE                       /* use default                      */
27
28 #undef TARGET_VERSION
29 #define TARGET_VERSION fprintf (stderr, " (Linux for S/390)");
30
31 /* Names to predefine in the preprocessor for this target machine.  */
32
33 #define CPP_PREDEFINES "-Dlinux -Asystem(linux) -Acpu(s390) -Amachine(s390) -D__s390__ -Asystem(unix) -Dunix -D__ELF__"
34
35 /* 
36  * Caller save not (always) working in gcc-2.95.2
37  */
38
39 #undef CC1_SPEC
40 #define CC1_SPEC "-fno-caller-saves"
41 #define CC1PLUS_SPEC "-fno-caller-saves"
42
43 #undef  LINK_SPEC
44 #ifdef CROSS_COMPILE
45 #define LINK_SPEC "-m elf_s390 %{shared:-shared} \
46   %{!shared: \
47     %{!ibcs: \
48       %{!static: \
49         %{rdynamic:-export-dynamic} \
50         %{!dynamic-linker:-dynamic-linker /lib/ld.so.1 \
51         -rpath-link=/usr/local/s390-ibm-linux/lib}} \
52         %{static:-static}}}"
53 #else
54 #define LINK_SPEC "-m elf_s390 %{shared:-shared} \
55   %{!shared: \
56     %{!ibcs: \
57       %{!static: \
58         %{rdynamic:-export-dynamic} \
59         %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}} \
60         %{static:-static}}}"
61 #endif
62
63 /* Need to define this. Otherwise define to BITS_PER_WORD in cexp.c.
64    But BITS_PER_WORD depends on target flags, which are not defined in 
65    cexpc.c.  */
66
67 #undef  WCHAR_TYPE
68 #define WCHAR_TYPE "int"
69 #undef  WCHAR_TYPE_SIZE
70 #define WCHAR_TYPE_SIZE 32
71
72 /* Character to start a comment.  */
73
74 #define ASM_COMMENT_START "#"
75
76
77 /* Assembler pseudos to introduce constants of various size.  */
78
79 #define ASM_SHORT "\t.word"
80 #define ASM_LONG "\t.long"
81 #define ASM_QUAD "\t.quad"
82 #define ASM_DOUBLE "\t.double"
83
84
85 /* Prefix for internally generated assembler labels.  */
86 #define LPREFIX ".L"
87
88 #define ASM_OUTPUT_LABELREF(FILE, NAME) \
89   fprintf (FILE, "%s", NAME);  
90
91
92 /* This is how to output the definition of a user-level label named NAME,
93    such as the label on a static function or variable NAME.  */
94
95 #undef ASM_OUTPUT_LABEL
96 #define ASM_OUTPUT_LABEL(FILE, NAME)     \
97   (assemble_name (FILE, NAME), fputs (":\n", FILE))
98
99 /* This is how to output an assembler line defining a `double' constant.  */
100
101
102 /* This is how to output an assembler line defining a `double' constant.  */
103
104 #undef ASM_OUTPUT_DOUBLE
105 #define ASM_OUTPUT_DOUBLE(FILE, VALUE)                  \
106   {                                                     \
107     long t[2];                                          \
108     REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t);           \
109     fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n",    \
110              t[0] & 0xffffffff, t[1] & 0xffffffff);     \
111   }
112
113 /* This is how to output an assembler line defining a `float' constant.  */
114
115 #undef ASM_OUTPUT_FLOAT
116 #define ASM_OUTPUT_FLOAT(FILE, VALUE)                   \
117   {                                                     \
118     long t;                                             \
119     REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t);           \
120     fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffff);  \
121   }
122
123 /* Store in OUTPUT a string (made with alloca) containing
124    an assembler-name for a local static variable named NAME.
125    LABELNO is an integer which is different for each call.  */
126
127 #undef ASM_FORMAT_PRIVATE_NAME
128 #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)  \
129 ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),    \
130   sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
131
132
133 #define ASM_OUTPUT_DOUBLE_INT(FILE, VALUE)                              \
134 do { fprintf ((FILE), "%s\t", ASM_QUAD);                                \
135   /* Work around bug in some GNU as versions */                         \
136   if (GET_CODE (VALUE) == CONST_INT && INTVAL (VALUE) < INT_MIN)        \
137     fprintf ((FILE), HOST_WIDE_INT_PRINT_HEX, INTVAL (x));              \
138   else                                                                  \
139     output_addr_const ((FILE), (VALUE));                                \
140   putc ('\n', (FILE));                                                  \
141  } while (0)
142
143
144 /* This is how to output an assembler line defining an `int' constant.  */
145
146 #undef ASM_OUTPUT_INT
147 #define ASM_OUTPUT_INT(FILE, VALUE)             \
148 do { fprintf (FILE, "%s\t", ASM_LONG);          \
149   output_addr_const (FILE, (VALUE));            \
150   putc ('\n',FILE);                             \
151  } while (0)
152
153 /* Likewise for `char' and `short' constants. 
154    is this supposed to do align too?? */
155
156 #define ASM_OUTPUT_SHORT(FILE, VALUE)           \
157 ( fprintf (FILE, "%s ", ASM_SHORT),             \
158   output_addr_const (FILE, (VALUE)),            \
159   putc ('\n',FILE))
160
161 #define ASM_OUTPUT_CHAR(FILE, VALUE)            \
162 ( fprintf (FILE, "%s ", ASM_BYTE_OP),           \
163   output_addr_const (FILE, (VALUE)),            \
164   putc ('\n', FILE))
165
166 /* This is how to output an assembler line for a numeric constant byte.  */
167
168 #define ASM_OUTPUT_BYTE(FILE, VALUE)  \
169   fprintf ((FILE), "%s 0x%x\n", ASM_BYTE_OP, (VALUE))
170
171      /* internal macro to output long */
172 #define _ASM_OUTPUT_LONG(FILE, VALUE)                                   \
173       fprintf (FILE, "\t.long\t0x%lX\n", VALUE);
174
175
176 /* This is how to output an element of a case-vector that is absolute.  */
177
178 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)                    \
179   fprintf (FILE, "%s\t%s%d\n", TARGET_64BIT?ASM_QUAD:ASM_LONG,  \
180            LPREFIX, VALUE)
181
182 /* This is how to output an element of a case-vector that is relative.  */
183
184 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)                \
185   fprintf (FILE, "%s\t%s%d-%s%d\n", TARGET_64BIT?ASM_QUAD:ASM_LONG,     \
186            LPREFIX, VALUE, LPREFIX, REL)
187
188
189
190 /* This is how to output an assembler line
191    that says to advance the location counter
192    to a multiple of 2**LOG bytes.  */
193
194 #define ASM_OUTPUT_ALIGN(FILE, LOG)      \
195     if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG))
196
197 /* This is how to output an assembler line
198    that says to advance the location counter by SIZE bytes.  */
199
200 #undef ASM_OUTPUT_SKIP 
201 #define ASM_OUTPUT_SKIP(FILE, SIZE)  \
202   fprintf ((FILE), "\t.set .,.+%u\n", (SIZE))
203
204 /* This is how to output an assembler line
205    that says to advance the location counter
206    to a multiple of 2**LOG bytes.  */
207
208 #define ASM_OUTPUT_ALIGN(FILE, LOG)     \
209     if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG))
210
211 /* This is how to output an assembler line
212    that says to advance the location counter by SIZE bytes.  */
213
214 #define ASM_OUTPUT_SKIP(FILE, SIZE)  \
215   fprintf ((FILE), "\t.set .,.+%u\n", (SIZE))
216
217 /* The routine used to output sequences of byte values.  We use a special
218    version of this for most svr4 targets because doing so makes the
219    generated assembly code more compact (and thus faster to assemble)
220    as well as more readable.  Note that if we find subparts of the
221    character sequence which end with NUL (and which are shorter than
222    STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING.  */
223
224 #undef ASM_OUTPUT_ASCII
225 #define ASM_OUTPUT_ASCII(FILE, STR, LENGTH)                             \
226 do {                                                                    \
227       register unsigned char *_ascii_bytes = (unsigned char *) (STR);   \
228       register unsigned char *limit = _ascii_bytes + (LENGTH);          \
229       register unsigned bytes_in_chunk = 0;                             \
230       for (; _ascii_bytes < limit; _ascii_bytes++)                      \
231         {                                                               \
232           register unsigned char *p;                                    \
233           if (bytes_in_chunk >= 64)                                     \
234             {                                                           \
235               fputc ('\n', (FILE));                                     \
236               bytes_in_chunk = 0;                                       \
237             }                                                           \
238           for (p = _ascii_bytes; p < limit && *p != '\0'; p++)          \
239             continue;                                                   \
240           if (p < limit && (p - _ascii_bytes) <= STRING_LIMIT)          \
241             {                                                           \
242               if (bytes_in_chunk > 0)                                   \
243                 {                                                       \
244                   fputc ('\n', (FILE));                                 \
245                   bytes_in_chunk = 0;                                   \
246                 }                                                       \
247               ASM_OUTPUT_LIMITED_STRING ((FILE), _ascii_bytes);         \
248               _ascii_bytes = p;                                         \
249             }                                                           \
250           else                                                          \
251             {                                                           \
252               if (bytes_in_chunk == 0)                                  \
253                 fprintf ((FILE), "%s\t", ASM_BYTE_OP);                  \
254               else                                                      \
255                 fputc (',', (FILE));                                    \
256               fprintf ((FILE), "0x%02x", *_ascii_bytes);                \
257               bytes_in_chunk += 5;                                      \
258             }                                                           \
259         }                                                               \
260       if (bytes_in_chunk > 0)                                           \
261         fprintf ((FILE), "\n");                                         \
262 } while (0)
263
264 /* Output before read-only data.  */
265
266 #define TEXT_SECTION_ASM_OP ".text"
267
268 /* Output before writable (initialized) data.  */
269
270 #define DATA_SECTION_ASM_OP ".data"
271
272 /* Output before writable (uninitialized) data.  */
273
274 #define BSS_SECTION_ASM_OP ".bss"
275
276 /* This is how to output a command to make the user-level label named NAME
277    defined for reference from other files.  */
278
279 #define ASM_GLOBALIZE_LABEL(FILE, NAME)  \
280   (fputs (".globl ", FILE), assemble_name (FILE, NAME), fputs ("\n", FILE))
281
282 #define DBX_REGISTER_NUMBER(REGNO) (REGNO)
283
284 /* Select section for constant in constant pool. 
285    We are in the right section. 
286    undef for 64 bit mode (linux64.h).
287  */
288
289 #undef SELECT_RTX_SECTION
290 #define SELECT_RTX_SECTION(MODE, X, ALIGN)
291
292 \f
293 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
294    Used for C++ multiple inheritance.  */
295 #define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION)              \
296 do {                                                                          \
297   if (TARGET_64BIT)                                                           \
298     {                                                                         \
299       if (flag_pic)                                                           \
300         {                                                                     \
301           fprintf (FILE, "\tlarl  1,0f\n");                                   \
302           fprintf (FILE, "\tagf   %d,0(1)\n",                                 \
303                    aggregate_value_p (TREE_TYPE                               \
304                                       (TREE_TYPE (FUNCTION))) ? 3 :2 );       \
305           fprintf (FILE, "\tlarl  1,");                                       \
306           assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0));      \
307           fprintf (FILE, "@GOTENT\n");                                        \
308           fprintf (FILE, "\tlg    1,0(1)\n");                                 \
309           fprintf (FILE, "\tbr    1\n");                                      \
310           fprintf (FILE, "0:\t.long  %d\n",DELTA);                            \
311         }                                                                     \
312       else                                                                    \
313         {                                                                     \
314           fprintf (FILE, "\tlarl  1,0f\n");                                   \
315           fprintf (FILE, "\tagf   %d,0(1)\n",                                 \
316           aggregate_value_p (TREE_TYPE                                        \
317                              (TREE_TYPE (FUNCTION))) ? 3 :2 );                \
318           fprintf (FILE, "\tjg  ");                                           \
319           assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0));      \
320           fprintf (FILE, "\n");                                               \
321           fprintf (FILE, "0:\t.long  %d\n",DELTA);                            \
322         }                                                                     \
323     }                                                                         \
324   else                                                                        \
325     {                                                                         \
326       if (flag_pic)                                                           \
327         {                                                                     \
328           fprintf (FILE, "\tbras  1,0f\n");                                   \
329           fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_-.\n");                \
330           fprintf (FILE, "\t.long  ");                                        \
331           assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0));      \
332           fprintf (FILE, "@GOT\n");                                           \
333           fprintf (FILE, "\t.long  %d\n",DELTA);                              \
334           fprintf (FILE, "0:\tal  %d,8(1)\n",                                 \
335                    aggregate_value_p (TREE_TYPE                               \
336                                       (TREE_TYPE (FUNCTION))) ? 3 : 2 );      \
337           fprintf (FILE, "\tl     0,4(1)\n");                                 \
338           fprintf (FILE, "\tal    1,0(1)\n");                                 \
339           fprintf (FILE, "\talr   1,0\n");                                    \
340           fprintf (FILE, "\tl     1,0(1)\n");                                 \
341           fprintf (FILE, "\tbr    1\n");                                      \
342         } else {                                                              \
343           fprintf (FILE, "\tbras  1,0f\n");                                   \
344           fprintf (FILE, "\t.long  ");                                        \
345           assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0));      \
346           fprintf (FILE, "-.\n");                                             \
347           fprintf (FILE, "\t.long  %d\n",DELTA);                              \
348           fprintf (FILE, "0:\tal  %d,4(1)\n",                                 \
349                    aggregate_value_p (TREE_TYPE                               \
350                                       (TREE_TYPE (FUNCTION))) ? 3 : 2 );      \
351           fprintf (FILE, "\tal    1,0(1)\n");                                 \
352           fprintf (FILE, "\tbr    1\n");                                      \
353        }                                                                      \
354     }                                                                         \
355 } while (0)
356
357 #endif