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