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