1 /* Definitions of target machine for GNU compiler for TILE-Gx. 2 Copyright (C) 2011-2021 Free Software Foundation, Inc. 3 Contributed by Walter Lee (walt@tilera.com) 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify it 8 under the terms of the GNU General Public License as published 9 by the Free Software Foundation; either version 3, or (at your 10 option) any later version. 11 12 GCC is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15 License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GCC; see the file COPYING3. If not see 19 <http://www.gnu.org/licenses/>. */ 20 21 /* Default target_flags if no switches are specified */ 22 #ifndef TARGET_DEFAULT 23 #define TARGET_DEFAULT 0 24 #endif 25 26 #ifndef TARGET_BIG_ENDIAN_DEFAULT 27 #define TARGET_BIG_ENDIAN_DEFAULT 0 28 #endif 29 30 #ifndef TARGET_ENDIAN_DEFAULT 31 #if TARGET_BIG_ENDIAN_DEFAULT 32 #define TARGET_ENDIAN_DEFAULT MASK_BIG_ENDIAN 33 #else 34 #define TARGET_ENDIAN_DEFAULT 0 35 #endif 36 #endif 37 38 /* This is used by tilegx_cpu_cpp_builtins to indicate the byte order 39 we're compiling for. */ 40 #define TILEGX_CPU_CPP_ENDIAN_BUILTINS() \ 41 do \ 42 { \ 43 if (TARGET_BIG_ENDIAN) \ 44 builtin_define ("__BIG_ENDIAN__"); \ 45 else \ 46 builtin_define ("__LITTLE_ENDIAN__"); \ 47 } \ 48 while (0) 49 50 #include "config/tilegx/tilegx-opts.h" 51 52 53 /* Target CPU builtins. */ 54 #define TARGET_CPU_CPP_BUILTINS() \ 55 tilegx_cpu_cpp_builtins (pfile) 56 57 #undef PTRDIFF_TYPE 58 #define PTRDIFF_TYPE (TARGET_32BIT ? "int" : "long int") 59 60 #undef SIZE_TYPE 61 #define SIZE_TYPE (TARGET_32BIT ? "unsigned int" : "long unsigned int") 62 63 #undef WCHAR_TYPE 64 #define WCHAR_TYPE "int" 65 66 #undef WCHAR_TYPE_SIZE 67 #define WCHAR_TYPE_SIZE 32 68 69 70 /* Target machine storage layout */ 71 72 #define BITS_BIG_ENDIAN 0 73 #define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN != 0) 74 #define WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN != 0) 75 #define FLOAT_WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN != 0) 76 77 #define UNITS_PER_WORD 8 78 #define PARM_BOUNDARY BITS_PER_WORD 79 #define STACK_BOUNDARY 128 80 #define FUNCTION_BOUNDARY 64 81 #define BIGGEST_ALIGNMENT 128 82 #define STRICT_ALIGNMENT 1 83 84 #define INT_TYPE_SIZE 32 85 #define LONG_TYPE_SIZE (TARGET_32BIT ? 32 : 64) 86 #define LONG_LONG_TYPE_SIZE 64 87 #define FLOAT_TYPE_SIZE 32 88 #define DOUBLE_TYPE_SIZE 64 89 #define LONG_DOUBLE_TYPE_SIZE 64 90 #define POINTER_SIZE LONG_TYPE_SIZE 91 92 #define PCC_BITFIELD_TYPE_MATTERS 1 93 #define FASTEST_ALIGNMENT 64 94 #define BIGGEST_FIELD_ALIGNMENT 128 95 #define WIDEST_HARDWARE_FP_SIZE 64 96 97 /* Make arrays of chars word-aligned for the same reasons. */ 98 #define DATA_ALIGNMENT(TYPE, ALIGN) \ 99 (TREE_CODE (TYPE) == ARRAY_TYPE \ 100 && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ 101 && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN)) 102 103 /* Make local arrays of chars word-aligned for the same reasons. */ 104 #define LOCAL_ALIGNMENT(TYPE, ALIGN) DATA_ALIGNMENT (TYPE, ALIGN) 105 106 107 /* Standard register usage. */ 108 109 #define FIRST_PSEUDO_REGISTER (64 + 4) 110 111 #define FIXED_REGISTERS \ 112 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 113 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 115 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, \ 116 1, 1, 1, 1} 117 #define CALL_REALLY_USED_REGISTERS \ 118 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 119 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \ 120 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 121 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 122 1, 1, 1, 1} 123 124 #define REG_ALLOC_ORDER { \ 125 10, 11, 12, 13, 14, /* call used */ \ 126 15, 16, 17, 18, 19, \ 127 20, 21, 22, 23, 24, \ 128 25, 26, 27, 28, 29, \ 129 \ 130 9, 8, 7, 6, 5, /* argument */ \ 131 4, 3, 2, 1, 0, \ 132 \ 133 55, /* return address */ \ 134 \ 135 30, 31, 32, 33, 34, /* call saved registers */ \ 136 35, 36, 37, 38, 39, \ 137 40, 41, 42, 43, 44, \ 138 45, 46, 47, 48, 49, \ 139 50, 51, \ 140 \ 141 52, /* hard frame pointer */ \ 142 53, 54, /* tp, sp */ \ 143 \ 144 56, 57, 58, 59, 60, /* special purpose */ \ 145 61, 62, 63, 64, 65, /* or fake registers */ \ 146 66, 67 \ 147 } 148 149 /* Register that holds an address into the text segment that can be 150 used by pic code. */ 151 #define TILEGX_PIC_TEXT_LABEL_REGNUM (flag_pic ? 50 : INVALID_REGNUM) 152 #define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 51 : INVALID_REGNUM) 153 #define HARD_FRAME_POINTER_REGNUM 52 154 #define THREAD_POINTER_REGNUM 53 155 #define STACK_POINTER_REGNUM 54 156 #define TILEGX_LINK_REGNUM 55 157 #define FRAME_POINTER_REGNUM 64 158 #define ARG_POINTER_REGNUM 65 159 /* SPR storing the comparison value for compare and exchange. */ 160 #define TILEGX_CMPEXCH_REGNUM 66 161 /* Pseudo registers used to enforce order between instructions that 162 touch the networks. */ 163 #define TILEGX_NETORDER_REGNUM 67 164 #define STATIC_CHAIN_REGNUM 10 165 166 167 enum reg_class 168 { 169 NO_REGS, 170 R0_REGS, 171 R1_REGS, 172 R2_REGS, 173 R3_REGS, 174 R4_REGS, 175 R5_REGS, 176 R6_REGS, 177 R7_REGS, 178 R8_REGS, 179 R9_REGS, 180 R10_REGS, 181 ALL_REGS, 182 LIM_REG_CLASSES 183 }; 184 185 #define N_REG_CLASSES (int) LIM_REG_CLASSES 186 187 /* Since GENERAL_REGS is the same class as ALL_REGS, don't give it a 188 different class number; just make it an alias. */ 189 #define GENERAL_REGS ALL_REGS 190 191 #define REG_CLASS_NAMES \ 192 { \ 193 "NO_REGS", \ 194 "R0_REGS", \ 195 "R1_REGS", \ 196 "R2_REGS", \ 197 "R3_REGS", \ 198 "R4_REGS", \ 199 "R5_REGS", \ 200 "R6_REGS", \ 201 "R7_REGS", \ 202 "R8_REGS", \ 203 "R9_REGS", \ 204 "R10_REGS", \ 205 "ALL_REGS" \ 206 } 207 208 #define REG_CLASS_CONTENTS \ 209 { \ 210 { 0 }, \ 211 { 1 << 0 }, \ 212 { 1 << 1 }, \ 213 { 1 << 2 }, \ 214 { 1 << 3 }, \ 215 { 1 << 4 }, \ 216 { 1 << 5 }, \ 217 { 1 << 6 }, \ 218 { 1 << 7 }, \ 219 { 1 << 8 }, \ 220 { 1 << 9 }, \ 221 { 1 << 10 }, \ 222 { 0xffffffff, 0xffffffff } \ 223 } 224 225 #define REGNO_REG_CLASS(REGNO) \ 226 ((unsigned)(REGNO) <= 10 ? \ 227 (enum reg_class)(R0_REGS + (REGNO)) : ALL_REGS) 228 229 #define INDEX_REG_CLASS NO_REGS 230 #define BASE_REG_CLASS ALL_REGS 231 232 #define PREFERRED_RELOAD_CLASS(X,CLASS) (CLASS) 233 234 #define CLASS_MAX_NREGS(CLASS, MODE) \ 235 ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) 236 237 238 /* Stack layout; function entry, exit and calling. */ 239 240 #define STACK_GROWS_DOWNWARD 1 241 #define FRAME_GROWS_DOWNWARD 1 242 243 #define DYNAMIC_CHAIN_ADDRESS(FRAME) \ 244 plus_constant (Pmode, (FRAME), UNITS_PER_WORD) 245 246 #define FIRST_PARM_OFFSET(FNDECL) 0 247 248 #define ACCUMULATE_OUTGOING_ARGS 1 249 250 #define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1 251 252 #define INCOMING_FRAME_SP_OFFSET 0 253 254 #define STACK_POINTER_OFFSET (2 * UNITS_PER_WORD) 255 256 #define ARG_POINTER_CFA_OFFSET(FNDECL) (-STACK_POINTER_OFFSET) 257 258 #define DEFAULT_PCC_STRUCT_RETURN 0 259 260 /* The first 10 registers may hold return value. */ 261 #define TILEGX_NUM_RETURN_REGS 10 262 263 /* The first 10 registers hold function arguments. */ 264 #define TILEGX_NUM_ARG_REGS 10 265 266 #define FUNCTION_ARG_REGNO_P(N) ((N) < TILEGX_NUM_ARG_REGS) 267 268 /* The type used to store the number of words of arguments scanned so 269 far during argument scanning. This includes any space that is 270 skipped. */ 271 #define CUMULATIVE_ARGS int 272 273 #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \ 274 ((CUM) = 0) 275 276 277 #define ELIMINABLE_REGS \ 278 {{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ 279 {ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ 280 {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ 281 {FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} 282 283 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ 284 ((OFFSET) = tilegx_initial_elimination_offset((FROM),(TO))) 285 286 #define PROFILE_BEFORE_PROLOGUE 1 287 288 #define FUNCTION_PROFILER(FILE, LABELNO) \ 289 tilegx_function_profiler (FILE, LABELNO) 290 291 #define TRAMPOLINE_SIZE (TARGET_32BIT ? 48 : 56) 292 #define TRAMPOLINE_ALIGNMENT 64 293 #define TRAMPOLINE_SECTION text_section 294 295 296 /* Call frame debugging information. */ 297 298 #define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, TILEGX_LINK_REGNUM) 299 300 #define RETURN_ADDR_RTX tilegx_return_addr 301 302 #define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (TILEGX_LINK_REGNUM) 303 304 #define DWARF_ZERO_REG 63 305 306 #define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N + 12) : INVALID_REGNUM) 307 #define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 11) 308 #define EH_RETURN_HANDLER_RTX tilegx_eh_return_handler_rtx () 309 310 #define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \ 311 tilegx_asm_preferred_eh_data_format ((CODE), (GLOBAL)) 312 313 314 /* Addressing modes, and classification of registers for them. */ 315 316 #define HAVE_POST_INCREMENT 1 317 #define HAVE_POST_DECREMENT 1 318 #define HAVE_POST_MODIFY_DISP 1 319 320 #define REGNO_OK_FOR_INDEX_P(regno) 0 321 #define REGNO_OK_FOR_BASE_P(regno) \ 322 ((regno) < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0) 323 324 #define MAX_REGS_PER_ADDRESS 1 325 326 #define CONSTANT_ADDRESS_P(X) 0 327 328 #define LEGITIMATE_PIC_OPERAND_P(X) tilegx_legitimate_pic_operand_p (X) 329 330 331 #define CASE_VECTOR_MODE Pmode 332 #define CASE_VECTOR_PC_RELATIVE 0 333 #define JUMP_TABLES_IN_TEXT_SECTION 0 334 335 #define DEFAULT_SIGNED_CHAR 1 336 337 #define MOVE_MAX UNITS_PER_WORD 338 339 /* Use a value of 11 for MOVE_RATIO and friends, because TILEPro 340 returns structs as large as 10 words in registers. Because of some 341 some code generation inefficiency, we never get smaller code for 342 turning that into a memcpy, so pick a value that guarantees this 343 doesn't happen. */ 344 #define TILEGX_CALL_RATIO 11 345 #define MOVE_RATIO(speed) ((speed) ? 15 : TILEGX_CALL_RATIO) 346 #define CLEAR_RATIO(speed) ((speed) ? 15 : TILEGX_CALL_RATIO) 347 #define SET_RATIO(speed) ((speed) ? 15 : TILEGX_CALL_RATIO) 348 349 #define WORD_REGISTER_OPERATIONS 1 350 351 #define LOAD_EXTEND_OP(MODE) ((MODE) == SImode ? SIGN_EXTEND : ZERO_EXTEND) 352 353 #define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \ 354 if (GET_MODE_CLASS (MODE) == MODE_INT \ 355 && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \ 356 { \ 357 if ((MODE) == SImode) \ 358 (UNSIGNEDP) = 0; \ 359 (MODE) = DImode; \ 360 } 361 362 /* Define SLOW_BYTE_ACCESS to avoid making a QI or HI mode 363 register. */ 364 #define SLOW_BYTE_ACCESS 1 365 366 #define SHIFT_COUNT_TRUNCATED 0 367 368 #define SHORT_IMMEDIATES_SIGN_EXTEND 1 369 370 #define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 64, 1) 371 #define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 64, 1) 372 373 #define Pmode (TARGET_32BIT ? SImode : DImode) 374 375 #define STACK_SIZE_MODE Pmode 376 377 #define STORE_FLAG_VALUE 1 378 379 #define FUNCTION_MODE DImode 380 381 #define NO_FUNCTION_CSE 1 382 383 #define ADJUST_INSN_LENGTH(INSN, LENGTH) \ 384 ((LENGTH) = tilegx_adjust_insn_length ((INSN), (LENGTH))) 385 386 #define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT 387 388 #define BRANCH_COST(speed_p, predictable_p) ((predictable_p) ? 2 : 6) 389 390 391 /* Control the assembler format that we output. */ 392 393 #undef NO_DOLLAR_IN_LABEL 394 395 #define ASM_COMMENT_START "##" 396 397 #define TEXT_SECTION_ASM_OP "\t.text" 398 399 #define DATA_SECTION_ASM_OP "\t.data" 400 401 #undef READONLY_DATA_SECTION_ASM_OP 402 #define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rodata, \"a\"" 403 404 #undef BSS_SECTION_ASM_OP 405 #define BSS_SECTION_ASM_OP "\t.section\t.bss, \"wa\"" 406 407 #undef INIT_SECTION_ASM_OP 408 #define INIT_SECTION_ASM_OP "\t.section\t.init, \"ax\"" 409 410 #undef FINI_SECTION_ASM_OP 411 #define FINI_SECTION_ASM_OP "\t.section\t.fini, \"ax\"" 412 413 #define GLOBAL_ASM_OP ".global " 414 415 #define SUPPORTS_WEAK 1 416 417 #define USER_LABEL_PREFIX "" 418 419 #define REGISTER_PREFIX "" 420 #define REGISTER_NAMES \ 421 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ 422 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \ 423 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \ 424 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", \ 425 "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", \ 426 "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47", \ 427 "r48", "r49", "r50", "r51", "r52", "tp", "sp", "lr", \ 428 "?r56?","idn0", "idn1", "udn0", "udn1", "udn2", "udn3", "zero", \ 429 "?FRAME?", "?ARG?", "?CMPEXCH?", "?NET?" } 430 431 #define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \ 432 tilegx_final_prescan_insn (insn) 433 434 #define ASM_OUTPUT_OPCODE(STREAM, PTR) \ 435 (PTR = tilegx_asm_output_opcode (STREAM, PTR)) 436 437 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ 438 do \ 439 { \ 440 char label[256]; \ 441 ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE)); \ 442 fprintf (FILE, "%s ", \ 443 integer_asm_op (GET_MODE_SIZE (Pmode), TRUE)); \ 444 assemble_name (FILE, label); \ 445 fprintf (FILE, "\n"); \ 446 } \ 447 while (0) 448 449 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ 450 do \ 451 { \ 452 char label[256]; \ 453 ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE)); \ 454 fprintf (FILE, "%s ", \ 455 integer_asm_op (GET_MODE_SIZE (Pmode), TRUE)); \ 456 assemble_name (FILE, label); \ 457 ASM_GENERATE_INTERNAL_LABEL (label, "L", (REL)); \ 458 fprintf (FILE, "-"); \ 459 assemble_name (FILE, label); \ 460 fprintf (FILE, "\n"); \ 461 } \ 462 while (0) 463 464 #define ASM_OUTPUT_ALIGN(FILE,LOG) \ 465 do { if ((LOG) != 0) fprintf (FILE, "\t.align %d\n", 1 << (LOG)); } while (0) 466 467 #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ 468 ( fputs (".comm ", (FILE)), \ 469 assemble_name ((FILE), (NAME)), \ 470 fprintf ((FILE), ",%u\n", (unsigned int)(ROUNDED))) 471 472 #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ 473 ( fputs (".lcomm ", (FILE)), \ 474 assemble_name ((FILE), (NAME)), \ 475 fprintf ((FILE), ",%u\n", (unsigned int)(ROUNDED))) 476 477 #define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ 478 static void __attribute__((__used__)) \ 479 call_ ## FUNC (void) \ 480 { \ 481 asm (SECTION_OP); \ 482 asm ("{ moveli r0, hw2_last(" #FUNC " - . - 8); lnk r1 }\n"); \ 483 asm ("shl16insli r0, r0, hw1(" #FUNC " - .)\n"); \ 484 asm ("shl16insli r0, r0, hw0(" #FUNC " - . + 8)\n"); \ 485 asm ("add r0, r1, r0\n"); \ 486 asm ("jalr r0\n"); \ 487 asm (TEXT_SECTION_ASM_OP); \ 488 } 489 490 491 492 #define INIT_EXPANDERS tilegx_init_expanders () 493 494 /* A C structure for machine-specific, per-function data. This is 495 added to the cfun structure. */ 496 typedef struct GTY(()) machine_function 497 { 498 /* Symbol for the text label used for pic. */ 499 rtx text_label_symbol; 500 501 /* Register for the text label. */ 502 rtx text_label_rtx; 503 504 /* Register for the pic offset table. */ 505 rtx got_rtx; 506 507 /* The function calls tls_get_addr. */ 508 int calls_tls_get_addr; 509 } machine_function; 510 511 #ifndef HAVE_AS_TLS 512 #define HAVE_AS_TLS 0 513 #endif 514 515 #ifndef ENDIAN_SPEC 516 #if TARGET_BIG_ENDIAN_DEFAULT 517 #define ENDIAN_SPEC \ 518 "%{!mlittle-endian:-EB} \ 519 %{mlittle-endian:%{mbig-endian: \ 520 %e-mbig-endian and -mlittle-endian may not be used together}-EL}" 521 #else 522 #define ENDIAN_SPEC \ 523 "%{!mbig-endian:-EL} \ 524 %{mbig-endian:%{mlittle-endian: \ 525 %e-mbig-endian and -mlittle-endian may not be used together}-EB}" 526 #endif 527 #endif 528 529 #define EXTRA_SPECS \ 530 { "endian_spec", ENDIAN_SPEC } 531