* config/alpha/unicosmk.h (TARGET_OS_CPP_BUILTINS): Fix typo.
[official-gcc.git] / gcc / config / alpha / unicosmk.h
blob4be7be537f1f50e763c1727e1c2a0266cddcd343
1 /* Definitions of target machine for GNU compiler, for DEC Alpha on Cray
2 T3E running Unicos/Mk.
3 Copyright (C) 2001
4 Free Software Foundation, Inc.
5 Contributed by Roman Lechtchinsky (rl@cs.tu-berlin.de)
7 This file is part of GNU CC.
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.
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.
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. */
24 #undef TARGET_ABI_UNICOSMK
25 #define TARGET_ABI_UNICOSMK 1
27 /* CAM requires a slash before floating-pointing instruction suffixes. */
29 #undef TARGET_AS_SLASH_BEFORE_SUFFIX
30 #define TARGET_AS_SLASH_BEFORE_SUFFIX 1
32 /* The following defines are necessary for the standard headers to work
33 correctly. */
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 builtin_define ("__INT_MAX__=9223372036854775807"); \
47 builtin_define ("__SHRT_MAX__=2147483647"); \
48 } while (0)
50 #define SHORT_TYPE_SIZE 32
52 #undef INT_TYPE_SIZE
53 #define INT_TYPE_SIZE 64
55 /* This is consistent with the definition Cray CC uses. */
56 #undef WCHAR_TYPE
57 #define WCHAR_TYPE "int"
58 #undef WCHAR_TYPE_SIZE
59 #define WCHAR_TYPE_SIZE 64
62 #define SIZE_TYPE "unsigned int"
63 #define PTRDIFF_TYPE "int"
66 /* Alphas are operated in big endian mode on the Cray T3E. */
68 #undef BITS_BIG_ENDIAN
69 #undef BYTES_BIG_ENDIAN
70 #undef WORDS_BIG_ENDIAN
71 #define BITS_BIG_ENDIAN 0
72 #define BYTES_BIG_ENDIAN 1
73 #define WORDS_BIG_ENDIAN 1
76 /* Every structure's size must be a multiple of this. */
78 #undef STRUCTURE_SIZE_BOUNDARY
79 #define STRUCTURE_SIZE_BOUNDARY 64
81 /* No data type wants to be aligned rounder than this. */
83 #undef BIGGEST_ALIGNMENT
84 #define BIGGEST_ALIGNMENT 256
86 /* Include the frame pointer in fixed_regs and call_used_regs as it can't be
87 used as a general-purpose register even in frameless functions.
88 ??? The global_regs hack is needed for now because -O2 sometimes tries to
89 eliminate $15 increments/decrements in frameless functions. */
91 #undef CONDITIONAL_REGISTER_USAGE
92 #define CONDITIONAL_REGISTER_USAGE \
93 do { \
94 fixed_regs[15] = 1; \
95 call_used_regs[15] = 1; \
96 global_regs[15] = 1; \
97 } while(0)
99 /* The stack frame grows downward. */
101 #define FRAME_GROWS_DOWNWARD
103 /* Define the offset between two registers, one to be eliminated, and the
104 other its replacement, at the start of a routine. This is somewhat
105 complicated on the T3E which is why we use a function. */
107 extern int unicosmk_initial_elimination_offset PARAMS ((int, int));
109 #undef INITIAL_ELIMINATION_OFFSET
110 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
111 do { \
112 (OFFSET) = unicosmk_initial_elimination_offset ((FROM), (TO)); \
113 } while (0)
116 /* Define this if stack space is still allocated for a parameter passed
117 in a register. On the T3E, stack space is preallocated for all outgoing
118 arguments, including those passed in registers. To avoid problems, we
119 assume that at least 48 bytes (i.e. enough space for all arguments passed
120 in registers) are allocated. */
122 #define REG_PARM_STACK_SPACE(DECL) 48
123 #define OUTGOING_REG_PARM_STACK_SPACE
125 /* If an argument can't be passed in registers even though not all argument
126 registers have been used yet, it is passed on the stack in the space
127 preallocated for these registers. */
129 #define STACK_PARMS_IN_REG_PARM_AREA
131 /* This evaluates to nonzero if we do not know how to pass TYPE solely in
132 registers. This is the case for all arguments that do not fit in two
133 registers. */
135 #define MUST_PASS_IN_STACK(MODE,TYPE) \
136 ((TYPE) != 0 \
137 && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST \
138 || (TREE_ADDRESSABLE (TYPE) || ALPHA_ARG_SIZE (MODE, TYPE, 0) > 2)))
140 /* Define a data type for recording info about an argument list
141 during the scan of that argument list. This data type should
142 hold all necessary information about the function itself
143 and about the args processed so far, enough to enable macros
144 such as FUNCTION_ARG to determine where the next arg should go.
146 On Unicos/Mk, this is a structure that contains various information for
147 the static subroutine information block (SSIB) and the call information
148 word (CIW). */
150 typedef struct {
152 /* The overall number of arguments. */
153 int num_args;
155 /* The overall size of the arguments in words. */
156 int num_arg_words;
158 /* The number of words passed in registers. */
159 int num_reg_words;
161 /* If an argument must be passed in the stack, all subsequent arguments
162 must be passed there, too. This flag indicates whether this is the
163 case. */
164 int force_stack;
166 /* This array indicates whether a word is passed in an integer register or
167 a floating point one. */
169 /* For each of the 6 register arguments, the corresponding flag in this
170 array indicates whether the argument is passed in an integer or a
171 floating point register. */
172 int reg_args_type[6];
174 } unicosmk_arg_info;
176 #undef CUMULATIVE_ARGS
177 #define CUMULATIVE_ARGS unicosmk_arg_info
179 /* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a
180 function whose data type is FNTYPE. For a library call, FNTYPE is 0. */
182 #undef INIT_CUMULATIVE_ARGS
183 #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
184 do { (CUM).num_args = 0; \
185 (CUM).num_arg_words = 0; \
186 (CUM).num_reg_words = 0; \
187 (CUM).force_stack = 0; \
188 } while(0)
190 /* Update the data in CUM to advance over an argument of mode MODE and data
191 type TYPE. (TYPE is null for libcalls where that information may not be
192 available.)
194 On Unicos/Mk, at most 6 words can be passed in registers. Structures
195 which fit in two words are passed in registers, larger structures are
196 passed on stack. */
198 #undef FUNCTION_ARG_ADVANCE
199 #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
200 do { \
201 int size; \
203 size = ALPHA_ARG_SIZE (MODE, TYPE, NAMED); \
205 if (size > 2 || MUST_PASS_IN_STACK (MODE, TYPE) \
206 || (CUM).num_reg_words + size > 6) \
207 (CUM).force_stack = 1; \
209 if (! (CUM).force_stack) \
211 int i; \
212 int isfloat; \
213 isfloat = (GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \
214 || GET_MODE_CLASS (MODE) == MODE_FLOAT); \
215 for (i = 0; i < size; i++) \
217 (CUM).reg_args_type[(CUM).num_reg_words] = isfloat; \
218 ++(CUM).num_reg_words; \
221 (CUM).num_arg_words += size; \
222 ++(CUM).num_args; \
223 } while(0)
225 /* We want the default definition for this.
226 ??? In fact, we should delete the definition from alpha.h as it
227 corresponds to the default definition for little-endian machines. */
229 #undef FUNCTION_ARG_PADDING
231 /* An argument is passed either entirely in registers or entirely on stack. */
233 #undef FUNCTION_ARG_PARTIAL_NREGS
234 /* #define FUNCTION_ARG_PARTIAL_NREGS(CUM,MODE,TYPE,NAMED) 0 */
236 /* Perform any needed actions needed for a function that is receiving a
237 variable number of arguments.
239 On Unicos/Mk, the standard subroutine __T3E_MISMATCH stores all register
240 arguments on the stack. Unfortunately, it doesn't always store the first
241 one (i.e. the one that arrives in $16 or $f16). This is not a problem
242 with stdargs as we always have at least one named argument there. This is
243 not always the case when varargs.h is used, however. In such cases, we
244 have to store the first argument ourselves. We use the information from
245 the CIW to determine whether the first argument arrives in $16 or $f16. */
247 #undef SETUP_INCOMING_VARARGS
248 #define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
249 { if ((CUM).num_reg_words < 6) \
251 if (! (NO_RTL)) \
253 int start; \
255 start = (CUM).num_reg_words; \
256 if (!current_function_varargs || start == 0) \
257 ++start; \
259 emit_insn (gen_umk_mismatch_args (GEN_INT (start))); \
260 if (current_function_varargs && (CUM).num_reg_words == 0) \
262 rtx tmp; \
263 rtx int_label, end_label; \
265 tmp = gen_reg_rtx (DImode); \
266 emit_move_insn (tmp, \
267 gen_rtx_ZERO_EXTRACT (DImode, \
268 gen_rtx_REG (DImode, 2),\
269 (GEN_INT (1)), \
270 (GEN_INT (7)))); \
271 int_label = gen_label_rtx (); \
272 end_label = gen_label_rtx (); \
273 emit_insn (gen_cmpdi (tmp, GEN_INT (0))); \
274 emit_jump_insn (gen_beq (int_label)); \
275 emit_move_insn (gen_rtx_MEM (DFmode, virtual_incoming_args_rtx),\
276 gen_rtx_REG (DFmode, 48)); \
277 emit_jump (end_label); \
278 emit_label (int_label); \
279 emit_move_insn (gen_rtx_MEM (DImode, virtual_incoming_args_rtx),\
280 gen_rtx_REG (DImode, 16)); \
281 emit_label (end_label); \
283 emit_insn (gen_arg_home_umk ()); \
286 PRETEND_SIZE = 0; \
290 /* This ensures that $15 increments/decrements in leaf functions won't get
291 eliminated. */
293 #undef EPILOGUE_USES
294 #define EPILOGUE_USES(REGNO) ((REGNO) == 26 || (REGNO) == 15)
296 /* Machine-specific function data. */
298 struct machine_function
300 /* List of call information words for calls from this function. */
301 struct rtx_def *first_ciw;
302 struct rtx_def *last_ciw;
303 int ciw_count;
305 /* List of deferred case vectors. */
306 struct rtx_def *addr_list;
309 /* Would have worked, only the stack doesn't seem to be executable
310 #undef TRAMPOLINE_TEMPLATE
311 #define TRAMPOLINE_TEMPLATE(FILE) \
312 do { fprintf (FILE, "\tbr $1,0\n"); \
313 fprintf (FILE, "\tldq $0,12($1)\n"); \
314 fprintf (FILE, "\tldq $1,20($1)\n"); \
315 fprintf (FILE, "\tjmp $31,(r0)\n"); \
316 fprintf (FILE, "\tbis $31,$31,$31\n"); \
317 fprintf (FILE, "\tbis $31,$31,$31\n"); \
318 } while (0) */
320 /* We don't support nested functions (yet). */
322 #undef TRAMPOLINE_TEMPLATE
323 #define TRAMPOLINE_TEMPLATE(FILE) abort ()
325 /* Specify the machine mode that this machine uses for the index in the
326 tablejump instruction. On Unicos/Mk, we don't support relative case
327 vectors yet, thus the entries should be absolute addresses. */
329 #undef CASE_VECTOR_MODE
330 #define CASE_VECTOR_MODE DImode
332 #undef CASE_VECTOR_PC_RELATIVE
334 /* Define this as 1 if `char' should by default be signed; else as 0. */
335 /* #define DEFAULT_SIGNED_CHAR 1 */
337 /* The Cray assembler is really weird with respect to sections. It has only
338 named sections and you can't reopen a section once it has been closed.
339 This means that we have to generate unique names whenever we want to
340 reenter the text or the data section. The following is a rather bad hack
341 as TEXT_SECTION_ASM_OP and DATA_SECTION_ASM_OP are supposed to be
342 constants. */
344 #undef TEXT_SECTION_ASM_OP
345 #define TEXT_SECTION_ASM_OP unicosmk_text_section ()
347 #undef DATA_SECTION_ASM_OP
348 #define DATA_SECTION_ASM_OP unicosmk_data_section ()
350 /* There are ni read-only sections on Unicos/Mk. */
352 #undef READONLY_DATA_SECTION
353 #define READONLY_DATA_SECTION data_section
355 /* Define extra sections for common data and SSIBs (static subroutine
356 information blocks). The actual section header is output by the callers
357 of these functions. */
359 #undef EXTRA_SECTIONS
360 #undef EXTRA_SECTION_FUNCTIONS
362 #define EXTRA_SECTIONS in_common, in_ssib
363 #define EXTRA_SECTION_FUNCTIONS \
364 COMMON_SECTION \
365 SSIB_SECTION
367 extern void common_section PARAMS ((void));
368 #define COMMON_SECTION \
369 void \
370 common_section () \
372 in_section = in_common; \
375 extern void ssib_section PARAMS ((void));
376 #define SSIB_SECTION \
377 void \
378 ssib_section () \
380 in_section = in_ssib; \
383 /* A C expression which evaluates to true if declshould be placed into a
384 unique section for some target-specific reason. On Unicos/Mk, functions
385 and public variables are always placed in unique sections. */
388 #define UNIQUE_SECTION_P(DECL) (TREE_PUBLIC (DECL) \
389 || TREE_CODE (DECL) == FUNCTION_DECL)
391 #define UNIQUE_SECTION(DECL, RELOC) unicosmk_unique_section (DECL, RELOC)
393 /* This outputs text to go at the start of an assembler file. */
395 #undef ASM_FILE_START
396 #define ASM_FILE_START(FILE) unicosmk_asm_file_start (FILE)
398 /* This outputs text to go at the end of an assembler file. */
400 #undef ASM_FILE_END
401 #define ASM_FILE_END(FILE) unicosmk_asm_file_end (FILE)
403 /* We take care of that in ASM_FILE_START. */
405 #undef ASM_OUTPUT_SOURCE_FILENAME
407 /* There is no directive for declaring a label as global. Instead, an
408 additional colon must be appended when the label is defined. */
410 #undef ASM_GLOBALIZE_LABEL
411 #define ASM_GLOBALIZE_LABEL(FILE,NAME)
413 /* This is how to output a label for a jump table. Arguments are the same as
414 for ASM_OUTPUT_INTERNAL_LABEL, except the insn for the jump table is
415 passed. */
417 #undef ASM_OUTPUT_CASE_LABEL
418 #define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \
419 ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM)
421 /* CAM has some restrictions with respect to string literals. It won't
422 accept lines with more that 256 characters which means that we have
423 to split long strings. Moreover, it only accepts escape sequences of
424 the form \nnn in the range 0 to 127. We generate .byte directives for
425 escapes characters greater than 127. And finally, ` must be escaped. */
427 #undef ASM_OUTPUT_ASCII
428 #define ASM_OUTPUT_ASCII(MYFILE, MYSTRING, MYLENGTH) \
429 do { \
430 FILE *_hide_asm_out_file = (MYFILE); \
431 const unsigned char *_hide_p = (const unsigned char *) (MYSTRING); \
432 int _hide_thissize = (MYLENGTH); \
433 int _size_so_far = 0; \
435 FILE *asm_out_file = _hide_asm_out_file; \
436 const unsigned char *p = _hide_p; \
437 int thissize = _hide_thissize; \
438 int in_ascii = 0; \
439 int i; \
441 for (i = 0; i < thissize; i++) \
443 register int c = p[i]; \
445 if (c > 127) \
447 if (in_ascii) \
449 fprintf (asm_out_file, "\"\n"); \
450 in_ascii = 0; \
453 fprintf (asm_out_file, "\t.byte\t%d\n", c); \
455 else \
457 if (! in_ascii) \
459 fprintf (asm_out_file, "\t.ascii\t\""); \
460 in_ascii = 1; \
461 _size_so_far = 0; \
463 else if (_size_so_far >= 64) \
465 fprintf (asm_out_file, "\"\n\t.ascii\t\""); \
466 _size_so_far = 0; \
469 if (c == '\"' || c == '\\' || c == '`') \
470 putc ('\\', asm_out_file); \
471 if (c >= ' ') \
472 putc (c, asm_out_file); \
473 else \
474 fprintf (asm_out_file, "\\%.3o", c); \
475 ++ _size_so_far; \
478 if (in_ascii) \
479 fprintf (asm_out_file, "\"\n"); \
481 } while(0)
483 /* This is how to output an element of a case-vector that is absolute. */
485 #undef ASM_OUTPUT_ADDR_VEC_ELT
486 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
487 fprintf (FILE, "\t.quad $L%d\n", (VALUE))
489 /* This is how to output an element of a case-vector that is relative.
490 (Unicos/Mk does not use such vectors yet). */
492 #undef ASM_OUTPUT_ADDR_DIFF_ELT
493 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) abort ()
495 /* We can't output case vectors in the same section as the function code
496 because CAM doesn't allow data definitions in code sections. Thus, we
497 simply record the case vectors and put them in a separate section after
498 the function. */
500 #define ASM_OUTPUT_ADDR_VEC(LAB,VEC) \
501 unicosmk_defer_case_vector ((LAB),(VEC))
503 #define ASM_OUTPUT_ADDR_DIFF_VEC(LAB,VEC) abort ()
505 /* This is how to output an assembler line that says to advance the location
506 counter to a multiple of 2**LOG bytes. Annoyingly, CAM always uses zeroes
507 to fill the unused space which does not work in code sections. We have to
508 be careful not to use the .align directive in code sections. */
510 #undef ASM_OUTPUT_ALIGN
511 #define ASM_OUTPUT_ALIGN(STREAM,LOG) unicosmk_output_align (STREAM, LOG)
513 /* This is how to advance the location counter by SIZE bytes. */
515 #undef ASM_OUTPUT_SKIP
516 #define ASM_OUTPUT_SKIP(STREAM,SIZE) \
517 fprintf ((STREAM), "\t.byte\t0:%d\n", (SIZE));
519 /* This says how to output an assembler line to define a global common
520 symbol. We need the alignment information because it has to be supplied
521 in the section header. */
523 #undef ASM_OUTPUT_COMMON
524 #define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
525 unicosmk_output_common ((FILE), (NAME), (SIZE), (ALIGN))
527 /* This says how to output an assembler line to define a local symbol. */
529 #undef ASM_OUTPUT_LOCAL
530 #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
531 do { data_section (); \
532 fprintf (FILE, "\t.align\t%d\n", floor_log2 ((ALIGN) / BITS_PER_UNIT));\
533 ASM_OUTPUT_LABEL ((FILE), (NAME)); \
534 fprintf (FILE, "\t.byte 0:%d\n", SIZE); \
535 } while (0)
537 /* CAM does not allow us to declare a symbol as external first and then
538 define it in the same file later. Thus, we keep a list of all external
539 references, remove all symbols defined locally from it and output it at
540 the end of the asm file. */
542 #define ASM_OUTPUT_EXTERNAL(FILE,DECL,NAME) \
543 unicosmk_add_extern ((NAME))
545 #define ASM_OUTPUT_EXTERNAL_LIBCALL(STREAM,SYMREF) \
546 unicosmk_add_extern (XSTR ((SYMREF), 0))
548 /* This is how to declare an object. We don't have to output anything if
549 it is a global variable because those go into unique `common' sections
550 and the section name is globally visible. For local variables, we simply
551 output the label. In any case, we have to record that no extern
552 declaration should be generated for the symbol. */
554 #define ASM_DECLARE_OBJECT_NAME(STREAM,NAME,DECL) \
555 do { tree name_tree; \
556 name_tree = get_identifier ((NAME)); \
557 TREE_ASM_WRITTEN (name_tree) = 1; \
558 if (!TREE_PUBLIC (DECL)) \
560 assemble_name (STREAM, NAME); \
561 fputs (":\n", STREAM); \
563 } while(0)
566 #define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \
567 unicosmk_output_section_name ((STREAM), (DECL), (NAME), (RELOC))
570 /* Switch into a generic section. */
571 #define TARGET_ASM_NAMED_SECTION unicosmk_asm_named_section
573 #undef ASM_OUTPUT_MAX_SKIP_ALIGN
574 #define ASM_OUTPUT_MAX_SKIP_ALIGN(STREAM,POWER,MAXSKIP)
576 #undef NM_FLAGS
578 #undef OBJECT_FORMAT_COFF
580 /* We cannot generate debugging information on Unicos/Mk. */
582 #undef SDB_DEBUGGING_INFO
583 #undef MIPS_DEBUGGING_INFO
584 #undef DBX_DEBUGGING_INFO
585 #undef DWARF_DEBUGGING_INFO
586 #undef DWARF2_DEBUGGING_INFO
587 #undef DWARF2_UNWIND_INFO
588 #undef INCOMING_RETURN_ADDR_RTX
591 /* We use the functions provided by the system library for integer
592 division. */
594 #undef UDIVDI3_LIBCALL
595 #undef DIVDI3_LIBCALL
596 #define UDIVDI3_LIBCALL "$uldiv"
597 #define DIVDI3_LIBCALL "$sldiv"
599 /* This is necessary to prevent gcc from generating calls to __divsi3. */
601 #define INIT_TARGET_OPTABS \
602 do { \
603 sdiv_optab->handlers[(int) SImode].libfunc = NULL_RTX; \
604 udiv_optab->handlers[(int) SImode].libfunc = NULL_RTX; \
605 } while (0)
607 #undef ASM_OUTPUT_SOURCE_LINE
609 /* We don't need a start file. */
611 #undef STARTFILE_SPEC
612 #define STARTFILE_SPEC ""
614 /* These are the libraries we have to link with.
615 ??? The Craylibs directory should be autoconfed. */
616 #undef LIB_SPEC
617 #define LIB_SPEC "-L/opt/ctl/craylibs/craylibs -lu -lm -lc -lsma"
619 #undef BUILD_VA_LIST_TYPE
620 #undef EXPAND_BUILTIN_VA_START
621 #undef EXPAND_BUILTIN_VA_ARG
623 #define EH_FRAME_IN_DATA_SECTION 1