1/* Definitions of target machine for GNU compiler for TILE-Gx.
2   Copyright (C) 2011-2020 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
167enum 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)		\
478static void __attribute__((__used__))				\
479call_ ## 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.  */
496typedef 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