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