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