OSDN Git Service

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