156893Sfenner/* Definitions of target machine for GNU compiler for TILEPro.
256893Sfenner   Copyright (C) 2011-2020 Free Software Foundation, Inc.
356893Sfenner   Contributed by Walter Lee (walt@tilera.com)
456893Sfenner
5127668Sbms   This file is part of GCC.
656893Sfenner
756893Sfenner   GCC is free software; you can redistribute it and/or modify it
856893Sfenner   under the terms of the GNU General Public License as published
9127668Sbms   by the Free Software Foundation; either version 3, or (at your
1056893Sfenner   option) any later version.
1156893Sfenner
12127668Sbms   GCC is distributed in the hope that it will be useful, but WITHOUT
1356893Sfenner   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1456893Sfenner   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
1556893Sfenner   License for more details.
16127668Sbms
1756893Sfenner   You should have received a copy of the GNU General Public License
1856893Sfenner   along with GCC; see the file COPYING3.  If not see
1956893Sfenner   <http://www.gnu.org/licenses/>.  */
2056893Sfenner
21127668Sbms/* This is used by tilepro_cpu_cpp_builtins to indicate the byte order
2256893Sfenner   we're compiling for.  */
2356893Sfenner#define TILEPRO_CPU_CPP_ENDIAN_BUILTINS()	\
2456893Sfenner  do						\
25127668Sbms    {						\
2656893Sfenner      if (BYTES_BIG_ENDIAN)			\
2756893Sfenner	builtin_define ("__BIG_ENDIAN__");	\
2856893Sfenner      else					\
2956893Sfenner	builtin_define ("__LITTLE_ENDIAN__");	\
3056893Sfenner    }						\
3156893Sfenner  while (0)
3256893Sfenner
3356893Sfenner/* Target CPU builtins.  */
3456893Sfenner#define TARGET_CPU_CPP_BUILTINS() \
3556893Sfenner  tilepro_cpu_cpp_builtins (pfile)
3656893Sfenner
3756893Sfenner#undef PTRDIFF_TYPE
3856893Sfenner#define PTRDIFF_TYPE "int"
39190207Srpaulo
4056893Sfenner#undef SIZE_TYPE
4156893Sfenner#define SIZE_TYPE "unsigned int"
42127668Sbms
43190207Srpaulo
4456893Sfenner/* Target machine storage layout */
4556893Sfenner
46127668Sbms#define BITS_BIG_ENDIAN 0
47127668Sbms#define BYTES_BIG_ENDIAN 0
4856893Sfenner#define WORDS_BIG_ENDIAN 0
4956893Sfenner
5056893Sfenner#define UNITS_PER_WORD 4
5156893Sfenner#define PARM_BOUNDARY 32
5256893Sfenner#define STACK_BOUNDARY 64
5356893Sfenner#define FUNCTION_BOUNDARY 64
5456893Sfenner#define BIGGEST_ALIGNMENT 64
55146775Ssam#define STRICT_ALIGNMENT 1
56146775Ssam
5756893Sfenner#define PCC_BITFIELD_TYPE_MATTERS 1
5856893Sfenner#define FASTEST_ALIGNMENT 32
59146775Ssam#define BIGGEST_FIELD_ALIGNMENT 64
60146775Ssam
61146775Ssam/* Make arrays of chars word-aligned for the same reasons.  */
62146775Ssam#define DATA_ALIGNMENT(TYPE, ALIGN)		\
6356893Sfenner  (TREE_CODE (TYPE) == ARRAY_TYPE		\
6456893Sfenner   && TYPE_MODE (TREE_TYPE (TYPE)) == QImode	\
6556893Sfenner   && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
6656893Sfenner
6756893Sfenner/* Make local arrays of chars word-aligned for the same reasons.  */
6856893Sfenner#define LOCAL_ALIGNMENT(TYPE, ALIGN) DATA_ALIGNMENT (TYPE, ALIGN)
6956893Sfenner
7056893Sfenner
7156893Sfenner/* Standard register usage.  */
7256893Sfenner
7356893Sfenner#define FIRST_PSEUDO_REGISTER (64 + 3)
7456893Sfenner
7556893Sfenner#define FIXED_REGISTERS \
7656893Sfenner {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
7756893Sfenner  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
7856893Sfenner  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
7956893Sfenner  0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, \
8056893Sfenner  1, 1, 1}
8156893Sfenner
8256893Sfenner#define CALL_REALLY_USED_REGISTERS \
8356893Sfenner {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
8456893Sfenner  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \
8556893Sfenner  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
8656893Sfenner  0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
8756893Sfenner  1, 1, 1}
8856893Sfenner
8956893Sfenner#define REG_ALLOC_ORDER {				\
9056893Sfenner      10, 11, 12, 13, 14, /* call used */		\
9156893Sfenner      15, 16, 17, 18, 19,				\
9256893Sfenner      20, 21, 22, 23, 24,				\
9356893Sfenner      25, 26, 27, 28, 29,				\
9456893Sfenner							\
9556893Sfenner      9, 8, 7, 6, 5,      /* argument */		\
9656893Sfenner      4, 3, 2, 1, 0,					\
9756893Sfenner							\
98146775Ssam      55,	          /* return address */		\
99146775Ssam							\
100146775Ssam      30, 31, 32, 33, 34, /* call saved registers */	\
101146775Ssam      35, 36, 37, 38, 39,				\
102146775Ssam      40, 41, 42, 43, 44,				\
103146775Ssam      45, 46, 47, 48, 49,				\
104146775Ssam      50, 51,						\
105146775Ssam							\
106146775Ssam      52, 		  /* hard frame pointer */	\
107146775Ssam      53, 54, 		  /* tp, sp */			\
108146775Ssam							\
109146775Ssam      56, 57, 58, 59, 60, /* special purpose */		\
110146775Ssam      61, 62, 63, 64, 65, /* or fake registers */	\
111146775Ssam      66						\
112146775Ssam}
113146775Ssam
114146775Ssam/* Register that holds an address into the text segment that can be
115146775Ssam   used by pic code.  */
116146775Ssam#define TILEPRO_PIC_TEXT_LABEL_REGNUM (flag_pic ? 50 : INVALID_REGNUM)
117146775Ssam#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 51 : INVALID_REGNUM)
118146775Ssam#define HARD_FRAME_POINTER_REGNUM 52
119146775Ssam#define THREAD_POINTER_REGNUM 53
120146775Ssam#define STACK_POINTER_REGNUM 54
121146775Ssam#define TILEPRO_LINK_REGNUM 55
122146775Ssam#define FRAME_POINTER_REGNUM 64
123146775Ssam#define ARG_POINTER_REGNUM 65
124146775Ssam/* Pseudo register used to enforce order between instructions that
125146775Ssam   touch the networks.  */
126146775Ssam#define TILEPRO_NETORDER_REGNUM 66
127146775Ssam#define STATIC_CHAIN_REGNUM 10
128146775Ssam
129146775Ssam
130146775Ssamenum reg_class
131146775Ssam{
132146775Ssam  NO_REGS,
133146775Ssam  R0_REGS,
134146775Ssam  R1_REGS,
135146775Ssam  R2_REGS,
136146775Ssam  R3_REGS,
137146775Ssam  R4_REGS,
138146775Ssam  R5_REGS,
139146775Ssam  R6_REGS,
140146775Ssam  R7_REGS,
141146775Ssam  R8_REGS,
142146775Ssam  R9_REGS,
143146775Ssam  R10_REGS,
144146775Ssam  ALL_REGS,
145146775Ssam  LIM_REG_CLASSES
146146775Ssam};
147146775Ssam
148146775Ssam#define N_REG_CLASSES (int) LIM_REG_CLASSES
149146775Ssam
150146775Ssam/* Since GENERAL_REGS is the same class as ALL_REGS, don't give it a
151146775Ssam   different class number; just make it an alias.  */
152146775Ssam#define GENERAL_REGS ALL_REGS
153146775Ssam
154146775Ssam#define REG_CLASS_NAMES	\
155146775Ssam  { \
156146775Ssam    "NO_REGS", \
157146775Ssam    "R0_REGS", \
158146775Ssam    "R1_REGS", \
159146775Ssam    "R2_REGS", \
160146775Ssam    "R3_REGS", \
161146775Ssam    "R4_REGS", \
162146775Ssam    "R5_REGS", \
163146775Ssam    "R6_REGS", \
164146775Ssam    "R7_REGS", \
165146775Ssam    "R8_REGS", \
166146775Ssam    "R9_REGS", \
167146775Ssam    "R10_REGS", \
168146775Ssam    "ALL_REGS" \
169146775Ssam  }
170146775Ssam
171146775Ssam#define REG_CLASS_CONTENTS \
172146775Ssam  { \
173146775Ssam    { 0 }, \
174146775Ssam    { 1 << 0 }, \
175146775Ssam    { 1 << 1 }, \
176146775Ssam    { 1 << 2 }, \
177146775Ssam    { 1 << 3 }, \
178146775Ssam    { 1 << 4 }, \
179146775Ssam    { 1 << 5 }, \
180146775Ssam    { 1 << 6 }, \
181146775Ssam    { 1 << 7 }, \
182146775Ssam    { 1 << 8 }, \
183146775Ssam    { 1 << 9 }, \
184146775Ssam    { 1 << 10 }, \
185146775Ssam    { 0xffffffff, 0xffffffff } \
186146775Ssam  }
187146775Ssam
188146775Ssam#define REGNO_REG_CLASS(REGNO) \
189146775Ssam  ((unsigned)(REGNO) <= 10 ? \
190146775Ssam   (enum reg_class)(R0_REGS + (REGNO)) : ALL_REGS)
191146775Ssam
192146775Ssam#define INDEX_REG_CLASS NO_REGS
193146775Ssam#define BASE_REG_CLASS ALL_REGS
194146775Ssam
195146775Ssam#define PREFERRED_RELOAD_CLASS(X,CLASS)  (CLASS)
196146775Ssam
197146775Ssam#define CLASS_MAX_NREGS(CLASS, MODE)	\
198146775Ssam ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
199146775Ssam
200146775Ssam
201146775Ssam/* Stack layout; function entry, exit and calling.  */
202146775Ssam
203146775Ssam#define STACK_GROWS_DOWNWARD 1
204146775Ssam#define FRAME_GROWS_DOWNWARD 1
20556893Sfenner
20656893Sfenner#define DYNAMIC_CHAIN_ADDRESS(FRAME) \
20756893Sfenner  plus_constant (Pmode, (FRAME), UNITS_PER_WORD)
20856893Sfenner
20956893Sfenner#define FIRST_PARM_OFFSET(FNDECL) 0
21056893Sfenner
211146775Ssam#define ACCUMULATE_OUTGOING_ARGS 1
212146775Ssam
213146775Ssam#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1
214146775Ssam
21556893Sfenner#define INCOMING_FRAME_SP_OFFSET 0
21656893Sfenner
21756893Sfenner#define STACK_POINTER_OFFSET (2 * UNITS_PER_WORD)
21856893Sfenner
21956893Sfenner#define ARG_POINTER_CFA_OFFSET(FNDECL) (-STACK_POINTER_OFFSET)
220
221#define DEFAULT_PCC_STRUCT_RETURN 0
222
223/* The first 10 registers may hold return value.  */
224#define TILEPRO_NUM_RETURN_REGS 10
225
226/* The first 10 registers hold function arguments.  */
227#define TILEPRO_NUM_ARG_REGS 10
228
229#define FUNCTION_ARG_REGNO_P(N) ((N) < TILEPRO_NUM_ARG_REGS)
230
231/* The type used to store the number of words of arguments scanned so
232   far during argument scanning.  This includes any space that is
233   skipped.  */
234#define CUMULATIVE_ARGS int
235
236#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
237 ((CUM) = 0)
238
239
240#define ELIMINABLE_REGS					\
241  {{ARG_POINTER_REGNUM,	 STACK_POINTER_REGNUM},		\
242  {ARG_POINTER_REGNUM,	 HARD_FRAME_POINTER_REGNUM},	\
243  {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},		\
244  {FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
245
246#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
247  ((OFFSET) = tilepro_initial_elimination_offset((FROM),(TO)))
248
249#define PROFILE_BEFORE_PROLOGUE 1
250
251#define FUNCTION_PROFILER(FILE, LABELNO) \
252  tilepro_function_profiler (FILE, LABELNO)
253
254#define TRAMPOLINE_SIZE 48
255#define TRAMPOLINE_ALIGNMENT 64
256#define TRAMPOLINE_SECTION text_section
257
258
259/* Call frame debugging information.  */
260
261#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, TILEPRO_LINK_REGNUM)
262
263#define RETURN_ADDR_RTX tilepro_return_addr
264
265#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (TILEPRO_LINK_REGNUM)
266
267#define DWARF_ZERO_REG 63
268
269#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N + 12) : INVALID_REGNUM)
270#define EH_RETURN_STACKADJ_RTX	gen_rtx_REG (Pmode, 11)
271#define EH_RETURN_HANDLER_RTX tilepro_eh_return_handler_rtx ()
272
273#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
274  tilepro_asm_preferred_eh_data_format ((CODE), (GLOBAL))
275
276
277/* Addressing modes, and classification of registers for them.  */
278
279#define HAVE_POST_INCREMENT 1
280#define HAVE_POST_DECREMENT 1
281#define HAVE_POST_MODIFY_DISP 1
282
283#define REGNO_OK_FOR_INDEX_P(regno) 0
284#define REGNO_OK_FOR_BASE_P(regno)	\
285  ((regno) < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0)
286
287#define MAX_REGS_PER_ADDRESS 1
288
289#define CONSTANT_ADDRESS_P(X) 0
290
291#define LEGITIMATE_PIC_OPERAND_P(X) tilepro_legitimate_pic_operand_p (X)
292
293
294#define CASE_VECTOR_MODE SImode
295#define CASE_VECTOR_PC_RELATIVE 0
296#define JUMP_TABLES_IN_TEXT_SECTION 0
297
298#define DEFAULT_SIGNED_CHAR 1
299
300#define MOVE_MAX UNITS_PER_WORD
301
302/* Use a value of 11 for MOVE_RATIO and friends, because TILEPro
303   returns structs as large as 10 words in registers.  Because of some
304   some code generation inefficiency, we never get smaller code for
305   turning that into a memcpy, so pick a value that guarantees this
306   doesn't happen.  */
307#define TILEPRO_CALL_RATIO 11
308#define MOVE_RATIO(speed) ((speed) ? 15 : TILEPRO_CALL_RATIO)
309#define CLEAR_RATIO(speed) ((speed) ? 15 : TILEPRO_CALL_RATIO)
310#define SET_RATIO(speed) ((speed) ? 15 : TILEPRO_CALL_RATIO)
311
312#define WORD_REGISTER_OPERATIONS 1
313
314#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
315
316#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE)	\
317  if (GET_MODE_CLASS (MODE) == MODE_INT		\
318      && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
319    (MODE) = SImode;
320
321/* Define SLOW_BYTE_ACCESS to avoid making a QI or HI mode
322   register.  */
323#define SLOW_BYTE_ACCESS 1
324
325#define SHIFT_COUNT_TRUNCATED 1
326
327#define SHORT_IMMEDIATES_SIGN_EXTEND 1
328
329#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
330#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
331
332#define Pmode SImode
333
334#define STORE_FLAG_VALUE 1
335
336#define FUNCTION_MODE SImode
337
338#define NO_FUNCTION_CSE 1
339
340#define ADJUST_INSN_LENGTH(INSN, LENGTH) \
341  ((LENGTH) = tilepro_adjust_insn_length ((INSN), (LENGTH)))
342
343#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
344
345#define BRANCH_COST(speed_p, predictable_p) ((predictable_p) ? 2 : 6)
346
347
348/* Control the assembler format that we output.  */
349
350#undef NO_DOLLAR_IN_LABEL
351
352#define ASM_COMMENT_START "##"
353
354#define TEXT_SECTION_ASM_OP "\t.text"
355
356#define DATA_SECTION_ASM_OP "\t.data"
357
358#undef READONLY_DATA_SECTION_ASM_OP
359#define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rodata, \"a\""
360
361#undef BSS_SECTION_ASM_OP
362#define BSS_SECTION_ASM_OP	"\t.section\t.bss, \"wa\""
363
364#undef INIT_SECTION_ASM_OP
365#define INIT_SECTION_ASM_OP	"\t.section\t.init, \"ax\""
366
367#undef FINI_SECTION_ASM_OP
368#define FINI_SECTION_ASM_OP	"\t.section\t.fini, \"ax\""
369
370#define GLOBAL_ASM_OP ".global "
371
372#define SUPPORTS_WEAK 1
373
374#define USER_LABEL_PREFIX ""
375
376#define REGISTER_PREFIX ""
377#define REGISTER_NAMES                                                  \
378  { "r0",   "r1",   "r2",   "r3",   "r4",   "r5",   "r6",   "r7",       \
379    "r8",   "r9",   "r10",  "r11",  "r12",  "r13",  "r14",  "r15",      \
380    "r16",  "r17",  "r18",  "r19",  "r20",  "r21",  "r22",  "r23",      \
381    "r24",  "r25",  "r26",  "r27",  "r28",  "r29",  "r30",  "r31",      \
382    "r32",  "r33",  "r34",  "r35",  "r36",  "r37",  "r38",  "r39",      \
383    "r40",  "r41",  "r42",  "r43",  "r44",  "r45",  "r46",  "r47",      \
384    "r48",  "r49",  "r50",  "r51",  "r52",  "tp",   "sp",   "lr",       \
385    "sn",   "idn0", "idn1", "udn0", "udn1", "udn2", "udn3", "zero",     \
386    "?FRAME?", "?ARG?", "?NET?" }
387
388/* This is used to help emit bundles.  */
389#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
390  tilepro_final_prescan_insn (insn)
391
392/* This is used to help emit bundles.  */
393#define ASM_OUTPUT_OPCODE(STREAM, PTR)	\
394  (PTR = tilepro_asm_output_opcode (STREAM, PTR))
395
396#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)		\
397  do							\
398    {							\
399      char label[256];					\
400      ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE));\
401      fprintf (FILE, "\t.word ");			\
402      assemble_name (FILE, label);			\
403      fprintf (FILE, "\n");				\
404    }							\
405  while (0)
406
407#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)	\
408  do								\
409    {								\
410      char label[256];						\
411      ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE));	\
412      fprintf (FILE, "\t.word ");				\
413      assemble_name (FILE, label);				\
414      ASM_GENERATE_INTERNAL_LABEL (label, "L", (REL));		\
415      fprintf (FILE, "-");					\
416      assemble_name (FILE, label);				\
417      fprintf (FILE, "\n");					\
418    }								\
419  while (0)
420
421#define ASM_OUTPUT_ALIGN(FILE,LOG)  \
422  do { if ((LOG) != 0) fprintf (FILE, "\t.align %d\n", 1 << (LOG)); } while (0)
423
424#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)	\
425  ( fputs (".comm ", (FILE)),				\
426    assemble_name ((FILE), (NAME)),			\
427    fprintf ((FILE), ",%u\n", (unsigned int)(ROUNDED)))
428
429#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)	\
430  ( fputs (".lcomm ", (FILE)),				\
431    assemble_name ((FILE), (NAME)),			\
432    fprintf ((FILE), ",%u\n", (unsigned int)(ROUNDED)))
433
434
435
436#define INIT_EXPANDERS tilepro_init_expanders ()
437
438/* A C structure for machine-specific, per-function data.  This is
439   added to the cfun structure.  */
440typedef struct GTY(()) machine_function
441{
442  /* Symbol for the text label used for pic.  */
443  rtx text_label_symbol;
444
445  /* Register for the text label.  */
446  rtx text_label_rtx;
447
448  /* Register for the pic offset table.  */
449  rtx got_rtx;
450
451  /* The function calls tls_get_addr.  */
452  int calls_tls_get_addr;
453} machine_function;
454
455#ifndef HAVE_AS_TLS
456#define HAVE_AS_TLS 0
457#endif
458