]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/tilegx/tilegx.h
Add support for the -mcmodel=MODEL flag on TILE-Gx.
[thirdparty/gcc.git] / gcc / config / tilegx / tilegx.h
CommitLineData
dd552284
WL
1/* Definitions of target machine for GNU compiler for TILE-Gx.
2 Copyright (C) 2011, 2012
3 Free Software Foundation, Inc.
4 Contributed by Walter Lee (walt@tilera.com)
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published
10 by the Free Software Foundation; either version 3, or (at your
11 option) any later version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
21
22/* This is used by tilegx_cpu_cpp_builtins to indicate the byte order
23 we're compiling for. */
24#define TILEGX_CPU_CPP_ENDIAN_BUILTINS() \
25 do \
26 { \
27 if (TARGET_BIG_ENDIAN) \
28 builtin_define ("__BIG_ENDIAN__"); \
29 else \
30 builtin_define ("__LITTLE_ENDIAN__"); \
31 } \
32 while (0)
33
1773cd77
WL
34#include "config/tilegx/tilegx-opts.h"
35
dd552284
WL
36
37/* Target CPU builtins. */
38#define TARGET_CPU_CPP_BUILTINS() \
39 tilegx_cpu_cpp_builtins (pfile)
40
41#undef PTRDIFF_TYPE
42#define PTRDIFF_TYPE (TARGET_32BIT ? "int" : "long int")
43
44#undef SIZE_TYPE
45#define SIZE_TYPE (TARGET_32BIT ? "unsigned int" : "long unsigned int")
46
47#undef WCHAR_TYPE
48#define WCHAR_TYPE "int"
49
50#undef WCHAR_TYPE_SIZE
51#define WCHAR_TYPE_SIZE 32
52\f
53
54/* Target machine storage layout */
55
56#define TARGET_BIG_ENDIAN 0
57#define BITS_BIG_ENDIAN 0
58#define BYTES_BIG_ENDIAN TARGET_BIG_ENDIAN
59#define WORDS_BIG_ENDIAN TARGET_BIG_ENDIAN
60
61#define UNITS_PER_WORD 8
62#define PARM_BOUNDARY BITS_PER_WORD
63#define STACK_BOUNDARY 64
64#define FUNCTION_BOUNDARY 64
65#define BIGGEST_ALIGNMENT 64
66#define STRICT_ALIGNMENT 1
67
68#define INT_TYPE_SIZE 32
69#define LONG_TYPE_SIZE (TARGET_32BIT ? 32 : 64)
70#define LONG_LONG_TYPE_SIZE 64
71#define FLOAT_TYPE_SIZE 32
72#define DOUBLE_TYPE_SIZE 64
73#define LONG_DOUBLE_TYPE_SIZE 64
74#define POINTER_SIZE LONG_TYPE_SIZE
75
76#define PCC_BITFIELD_TYPE_MATTERS 1
77#define FASTEST_ALIGNMENT 64
78#define BIGGEST_FIELD_ALIGNMENT 64
79#define WIDEST_HARDWARE_FP_SIZE 64
80
81/* Unaligned moves trap and are very slow. */
82#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) 1
83
84/* Make strings word-aligned so strcpy from constants will be
85 faster. */
86#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
87 ((TREE_CODE (EXP) == STRING_CST \
88 && (ALIGN) < FASTEST_ALIGNMENT) \
89 ? FASTEST_ALIGNMENT : (ALIGN))
90
91/* Make arrays of chars word-aligned for the same reasons. */
92#define DATA_ALIGNMENT(TYPE, ALIGN) \
93 (TREE_CODE (TYPE) == ARRAY_TYPE \
94 && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
95 && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
96
97/* Make local arrays of chars word-aligned for the same reasons. */
98#define LOCAL_ALIGNMENT(TYPE, ALIGN) DATA_ALIGNMENT (TYPE, ALIGN)
99\f
100
101/* Standard register usage. */
102
103#define FIRST_PSEUDO_REGISTER (64 + 4)
104
105#define FIXED_REGISTERS \
106 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
108 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
109 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, \
110 1, 1, 1, 1}
111#define CALL_USED_REGISTERS \
112 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
113 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
116 1, 1, 1, 1}
117
118#define CALL_REALLY_USED_REGISTERS \
119 CALL_USED_REGISTERS
120
121#define REG_ALLOC_ORDER { \
122 10, 11, 12, 13, 14, /* call used */ \
123 15, 16, 17, 18, 19, \
124 20, 21, 22, 23, 24, \
125 25, 26, 27, 28, 29, \
126 \
127 9, 8, 7, 6, 5, /* argument */ \
128 4, 3, 2, 1, 0, \
129 \
130 55, /* return address */ \
131 \
132 30, 31, 32, 33, 34, /* call saved registers */ \
133 35, 36, 37, 38, 39, \
134 40, 41, 42, 43, 44, \
135 45, 46, 47, 48, 49, \
136 50, 51, \
137 \
138 52, /* hard frame pointer */ \
139 53, 54, /* tp, sp */ \
140 \
141 56, 57, 58, 59, 60, /* special purpose */ \
142 61, 62, 63, 64, 65, /* or fake registers */ \
143 66, 67 \
144}
145
146#define HARD_REGNO_NREGS(REGNO, MODE) \
147 ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
148
149#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
150
151#define MODES_TIEABLE_P(MODE1, MODE2) 1
152
153/* Register that holds an address into the text segment that can be
154 used by pic code. */
155#define TILEGX_PIC_TEXT_LABEL_REGNUM (flag_pic ? 50 : INVALID_REGNUM)
156#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 51 : INVALID_REGNUM)
157#define HARD_FRAME_POINTER_REGNUM 52
158#define THREAD_POINTER_REGNUM 53
159#define STACK_POINTER_REGNUM 54
160#define TILEGX_LINK_REGNUM 55
161#define FRAME_POINTER_REGNUM 64
162#define ARG_POINTER_REGNUM 65
163/* SPR storing the comparison value for compare and exchange. */
164#define TILEGX_CMPEXCH_REGNUM 66
165/* Pseudo registers used to enforce order between instructions that
166 touch the networks. */
167#define TILEGX_NETORDER_REGNUM 67
168#define STATIC_CHAIN_REGNUM 10
169\f
170
171enum reg_class
172{
173 NO_REGS,
174 R0_REGS,
175 R1_REGS,
176 R2_REGS,
177 R3_REGS,
178 R4_REGS,
179 R5_REGS,
180 R6_REGS,
181 R7_REGS,
182 R8_REGS,
183 R9_REGS,
184 R10_REGS,
185 ALL_REGS,
186 LIM_REG_CLASSES
187};
188
189#define N_REG_CLASSES (int) LIM_REG_CLASSES
190
191/* Since GENERAL_REGS is the same class as ALL_REGS, don't give it a
192 different class number; just make it an alias. */
193#define GENERAL_REGS ALL_REGS
194
195#define REG_CLASS_NAMES \
196 { \
197 "NO_REGS", \
198 "R0_REGS", \
199 "R1_REGS", \
200 "R2_REGS", \
201 "R3_REGS", \
202 "R4_REGS", \
203 "R5_REGS", \
204 "R6_REGS", \
205 "R7_REGS", \
206 "R8_REGS", \
207 "R9_REGS", \
208 "R10_REGS", \
209 "ALL_REGS" \
210 }
211
212#define REG_CLASS_CONTENTS \
213 { \
214 { 0 }, \
215 { 1 << 0 }, \
216 { 1 << 1 }, \
217 { 1 << 2 }, \
218 { 1 << 3 }, \
219 { 1 << 4 }, \
220 { 1 << 5 }, \
221 { 1 << 6 }, \
222 { 1 << 7 }, \
223 { 1 << 8 }, \
224 { 1 << 9 }, \
225 { 1 << 10 }, \
226 { 0xffffffff, 0xffffffff } \
227 }
228
229#define REGNO_REG_CLASS(REGNO) \
230 ((unsigned)(REGNO) <= 10 ? \
231 (enum reg_class)(R0_REGS + (REGNO)) : ALL_REGS)
232
233#define INDEX_REG_CLASS NO_REGS
234#define BASE_REG_CLASS ALL_REGS
235
236#define PREFERRED_RELOAD_CLASS(X,CLASS) (CLASS)
237
238#define CLASS_MAX_NREGS(CLASS, MODE) \
239 ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
240\f
241
242/* Stack layout; function entry, exit and calling. */
243
244#define STACK_GROWS_DOWNWARD
245#define FRAME_GROWS_DOWNWARD 1
246#define STARTING_FRAME_OFFSET 0
247
0a81f074
RS
248#define DYNAMIC_CHAIN_ADDRESS(FRAME) \
249 plus_constant (Pmode, (FRAME), UNITS_PER_WORD)
dd552284
WL
250
251#define FIRST_PARM_OFFSET(FNDECL) 0
252
253#define ACCUMULATE_OUTGOING_ARGS 1
254
255#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1
256
257#define INCOMING_FRAME_SP_OFFSET 0
258
259#define STACK_POINTER_OFFSET (2 * UNITS_PER_WORD)
260
261#define ARG_POINTER_CFA_OFFSET(FNDECL) (-STACK_POINTER_OFFSET)
262
263#define DEFAULT_PCC_STRUCT_RETURN 0
264
265/* The first 10 registers may hold return value. */
266#define TILEGX_NUM_RETURN_REGS 10
267
268/* The first 10 registers hold function arguments. */
269#define TILEGX_NUM_ARG_REGS 10
270
271#define FUNCTION_ARG_REGNO_P(N) ((N) < TILEGX_NUM_ARG_REGS)
272
273/* The type used to store the number of words of arguments scanned so
274 far during argument scanning. This includes any space that is
275 skipped. */
276#define CUMULATIVE_ARGS int
277
278#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
279 ((CUM) = 0)
280\f
281
282#define ELIMINABLE_REGS \
283 {{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
284 {ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
285 {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
286 {FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
287
288#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
289 ((OFFSET) = tilegx_initial_elimination_offset((FROM),(TO)))
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\f
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\f
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\f
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
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
372
373/* We represent all SI values as sign-extended DI values in
374 registers. */
375#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) \
376 ((INPREC) <= 32 || (OUTPREC) > 32)
377
378#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 64, 1)
379#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 64, 1)
380
381#define Pmode (TARGET_32BIT ? SImode : DImode)
382
383#define STACK_SIZE_MODE Pmode
384
385#define STORE_FLAG_VALUE 1
386
387#define FUNCTION_MODE DImode
388
389#define NO_FUNCTION_CSE 1
390
391#define ADJUST_INSN_LENGTH(INSN, LENGTH) \
392 ((LENGTH) = tilegx_adjust_insn_length ((INSN), (LENGTH)))
393
394#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
395
396#define BRANCH_COST(speed_p, predictable_p) ((predictable_p) ? 2 : 6)
397\f
398
399/* Control the assembler format that we output. */
400
401#undef NO_DOLLAR_IN_LABEL
402
403#define ASM_COMMENT_START "##"
404
405#define TEXT_SECTION_ASM_OP "\t.text"
406
407#define DATA_SECTION_ASM_OP "\t.data"
408
409#undef READONLY_DATA_SECTION_ASM_OP
410#define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rodata, \"a\""
411
412#undef BSS_SECTION_ASM_OP
413#define BSS_SECTION_ASM_OP "\t.section\t.bss, \"wa\""
414
415#undef INIT_SECTION_ASM_OP
416#define INIT_SECTION_ASM_OP "\t.section\t.init, \"ax\""
417
418#undef FINI_SECTION_ASM_OP
419#define FINI_SECTION_ASM_OP "\t.section\t.fini, \"ax\""
420
421#define GLOBAL_ASM_OP ".global "
422
423#define SUPPORTS_WEAK 1
424
425#define USER_LABEL_PREFIX ""
426
427#define REGISTER_PREFIX ""
428#define REGISTER_NAMES \
429 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
430 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
431 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
432 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", \
433 "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", \
434 "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47", \
435 "r48", "r49", "r50", "r51", "r52", "tp", "sp", "lr", \
436 "?r56?","idn0", "idn1", "udn0", "udn1", "udn2", "udn3", "zero", \
437 "?FRAME?", "?ARG?", "?CMPEXCH?", "?NET?" }
438
439#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
440 tilegx_final_prescan_insn (insn)
441
442#define ASM_OUTPUT_OPCODE(STREAM, PTR) \
443 (PTR = tilegx_asm_output_opcode (STREAM, PTR))
444
445#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
446 do \
447 { \
448 char label[256]; \
449 ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE)); \
450 fprintf (FILE, "\t%s ", \
451 integer_asm_op (GET_MODE_SIZE (Pmode), TRUE)); \
452 assemble_name (FILE, label); \
453 fprintf (FILE, "\n"); \
454 } \
455 while (0)
456
457#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
458 do \
459 { \
460 char label[256]; \
461 ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE)); \
462 fprintf (FILE, "\t%s ", \
463 integer_asm_op (GET_MODE_SIZE (Pmode), TRUE)); \
464 assemble_name (FILE, label); \
465 ASM_GENERATE_INTERNAL_LABEL (label, "L", (REL)); \
466 fprintf (FILE, "-"); \
467 assemble_name (FILE, label); \
468 fprintf (FILE, "\n"); \
469 } \
470 while (0)
471
472#define ASM_OUTPUT_ALIGN(FILE,LOG) \
473 do { if ((LOG) != 0) fprintf (FILE, "\t.align %d\n", 1 << (LOG)); } while (0)
474
475#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
476 ( fputs (".comm ", (FILE)), \
477 assemble_name ((FILE), (NAME)), \
478 fprintf ((FILE), ",%u\n", (unsigned int)(ROUNDED)))
479
480#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
481 ( fputs (".lcomm ", (FILE)), \
482 assemble_name ((FILE), (NAME)), \
483 fprintf ((FILE), ",%u\n", (unsigned int)(ROUNDED)))
484
1773cd77
WL
485#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
486static void __attribute__((__used__)) \
487call_ ## FUNC (void) \
488{ \
489 asm (SECTION_OP); \
490 asm ("{ moveli r0, hw2_last(" #FUNC " - . - 8); lnk r1 }\n"); \
491 asm ("shl16insli r0, r0, hw1(" #FUNC " - .)\n"); \
492 asm ("shl16insli r0, r0, hw0(" #FUNC " - . + 8)\n"); \
493 asm ("add r0, r1, r0\n"); \
494 asm ("jalr r0\n"); \
495 asm (TEXT_SECTION_ASM_OP); \
496}
497
dd552284
WL
498\f
499
500#define INIT_EXPANDERS tilegx_init_expanders ()
501
502/* A C structure for machine-specific, per-function data. This is
503 added to the cfun structure. */
504typedef struct GTY(()) machine_function
505{
506 /* Symbol for the text label used for pic. */
507 rtx text_label_symbol;
508
509 /* Register for the text label. */
510 rtx text_label_rtx;
511
512 /* Register for the pic offset table. */
513 rtx got_rtx;
514
515 /* The function calls tls_get_addr. */
516 int calls_tls_get_addr;
517} machine_function;
518
519#ifndef HAVE_AS_TLS
520#define HAVE_AS_TLS 0
521#endif