OSDN Git Service

2006-03-01 Andrew Pinski <pinskia@physics.uc.edu>
[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, 2005
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, 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, 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 1
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) gcc_unreachable ()
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 /* There are no read-only sections on Unicos/Mk.  */
248
249 #undef READONLY_DATA_SECTION_ASM_OP
250
251 /* We take care of this in unicosmk_file_start.  */
252
253 #undef ASM_OUTPUT_SOURCE_FILENAME
254
255 /* This is how to output a label for a jump table.  Arguments are the same as
256    for (*targetm.asm_out.internal_label), except the insn for the jump table is
257    passed.  */
258
259 #undef ASM_OUTPUT_CASE_LABEL
260 #define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN)        \
261   (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM)
262
263 /* CAM has some restrictions with respect to string literals. It won't
264    accept lines with more that 256 characters which means that we have
265    to split long strings. Moreover, it only accepts escape sequences of
266    the form \nnn in the range 0 to 127. We generate .byte directives for
267    escapes characters greater than 127. And finally, ` must be escaped.  */
268
269 #undef ASM_OUTPUT_ASCII
270 #define ASM_OUTPUT_ASCII(MYFILE, MYSTRING, MYLENGTH) \
271   do {                                                                        \
272     FILE *_hide_asm_out_file = (MYFILE);                                      \
273     const unsigned char *_hide_p = (const unsigned char *) (MYSTRING);        \
274     int _hide_thissize = (MYLENGTH);                                          \
275     int _size_so_far = 0;                                                     \
276     {                                                                         \
277       FILE *asm_out_file = _hide_asm_out_file;                                \
278       const unsigned char *p = _hide_p;                                       \
279       int thissize = _hide_thissize;                                          \
280       int in_ascii = 0;                                                       \
281       int i;                                                                  \
282                                                                               \
283       for (i = 0; i < thissize; i++)                                          \
284         {                                                                     \
285           register int c = p[i];                                              \
286                                                                               \
287           if (c > 127)                                                        \
288             {                                                                 \
289               if (in_ascii)                                                   \
290                 {                                                             \
291                   fprintf (asm_out_file, "\"\n");                             \
292                   in_ascii = 0;                                               \
293                 }                                                             \
294                                                                               \
295               fprintf (asm_out_file, "\t.byte\t%d\n", c);                     \
296             }                                                                 \
297           else                                                                \
298             {                                                                 \
299               if (! in_ascii)                                                 \
300                 {                                                             \
301                   fprintf (asm_out_file, "\t.ascii\t\"");                     \
302                   in_ascii = 1;                                               \
303                   _size_so_far = 0;                                           \
304                 }                                                             \
305               else if (_size_so_far >= 64)                                    \
306                 {                                                             \
307                   fprintf (asm_out_file, "\"\n\t.ascii\t\"");                 \
308                   _size_so_far = 0;                                           \
309                 }                                                             \
310                                                                               \
311               if (c == '\"' || c == '\\' || c == '`')                         \
312                 putc ('\\', asm_out_file);                                    \
313               if (c >= ' ')                                                   \
314                 putc (c, asm_out_file);                                       \
315               else                                                            \
316                 fprintf (asm_out_file, "\\%.3o", c);                          \
317               ++ _size_so_far;                                                \
318             }                                                                 \
319         }                                                                     \
320       if (in_ascii)                                                           \
321         fprintf (asm_out_file, "\"\n");                                       \
322     }                                                                         \
323   } while(0)
324
325 /* This is how to output an element of a case-vector that is absolute.  */
326
327 #undef ASM_OUTPUT_ADDR_VEC_ELT
328 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)    \
329   fprintf (FILE, "\t.quad $L%d\n", (VALUE))
330
331 /* This is how to output an element of a case-vector that is relative.
332    (Unicos/Mk does not use such vectors yet).  */
333
334 #undef ASM_OUTPUT_ADDR_DIFF_ELT
335 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) gcc_unreachable ()
336
337 /* We can't output case vectors in the same section as the function code
338    because CAM doesn't allow data definitions in code sections. Thus, we
339    simply record the case vectors and put them in a separate section after
340    the function.  */
341
342 #define ASM_OUTPUT_ADDR_VEC(LAB,VEC) \
343   unicosmk_defer_case_vector ((LAB),(VEC))
344
345 #define ASM_OUTPUT_ADDR_DIFF_VEC(LAB,VEC) gcc_unreachable ()
346
347 /* This is how to output an assembler line that says to advance the location
348    counter to a multiple of 2**LOG bytes. Annoyingly, CAM always uses zeroes
349    to fill the unused space which does not work in code sections. We have to 
350    be careful not to use the .align directive in code sections.  */
351
352 #undef ASM_OUTPUT_ALIGN
353 #define ASM_OUTPUT_ALIGN(STREAM,LOG) unicosmk_output_align (STREAM, LOG)
354
355 /* This is how to advance the location counter by SIZE bytes.  */
356
357 #undef ASM_OUTPUT_SKIP
358 #define ASM_OUTPUT_SKIP(STREAM,SIZE)                    \
359   fprintf ((STREAM), "\t.byte\t0:"HOST_WIDE_INT_PRINT_UNSIGNED"\n",\
360            (SIZE));
361
362 /* This says how to output an assembler line to define a global common
363    symbol. We need the alignment information because it has to be supplied
364    in the section header.  */ 
365
366 #undef ASM_OUTPUT_COMMON
367 #define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)      \
368   unicosmk_output_common ((FILE), (NAME), (SIZE), (ALIGN))
369
370 /* This says how to output an assembler line to define a local symbol.  */
371
372 #undef ASM_OUTPUT_LOCAL
373 #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
374   do { switch_to_section (data_section);                \
375        fprintf (FILE, "\t.align\t%d\n", floor_log2 ((ALIGN) / BITS_PER_UNIT));\
376        ASM_OUTPUT_LABEL ((FILE), (NAME));               \
377        fprintf (FILE, "\t.byte 0:"HOST_WIDE_INT_PRINT_UNSIGNED"\n",(SIZE));\
378   } while (0)
379
380 /* CAM does not allow us to declare a symbol as external first and then
381    define it in the same file later. Thus, we keep a list of all external
382    references, remove all symbols defined locally from it and output it at
383    the end of the asm file.  */
384    
385 #define ASM_OUTPUT_EXTERNAL(FILE,DECL,NAME) \
386   unicosmk_add_extern ((NAME))
387
388 #define ASM_OUTPUT_EXTERNAL_LIBCALL(STREAM,SYMREF)      \
389   unicosmk_add_extern (XSTR ((SYMREF), 0))
390
391 /* This is how to declare an object. We don't have to output anything if
392    it is a global variable because those go into unique `common' sections
393    and the section name is globally visible. For local variables, we simply
394    output the label. In any case, we have to record that no extern
395    declaration should be generated for the symbol.  */
396
397 #define ASM_DECLARE_OBJECT_NAME(STREAM,NAME,DECL)       \
398   do { tree name_tree;                                  \
399        name_tree = get_identifier ((NAME));             \
400        TREE_ASM_WRITTEN (name_tree) = 1;                \
401        if (!TREE_PUBLIC (DECL))                         \
402          {                                              \
403            assemble_name (STREAM, NAME);                \
404            fputs (":\n", STREAM);                       \
405          }                                              \
406   } while(0)
407
408 /* Switch into a generic section.  */
409 #define TARGET_ASM_NAMED_SECTION unicosmk_asm_named_section
410 #define TARGET_ASM_INIT_SECTIONS unicosmk_init_sections
411
412 #undef ASM_OUTPUT_MAX_SKIP_ALIGN
413 #define ASM_OUTPUT_MAX_SKIP_ALIGN(STREAM,POWER,MAXSKIP)
414 \f
415 #undef NM_FLAGS
416
417 #undef OBJECT_FORMAT_COFF
418
419 /* We cannot generate debugging information on Unicos/Mk.  */
420
421 #undef SDB_DEBUGGING_INFO
422 #undef MIPS_DEBUGGING_INFO
423 #undef DBX_DEBUGGING_INFO
424 #undef DWARF2_DEBUGGING_INFO
425 #undef DWARF2_UNWIND_INFO
426 #undef INCOMING_RETURN_ADDR_RTX
427 #undef PREFERRED_DEBUGGING_TYPE
428
429 /* We don't need a start file.  */
430
431 #undef STARTFILE_SPEC
432 #define STARTFILE_SPEC ""
433
434 /* These are the libraries we have to link with.
435    ??? The Craylibs directory should be autoconfed.  */
436 #undef LIB_SPEC
437 #define LIB_SPEC "-L/opt/ctl/craylibs/craylibs -lu -lm -lc -lsma"
438
439 #undef EXPAND_BUILTIN_VA_START
440
441 #define EH_FRAME_IN_DATA_SECTION 1