xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/tilegx/tilegx.h (revision 04028aa9310ca9c619eca5cf58ddf1e58624d1d7)
1 /* Definitions of target machine for GNU compiler for TILE-Gx.
2    Copyright (C) 2011-2013 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 /* This is used by tilegx_cpu_cpp_builtins to indicate the byte order
22    we're compiling for.  */
23 #define TILEGX_CPU_CPP_ENDIAN_BUILTINS()	\
24   do						\
25     {						\
26       if (TARGET_BIG_ENDIAN)			\
27 	builtin_define ("__BIG_ENDIAN__");	\
28       else					\
29 	builtin_define ("__LITTLE_ENDIAN__");	\
30     }						\
31   while (0)
32 
33 #include "config/tilegx/tilegx-opts.h"
34 
35 
36 /* Target CPU builtins.  */
37 #define TARGET_CPU_CPP_BUILTINS() \
38   tilegx_cpu_cpp_builtins (pfile)
39 
40 #undef PTRDIFF_TYPE
41 #define PTRDIFF_TYPE (TARGET_32BIT ? "int" : "long int")
42 
43 #undef SIZE_TYPE
44 #define SIZE_TYPE (TARGET_32BIT ? "unsigned int" : "long unsigned int")
45 
46 #undef WCHAR_TYPE
47 #define WCHAR_TYPE "int"
48 
49 #undef WCHAR_TYPE_SIZE
50 #define WCHAR_TYPE_SIZE 32
51 
52 
53 /* Target machine storage layout */
54 
55 #define TARGET_BIG_ENDIAN 0
56 #define BITS_BIG_ENDIAN 0
57 #define BYTES_BIG_ENDIAN TARGET_BIG_ENDIAN
58 #define WORDS_BIG_ENDIAN TARGET_BIG_ENDIAN
59 
60 #define UNITS_PER_WORD 8
61 #define PARM_BOUNDARY BITS_PER_WORD
62 #define STACK_BOUNDARY 64
63 #define FUNCTION_BOUNDARY 64
64 #define BIGGEST_ALIGNMENT 64
65 #define STRICT_ALIGNMENT 1
66 
67 #define INT_TYPE_SIZE         32
68 #define LONG_TYPE_SIZE        (TARGET_32BIT ? 32 : 64)
69 #define LONG_LONG_TYPE_SIZE   64
70 #define FLOAT_TYPE_SIZE       32
71 #define DOUBLE_TYPE_SIZE      64
72 #define LONG_DOUBLE_TYPE_SIZE 64
73 #define POINTER_SIZE          LONG_TYPE_SIZE
74 
75 #define PCC_BITFIELD_TYPE_MATTERS 1
76 #define FASTEST_ALIGNMENT 64
77 #define BIGGEST_FIELD_ALIGNMENT 64
78 #define WIDEST_HARDWARE_FP_SIZE 64
79 
80 /* Unaligned moves trap and are very slow.  */
81 #define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) 1
82 
83 /* Make strings word-aligned so strcpy from constants will be
84    faster.  */
85 #define CONSTANT_ALIGNMENT(EXP, ALIGN)  \
86   ((TREE_CODE (EXP) == STRING_CST	\
87     && (ALIGN) < FASTEST_ALIGNMENT)	\
88    ? FASTEST_ALIGNMENT : (ALIGN))
89 
90 /* Make arrays of chars word-aligned for the same reasons.  */
91 #define DATA_ALIGNMENT(TYPE, ALIGN)		\
92   (TREE_CODE (TYPE) == ARRAY_TYPE		\
93    && TYPE_MODE (TREE_TYPE (TYPE)) == QImode	\
94    && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
95 
96 /* Make local arrays of chars word-aligned for the same reasons.  */
97 #define LOCAL_ALIGNMENT(TYPE, ALIGN) DATA_ALIGNMENT (TYPE, ALIGN)
98 
99 
100 /* Standard register usage.  */
101 
102 #define FIRST_PSEUDO_REGISTER (64 + 4)
103 
104 #define FIXED_REGISTERS \
105  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
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, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, \
109   1, 1, 1, 1}
110 #define CALL_USED_REGISTERS \
111  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
112   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
115   1, 1, 1, 1}
116 
117 #define CALL_REALLY_USED_REGISTERS \
118  CALL_USED_REGISTERS
119 
120 #define REG_ALLOC_ORDER {				\
121       10, 11, 12, 13, 14, /* call used */		\
122       15, 16, 17, 18, 19,				\
123       20, 21, 22, 23, 24,				\
124       25, 26, 27, 28, 29,				\
125 							\
126       9, 8, 7, 6, 5,      /* argument */		\
127       4, 3, 2, 1, 0,					\
128 							\
129       55,	          /* return address */		\
130 							\
131       30, 31, 32, 33, 34, /* call saved registers */	\
132       35, 36, 37, 38, 39,				\
133       40, 41, 42, 43, 44,				\
134       45, 46, 47, 48, 49,				\
135       50, 51,						\
136 							\
137       52, 		  /* hard frame pointer */	\
138       53, 54, 		  /* tp, sp */			\
139 							\
140       56, 57, 58, 59, 60, /* special purpose */		\
141       61, 62, 63, 64, 65, /* or fake registers */	\
142       66, 67						\
143 }
144 
145 #define HARD_REGNO_NREGS(REGNO, MODE)	\
146   ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
147 
148 #define HARD_REGNO_MODE_OK(REGNO, MODE) 1
149 
150 #define MODES_TIEABLE_P(MODE1, MODE2)  1
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
244 #define FRAME_GROWS_DOWNWARD 1
245 #define STARTING_FRAME_OFFSET 0
246 
247 #define DYNAMIC_CHAIN_ADDRESS(FRAME) \
248   plus_constant (Pmode, (FRAME), UNITS_PER_WORD)
249 
250 #define FIRST_PARM_OFFSET(FNDECL) 0
251 
252 #define ACCUMULATE_OUTGOING_ARGS 1
253 
254 #define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1
255 
256 #define INCOMING_FRAME_SP_OFFSET 0
257 
258 #define STACK_POINTER_OFFSET (2 * UNITS_PER_WORD)
259 
260 #define ARG_POINTER_CFA_OFFSET(FNDECL) (-STACK_POINTER_OFFSET)
261 
262 #define DEFAULT_PCC_STRUCT_RETURN 0
263 
264 /* The first 10 registers may hold return value.  */
265 #define TILEGX_NUM_RETURN_REGS 10
266 
267 /* The first 10 registers hold function arguments.  */
268 #define TILEGX_NUM_ARG_REGS 10
269 
270 #define FUNCTION_ARG_REGNO_P(N) ((N) < TILEGX_NUM_ARG_REGS)
271 
272 /* The type used to store the number of words of arguments scanned so
273    far during argument scanning.  This includes any space that is
274    skipped.  */
275 #define CUMULATIVE_ARGS int
276 
277 #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
278  ((CUM) = 0)
279 
280 
281 #define ELIMINABLE_REGS					\
282   {{ARG_POINTER_REGNUM,	 STACK_POINTER_REGNUM},		\
283   {ARG_POINTER_REGNUM,	 HARD_FRAME_POINTER_REGNUM},	\
284   {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},		\
285   {FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
286 
287 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
288   ((OFFSET) = tilegx_initial_elimination_offset((FROM),(TO)))
289 
290 #define PROFILE_BEFORE_PROLOGUE 1
291 
292 #define FUNCTION_PROFILER(FILE, LABELNO) \
293   tilegx_function_profiler (FILE, LABELNO)
294 
295 #define TRAMPOLINE_SIZE (TARGET_32BIT ? 48 : 56)
296 #define TRAMPOLINE_ALIGNMENT 64
297 #define TRAMPOLINE_SECTION text_section
298 
299 
300 /* Call frame debugging information.  */
301 
302 #define INCOMING_RETURN_ADDR_RTX  gen_rtx_REG (Pmode, TILEGX_LINK_REGNUM)
303 
304 #define RETURN_ADDR_RTX tilegx_return_addr
305 
306 #define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (TILEGX_LINK_REGNUM)
307 
308 #define DWARF_ZERO_REG 63
309 
310 #define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N + 12) : INVALID_REGNUM)
311 #define EH_RETURN_STACKADJ_RTX	gen_rtx_REG (Pmode, 11)
312 #define EH_RETURN_HANDLER_RTX tilegx_eh_return_handler_rtx ()
313 
314 #define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
315   tilegx_asm_preferred_eh_data_format ((CODE), (GLOBAL))
316 
317 
318 /* Addressing modes, and classification of registers for them.  */
319 
320 #define HAVE_POST_INCREMENT 1
321 #define HAVE_POST_DECREMENT 1
322 #define HAVE_POST_MODIFY_DISP 1
323 
324 #define REGNO_OK_FOR_INDEX_P(regno) 0
325 #define REGNO_OK_FOR_BASE_P(regno)	\
326   ((regno) < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0)
327 
328 #define MAX_REGS_PER_ADDRESS 1
329 
330 #define CONSTANT_ADDRESS_P(X) 0
331 
332 #define LEGITIMATE_PIC_OPERAND_P(X) tilegx_legitimate_pic_operand_p (X)
333 
334 
335 #define CASE_VECTOR_MODE Pmode
336 #define CASE_VECTOR_PC_RELATIVE 0
337 #define JUMP_TABLES_IN_TEXT_SECTION 0
338 
339 #define DEFAULT_SIGNED_CHAR 1
340 
341 #define MOVE_MAX UNITS_PER_WORD
342 
343 /* Use a value of 11 for MOVE_RATIO and friends, because TILEPro
344    returns structs as large as 10 words in registers.  Because of some
345    some code generation inefficiency, we never get smaller code for
346    turning that into a memcpy, so pick a value that guarantees this
347    doesn't happen.  */
348 #define TILEGX_CALL_RATIO 11
349 #define MOVE_RATIO(speed) ((speed) ? 15 : TILEGX_CALL_RATIO)
350 #define CLEAR_RATIO(speed) ((speed) ? 15 : TILEGX_CALL_RATIO)
351 #define SET_RATIO(speed) ((speed) ? 15 : TILEGX_CALL_RATIO)
352 
353 #define WORD_REGISTER_OPERATIONS
354 
355 #define LOAD_EXTEND_OP(MODE) ((MODE) == SImode ? SIGN_EXTEND : ZERO_EXTEND)
356 
357 #define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE)	\
358   if (GET_MODE_CLASS (MODE) == MODE_INT		\
359       && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
360     {                                           \
361       if ((MODE) == SImode)                     \
362         (UNSIGNEDP) = 0;                        \
363       (MODE) = DImode;                          \
364     }
365 
366 /* Define SLOW_BYTE_ACCESS to avoid making a QI or HI mode
367    register.  */
368 #define SLOW_BYTE_ACCESS 1
369 
370 #define SHIFT_COUNT_TRUNCATED 0
371 
372 #define SHORT_IMMEDIATES_SIGN_EXTEND
373 
374 /* We represent all SI values as sign-extended DI values in
375    registers.  */
376 #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) \
377   ((INPREC) <= 32 || (OUTPREC) > 32)
378 
379 #define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 64, 1)
380 #define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 64, 1)
381 
382 #define Pmode (TARGET_32BIT ? SImode : DImode)
383 
384 #define STACK_SIZE_MODE Pmode
385 
386 #define STORE_FLAG_VALUE 1
387 
388 #define FUNCTION_MODE DImode
389 
390 #define NO_FUNCTION_CSE 1
391 
392 #define ADJUST_INSN_LENGTH(INSN, LENGTH) \
393   ((LENGTH) = tilegx_adjust_insn_length ((INSN), (LENGTH)))
394 
395 #define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
396 
397 #define BRANCH_COST(speed_p, predictable_p) ((predictable_p) ? 2 : 6)
398 
399 
400 /* Control the assembler format that we output.  */
401 
402 #undef NO_DOLLAR_IN_LABEL
403 
404 #define ASM_COMMENT_START "##"
405 
406 #define TEXT_SECTION_ASM_OP "\t.text"
407 
408 #define DATA_SECTION_ASM_OP "\t.data"
409 
410 #undef READONLY_DATA_SECTION_ASM_OP
411 #define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rodata, \"a\""
412 
413 #undef BSS_SECTION_ASM_OP
414 #define BSS_SECTION_ASM_OP	"\t.section\t.bss, \"wa\""
415 
416 #undef INIT_SECTION_ASM_OP
417 #define INIT_SECTION_ASM_OP	"\t.section\t.init, \"ax\""
418 
419 #undef FINI_SECTION_ASM_OP
420 #define FINI_SECTION_ASM_OP	"\t.section\t.fini, \"ax\""
421 
422 #define GLOBAL_ASM_OP ".global "
423 
424 #define SUPPORTS_WEAK 1
425 
426 #define USER_LABEL_PREFIX ""
427 
428 #define REGISTER_PREFIX ""
429 #define REGISTER_NAMES                                                  \
430   { "r0",   "r1",   "r2",   "r3",   "r4",   "r5",   "r6",   "r7",       \
431     "r8",   "r9",   "r10",  "r11",  "r12",  "r13",  "r14",  "r15",      \
432     "r16",  "r17",  "r18",  "r19",  "r20",  "r21",  "r22",  "r23",      \
433     "r24",  "r25",  "r26",  "r27",  "r28",  "r29",  "r30",  "r31",      \
434     "r32",  "r33",  "r34",  "r35",  "r36",  "r37",  "r38",  "r39",      \
435     "r40",  "r41",  "r42",  "r43",  "r44",  "r45",  "r46",  "r47",      \
436     "r48",  "r49",  "r50",  "r51",  "r52",  "tp",   "sp",   "lr",       \
437     "?r56?","idn0", "idn1", "udn0", "udn1", "udn2", "udn3", "zero",     \
438     "?FRAME?", "?ARG?", "?CMPEXCH?", "?NET?" }
439 
440 #define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
441   tilegx_final_prescan_insn (insn)
442 
443 #define ASM_OUTPUT_OPCODE(STREAM, PTR)	\
444   (PTR = tilegx_asm_output_opcode (STREAM, PTR))
445 
446 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)			\
447   do								\
448     {								\
449       char label[256];						\
450       ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE));	\
451       fprintf (FILE, "%s ",					\
452                integer_asm_op (GET_MODE_SIZE (Pmode), TRUE));	\
453       assemble_name (FILE, label);				\
454       fprintf (FILE, "\n");					\
455     }								\
456   while (0)
457 
458 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)	\
459   do								\
460     {								\
461       char label[256];						\
462       ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE));	\
463       fprintf (FILE, "%s ", 					\
464                integer_asm_op (GET_MODE_SIZE (Pmode), TRUE));	\
465       assemble_name (FILE, label);				\
466       ASM_GENERATE_INTERNAL_LABEL (label, "L", (REL));		\
467       fprintf (FILE, "-");					\
468       assemble_name (FILE, label);				\
469       fprintf (FILE, "\n");					\
470     }								\
471   while (0)
472 
473 #define ASM_OUTPUT_ALIGN(FILE,LOG)  \
474   do { if ((LOG) != 0) fprintf (FILE, "\t.align %d\n", 1 << (LOG)); } while (0)
475 
476 #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)	\
477   ( fputs (".comm ", (FILE)),				\
478     assemble_name ((FILE), (NAME)),			\
479     fprintf ((FILE), ",%u\n", (unsigned int)(ROUNDED)))
480 
481 #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)	\
482   ( fputs (".lcomm ", (FILE)),				\
483     assemble_name ((FILE), (NAME)),			\
484     fprintf ((FILE), ",%u\n", (unsigned int)(ROUNDED)))
485 
486 #define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC)		\
487 static void __attribute__((__used__))				\
488 call_ ## FUNC (void)						\
489 {								\
490   asm (SECTION_OP);						\
491   asm ("{ moveli r0, hw2_last(" #FUNC " - . - 8); lnk r1 }\n");	\
492   asm ("shl16insli r0, r0, hw1(" #FUNC " - .)\n");		\
493   asm ("shl16insli r0, r0, hw0(" #FUNC " - . + 8)\n");		\
494   asm ("add r0, r1, r0\n");					\
495   asm ("jalr r0\n");						\
496   asm (TEXT_SECTION_ASM_OP);					\
497 }
498 
499 
500 
501 #define INIT_EXPANDERS tilegx_init_expanders ()
502 
503 /* A C structure for machine-specific, per-function data.  This is
504    added to the cfun structure.  */
505 typedef struct GTY(()) machine_function
506 {
507   /* Symbol for the text label used for pic.  */
508   rtx text_label_symbol;
509 
510   /* Register for the text label.  */
511   rtx text_label_rtx;
512 
513   /* Register for the pic offset table.  */
514   rtx got_rtx;
515 
516   /* The function calls tls_get_addr.  */
517   int calls_tls_get_addr;
518 } machine_function;
519 
520 #ifndef HAVE_AS_TLS
521 #define HAVE_AS_TLS 0
522 #endif
523