xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/microblaze/microblaze.h (revision 1580a27b92f58fcdcb23fdfbc04a7c2b54a0b7c8)
1 /* Definitions of target machine for GNU compiler for Xilinx MicroBlaze.
2    Copyright (C) 2009-2015 Free Software Foundation, Inc.
3 
4    Contributed by Michael Eager <eager@eagercon.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 /* Standard GCC variables that we reference.  */
23 
24 /* MicroBlaze external variables defined in microblaze.c.  */
25 
26 /* Which pipeline to schedule for.  */
27 enum pipeline_type
28 {
29   MICROBLAZE_PIPE_3 = 0,
30   MICROBLAZE_PIPE_5 = 1
31 };
32 
33 #define MICROBLAZE_MASK_NO_UNSAFE_DELAY         0x00000001
34 
35 /* print_operand punctuation chars */
36 extern char microblaze_print_operand_punct[];
37 
38 /* # bytes of data/sdata cutoff */
39 extern int microblaze_section_threshold;
40 
41 /* Map register # to debug register # */
42 extern int microblaze_dbx_regno[];
43 
44 extern int microblaze_no_unsafe_delay;
45 extern int microblaze_has_clz;
46 extern enum pipeline_type microblaze_pipe;
47 
48 #define OBJECT_FORMAT_ELF
49 
50 #if TARGET_BIG_ENDIAN_DEFAULT
51 #define TARGET_ENDIAN_DEFAULT    0
52 #define TARGET_ENDIAN_OPTION     "mbig-endian"
53 #else
54 #define TARGET_ENDIAN_DEFAULT    MASK_LITTLE_ENDIAN
55 #define TARGET_ENDIAN_OPTION     "mlittle-endian"
56 #endif
57 
58 /* Default target_flags if no switches are specified  */
59 #define TARGET_DEFAULT      (MASK_SOFT_MUL | MASK_SOFT_DIV | MASK_SOFT_FLOAT \
60                              | TARGET_ENDIAN_DEFAULT)
61 
62 /* Do we have CLZ?  */
63 #define TARGET_HAS_CLZ      (TARGET_PATTERN_COMPARE && microblaze_has_clz)
64 
65 /* The default is to support PIC.  */
66 #define TARGET_SUPPORTS_PIC 1
67 
68 /* The default is to not need GOT for TLS.  */
69 #define TLS_NEEDS_GOT 0
70 
71 /* What is the default setting for -mcpu= . We set it to v4.00.a even though
72    we are actually ahead. This is safest version that has generate code
73    compatible for the original ISA */
74 #define MICROBLAZE_DEFAULT_CPU      "v4.00.a"
75 
76 /* Macros to decide whether certain features are available or not,
77    depending on the instruction set architecture level.  */
78 
79 #define DRIVER_SELF_SPECS    				\
80 	"%{mxl-soft-mul:%<mno-xl-soft-mul}", 		\
81 	"%{mno-xl-barrel-shift:%<mxl-barrel-shift}", 	\
82 	"%{mno-xl-pattern-compare:%<mxl-pattern-compare}", \
83 	"%{mxl-soft-div:%<mno-xl-soft-div}", 		\
84 	"%{mxl-reorder:%<mno-xl-reorder}", 		\
85 	"%{msoft-float:%<mhard-float}"
86 
87 /* Tell collect what flags to pass to nm.  */
88 #ifndef NM_FLAGS
89 #define NM_FLAGS "-Bn"
90 #endif
91 
92 /* Names to predefine in the preprocessor for this target machine.  */
93 #define TARGET_CPU_CPP_BUILTINS() microblaze_cpp_define (pfile)
94 
95 /* Assembler specs.  */
96 
97 #define TARGET_ASM_SPEC ""
98 
99 #define ASM_SPEC "\
100 %(target_asm_spec) \
101 %{mbig-endian:-EB} \
102 %{mlittle-endian:-EL}"
103 
104 /* Extra switches sometimes passed to the linker.  */
105 /* -xl-mode-xmdstub translated to -Zxl-mode-xmdstub -- deprecated.  */
106 
107 #define LINK_SPEC "%{shared:-shared} -N -relax \
108   %{mbig-endian:-EB --oformat=elf32-microblaze} \
109   %{mlittle-endian:-EL --oformat=elf32-microblazeel} \
110   %{Zxl-mode-xmdstub:-defsym _TEXT_START_ADDR=0x800} \
111   %{mxl-mode-xmdstub:-defsym _TEXT_START_ADDR=0x800} \
112   %{mxl-gp-opt:%{G*}} %{!mxl-gp-opt: -G 0} \
113   %{!T*: -dT xilinx.ld%s}"
114 
115 /* Specs for the compiler proper  */
116 
117 #ifndef CC1_SPEC
118 #define CC1_SPEC " \
119 %{G*} \
120 %(subtarget_cc1_spec) \
121 %{mxl-multiply-high:-mcpu=v6.00.a} \
122 "
123 #endif
124 
125 #define EXTRA_SPECS							\
126   { "target_asm_spec", TARGET_ASM_SPEC },				\
127   SUBTARGET_EXTRA_SPECS
128 
129 /* Local compiler-generated symbols must have a prefix that the assembler
130    understands.   */
131 
132 #ifndef LOCAL_LABEL_PREFIX
133 #define LOCAL_LABEL_PREFIX	"$"
134 #endif
135 
136 /* fixed registers.  */
137 #define MB_ABI_BASE_REGNUM                   0
138 #define MB_ABI_STACK_POINTER_REGNUM          1
139 #define MB_ABI_GPRO_REGNUM                   2
140 #define MB_ABI_GPRW_REGNUM                  13
141 #define MB_ABI_INTR_RETURN_ADDR_REGNUM      14
142 #define MB_ABI_SUB_RETURN_ADDR_REGNUM       15
143 #define MB_ABI_DEBUG_RETURN_ADDR_REGNUM     16
144 #define MB_ABI_EXCEPTION_RETURN_ADDR_REGNUM 17
145 #define MB_ABI_ASM_TEMP_REGNUM              18
146 /* This is our temp register.  */
147 #define MB_ABI_FRAME_POINTER_REGNUM         19
148 #define MB_ABI_PIC_ADDR_REGNUM              20
149 #define MB_ABI_PIC_FUNC_REGNUM              21
150 /* Volatile registers.  */
151 #define MB_ABI_INT_RETURN_VAL_REGNUM         3
152 #define MB_ABI_INT_RETURN_VAL2_REGNUM        4
153 #define MB_ABI_FIRST_ARG_REGNUM              5
154 #define MB_ABI_LAST_ARG_REGNUM              10
155 #define MB_ABI_MAX_ARG_REGS                 (MB_ABI_LAST_ARG_REGNUM 	\
156 					     - MB_ABI_FIRST_ARG_REGNUM + 1)
157 #define MB_ABI_STATIC_CHAIN_REGNUM           3
158 #define MB_ABI_TEMP1_REGNUM                 11
159 #define MB_ABI_TEMP2_REGNUM                 12
160 #define MB_ABI_MSR_SAVE_REG                 11
161 /* Volatile register used to save MSR in interrupt handlers.  */
162 
163 
164 /* Debug stuff.  */
165 
166 /* How to renumber registers for dbx and gdb.  */
167 #define DBX_REGISTER_NUMBER(REGNO) microblaze_dbx_regno[(REGNO)]
168 
169 /* Generate DWARF exception handling info.  */
170 #define DWARF2_UNWIND_INFO 1
171 
172 /* Don't generate .loc operations.  */
173 #define DWARF2_ASM_LINE_DEBUG_INFO 0
174 
175 /* The DWARF 2 CFA column which tracks the return address.  */
176 #define DWARF_FRAME_RETURN_COLUMN \
177 	(GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM)
178 
179 /* Initial state of return address on entry to func = R15.
180    Actually, the RA is at R15+8, but gcc doesn't know how
181    to generate this.
182    NOTE:  GDB has a workaround and expects this incorrect value.
183    If this is fixed, a corresponding fix to GDB is needed.  */
184 #define INCOMING_RETURN_ADDR_RTX  			\
185   gen_rtx_REG (VOIDmode, GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM)
186 
187 /* Use DWARF 2 debugging information by default.  */
188 #define DWARF2_DEBUGGING_INFO
189 #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
190 
191 /* Target machine storage layout */
192 
193 #define BITS_BIG_ENDIAN 0
194 #define BYTES_BIG_ENDIAN (TARGET_LITTLE_ENDIAN == 0)
195 #define WORDS_BIG_ENDIAN (BYTES_BIG_ENDIAN)
196 #define BITS_PER_WORD           32
197 #define UNITS_PER_WORD          4
198 #define MIN_UNITS_PER_WORD      4
199 #define INT_TYPE_SIZE           32
200 #define SHORT_TYPE_SIZE         16
201 #define LONG_TYPE_SIZE          32
202 #define LONG_LONG_TYPE_SIZE     64
203 #define FLOAT_TYPE_SIZE         32
204 #define DOUBLE_TYPE_SIZE        64
205 #define LONG_DOUBLE_TYPE_SIZE   64
206 #define POINTER_SIZE            32
207 #define PARM_BOUNDARY           32
208 #define FUNCTION_BOUNDARY       32
209 #define EMPTY_FIELD_BOUNDARY    32
210 #define STRUCTURE_SIZE_BOUNDARY 8
211 #define BIGGEST_ALIGNMENT       32
212 #define STRICT_ALIGNMENT        1
213 #define PCC_BITFIELD_TYPE_MATTERS 1
214 
215 #undef SIZE_TYPE
216 #define SIZE_TYPE "unsigned int"
217 
218 #undef PTRDIFF_TYPE
219 #define PTRDIFF_TYPE "int"
220 
221 #define CONSTANT_ALIGNMENT(EXP, ALIGN)					\
222   ((TREE_CODE (EXP) == STRING_CST  || TREE_CODE (EXP) == CONSTRUCTOR)	\
223    && (ALIGN) < BITS_PER_WORD						\
224 	? BITS_PER_WORD							\
225 	: (ALIGN))
226 
227 #define DATA_ALIGNMENT(TYPE, ALIGN)					\
228   ((((ALIGN) < BITS_PER_WORD)						\
229     && (TREE_CODE (TYPE) == ARRAY_TYPE					\
230 	|| TREE_CODE (TYPE) == UNION_TYPE				\
231 	|| TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
232 
233 #define LOCAL_ALIGNMENT(TYPE, ALIGN)     				\
234     (((TREE_CODE (TYPE) == ARRAY_TYPE 					\
235        && TYPE_MODE (TREE_TYPE (TYPE)) == QImode)			\
236      && (ALIGN) < BITS_PER_WORD) ? BITS_PER_WORD : (ALIGN))
237 
238 #define WORD_REGISTER_OPERATIONS
239 
240 #define LOAD_EXTEND_OP(MODE)  ZERO_EXTEND
241 
242 #define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE)	\
243   if (GET_MODE_CLASS (MODE) == MODE_INT		\
244       && GET_MODE_SIZE (MODE) < 4)		\
245     (MODE) = SImode;
246 
247 /* Standard register usage.  */
248 
249 /* On the MicroBlaze, we have 32 integer registers */
250 
251 #define FIRST_PSEUDO_REGISTER 36
252 
253 #define FIXED_REGISTERS							\
254 {									\
255   1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,			\
256   1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,			\
257   1, 1, 1, 1 								\
258 }
259 
260 #define CALL_USED_REGISTERS						\
261 {									\
262   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,			\
263   1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,			\
264   1, 1, 1, 1								\
265 }
266 #define GP_REG_FIRST    0
267 #define GP_REG_LAST     31
268 #define GP_REG_NUM      (GP_REG_LAST - GP_REG_FIRST + 1)
269 #define GP_DBX_FIRST    0
270 
271 #define ST_REG		32
272 #define AP_REG_NUM      33
273 #define RAP_REG_NUM     34
274 #define FRP_REG_NUM     35
275 
276 #define GP_REG_P(REGNO) ((unsigned) ((REGNO) - GP_REG_FIRST) < GP_REG_NUM)
277 #define ST_REG_P(REGNO) ((REGNO) == ST_REG)
278 
279 #define HARD_REGNO_NREGS(REGNO, MODE)					\
280 	((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
281 
282 /* Value is 1 if hard register REGNO can hold a value of machine-mode
283    MODE.  In 32 bit mode, require that DImode and DFmode be in even
284    registers.  For DImode, this makes some of the insns easier to
285    write, since you don't have to worry about a DImode value in
286    registers 3 & 4, producing a result in 4 & 5.
287 
288    To make the code simpler HARD_REGNO_MODE_OK now just references an
289    array built in override_options.  Because machmodes.h is not yet
290    included before this file is processed, the MODE bound can't be
291    expressed here.  */
292 extern char microblaze_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER];
293 #define HARD_REGNO_MODE_OK(REGNO, MODE)					\
294             microblaze_hard_regno_mode_ok[ (int)(MODE) ][ (REGNO)]
295 
296 #define MODES_TIEABLE_P(MODE1, MODE2)					\
297   ((GET_MODE_CLASS (MODE1) == MODE_FLOAT ||				\
298     GET_MODE_CLASS (MODE1) == MODE_COMPLEX_FLOAT)			\
299    == (GET_MODE_CLASS (MODE2) == MODE_FLOAT ||				\
300        GET_MODE_CLASS (MODE2) == MODE_COMPLEX_FLOAT))
301 
302 #define STACK_POINTER_REGNUM   (GP_REG_FIRST + MB_ABI_STACK_POINTER_REGNUM)
303 
304 #define STACK_POINTER_OFFSET   FIRST_PARM_OFFSET(FNDECL)
305 
306 /* Base register for access to local variables of the function.  We
307    pretend that the frame pointer is
308    MB_ABI_INTR_RETURN_ADDR_REGNUM, and then eliminate it
309    to HARD_FRAME_POINTER_REGNUM.  We can get away with this because
310    rMB_ABI_INTR_RETUREN_ADDR_REGNUM is a fixed
311    register(return address for interrupt), and will not be used for
312    anything else.  */
313 
314 #define FRAME_POINTER_REGNUM 		FRP_REG_NUM
315 #define HARD_FRAME_POINTER_REGNUM       \
316         (GP_REG_FIRST + MB_ABI_FRAME_POINTER_REGNUM)
317 #define ARG_POINTER_REGNUM		AP_REG_NUM
318 #define RETURN_ADDRESS_POINTER_REGNUM	RAP_REG_NUM
319 #define STATIC_CHAIN_REGNUM             \
320         (GP_REG_FIRST + MB_ABI_STATIC_CHAIN_REGNUM)
321 
322 /* registers used in prologue/epilogue code when the stack frame
323    is larger than 32K bytes.  These registers must come from the
324    scratch register set, and not used for passing and returning
325    arguments and any other information used in the calling sequence
326    (such as pic).  */
327 
328 #define MICROBLAZE_TEMP1_REGNUM         \
329         (GP_REG_FIRST + MB_ABI_TEMP1_REGNUM)
330 
331 #define MICROBLAZE_TEMP2_REGNUM         \
332         (GP_REG_FIRST + MB_ABI_TEMP2_REGNUM)
333 
334 #define NO_FUNCTION_CSE                 1
335 
336 #define PIC_OFFSET_TABLE_REGNUM   (GP_REG_FIRST + MB_ABI_PIC_ADDR_REGNUM)
337 
338 enum reg_class
339 {
340   NO_REGS,			/* no registers in set.  */
341   GR_REGS,			/* integer registers.  */
342   ST_REGS,			/* status register.  */
343   ALL_REGS,			/* all registers.  */
344   LIM_REG_CLASSES		/* max value + 1.  */
345 };
346 
347 #define N_REG_CLASSES 		(int) LIM_REG_CLASSES
348 
349 #define GENERAL_REGS 		GR_REGS
350 
351 #define REG_CLASS_NAMES							\
352 {									\
353   "NO_REGS",								\
354   "GR_REGS",								\
355   "ST_REGS",								\
356   "ALL_REGS"								\
357 }
358 
359 #define REG_CLASS_CONTENTS						\
360 {									\
361   { 0x00000000, 0x00000000 },		/* no registers.  */		\
362   { 0xffffffff, 0x00000000 },		/* integer registers.  */	\
363   { 0x00000000, 0x00000001 },		/* status registers.  */	\
364   { 0xffffffff, 0x0000000f }		/* all registers.  */		\
365 }
366 
367 extern enum reg_class microblaze_regno_to_class[];
368 
369 #define REGNO_REG_CLASS(REGNO) 		microblaze_regno_to_class[ (REGNO) ]
370 
371 #define BASE_REG_CLASS  		GR_REGS
372 
373 #define INDEX_REG_CLASS 		GR_REGS
374 
375 #define GR_REG_CLASS_P(CLASS) 		((CLASS) == GR_REGS)
376 
377 /* REGISTER AND CONSTANT CLASSES */
378 
379 #define SMALL_INT(X) ((unsigned HOST_WIDE_INT) (INTVAL (X) + 0x8000) < 0x10000)
380 #define LARGE_INT(X) \
381   (INTVAL (X) > 0 && UINTVAL (X) >= 0x80000000 && UINTVAL (X) <= 0xffffffff)
382 #define PLT_ADDR_P(X) (GET_CODE (X) == UNSPEC && XINT (X,1) == UNSPEC_PLT)
383 /* Test for a valid operand for a call instruction.
384    Don't allow the arg pointer register or virtual regs
385    since they may change into reg + const, which the patterns
386    can't handle yet.  */
387 #define CALL_INSN_OP(X) (CONSTANT_ADDRESS_P (X) \
388                          || (GET_CODE (X) == REG && X != arg_pointer_rtx\
389                              && ! (REGNO (X) >= FIRST_PSEUDO_REGISTER	\
390                              && REGNO (X) <= LAST_VIRTUAL_REGISTER)))
391 
392 /* True if VALUE is a signed 16-bit number.  */
393 #define SMALL_OPERAND(VALUE) 						\
394   ((unsigned HOST_WIDE_INT) (VALUE) + 0x8000 < 0x10000)
395 
396 /* Constant which cannot be loaded in one instruction.  */
397 #define LARGE_OPERAND(VALUE)						\
398   ((((VALUE) & ~0x0000ffff) != 0)					\
399    && (((VALUE) & ~0x0000ffff) != ~0x0000ffff)				\
400    && (((VALUE) & 0x0000ffff) != 0					\
401        || (((VALUE) & ~2147483647) != 0					\
402 	   && ((VALUE) & ~2147483647) != ~2147483647)))
403 
404 #define PREFERRED_RELOAD_CLASS(X,CLASS)					\
405   ((CLASS) != ALL_REGS							\
406    ? (CLASS)							\
407    : ((GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT			\
408        || GET_MODE_CLASS (GET_MODE (X)) == MODE_COMPLEX_FLOAT)		\
409       ? (GR_REGS)			\
410       : ((GET_MODE_CLASS (GET_MODE (X)) == MODE_INT			\
411 	  || GET_MODE (X) == VOIDmode)					\
412 	 ? (GR_REGS) : (CLASS))))
413 
414 /* Stack layout; function entry, exit and calling.  */
415 
416 #define STACK_GROWS_DOWNWARD
417 
418 /* Changed the starting frame offset to including the new link stuff */
419 #define STARTING_FRAME_OFFSET						\
420    (crtl->outgoing_args_size + FIRST_PARM_OFFSET(FNDECL))
421 
422 /* The return address for the current frame is in r31 if this is a leaf
423    function.  Otherwise, it is on the stack.  It is at a variable offset
424    from sp/fp/ap, so we define a fake hard register rap which is a
425    poiner to the return address on the stack.  This always gets eliminated
426    during reload to be either the frame pointer or the stack pointer plus
427    an offset.  */
428 
429 #define RETURN_ADDR_RTX(count, frame)			\
430   microblaze_return_addr(count,frame)
431 
432 extern struct microblaze_frame_info current_frame_info;
433 
434 #define ELIMINABLE_REGS							\
435 {{ ARG_POINTER_REGNUM,   STACK_POINTER_REGNUM},				\
436  { ARG_POINTER_REGNUM,   GP_REG_FIRST + MB_ABI_FRAME_POINTER_REGNUM},	\
437  { RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM},		\
438  { RETURN_ADDRESS_POINTER_REGNUM, 					\
439    GP_REG_FIRST + MB_ABI_FRAME_POINTER_REGNUM},				\
440  { RETURN_ADDRESS_POINTER_REGNUM, 					\
441    GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM},			\
442  { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},				\
443  { FRAME_POINTER_REGNUM, GP_REG_FIRST + MB_ABI_FRAME_POINTER_REGNUM}}
444 
445 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)			 \
446         (OFFSET) = microblaze_initial_elimination_offset ((FROM), (TO))
447 
448 #define ACCUMULATE_OUTGOING_ARGS        1
449 
450 #define FIRST_PARM_OFFSET(FNDECL)		(UNITS_PER_WORD)
451 
452 #define ARG_POINTER_CFA_OFFSET(FNDECL)		0
453 
454 #define REG_PARM_STACK_SPACE(FNDECL)  		(MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD)
455 
456 #define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE)	1
457 
458 #define STACK_BOUNDARY				32
459 
460 #define NUM_OF_ARGS				6
461 
462 #define GP_RETURN				(GP_REG_FIRST + MB_ABI_INT_RETURN_VAL_REGNUM)
463 
464 #define GP_ARG_FIRST				(GP_REG_FIRST + MB_ABI_FIRST_ARG_REGNUM)
465 #define GP_ARG_LAST				(GP_REG_FIRST + MB_ABI_LAST_ARG_REGNUM)
466 
467 #define MAX_ARGS_IN_REGISTERS			MB_ABI_MAX_ARG_REGS
468 
469 #define LIBCALL_VALUE(MODE)						\
470   gen_rtx_REG (								\
471 	   ((GET_MODE_CLASS (MODE) != MODE_INT				\
472 	     || GET_MODE_SIZE (MODE) >= 4)				\
473 	    ? (MODE)							\
474 	    : SImode), GP_RETURN)
475 
476 /* 1 if N is a possible register number for a function value.
477    On the MicroBlaze, R2 R3 are the only register thus used.
478    Currently, R2 are only implemented  here (C has no complex type)  */
479 
480 #define FUNCTION_VALUE_REGNO_P(N)		((N) == GP_RETURN)
481 
482 #define FUNCTION_ARG_REGNO_P(N)			(((N) >= GP_ARG_FIRST && (N) <= GP_ARG_LAST))
483 
484 typedef struct microblaze_args
485 {
486   int gp_reg_found;		/* whether a gp register was found yet */
487   int arg_number;		/* argument number */
488   int arg_words;		/* # total words the arguments take */
489   int fp_arg_words;		/* # words for FP args */
490   int last_arg_fp;		/* nonzero if last arg was FP (EABI only) */
491   int fp_code;			/* Mode of FP arguments */
492   int num_adjusts;		/* number of adjustments made */
493   /* Adjustments made to args pass in regs.  */
494   /* ??? The size is doubled to work around a bug in the code that sets the
495      adjustments in function_arg.  */
496   rtx adjust[MAX_ARGS_IN_REGISTERS * 2];
497 } CUMULATIVE_ARGS;
498 
499 #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,FNDECL,N_NAMED_ARGS)	\
500   init_cumulative_args (&CUM, FNTYPE, LIBNAME)
501 
502 #define NO_PROFILE_COUNTERS			1
503 
504 #define FUNCTION_PROFILER(FILE, LABELNO) { \
505   {                                        \
506     fprintf (FILE, "\tbrki\tr16,_mcount\n");           \
507   }                                                    \
508  }
509 
510 #define EXIT_IGNORE_STACK			1
511 
512 /* 4 insns + 2 words of data.  */
513 #define TRAMPOLINE_SIZE				(6 * 4)
514 
515 #define TRAMPOLINE_ALIGNMENT			32
516 
517 #define REGNO_OK_FOR_BASE_P(regno)		microblaze_regno_ok_for_base_p ((regno), 1)
518 
519 #define REGNO_OK_FOR_INDEX_P(regno)		microblaze_regno_ok_for_base_p ((regno), 1)
520 
521 #ifndef REG_OK_STRICT
522 #define REG_STRICT_FLAG				0
523 #else
524 #define REG_STRICT_FLAG				1
525 #endif
526 
527 #define REG_OK_FOR_BASE_P(X)    \
528   microblaze_regno_ok_for_base_p (REGNO (X), REG_STRICT_FLAG)
529 
530 #define REG_OK_FOR_INDEX_P(X)   \
531   microblaze_regno_ok_for_base_p (REGNO (X), REG_STRICT_FLAG)
532 
533 #define MAX_REGS_PER_ADDRESS 2
534 
535 
536 /* Identify valid constant addresses.  Exclude if PIC addr which
537    needs scratch register.  */
538 #define CONSTANT_ADDRESS_P(X)						\
539   (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF		\
540     || GET_CODE (X) == CONST_INT 		                        \
541     || (GET_CODE (X) == CONST						\
542 	&& ! (flag_pic && pic_address_needs_scratch (X))))
543 
544 /* Define this, so that when PIC, reload won't try to reload invalid
545    addresses which require two reload registers.  */
546 #define LEGITIMATE_PIC_OPERAND_P(X)  microblaze_legitimate_pic_operand (X)
547 
548 #define CASE_VECTOR_MODE			(SImode)
549 
550 #ifndef DEFAULT_SIGNED_CHAR
551 #define DEFAULT_SIGNED_CHAR			1
552 #endif
553 
554 #define MOVE_MAX				4
555 #define MAX_MOVE_MAX				8
556 
557 #define SLOW_BYTE_ACCESS			1
558 
559 /* sCOND operations return 1.  */
560 #define STORE_FLAG_VALUE			1
561 
562 #define SHIFT_COUNT_TRUNCATED			1
563 
564 /* This results in inefficient code for 64 bit to 32 conversions.
565    Something needs to be done about this.  Perhaps not use any 32 bit
566    instructions?  Perhaps use PROMOTE_MODE?  */
567 #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC)  1
568 
569 #define Pmode SImode
570 
571 #define FUNCTION_MODE   SImode
572 
573 /* Mode should always be SImode */
574 #define REGISTER_MOVE_COST(MODE, FROM, TO)			\
575   ( GR_REG_CLASS_P (FROM) && GR_REG_CLASS_P (TO) ? 2 		\
576    : (FROM) == ST_REGS && GR_REG_CLASS_P (TO) ? 4		\
577    : 12)
578 
579 #define MEMORY_MOVE_COST(MODE,CLASS,TO_P) \
580   (4 + memory_move_secondary_cost ((MODE), (CLASS), (TO_P)))
581 
582 #define BRANCH_COST(speed_p, predictable_p)	2
583 
584 /* Control the assembler format that we output.  */
585 #define ASM_APP_ON " #APP\n"
586 #define ASM_APP_OFF " #NO_APP\n"
587 
588 #define REGISTER_NAMES {						\
589   "r0",   "r1",   "r2",   "r3",   "r4",   "r5",   "r6",   "r7",		\
590   "r8",   "r9",   "r10",  "r11",  "r12",  "r13",  "r14",  "r15",	\
591   "r16",  "r17",  "r18",  "r19",  "r20",  "r21",  "r22",  "r23",	\
592   "r24",  "r25",  "r26",  "r27",  "r28",  "r29",  "r30",  "r31",	\
593   "rmsr", "$ap",  "$rap", "$frp" }
594 
595 #define ADDITIONAL_REGISTER_NAMES					\
596 {									\
597   { "r0",	 0 + GP_REG_FIRST },					\
598   { "r1",	 1 + GP_REG_FIRST },					\
599   { "r2",	 2 + GP_REG_FIRST },					\
600   { "r3",	 3 + GP_REG_FIRST },					\
601   { "r4",	 4 + GP_REG_FIRST },					\
602   { "r5",	 5 + GP_REG_FIRST },					\
603   { "r6",	 6 + GP_REG_FIRST },					\
604   { "r7",	 7 + GP_REG_FIRST },					\
605   { "r8",	 8 + GP_REG_FIRST },					\
606   { "r9",	 9 + GP_REG_FIRST },					\
607   { "r10",	10 + GP_REG_FIRST },					\
608   { "r11",	11 + GP_REG_FIRST },					\
609   { "r12",	12 + GP_REG_FIRST },					\
610   { "r13",	13 + GP_REG_FIRST },					\
611   { "r14",	14 + GP_REG_FIRST },					\
612   { "r15",	15 + GP_REG_FIRST },					\
613   { "r16",	16 + GP_REG_FIRST },					\
614   { "r17",	17 + GP_REG_FIRST },					\
615   { "r18",	18 + GP_REG_FIRST },					\
616   { "r19",	19 + GP_REG_FIRST },					\
617   { "r20",	20 + GP_REG_FIRST },					\
618   { "r21",	21 + GP_REG_FIRST },					\
619   { "r22",	22 + GP_REG_FIRST },					\
620   { "r23",	23 + GP_REG_FIRST },					\
621   { "r24",	24 + GP_REG_FIRST },					\
622   { "r25",	25 + GP_REG_FIRST },					\
623   { "r26",	26 + GP_REG_FIRST },					\
624   { "r27",	27 + GP_REG_FIRST },					\
625   { "r28",	28 + GP_REG_FIRST },					\
626   { "r29",	29 + GP_REG_FIRST },					\
627   { "r30",	30 + GP_REG_FIRST },					\
628   { "r31",	31 + GP_REG_FIRST },					\
629   { "rmsr",     ST_REG}							\
630 }
631 
632 #define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE)
633 
634 #define PRINT_OPERAND_PUNCT_VALID_P(CODE) microblaze_print_operand_punct[CODE]
635 
636 #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
637 
638 /* ASM_OUTPUT_ALIGNED_COMMON and ASM_OUTPUT_ALIGNED_LOCAL
639 
640    Unfortunately, we still need to set the section explicitly. Somehow,
641    our binutils assign .comm and .lcomm variables to the "current" section
642    in the assembly file, rather than where they implicitly belong. We need to
643    remove this explicit setting in GCC when binutils can understand sections
644    better.  */
645 #undef	ASM_OUTPUT_ALIGNED_COMMON
646 #define	ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)		\
647 do {									\
648   if ((SIZE) > 0 && (SIZE) <= INT_MAX					\
649       && (int) (SIZE) <= microblaze_section_threshold			\
650       && TARGET_XLGPOPT)						\
651     {                                                                   \
652       switch_to_section (sbss_section);					\
653     }									\
654   else									\
655     {									\
656       switch_to_section (bss_section);					\
657     }                                                                   \
658   fprintf (FILE, "%s", COMMON_ASM_OP);                                  \
659   assemble_name ((FILE), (NAME));					\
660   fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",		\
661            (SIZE), (ALIGN) / BITS_PER_UNIT);                            \
662   ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
663 } while (0)
664 
665 #undef ASM_OUTPUT_ALIGNED_LOCAL
666 #define	ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
667 do {									\
668   if ((SIZE) > 0 && (SIZE) <= INT_MAX					\
669       && (int) (SIZE) <= microblaze_section_threshold			\
670       && TARGET_XLGPOPT)						\
671     {                                                                   \
672       switch_to_section (sbss_section);					\
673     }									\
674   else									\
675     {									\
676       switch_to_section (bss_section);					\
677     }                                                                   \
678   fprintf (FILE, "%s", LCOMMON_ASM_OP);                                 \
679   assemble_name ((FILE), (NAME));					\
680   fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",		\
681            (SIZE), (ALIGN) / BITS_PER_UNIT);                            \
682   ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
683 } while (0)
684 
685 #define	ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN)		\
686 do {									\
687   ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN);			\
688 } while (0)
689 
690 #define ASM_DECLARE_FUNCTION_NAME(STREAM,NAME,DECL)                     \
691 {                                                                       \
692 }
693 
694 #undef TARGET_ASM_CONSTRUCTOR
695 #define TARGET_ASM_CONSTRUCTOR microblaze_elf_asm_constructor
696 
697 #undef TARGET_ASM_DESTRUCTOR
698 #define TARGET_ASM_DESTRUCTOR microblaze_elf_asm_destructor
699 
700 #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)			\
701   sprintf ((LABEL), "*%s%s%ld", (LOCAL_LABEL_PREFIX), (PREFIX), (long)(NUM))
702 
703 #define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE)				\
704   fprintf (STREAM, "\t%s\t%sL%d\n",					\
705 	   ".gpword",                                                   \
706 	   LOCAL_LABEL_PREFIX, VALUE)
707 
708 #define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL)		\
709 do {									\
710   if (flag_pic == 2)                                               \
711     fprintf (STREAM, "\t%s\t%sL%d@GOTOFF\n",                            \
712 	     ".gpword",                                                 \
713 	     LOCAL_LABEL_PREFIX, VALUE);				\
714   else                                                                  \
715     fprintf (STREAM, "\t%s\t%sL%d\n",					\
716 	     ".gpword",                                                 \
717 	     LOCAL_LABEL_PREFIX, VALUE);				\
718 } while (0)
719 
720 #define ASM_OUTPUT_ALIGN(STREAM,LOG)					\
721   fprintf (STREAM, "\t.align\t%d\n", (LOG))
722 
723 #define ASM_OUTPUT_SKIP(STREAM,SIZE)					\
724   fprintf (STREAM, "\t.space\t%lu\n", (SIZE))
725 
726 #define ASCII_DATA_ASM_OP		"\t.ascii\t"
727 #define STRING_ASM_OP			"\t.asciz\t"
728 
729 #undef TARGET_ASM_OUTPUT_IDENT
730 #define TARGET_ASM_OUTPUT_IDENT microblaze_asm_output_ident
731 
732 /* Default to -G 8 */
733 #ifndef MICROBLAZE_DEFAULT_GVALUE
734 #define MICROBLAZE_DEFAULT_GVALUE 8
735 #endif
736 
737 /* Given a decl node or constant node, choose the section to output it in
738    and select that section.  */
739 
740 /* Store in OUTPUT a string (made with alloca) containing
741    an assembler-name for a local static variable named NAME.
742    LABELNO is an integer which is different for each call.  */
743 #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)			\
744 ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),			\
745   sprintf ((OUTPUT), "%s.%lu", (NAME), (unsigned long)(LABELNO)))
746 
747 /* How to start an assembler comment.
748    The leading space is important (the microblaze assembler requires it).  */
749 #ifndef ASM_COMMENT_START
750 #define ASM_COMMENT_START		" #"
751 #endif
752 
753 #define BSS_VAR         1
754 #define SBSS_VAR        2
755 #define DATA_VAR        4
756 #define SDATA_VAR       5
757 #define RODATA_VAR      6
758 #define SDATA2_VAR      7
759 
760 /* These definitions are used in with the shift_type flag in the rtl.  */
761 #define SHIFT_CONST     1
762 #define SHIFT_REG       2
763 #define USE_ADDK        3
764 
765 /* Handle interrupt attribute.  */
766 extern int interrupt_handler;
767 extern int fast_interrupt;
768 extern int save_volatiles;
769 
770 #define INTERRUPT_HANDLER_NAME "_interrupt_handler"
771 /* The function name for the function tagged with attribute break_handler
772    has been set in the RTL as _break_handler. This function name is used
773    in the generation of directives .ent .end and .global. */
774 #define BREAK_HANDLER_NAME "_break_handler"
775 #define FAST_INTERRUPT_NAME "_fast_interrupt"
776 
777 /* The following #defines are used in the headers files. Always retain these.  */
778 
779 /* Added for declaring size at the end of the function.  */
780 #undef ASM_DECLARE_FUNCTION_SIZE
781 #define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)			\
782   do {									\
783     if (!flag_inhibit_size_directive)					\
784       {									\
785         char label[256];						\
786 	static int labelno;						\
787 	labelno++;							\
788 	ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno);		\
789         (*targetm.asm_out.internal_label) (FILE, "Lfe", labelno);	\
790 	fprintf (FILE, "%s", SIZE_ASM_OP);				\
791 	assemble_name (FILE, (FNAME));					\
792         fprintf (FILE, ",");						\
793 	assemble_name (FILE, label);					\
794         fprintf (FILE, "-");						\
795 	assemble_name (FILE, (FNAME));					\
796 	putc ('\n', FILE);						\
797       }									\
798   } while (0)
799 
800 #define GLOBAL_ASM_OP			"\t.globl\t"
801 #define TYPE_ASM_OP			"\t.type\t"
802 #define SIZE_ASM_OP			"\t.size\t"
803 #define COMMON_ASM_OP			"\t.comm\t"
804 #define LCOMMON_ASM_OP			"\t.lcomm\t"
805 
806 #define MAX_OFILE_ALIGNMENT		(32768*8)
807 
808 #define TYPE_OPERAND_FMT        	"@%s"
809 
810 /* Write the extra assembler code needed to declare an object properly.  */
811 #undef ASM_DECLARE_OBJECT_NAME
812 #define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL)			\
813   do {									\
814     fprintf (FILE, "%s", TYPE_ASM_OP);			         	\
815     assemble_name (FILE, NAME);						\
816     putc (',', FILE);							\
817     fprintf (FILE, TYPE_OPERAND_FMT, "object");				\
818     putc ('\n', FILE);							\
819     size_directive_output = 0;						\
820     if (!flag_inhibit_size_directive && DECL_SIZE (DECL))		\
821       {									\
822 	size_directive_output = 1;					\
823 	fprintf (FILE, "%s", SIZE_ASM_OP);				\
824 	assemble_name (FILE, NAME);					\
825 	fprintf (FILE, "," HOST_WIDE_INT_PRINT_DEC "\n",		\
826 	int_size_in_bytes (TREE_TYPE (DECL)));				\
827       }									\
828     microblaze_declare_object (FILE, NAME, "", ":\n", 0);			\
829   } while (0)
830 
831 #undef ASM_FINISH_DECLARE_OBJECT
832 #define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END)	 \
833 do {									 \
834      const char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0);		 \
835      if (!flag_inhibit_size_directive && DECL_SIZE (DECL)		 \
836          && ! AT_END && TOP_LEVEL					 \
837 	 && DECL_INITIAL (DECL) == error_mark_node			 \
838 	 && !size_directive_output)					 \
839        {								 \
840 	 size_directive_output = 1;					 \
841 	 fprintf (FILE, "%s", SIZE_ASM_OP);			         \
842 	 assemble_name (FILE, name);					 \
843 	 fprintf (FILE, "," HOST_WIDE_INT_PRINT_DEC "\n",		 \
844 		  int_size_in_bytes (TREE_TYPE (DECL)));		 \
845        }								 \
846    } while (0)
847 
848 #define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2)                            \
849  do { fputc ( '\t', FILE);                                            \
850       assemble_name (FILE, LABEL1);                                   \
851       fputs ( " = ", FILE);                                           \
852       assemble_name (FILE, LABEL2);                                   \
853       fputc ( '\n', FILE);                                            \
854  } while (0)
855 
856 #define ASM_WEAKEN_LABEL(FILE,NAME) 					\
857  do { fputs ("\t.weakext\t", FILE);					\
858       assemble_name (FILE, NAME);					\
859       fputc ('\n', FILE);						\
860     } while (0)
861 
862 #define MAKE_DECL_ONE_ONLY(DECL)	(DECL_WEAK (DECL) = 1)
863 #undef UNIQUE_SECTION_P
864 #define UNIQUE_SECTION_P(DECL)		(DECL_ONE_ONLY (DECL))
865 
866 #undef TARGET_ASM_NAMED_SECTION
867 #define TARGET_ASM_NAMED_SECTION        default_elf_asm_named_section
868 
869 /* Define the strings to put out for each section in the object file.
870 
871    Note: For ctors/dtors, we want to give these sections the SHF_WRITE
872    attribute to allow shared libraries to patch/resolve addresses into
873    these locations.  On Microblaze, there is no concept of shared libraries
874    yet, so this is for future use.  */
875 #define TEXT_SECTION_ASM_OP	"\t.text"
876 #define DATA_SECTION_ASM_OP	"\t.data"
877 #define READONLY_DATA_SECTION_ASM_OP    \
878                                 "\t.rodata"
879 #define BSS_SECTION_ASM_OP      "\t.bss"
880 #define CTORS_SECTION_ASM_OP    "\t.section\t.ctors,\"aw\""
881 #define DTORS_SECTION_ASM_OP    "\t.section\t.dtors,\"aw\""
882 #define INIT_SECTION_ASM_OP     "\t.section\t.init,\"ax\""
883 #define FINI_SECTION_ASM_OP     "\t.section\t.fini,\"ax\""
884 
885 #define SDATA_SECTION_ASM_OP	"\t.sdata"	/* Small RW initialized data   */
886 #define SDATA2_SECTION_ASM_OP	"\t.sdata2"	/* Small RO initialized data   */
887 #define SBSS_SECTION_ASM_OP     "\t.sbss"	/* Small RW uninitialized data */
888 #define SBSS2_SECTION_ASM_OP    "\t.sbss2"	/* Small RO uninitialized data */
889 
890 /* We do this to save a few 10s of code space that would be taken up
891    by the call_FUNC () wrappers, used by the generic CRT_CALL_STATIC_FUNCTION
892    definition in crtstuff.c.  */
893 #define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC)	\
894     asm ( SECTION_OP "\n"                               \
895           "\tbrlid   r15, " #FUNC "\n\t nop\n"         \
896           TEXT_SECTION_ASM_OP);
897 
898 /* We need to group -lm as well, since some Newlib math functions
899    reference __errno!  */
900 #undef LIB_SPEC
901 #define LIB_SPEC \
902 "%{!nostdlib: \
903 %{pg:-start-group -lxilprofile -lgloss -lxil -lc -lm -end-group } \
904 %{!pg:-start-group -lgloss -lxil -lc -lm -end-group }} "
905 
906 /* microblaze-unknown-elf target has no support of C99 runtime */
907 #undef TARGET_LIBC_HAS_FUNCTION
908 #define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
909 
910 #undef  ENDFILE_SPEC
911 #define ENDFILE_SPEC "crtend.o%s crtn.o%s"
912 
913 #define STARTFILE_EXECUTABLE_SPEC   "crt0.o%s crti.o%s crtbegin.o%s"
914 #define STARTFILE_XMDSTUB_SPEC      "crt1.o%s crti.o%s crtbegin.o%s"
915 #define STARTFILE_BOOTSTRAP_SPEC    "crt2.o%s crti.o%s crtbegin.o%s"
916 #define STARTFILE_NOVECTORS_SPEC    "crt3.o%s crti.o%s crtbegin.o%s"
917 #define STARTFILE_CRTINIT_SPEC      "%{!pg: %{!mno-clearbss: crtinit.o%s} \
918 %{mno-clearbss: sim-crtinit.o%s}} \
919 %{pg: %{!mno-clearbss: pgcrtinit.o%s} %{mno-clearbss: sim-pgcrtinit.o%s}}"
920 
921 #define STARTFILE_DEFAULT_SPEC      STARTFILE_EXECUTABLE_SPEC
922 
923 #undef SUBTARGET_EXTRA_SPECS
924 #define	SUBTARGET_EXTRA_SPECS						\
925   { "startfile_executable",	STARTFILE_EXECUTABLE_SPEC },		\
926   { "startfile_xmdstub",	STARTFILE_XMDSTUB_SPEC },		\
927   { "startfile_bootstrap",	STARTFILE_BOOTSTRAP_SPEC },		\
928   { "startfile_novectors",	STARTFILE_NOVECTORS_SPEC },		\
929   { "startfile_crtinit",        STARTFILE_CRTINIT_SPEC },               \
930   { "startfile_default",	STARTFILE_DEFAULT_SPEC },
931 
932 #undef  STARTFILE_SPEC
933 #define STARTFILE_SPEC  "\
934 %{Zxl-mode-executable   : %(startfile_executable)  ; \
935   mxl-mode-executable   : %(startfile_executable)  ; \
936   Zxl-mode-xmdstub      : %(startfile_xmdstub)     ; \
937   mxl-mode-xmdstub      : %(startfile_xmdstub)     ; \
938   Zxl-mode-bootstrap    : %(startfile_bootstrap)   ; \
939   mxl-mode-bootstrap    : %(startfile_bootstrap)   ; \
940   Zxl-mode-novectors    : %(startfile_novectors)   ; \
941   mxl-mode-novectors    : %(startfile_novectors)   ; \
942   Zxl-mode-xilkernel    : %(startfile_xilkernel)   ; \
943   mxl-mode-xilkernel    : %(startfile_xilkernel)   ; \
944                         : %(startfile_default)       \
945 } \
946 %(startfile_crtinit)"
947