OSDN Git Service

* config/alpha/alpha-protos.h, config/alpha/elf.h,
[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
4    Free Software Foundation, Inc.
5    Contributed by Roman Lechtchinsky (rl@cs.tu-berlin.de)
6
7 This file is part of GNU CC.
8
9 GNU CC 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 GNU CC 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 GNU CC; 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 /* This evaluates to nonzero if we do not know how to pass TYPE solely in
128    registers. This is the case for all arguments that do not fit in two
129    registers.  */
130
131 #define MUST_PASS_IN_STACK(MODE,TYPE)                                   \
132   ((TYPE) != 0                                                          \
133    && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST                      \
134        || (TREE_ADDRESSABLE (TYPE) || ALPHA_ARG_SIZE (MODE, TYPE, 0) > 2)))
135
136 /* Define a data type for recording info about an argument list
137    during the scan of that argument list.  This data type should
138    hold all necessary information about the function itself
139    and about the args processed so far, enough to enable macros
140    such as FUNCTION_ARG to determine where the next arg should go.
141
142    On Unicos/Mk, this is a structure that contains various information for
143    the static subroutine information block (SSIB) and the call information
144    word (CIW).  */
145
146 typedef struct {
147
148   /* The overall number of arguments.  */
149   int num_args;
150
151   /* The overall size of the arguments in words.  */
152   int num_arg_words;
153
154   /* The number of words passed in registers.  */
155   int num_reg_words;
156
157   /* If an argument must be passed in the stack, all subsequent arguments
158      must be passed there, too. This flag indicates whether this is the
159      case.  */
160   int force_stack;
161
162   /* This array indicates whether a word is passed in an integer register or
163      a floating point one.  */
164
165   /* For each of the 6 register arguments, the corresponding flag in this
166      array indicates whether the argument is passed in an integer or a
167      floating point register.  */
168   int reg_args_type[6];
169
170 } unicosmk_arg_info;
171
172 #undef CUMULATIVE_ARGS
173 #define CUMULATIVE_ARGS unicosmk_arg_info
174
175 /* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a
176    function whose data type is FNTYPE.  For a library call, FNTYPE is 0.  */
177
178 #undef INIT_CUMULATIVE_ARGS
179 #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT)       \
180   do { (CUM).num_args = 0;                                      \
181        (CUM).num_arg_words = 0;                                 \
182        (CUM).num_reg_words = 0;                                 \
183        (CUM).force_stack = 0;                                   \
184   } while(0)
185
186 /* Update the data in CUM to advance over an argument of mode MODE and data
187    type TYPE. (TYPE is null for libcalls where that information may not be
188    available.)
189
190    On Unicos/Mk, at most 6 words can be passed in registers. Structures
191    which fit in two words are passed in registers, larger structures are
192    passed on stack.  */
193
194 #undef FUNCTION_ARG_ADVANCE
195 #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)            \
196 do {                                                            \
197   int size;                                                     \
198                                                                 \
199   size = ALPHA_ARG_SIZE (MODE, TYPE, NAMED);                    \
200                                                                 \
201   if (size > 2 || MUST_PASS_IN_STACK (MODE, TYPE)               \
202       || (CUM).num_reg_words + size > 6)                        \
203     (CUM).force_stack = 1;                                      \
204                                                                 \
205   if (! (CUM).force_stack)                                      \
206     {                                                           \
207       int i;                                                    \
208       int isfloat;                                              \
209       isfloat = (GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT    \
210               || GET_MODE_CLASS (MODE) == MODE_FLOAT);          \
211       for (i = 0; i < size; i++)                                \
212         {                                                       \
213           (CUM).reg_args_type[(CUM).num_reg_words] = isfloat;   \
214           ++(CUM).num_reg_words;                                \
215         }                                                       \
216     }                                                           \
217   (CUM).num_arg_words += size;                                  \
218   ++(CUM).num_args;                                             \
219 } while(0)
220
221 /* We want the default definition for this.
222    ??? In fact, we should delete the definition from alpha.h as it
223    corresponds to the default definition for little-endian machines.  */
224
225 #undef FUNCTION_ARG_PADDING
226
227 /* An argument is passed either entirely in registers or entirely on stack.  */
228  
229 #undef FUNCTION_ARG_PARTIAL_NREGS
230 /* #define FUNCTION_ARG_PARTIAL_NREGS(CUM,MODE,TYPE,NAMED) 0 */
231
232 /* Perform any needed actions needed for a function that is receiving a
233    variable number of arguments.
234
235    On Unicos/Mk, the standard subroutine __T3E_MISMATCH stores all register
236    arguments on the stack. Unfortunately, it doesn't always store the first
237    one (i.e. the one that arrives in $16 or $f16). This is not a problem
238    with stdargs as we always have at least one named argument there.  */
239
240 #undef SETUP_INCOMING_VARARGS
241 #define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL)       \
242 { if ((CUM).num_reg_words < 6)                                          \
243     {                                                                   \
244       if (! (NO_RTL))                                                   \
245         {                                                               \
246           int start = (CUM).num_reg_words + 1;                          \
247                                                                         \
248           emit_insn (gen_umk_mismatch_args (GEN_INT (start)));          \
249           emit_insn (gen_arg_home_umk ());                              \
250         }                                                               \
251                                                                         \
252       PRETEND_SIZE = 0;                                                 \
253     }                                                                   \
254 }
255
256 /* This ensures that $15 increments/decrements in leaf functions won't get
257    eliminated.  */
258
259 #undef EPILOGUE_USES
260 #define EPILOGUE_USES(REGNO)  ((REGNO) == 26 || (REGNO) == 15)
261
262 /* Would have worked, only the stack doesn't seem to be executable
263 #undef TRAMPOLINE_TEMPLATE
264 #define TRAMPOLINE_TEMPLATE(FILE)                       \
265 do { fprintf (FILE, "\tbr $1,0\n");                     \
266      fprintf (FILE, "\tldq $0,12($1)\n");               \
267      fprintf (FILE, "\tldq $1,20($1)\n");               \
268      fprintf (FILE, "\tjmp $31,(r0)\n");                \
269      fprintf (FILE, "\tbis $31,$31,$31\n");             \
270      fprintf (FILE, "\tbis $31,$31,$31\n");             \
271 } while (0) */
272
273 /* We don't support nested functions (yet).  */
274
275 #undef TRAMPOLINE_TEMPLATE
276 #define TRAMPOLINE_TEMPLATE(FILE) abort ()
277 \f
278 /* Specify the machine mode that this machine uses for the index in the
279    tablejump instruction. On Unicos/Mk, we don't support relative case
280    vectors yet, thus the entries should be absolute addresses.  */ 
281
282 #undef CASE_VECTOR_MODE
283 #define CASE_VECTOR_MODE DImode
284
285 #undef CASE_VECTOR_PC_RELATIVE
286
287 /* Define this as 1 if `char' should by default be signed; else as 0.  */
288 /* #define DEFAULT_SIGNED_CHAR 1 */
289
290 /* The Cray assembler is really weird with respect to sections. It has only
291    named sections and you can't reopen a section once it has been closed.
292    This means that we have to generate unique names whenever we want to
293    reenter the text or the data section. The following is a rather bad hack
294    as TEXT_SECTION_ASM_OP and DATA_SECTION_ASM_OP are supposed to be
295    constants.  */
296
297 #undef TEXT_SECTION_ASM_OP
298 #define TEXT_SECTION_ASM_OP unicosmk_text_section ()
299
300 #undef DATA_SECTION_ASM_OP
301 #define DATA_SECTION_ASM_OP unicosmk_data_section ()
302
303 /* There are no read-only sections on Unicos/Mk.  */
304
305 #undef READONLY_DATA_SECTION_ASM_OP
306 #define READONLY_DATA_SECTION data_section
307
308 /* Define extra sections for common data and SSIBs (static subroutine
309    information blocks). The actual section header is output by the callers
310    of these functions.  */
311
312 #undef EXTRA_SECTIONS
313 #undef EXTRA_SECTION_FUNCTIONS
314
315 #define EXTRA_SECTIONS in_common, in_ssib
316 #define EXTRA_SECTION_FUNCTIONS \
317 COMMON_SECTION                  \
318 SSIB_SECTION    
319
320 extern void common_section (void);
321 #define COMMON_SECTION          \
322 void                            \
323 common_section ()               \
324 {                               \
325   in_section = in_common;       \
326 }
327
328 extern void ssib_section (void);
329 #define SSIB_SECTION            \
330 void                            \
331 ssib_section ()                 \
332 {                               \
333   in_section = in_ssib;         \
334 }
335
336 /* This outputs text to go at the start of an assembler file.  */
337
338 #undef ASM_FILE_START
339 #define ASM_FILE_START(FILE)    unicosmk_asm_file_start (FILE)
340
341 /* This outputs text to go at the end of an assembler file.  */
342
343 #define TARGET_ASM_FILE_END     unicosmk_file_end
344
345 /* We take care of that in ASM_FILE_START.  */
346
347 #undef ASM_OUTPUT_SOURCE_FILENAME
348
349 /* This is how to output a label for a jump table.  Arguments are the same as
350    for (*targetm.asm_out.internal_label), except the insn for the jump table is
351    passed.  */
352
353 #undef ASM_OUTPUT_CASE_LABEL
354 #define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN)        \
355   (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM)
356
357 /* CAM has some restrictions with respect to string literals. It won't
358    accept lines with more that 256 characters which means that we have
359    to split long strings. Moreover, it only accepts escape sequences of
360    the form \nnn in the range 0 to 127. We generate .byte directives for
361    escapes characters greater than 127. And finally, ` must be escaped.  */
362
363 #undef ASM_OUTPUT_ASCII
364 #define ASM_OUTPUT_ASCII(MYFILE, MYSTRING, MYLENGTH) \
365   do {                                                                        \
366     FILE *_hide_asm_out_file = (MYFILE);                                      \
367     const unsigned char *_hide_p = (const unsigned char *) (MYSTRING);        \
368     int _hide_thissize = (MYLENGTH);                                          \
369     int _size_so_far = 0;                                                     \
370     {                                                                         \
371       FILE *asm_out_file = _hide_asm_out_file;                                \
372       const unsigned char *p = _hide_p;                                       \
373       int thissize = _hide_thissize;                                          \
374       int in_ascii = 0;                                                       \
375       int i;                                                                  \
376                                                                               \
377       for (i = 0; i < thissize; i++)                                          \
378         {                                                                     \
379           register int c = p[i];                                              \
380                                                                               \
381           if (c > 127)                                                        \
382             {                                                                 \
383               if (in_ascii)                                                   \
384                 {                                                             \
385                   fprintf (asm_out_file, "\"\n");                             \
386                   in_ascii = 0;                                               \
387                 }                                                             \
388                                                                               \
389               fprintf (asm_out_file, "\t.byte\t%d\n", c);                     \
390             }                                                                 \
391           else                                                                \
392             {                                                                 \
393               if (! in_ascii)                                                 \
394                 {                                                             \
395                   fprintf (asm_out_file, "\t.ascii\t\"");                     \
396                   in_ascii = 1;                                               \
397                   _size_so_far = 0;                                           \
398                 }                                                             \
399               else if (_size_so_far >= 64)                                    \
400                 {                                                             \
401                   fprintf (asm_out_file, "\"\n\t.ascii\t\"");                 \
402                   _size_so_far = 0;                                           \
403                 }                                                             \
404                                                                               \
405               if (c == '\"' || c == '\\' || c == '`')                         \
406                 putc ('\\', asm_out_file);                                    \
407               if (c >= ' ')                                                   \
408                 putc (c, asm_out_file);                                       \
409               else                                                            \
410                 fprintf (asm_out_file, "\\%.3o", c);                          \
411               ++ _size_so_far;                                                \
412             }                                                                 \
413         }                                                                     \
414       if (in_ascii)                                                           \
415         fprintf (asm_out_file, "\"\n");                                       \
416     }                                                                         \
417   } while(0)
418
419 /* This is how to output an element of a case-vector that is absolute.  */
420
421 #undef ASM_OUTPUT_ADDR_VEC_ELT
422 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)    \
423   fprintf (FILE, "\t.quad $L%d\n", (VALUE))
424
425 /* This is how to output an element of a case-vector that is relative.
426    (Unicos/Mk does not use such vectors yet).  */
427
428 #undef ASM_OUTPUT_ADDR_DIFF_ELT
429 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) abort ()
430
431 /* We can't output case vectors in the same section as the function code
432    because CAM doesn't allow data definitions in code sections. Thus, we
433    simply record the case vectors and put them in a separate section after
434    the function.  */
435
436 #define ASM_OUTPUT_ADDR_VEC(LAB,VEC) \
437   unicosmk_defer_case_vector ((LAB),(VEC))
438
439 #define ASM_OUTPUT_ADDR_DIFF_VEC(LAB,VEC) abort ()
440
441 /* This is how to output an assembler line that says to advance the location
442    counter to a multiple of 2**LOG bytes. Annoyingly, CAM always uses zeroes
443    to fill the unused space which does not work in code sections. We have to 
444    be careful not to use the .align directive in code sections.  */
445
446 #undef ASM_OUTPUT_ALIGN
447 #define ASM_OUTPUT_ALIGN(STREAM,LOG) unicosmk_output_align (STREAM, LOG)
448
449 /* This is how to advance the location counter by SIZE bytes.  */
450
451 #undef ASM_OUTPUT_SKIP
452 #define ASM_OUTPUT_SKIP(STREAM,SIZE)                    \
453   fprintf ((STREAM), "\t.byte\t0:"HOST_WIDE_INT_PRINT_UNSIGNED"\n",\
454            (SIZE));
455
456 /* This says how to output an assembler line to define a global common
457    symbol. We need the alignment information because it has to be supplied
458    in the section header.  */ 
459
460 #undef ASM_OUTPUT_COMMON
461 #define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)      \
462   unicosmk_output_common ((FILE), (NAME), (SIZE), (ALIGN))
463
464 /* This says how to output an assembler line to define a local symbol.  */
465
466 #undef ASM_OUTPUT_LOCAL
467 #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
468   do { data_section ();                                 \
469        fprintf (FILE, "\t.align\t%d\n", floor_log2 ((ALIGN) / BITS_PER_UNIT));\
470        ASM_OUTPUT_LABEL ((FILE), (NAME));               \
471        fprintf (FILE, "\t.byte 0:"HOST_WIDE_INT_PRINT_UNSIGNED"\n",(SIZE));\
472   } while (0)
473
474 /* CAM does not allow us to declare a symbol as external first and then
475    define it in the same file later. Thus, we keep a list of all external
476    references, remove all symbols defined locally from it and output it at
477    the end of the asm file.  */
478    
479 #define ASM_OUTPUT_EXTERNAL(FILE,DECL,NAME) \
480   unicosmk_add_extern ((NAME))
481
482 #define ASM_OUTPUT_EXTERNAL_LIBCALL(STREAM,SYMREF)      \
483   unicosmk_add_extern (XSTR ((SYMREF), 0))
484
485 /* This is how to declare an object. We don't have to output anything if
486    it is a global variable because those go into unique `common' sections
487    and the section name is globally visible. For local variables, we simply
488    output the label. In any case, we have to record that no extern
489    declaration should be generated for the symbol.  */
490
491 #define ASM_DECLARE_OBJECT_NAME(STREAM,NAME,DECL)       \
492   do { tree name_tree;                                  \
493        name_tree = get_identifier ((NAME));             \
494        TREE_ASM_WRITTEN (name_tree) = 1;                \
495        if (!TREE_PUBLIC (DECL))                         \
496          {                                              \
497            assemble_name (STREAM, NAME);                \
498            fputs (":\n", STREAM);                       \
499          }                                              \
500   } while(0)
501
502 /*
503 #define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC)      \
504   unicosmk_output_section_name ((STREAM), (DECL), (NAME), (RELOC))
505 */
506
507 /* Switch into a generic section.  */
508 #define TARGET_ASM_NAMED_SECTION unicosmk_asm_named_section
509
510 #undef ASM_OUTPUT_MAX_SKIP_ALIGN
511 #define ASM_OUTPUT_MAX_SKIP_ALIGN(STREAM,POWER,MAXSKIP)
512 \f
513 #undef NM_FLAGS
514
515 #undef OBJECT_FORMAT_COFF
516
517 /* We cannot generate debugging information on Unicos/Mk.  */
518
519 #undef SDB_DEBUGGING_INFO
520 #undef MIPS_DEBUGGING_INFO
521 #undef DBX_DEBUGGING_INFO
522 #undef DWARF_DEBUGGING_INFO
523 #undef DWARF2_DEBUGGING_INFO
524 #undef DWARF2_UNWIND_INFO
525 #undef INCOMING_RETURN_ADDR_RTX
526
527
528 /* We use the functions provided by the system library for integer
529    division.  */
530
531 #undef UDIVDI3_LIBCALL
532 #undef DIVDI3_LIBCALL
533 #define UDIVDI3_LIBCALL "$uldiv"
534 #define DIVDI3_LIBCALL "$sldiv"
535
536 /* This is necessary to prevent gcc from generating calls to __divsi3.  */
537
538 #define INIT_TARGET_OPTABS                                      \
539   do {                                                          \
540     sdiv_optab->handlers[(int) SImode].libfunc = NULL_RTX;      \
541     udiv_optab->handlers[(int) SImode].libfunc = NULL_RTX;      \
542   } while (0)
543
544 #undef ASM_OUTPUT_SOURCE_LINE
545
546 /* We don't need a start file.  */
547
548 #undef STARTFILE_SPEC
549 #define STARTFILE_SPEC ""
550
551 /* These are the libraries we have to link with.
552    ??? The Craylibs directory should be autoconfed.  */
553 #undef LIB_SPEC
554 #define LIB_SPEC "-L/opt/ctl/craylibs/craylibs -lu -lm -lc -lsma"
555
556 #undef BUILD_VA_LIST_TYPE
557 #undef EXPAND_BUILTIN_VA_START
558 #undef EXPAND_BUILTIN_VA_ARG
559
560 #define EH_FRAME_IN_DATA_SECTION 1