OSDN Git Service

02b3dde3db58946fa1c34bbe32dbda5ab1f89e56
[pf3gnuchains/gcc-fork.git] / gcc / config / alpha / unicosmk.h
1 /* Definitions of target machine for GNU compiler, for DEC Alpha on Cray
2    T3E running Unicos/Mk.
3    Copyright (C) 2001, 2002, 2004
4    Free Software Foundation, Inc.
5    Contributed by Roman Lechtchinsky (rl@cs.tu-berlin.de)
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13
14 GCC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING.  If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA.  */
23
24 #undef TARGET_ABI_UNICOSMK
25 #define TARGET_ABI_UNICOSMK 1
26
27 /* CAM requires a slash before floating-pointing instruction suffixes.  */
28
29 #undef TARGET_AS_SLASH_BEFORE_SUFFIX
30 #define TARGET_AS_SLASH_BEFORE_SUFFIX 1
31
32 /* The following defines are necessary for the standard headers to work
33    correctly.  */
34
35 #define TARGET_OS_CPP_BUILTINS()                                \
36     do {                                                        \
37         builtin_define ("__unix");                              \
38         builtin_define ("_UNICOS=205");                         \
39         builtin_define ("_CRAY");                               \
40         builtin_define ("_CRAYT3E");                            \
41         builtin_define ("_CRAYMPP");                            \
42         builtin_define ("_CRAYIEEE");                           \
43         builtin_define ("_ADDR64");                             \
44         builtin_define ("_LD64");                               \
45         builtin_define ("__UNICOSMK__");                        \
46     } while (0)
47
48 #define SHORT_TYPE_SIZE 32
49
50 #undef INT_TYPE_SIZE
51 #define INT_TYPE_SIZE 64
52
53 /* This is consistent with the definition Cray CC uses.  */
54 #undef WCHAR_TYPE
55 #define WCHAR_TYPE "int"
56 #undef WCHAR_TYPE_SIZE
57 #define WCHAR_TYPE_SIZE 64
58
59 /*
60 #define SIZE_TYPE "unsigned int"
61 #define PTRDIFF_TYPE "int"
62 */
63
64 /* Alphas are operated in big endian mode on the Cray T3E.  */
65
66 #undef BITS_BIG_ENDIAN
67 #undef BYTES_BIG_ENDIAN
68 #undef WORDS_BIG_ENDIAN
69 #define BITS_BIG_ENDIAN 0
70 #define BYTES_BIG_ENDIAN 1
71 #define WORDS_BIG_ENDIAN 1
72
73
74 /* Every structure's size must be a multiple of this.  */
75
76 #undef STRUCTURE_SIZE_BOUNDARY
77 #define STRUCTURE_SIZE_BOUNDARY 64
78
79 /* No data type wants to be aligned rounder than this.  */
80
81 #undef BIGGEST_ALIGNMENT
82 #define BIGGEST_ALIGNMENT 256
83
84 /* Include the frame pointer in fixed_regs and call_used_regs as it can't be 
85    used as a general-purpose register even in frameless functions.
86    ??? The global_regs hack is needed for now because -O2 sometimes tries to 
87    eliminate $15 increments/decrements in frameless functions.  */
88
89 #undef CONDITIONAL_REGISTER_USAGE
90 #define CONDITIONAL_REGISTER_USAGE      \
91   do {                                  \
92     fixed_regs[15] = 1;                 \
93     call_used_regs[15] = 1;             \
94     global_regs[15] = 1;                \
95   } while(0)
96 \f
97 /* The stack frame grows downward.  */
98
99 #define FRAME_GROWS_DOWNWARD
100
101 /* Define the offset between two registers, one to be eliminated, and the
102    other its replacement, at the start of a routine. This is somewhat
103    complicated on the T3E which is why we use a function.  */
104
105 #undef INITIAL_ELIMINATION_OFFSET
106 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)                    \
107   do {                                                                  \
108     (OFFSET) = unicosmk_initial_elimination_offset ((FROM), (TO));      \
109   } while (0)
110
111
112 /* Define this if stack space is still allocated for a parameter passed
113    in a register. On the T3E, stack space is preallocated for all outgoing
114    arguments, including those passed in registers. To avoid problems, we
115    assume that at least 48 bytes (i.e. enough space for all arguments passed
116    in registers) are allocated.  */
117
118 #define REG_PARM_STACK_SPACE(DECL) 48
119 #define OUTGOING_REG_PARM_STACK_SPACE
120
121 /* If an argument can't be passed in registers even though not all argument
122    registers have been used yet, it is passed on the stack in the space 
123    preallocated for these registers.  */
124
125 #define STACK_PARMS_IN_REG_PARM_AREA
126
127 /* Define a data type for recording info about an argument list
128    during the scan of that argument list.  This data type should
129    hold all necessary information about the function itself
130    and about the args processed so far, enough to enable macros
131    such as FUNCTION_ARG to determine where the next arg should go.
132
133    On Unicos/Mk, this is a structure that contains various information for
134    the static subroutine information block (SSIB) and the call information
135    word (CIW).  */
136
137 typedef struct {
138
139   /* The overall number of arguments.  */
140   int num_args;
141
142   /* The overall size of the arguments in words.  */
143   int num_arg_words;
144
145   /* The number of words passed in registers.  */
146   int num_reg_words;
147
148   /* If an argument must be passed in the stack, all subsequent arguments
149      must be passed there, too. This flag indicates whether this is the
150      case.  */
151   int force_stack;
152
153   /* This array indicates whether a word is passed in an integer register or
154      a floating point one.  */
155
156   /* For each of the 6 register arguments, the corresponding flag in this
157      array indicates whether the argument is passed in an integer or a
158      floating point register.  */
159   int reg_args_type[6];
160
161 } unicosmk_arg_info;
162
163 #undef CUMULATIVE_ARGS
164 #define CUMULATIVE_ARGS unicosmk_arg_info
165
166 /* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a
167    function whose data type is FNTYPE.  For a library call, FNTYPE is 0.  */
168
169 #undef INIT_CUMULATIVE_ARGS
170 #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
171   do { (CUM).num_args = 0;                                      \
172        (CUM).num_arg_words = 0;                                 \
173        (CUM).num_reg_words = 0;                                 \
174        (CUM).force_stack = 0;                                   \
175   } while(0)
176
177 /* Update the data in CUM to advance over an argument of mode MODE and data
178    type TYPE. (TYPE is null for libcalls where that information may not be
179    available.)
180
181    On Unicos/Mk, at most 6 words can be passed in registers. Structures
182    which fit in two words are passed in registers, larger structures are
183    passed on stack.  */
184
185 #undef FUNCTION_ARG_ADVANCE
186 #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)            \
187 do {                                                            \
188   int size;                                                     \
189                                                                 \
190   size = ALPHA_ARG_SIZE (MODE, TYPE, NAMED);                    \
191                                                                 \
192   if (size > 2                                                  \
193       || (CUM).num_reg_words + size > 6                         \
194       || targetm.calls.must_pass_in_stack (MODE, TYPE))         \
195     (CUM).force_stack = 1;                                      \
196                                                                 \
197   if (! (CUM).force_stack)                                      \
198     {                                                           \
199       int i;                                                    \
200       int isfloat;                                              \
201       isfloat = (GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT    \
202               || GET_MODE_CLASS (MODE) == MODE_FLOAT);          \
203       for (i = 0; i < size; i++)                                \
204         {                                                       \
205           (CUM).reg_args_type[(CUM).num_reg_words] = isfloat;   \
206           ++(CUM).num_reg_words;                                \
207         }                                                       \
208     }                                                           \
209   (CUM).num_arg_words += size;                                  \
210   ++(CUM).num_args;                                             \
211 } while(0)
212
213 /* This ensures that $15 increments/decrements in leaf functions won't get
214    eliminated.  */
215
216 #undef EPILOGUE_USES
217 #define EPILOGUE_USES(REGNO)  ((REGNO) == 26 || (REGNO) == 15)
218
219 /* Would have worked, only the stack doesn't seem to be executable
220 #undef TRAMPOLINE_TEMPLATE
221 #define TRAMPOLINE_TEMPLATE(FILE)                       \
222 do { fprintf (FILE, "\tbr $1,0\n");                     \
223      fprintf (FILE, "\tldq $0,12($1)\n");               \
224      fprintf (FILE, "\tldq $1,20($1)\n");               \
225      fprintf (FILE, "\tjmp $31,(r0)\n");                \
226      fprintf (FILE, "\tbis $31,$31,$31\n");             \
227      fprintf (FILE, "\tbis $31,$31,$31\n");             \
228 } while (0) */
229
230 /* We don't support nested functions (yet).  */
231
232 #undef TRAMPOLINE_TEMPLATE
233 #define TRAMPOLINE_TEMPLATE(FILE) abort ()
234 \f
235 /* Specify the machine mode that this machine uses for the index in the
236    tablejump instruction. On Unicos/Mk, we don't support relative case
237    vectors yet, thus the entries should be absolute addresses.  */ 
238
239 #undef CASE_VECTOR_MODE
240 #define CASE_VECTOR_MODE DImode
241
242 #undef CASE_VECTOR_PC_RELATIVE
243
244 /* Define this as 1 if `char' should by default be signed; else as 0.  */
245 /* #define DEFAULT_SIGNED_CHAR 1 */
246
247 /* The Cray assembler is really weird with respect to sections. It has only
248    named sections and you can't reopen a section once it has been closed.
249    This means that we have to generate unique names whenever we want to
250    reenter the text or the data section. The following is a rather bad hack
251    as TEXT_SECTION_ASM_OP and DATA_SECTION_ASM_OP are supposed to be
252    constants.  */
253
254 #undef TEXT_SECTION_ASM_OP
255 #define TEXT_SECTION_ASM_OP unicosmk_text_section ()
256
257 #undef DATA_SECTION_ASM_OP
258 #define DATA_SECTION_ASM_OP unicosmk_data_section ()
259
260 /* There are no read-only sections on Unicos/Mk.  */
261
262 #undef READONLY_DATA_SECTION_ASM_OP
263 #define READONLY_DATA_SECTION data_section
264
265 /* Define extra sections for common data and SSIBs (static subroutine
266    information blocks). The actual section header is output by the callers
267    of these functions.  */
268
269 #undef EXTRA_SECTIONS
270 #undef EXTRA_SECTION_FUNCTIONS
271
272 #define EXTRA_SECTIONS in_common, in_ssib
273 #define EXTRA_SECTION_FUNCTIONS \
274 COMMON_SECTION                  \
275 SSIB_SECTION    
276
277 extern void common_section (void);
278 #define COMMON_SECTION          \
279 void                            \
280 common_section (void)           \
281 {                               \
282   in_section = in_common;       \
283 }
284
285 extern void ssib_section (void);
286 #define SSIB_SECTION            \
287 void                            \
288 ssib_section (void)             \
289 {                               \
290   in_section = in_ssib;         \
291 }
292
293 /* We take care of this in unicosmk_file_start.  */
294
295 #undef ASM_OUTPUT_SOURCE_FILENAME
296
297 /* This is how to output a label for a jump table.  Arguments are the same as
298    for (*targetm.asm_out.internal_label), except the insn for the jump table is
299    passed.  */
300
301 #undef ASM_OUTPUT_CASE_LABEL
302 #define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN)        \
303   (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM)
304
305 /* CAM has some restrictions with respect to string literals. It won't
306    accept lines with more that 256 characters which means that we have
307    to split long strings. Moreover, it only accepts escape sequences of
308    the form \nnn in the range 0 to 127. We generate .byte directives for
309    escapes characters greater than 127. And finally, ` must be escaped.  */
310
311 #undef ASM_OUTPUT_ASCII
312 #define ASM_OUTPUT_ASCII(MYFILE, MYSTRING, MYLENGTH) \
313   do {                                                                        \
314     FILE *_hide_asm_out_file = (MYFILE);                                      \
315     const unsigned char *_hide_p = (const unsigned char *) (MYSTRING);        \
316     int _hide_thissize = (MYLENGTH);                                          \
317     int _size_so_far = 0;                                                     \
318     {                                                                         \
319       FILE *asm_out_file = _hide_asm_out_file;                                \
320       const unsigned char *p = _hide_p;                                       \
321       int thissize = _hide_thissize;                                          \
322       int in_ascii = 0;                                                       \
323       int i;                                                                  \
324                                                                               \
325       for (i = 0; i < thissize; i++)                                          \
326         {                                                                     \
327           register int c = p[i];                                              \
328                                                                               \
329           if (c > 127)                                                        \
330             {                                                                 \
331               if (in_ascii)                                                   \
332                 {                                                             \
333                   fprintf (asm_out_file, "\"\n");                             \
334                   in_ascii = 0;                                               \
335                 }                                                             \
336                                                                               \
337               fprintf (asm_out_file, "\t.byte\t%d\n", c);                     \
338             }                                                                 \
339           else                                                                \
340             {                                                                 \
341               if (! in_ascii)                                                 \
342                 {                                                             \
343                   fprintf (asm_out_file, "\t.ascii\t\"");                     \
344                   in_ascii = 1;                                               \
345                   _size_so_far = 0;                                           \
346                 }                                                             \
347               else if (_size_so_far >= 64)                                    \
348                 {                                                             \
349                   fprintf (asm_out_file, "\"\n\t.ascii\t\"");                 \
350                   _size_so_far = 0;                                           \
351                 }                                                             \
352                                                                               \
353               if (c == '\"' || c == '\\' || c == '`')                         \
354                 putc ('\\', asm_out_file);                                    \
355               if (c >= ' ')                                                   \
356                 putc (c, asm_out_file);                                       \
357               else                                                            \
358                 fprintf (asm_out_file, "\\%.3o", c);                          \
359               ++ _size_so_far;                                                \
360             }                                                                 \
361         }                                                                     \
362       if (in_ascii)                                                           \
363         fprintf (asm_out_file, "\"\n");                                       \
364     }                                                                         \
365   } while(0)
366
367 /* This is how to output an element of a case-vector that is absolute.  */
368
369 #undef ASM_OUTPUT_ADDR_VEC_ELT
370 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)    \
371   fprintf (FILE, "\t.quad $L%d\n", (VALUE))
372
373 /* This is how to output an element of a case-vector that is relative.
374    (Unicos/Mk does not use such vectors yet).  */
375
376 #undef ASM_OUTPUT_ADDR_DIFF_ELT
377 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) abort ()
378
379 /* We can't output case vectors in the same section as the function code
380    because CAM doesn't allow data definitions in code sections. Thus, we
381    simply record the case vectors and put them in a separate section after
382    the function.  */
383
384 #define ASM_OUTPUT_ADDR_VEC(LAB,VEC) \
385   unicosmk_defer_case_vector ((LAB),(VEC))
386
387 #define ASM_OUTPUT_ADDR_DIFF_VEC(LAB,VEC) abort ()
388
389 /* This is how to output an assembler line that says to advance the location
390    counter to a multiple of 2**LOG bytes. Annoyingly, CAM always uses zeroes
391    to fill the unused space which does not work in code sections. We have to 
392    be careful not to use the .align directive in code sections.  */
393
394 #undef ASM_OUTPUT_ALIGN
395 #define ASM_OUTPUT_ALIGN(STREAM,LOG) unicosmk_output_align (STREAM, LOG)
396
397 /* This is how to advance the location counter by SIZE bytes.  */
398
399 #undef ASM_OUTPUT_SKIP
400 #define ASM_OUTPUT_SKIP(STREAM,SIZE)                    \
401   fprintf ((STREAM), "\t.byte\t0:"HOST_WIDE_INT_PRINT_UNSIGNED"\n",\
402            (SIZE));
403
404 /* This says how to output an assembler line to define a global common
405    symbol. We need the alignment information because it has to be supplied
406    in the section header.  */ 
407
408 #undef ASM_OUTPUT_COMMON
409 #define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)      \
410   unicosmk_output_common ((FILE), (NAME), (SIZE), (ALIGN))
411
412 /* This says how to output an assembler line to define a local symbol.  */
413
414 #undef ASM_OUTPUT_LOCAL
415 #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
416   do { data_section ();                                 \
417        fprintf (FILE, "\t.align\t%d\n", floor_log2 ((ALIGN) / BITS_PER_UNIT));\
418        ASM_OUTPUT_LABEL ((FILE), (NAME));               \
419        fprintf (FILE, "\t.byte 0:"HOST_WIDE_INT_PRINT_UNSIGNED"\n",(SIZE));\
420   } while (0)
421
422 /* CAM does not allow us to declare a symbol as external first and then
423    define it in the same file later. Thus, we keep a list of all external
424    references, remove all symbols defined locally from it and output it at
425    the end of the asm file.  */
426    
427 #define ASM_OUTPUT_EXTERNAL(FILE,DECL,NAME) \
428   unicosmk_add_extern ((NAME))
429
430 #define ASM_OUTPUT_EXTERNAL_LIBCALL(STREAM,SYMREF)      \
431   unicosmk_add_extern (XSTR ((SYMREF), 0))
432
433 /* This is how to declare an object. We don't have to output anything if
434    it is a global variable because those go into unique `common' sections
435    and the section name is globally visible. For local variables, we simply
436    output the label. In any case, we have to record that no extern
437    declaration should be generated for the symbol.  */
438
439 #define ASM_DECLARE_OBJECT_NAME(STREAM,NAME,DECL)       \
440   do { tree name_tree;                                  \
441        name_tree = get_identifier ((NAME));             \
442        TREE_ASM_WRITTEN (name_tree) = 1;                \
443        if (!TREE_PUBLIC (DECL))                         \
444          {                                              \
445            assemble_name (STREAM, NAME);                \
446            fputs (":\n", STREAM);                       \
447          }                                              \
448   } while(0)
449
450 /* Switch into a generic section.  */
451 #define TARGET_ASM_NAMED_SECTION unicosmk_asm_named_section
452
453 #undef ASM_OUTPUT_MAX_SKIP_ALIGN
454 #define ASM_OUTPUT_MAX_SKIP_ALIGN(STREAM,POWER,MAXSKIP)
455 \f
456 #undef NM_FLAGS
457
458 #undef OBJECT_FORMAT_COFF
459
460 /* We cannot generate debugging information on Unicos/Mk.  */
461
462 #undef SDB_DEBUGGING_INFO
463 #undef MIPS_DEBUGGING_INFO
464 #undef DBX_DEBUGGING_INFO
465 #undef DWARF2_DEBUGGING_INFO
466 #undef DWARF2_UNWIND_INFO
467 #undef INCOMING_RETURN_ADDR_RTX
468 #undef PREFERRED_DEBUGGING_TYPE
469
470 /* We don't need a start file.  */
471
472 #undef STARTFILE_SPEC
473 #define STARTFILE_SPEC ""
474
475 /* These are the libraries we have to link with.
476    ??? The Craylibs directory should be autoconfed.  */
477 #undef LIB_SPEC
478 #define LIB_SPEC "-L/opt/ctl/craylibs/craylibs -lu -lm -lc -lsma"
479
480 #undef EXPAND_BUILTIN_VA_START
481
482 #define EH_FRAME_IN_DATA_SECTION 1