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 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 
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, N_NAMED_ARGS) \
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 /* An argument is passed either entirely in registers or entirely on stack.  */
222 
223 #undef FUNCTION_ARG_PARTIAL_NREGS
224 /* #define FUNCTION_ARG_PARTIAL_NREGS(CUM,MODE,TYPE,NAMED) 0 */
225 
226 /* This ensures that $15 increments/decrements in leaf functions won't get
227    eliminated.  */
228 
229 #undef EPILOGUE_USES
230 #define EPILOGUE_USES(REGNO)  ((REGNO) == 26 || (REGNO) == 15)
231 
232 /* Would have worked, only the stack doesn't seem to be executable
233 #undef TRAMPOLINE_TEMPLATE
234 #define TRAMPOLINE_TEMPLATE(FILE)			\
235 do { fprintf (FILE, "\tbr $1,0\n");			\
236      fprintf (FILE, "\tldq $0,12($1)\n");		\
237      fprintf (FILE, "\tldq $1,20($1)\n");		\
238      fprintf (FILE, "\tjmp $31,(r0)\n");		\
239      fprintf (FILE, "\tbis $31,$31,$31\n");		\
240      fprintf (FILE, "\tbis $31,$31,$31\n");		\
241 } while (0) */
242 
243 /* We don't support nested functions (yet).  */
244 
245 #undef TRAMPOLINE_TEMPLATE
246 #define TRAMPOLINE_TEMPLATE(FILE) abort ()
247 
248 /* Specify the machine mode that this machine uses for the index in the
249    tablejump instruction. On Unicos/Mk, we don't support relative case
250    vectors yet, thus the entries should be absolute addresses.  */
251 
252 #undef CASE_VECTOR_MODE
253 #define CASE_VECTOR_MODE DImode
254 
255 #undef CASE_VECTOR_PC_RELATIVE
256 
257 /* Define this as 1 if `char' should by default be signed; else as 0.  */
258 /* #define DEFAULT_SIGNED_CHAR 1 */
259 
260 /* The Cray assembler is really weird with respect to sections. It has only
261    named sections and you can't reopen a section once it has been closed.
262    This means that we have to generate unique names whenever we want to
263    reenter the text or the data section. The following is a rather bad hack
264    as TEXT_SECTION_ASM_OP and DATA_SECTION_ASM_OP are supposed to be
265    constants.  */
266 
267 #undef TEXT_SECTION_ASM_OP
268 #define TEXT_SECTION_ASM_OP unicosmk_text_section ()
269 
270 #undef DATA_SECTION_ASM_OP
271 #define DATA_SECTION_ASM_OP unicosmk_data_section ()
272 
273 /* There are no read-only sections on Unicos/Mk.  */
274 
275 #undef READONLY_DATA_SECTION_ASM_OP
276 #define READONLY_DATA_SECTION data_section
277 
278 /* Define extra sections for common data and SSIBs (static subroutine
279    information blocks). The actual section header is output by the callers
280    of these functions.  */
281 
282 #undef EXTRA_SECTIONS
283 #undef EXTRA_SECTION_FUNCTIONS
284 
285 #define EXTRA_SECTIONS in_common, in_ssib
286 #define EXTRA_SECTION_FUNCTIONS	\
287 COMMON_SECTION			\
288 SSIB_SECTION
289 
290 extern void common_section (void);
291 #define COMMON_SECTION		\
292 void				\
293 common_section (void)		\
294 {				\
295   in_section = in_common;	\
296 }
297 
298 extern void ssib_section (void);
299 #define SSIB_SECTION		\
300 void				\
301 ssib_section (void)		\
302 {				\
303   in_section = in_ssib;		\
304 }
305 
306 /* We take care of this in unicosmk_file_start.  */
307 
308 #undef ASM_OUTPUT_SOURCE_FILENAME
309 
310 /* This is how to output a label for a jump table.  Arguments are the same as
311    for (*targetm.asm_out.internal_label), except the insn for the jump table is
312    passed.  */
313 
314 #undef ASM_OUTPUT_CASE_LABEL
315 #define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN)	\
316   (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM)
317 
318 /* CAM has some restrictions with respect to string literals. It won't
319    accept lines with more that 256 characters which means that we have
320    to split long strings. Moreover, it only accepts escape sequences of
321    the form \nnn in the range 0 to 127. We generate .byte directives for
322    escapes characters greater than 127. And finally, ` must be escaped.  */
323 
324 #undef ASM_OUTPUT_ASCII
325 #define ASM_OUTPUT_ASCII(MYFILE, MYSTRING, MYLENGTH) \
326   do {									      \
327     FILE *_hide_asm_out_file = (MYFILE);				      \
328     const unsigned char *_hide_p = (const unsigned char *) (MYSTRING);	      \
329     int _hide_thissize = (MYLENGTH);					      \
330     int _size_so_far = 0;						      \
331     {									      \
332       FILE *asm_out_file = _hide_asm_out_file;				      \
333       const unsigned char *p = _hide_p;					      \
334       int thissize = _hide_thissize;					      \
335       int in_ascii = 0;							      \
336       int i;								      \
337 									      \
338       for (i = 0; i < thissize; i++)					      \
339 	{								      \
340 	  register int c = p[i];					      \
341 									      \
342 	  if (c > 127)							      \
343 	    {								      \
344 	      if (in_ascii)						      \
345 		{							      \
346 		  fprintf (asm_out_file, "\"\n");			      \
347 		  in_ascii = 0;						      \
348 		}							      \
349 									      \
350 	      fprintf (asm_out_file, "\t.byte\t%d\n", c);		      \
351 	    }								      \
352 	  else								      \
353 	    {								      \
354 	      if (! in_ascii)						      \
355 		{							      \
356 		  fprintf (asm_out_file, "\t.ascii\t\"");		      \
357 		  in_ascii = 1;						      \
358 		  _size_so_far = 0;					      \
359 		}							      \
360 	      else if (_size_so_far >= 64)				      \
361 		{							      \
362 		  fprintf (asm_out_file, "\"\n\t.ascii\t\"");		      \
363 		  _size_so_far = 0;					      \
364 		}							      \
365 									      \
366 	      if (c == '\"' || c == '\\' || c == '`')			      \
367 		putc ('\\', asm_out_file);				      \
368 	      if (c >= ' ')						      \
369 		putc (c, asm_out_file);					      \
370 	      else							      \
371 		fprintf (asm_out_file, "\\%.3o", c);			      \
372 	      ++ _size_so_far;						      \
373 	    }								      \
374 	}								      \
375       if (in_ascii)							      \
376 	fprintf (asm_out_file, "\"\n");					      \
377     }									      \
378   } while(0)
379 
380 /* This is how to output an element of a case-vector that is absolute.  */
381 
382 #undef ASM_OUTPUT_ADDR_VEC_ELT
383 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)	\
384   fprintf (FILE, "\t.quad $L%d\n", (VALUE))
385 
386 /* This is how to output an element of a case-vector that is relative.
387    (Unicos/Mk does not use such vectors yet).  */
388 
389 #undef ASM_OUTPUT_ADDR_DIFF_ELT
390 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) abort ()
391 
392 /* We can't output case vectors in the same section as the function code
393    because CAM doesn't allow data definitions in code sections. Thus, we
394    simply record the case vectors and put them in a separate section after
395    the function.  */
396 
397 #define ASM_OUTPUT_ADDR_VEC(LAB,VEC) \
398   unicosmk_defer_case_vector ((LAB),(VEC))
399 
400 #define ASM_OUTPUT_ADDR_DIFF_VEC(LAB,VEC) abort ()
401 
402 /* This is how to output an assembler line that says to advance the location
403    counter to a multiple of 2**LOG bytes. Annoyingly, CAM always uses zeroes
404    to fill the unused space which does not work in code sections. We have to
405    be careful not to use the .align directive in code sections.  */
406 
407 #undef ASM_OUTPUT_ALIGN
408 #define ASM_OUTPUT_ALIGN(STREAM,LOG) unicosmk_output_align (STREAM, LOG)
409 
410 /* This is how to advance the location counter by SIZE bytes.  */
411 
412 #undef ASM_OUTPUT_SKIP
413 #define ASM_OUTPUT_SKIP(STREAM,SIZE)			\
414   fprintf ((STREAM), "\t.byte\t0:"HOST_WIDE_INT_PRINT_UNSIGNED"\n",\
415 	   (SIZE));
416 
417 /* This says how to output an assembler line to define a global common
418    symbol. We need the alignment information because it has to be supplied
419    in the section header.  */
420 
421 #undef ASM_OUTPUT_COMMON
422 #define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)	\
423   unicosmk_output_common ((FILE), (NAME), (SIZE), (ALIGN))
424 
425 /* This says how to output an assembler line to define a local symbol.  */
426 
427 #undef ASM_OUTPUT_LOCAL
428 #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
429   do { data_section ();					\
430        fprintf (FILE, "\t.align\t%d\n", floor_log2 ((ALIGN) / BITS_PER_UNIT));\
431        ASM_OUTPUT_LABEL ((FILE), (NAME));		\
432        fprintf (FILE, "\t.byte 0:"HOST_WIDE_INT_PRINT_UNSIGNED"\n",(SIZE));\
433   } while (0)
434 
435 /* CAM does not allow us to declare a symbol as external first and then
436    define it in the same file later. Thus, we keep a list of all external
437    references, remove all symbols defined locally from it and output it at
438    the end of the asm file.  */
439 
440 #define ASM_OUTPUT_EXTERNAL(FILE,DECL,NAME) \
441   unicosmk_add_extern ((NAME))
442 
443 #define ASM_OUTPUT_EXTERNAL_LIBCALL(STREAM,SYMREF)	\
444   unicosmk_add_extern (XSTR ((SYMREF), 0))
445 
446 /* This is how to declare an object. We don't have to output anything if
447    it is a global variable because those go into unique `common' sections
448    and the section name is globally visible. For local variables, we simply
449    output the label. In any case, we have to record that no extern
450    declaration should be generated for the symbol.  */
451 
452 #define ASM_DECLARE_OBJECT_NAME(STREAM,NAME,DECL) 	\
453   do { tree name_tree;					\
454        name_tree = get_identifier ((NAME));		\
455        TREE_ASM_WRITTEN (name_tree) = 1;		\
456        if (!TREE_PUBLIC (DECL))				\
457 	 {						\
458 	   assemble_name (STREAM, NAME);		\
459 	   fputs (":\n", STREAM);			\
460          }						\
461   } while(0)
462 
463 /*
464 #define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC)	\
465   unicosmk_output_section_name ((STREAM), (DECL), (NAME), (RELOC))
466 */
467 
468 /* Switch into a generic section.  */
469 #define TARGET_ASM_NAMED_SECTION unicosmk_asm_named_section
470 
471 #undef ASM_OUTPUT_MAX_SKIP_ALIGN
472 #define ASM_OUTPUT_MAX_SKIP_ALIGN(STREAM,POWER,MAXSKIP)
473 
474 #undef NM_FLAGS
475 
476 #undef OBJECT_FORMAT_COFF
477 
478 /* We cannot generate debugging information on Unicos/Mk.  */
479 
480 #undef SDB_DEBUGGING_INFO
481 #undef MIPS_DEBUGGING_INFO
482 #undef DBX_DEBUGGING_INFO
483 #undef DWARF2_DEBUGGING_INFO
484 #undef DWARF2_UNWIND_INFO
485 #undef INCOMING_RETURN_ADDR_RTX
486 #undef ASM_OUTPUT_SOURCE_LINE
487 
488 /* We don't need a start file.  */
489 
490 #undef STARTFILE_SPEC
491 #define STARTFILE_SPEC ""
492 
493 /* These are the libraries we have to link with.
494    ??? The Craylibs directory should be autoconfed.  */
495 #undef LIB_SPEC
496 #define LIB_SPEC "-L/opt/ctl/craylibs/craylibs -lu -lm -lc -lsma"
497 
498 #undef EXPAND_BUILTIN_VA_START
499 #undef EXPAND_BUILTIN_VA_ARG
500 
501 #define EH_FRAME_IN_DATA_SECTION 1
502