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