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