Always pass explicit location to fatal_error.
[official-gcc.git] / gcc / config / nios2 / nios2.c
blobdf33077947c00b6bb687cca62585c8f8b349dc66
1 /* Target machine subroutines for Altera Nios II.
2 Copyright (C) 2012-2015 Free Software Foundation, Inc.
3 Contributed by Jonah Graham (jgraham@altera.com),
4 Will Reece (wreece@altera.com), and Jeff DaSilva (jdasilva@altera.com).
5 Contributed by Mentor Graphics, Inc.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "hash-set.h"
29 #include "machmode.h"
30 #include "vec.h"
31 #include "double-int.h"
32 #include "input.h"
33 #include "alias.h"
34 #include "symtab.h"
35 #include "wide-int.h"
36 #include "inchash.h"
37 #include "tree.h"
38 #include "fold-const.h"
39 #include "regs.h"
40 #include "hard-reg-set.h"
41 #include "insn-config.h"
42 #include "conditions.h"
43 #include "output.h"
44 #include "insn-attr.h"
45 #include "flags.h"
46 #include "recog.h"
47 #include "hashtab.h"
48 #include "function.h"
49 #include "statistics.h"
50 #include "real.h"
51 #include "fixed-value.h"
52 #include "expmed.h"
53 #include "dojump.h"
54 #include "explow.h"
55 #include "calls.h"
56 #include "emit-rtl.h"
57 #include "varasm.h"
58 #include "stmt.h"
59 #include "expr.h"
60 #include "insn-codes.h"
61 #include "optabs.h"
62 #include "ggc.h"
63 #include "predict.h"
64 #include "dominance.h"
65 #include "cfg.h"
66 #include "cfgrtl.h"
67 #include "cfganal.h"
68 #include "lcm.h"
69 #include "cfgbuild.h"
70 #include "cfgcleanup.h"
71 #include "basic-block.h"
72 #include "diagnostic-core.h"
73 #include "toplev.h"
74 #include "target.h"
75 #include "target-def.h"
76 #include "tm_p.h"
77 #include "langhooks.h"
78 #include "df.h"
79 #include "debug.h"
80 #include "reload.h"
81 #include "stor-layout.h"
82 #include "builtins.h"
84 /* Forward function declarations. */
85 static bool prologue_saved_reg_p (unsigned);
86 static void nios2_load_pic_register (void);
87 static void nios2_register_custom_code (unsigned int, enum nios2_ccs_code, int);
88 static const char *nios2_unspec_reloc_name (int);
89 static void nios2_register_builtin_fndecl (unsigned, tree);
91 /* Threshold for data being put into the small data/bss area, instead
92 of the normal data area (references to the small data/bss area take
93 1 instruction, and use the global pointer, references to the normal
94 data area takes 2 instructions). */
95 unsigned HOST_WIDE_INT nios2_section_threshold = NIOS2_DEFAULT_GVALUE;
97 struct GTY (()) machine_function
99 /* Current frame information, to be filled in by nios2_compute_frame_layout
100 with register save masks, and offsets for the current function. */
102 /* Mask of registers to save. */
103 unsigned int save_mask;
104 /* Number of bytes that the entire frame takes up. */
105 int total_size;
106 /* Number of bytes that variables take up. */
107 int var_size;
108 /* Number of bytes that outgoing arguments take up. */
109 int args_size;
110 /* Number of bytes needed to store registers in frame. */
111 int save_reg_size;
112 /* Offset from new stack pointer to store registers. */
113 int save_regs_offset;
114 /* Offset from save_regs_offset to store frame pointer register. */
115 int fp_save_offset;
116 /* != 0 if frame layout already calculated. */
117 int initialized;
120 /* State to track the assignment of custom codes to FPU/custom builtins. */
121 static enum nios2_ccs_code custom_code_status[256];
122 static int custom_code_index[256];
123 /* Set to true if any conflicts (re-use of a code between 0-255) are found. */
124 static bool custom_code_conflict = false;
127 /* Definition of builtin function types for nios2. */
129 #define N2_FTYPES \
130 N2_FTYPE(1, (SF)) \
131 N2_FTYPE(1, (VOID)) \
132 N2_FTYPE(2, (DF, DF)) \
133 N2_FTYPE(3, (DF, DF, DF)) \
134 N2_FTYPE(2, (DF, SF)) \
135 N2_FTYPE(2, (DF, SI)) \
136 N2_FTYPE(2, (DF, UI)) \
137 N2_FTYPE(2, (SF, DF)) \
138 N2_FTYPE(2, (SF, SF)) \
139 N2_FTYPE(3, (SF, SF, SF)) \
140 N2_FTYPE(2, (SF, SI)) \
141 N2_FTYPE(2, (SF, UI)) \
142 N2_FTYPE(2, (SI, CVPTR)) \
143 N2_FTYPE(2, (SI, DF)) \
144 N2_FTYPE(3, (SI, DF, DF)) \
145 N2_FTYPE(2, (SI, SF)) \
146 N2_FTYPE(3, (SI, SF, SF)) \
147 N2_FTYPE(2, (SI, SI)) \
148 N2_FTYPE(2, (UI, CVPTR)) \
149 N2_FTYPE(2, (UI, DF)) \
150 N2_FTYPE(2, (UI, SF)) \
151 N2_FTYPE(2, (VOID, DF)) \
152 N2_FTYPE(2, (VOID, SF)) \
153 N2_FTYPE(3, (VOID, SI, SI)) \
154 N2_FTYPE(3, (VOID, VPTR, SI))
156 #define N2_FTYPE_OP1(R) N2_FTYPE_ ## R ## _VOID
157 #define N2_FTYPE_OP2(R, A1) N2_FTYPE_ ## R ## _ ## A1
158 #define N2_FTYPE_OP3(R, A1, A2) N2_FTYPE_ ## R ## _ ## A1 ## _ ## A2
160 /* Expand ftcode enumeration. */
161 enum nios2_ftcode {
162 #define N2_FTYPE(N,ARGS) N2_FTYPE_OP ## N ARGS,
163 N2_FTYPES
164 #undef N2_FTYPE
165 N2_FTYPE_MAX
168 /* Return the tree function type, based on the ftcode. */
169 static tree
170 nios2_ftype (enum nios2_ftcode ftcode)
172 static tree types[(int) N2_FTYPE_MAX];
174 tree N2_TYPE_SF = float_type_node;
175 tree N2_TYPE_DF = double_type_node;
176 tree N2_TYPE_SI = integer_type_node;
177 tree N2_TYPE_UI = unsigned_type_node;
178 tree N2_TYPE_VOID = void_type_node;
180 static const_tree N2_TYPE_CVPTR, N2_TYPE_VPTR;
181 if (!N2_TYPE_CVPTR)
183 /* const volatile void *. */
184 N2_TYPE_CVPTR
185 = build_pointer_type (build_qualified_type (void_type_node,
186 (TYPE_QUAL_CONST
187 | TYPE_QUAL_VOLATILE)));
188 /* volatile void *. */
189 N2_TYPE_VPTR
190 = build_pointer_type (build_qualified_type (void_type_node,
191 TYPE_QUAL_VOLATILE));
193 if (types[(int) ftcode] == NULL_TREE)
194 switch (ftcode)
196 #define N2_FTYPE_ARGS1(R) N2_TYPE_ ## R
197 #define N2_FTYPE_ARGS2(R,A1) N2_TYPE_ ## R, N2_TYPE_ ## A1
198 #define N2_FTYPE_ARGS3(R,A1,A2) N2_TYPE_ ## R, N2_TYPE_ ## A1, N2_TYPE_ ## A2
199 #define N2_FTYPE(N,ARGS) \
200 case N2_FTYPE_OP ## N ARGS: \
201 types[(int) ftcode] \
202 = build_function_type_list (N2_FTYPE_ARGS ## N ARGS, NULL_TREE); \
203 break;
204 N2_FTYPES
205 #undef N2_FTYPE
206 default: gcc_unreachable ();
208 return types[(int) ftcode];
212 /* Definition of FPU instruction descriptions. */
214 struct nios2_fpu_insn_info
216 const char *name;
217 int num_operands, *optvar;
218 int opt, no_opt;
219 #define N2F_DF 0x1
220 #define N2F_DFREQ 0x2
221 #define N2F_UNSAFE 0x4
222 #define N2F_FINITE 0x8
223 #define N2F_NO_ERRNO 0x10
224 unsigned int flags;
225 enum insn_code icode;
226 enum nios2_ftcode ftcode;
229 /* Base macro for defining FPU instructions. */
230 #define N2FPU_INSN_DEF_BASE(insn, nop, flags, icode, args) \
231 { #insn, nop, &nios2_custom_ ## insn, OPT_mcustom_##insn##_, \
232 OPT_mno_custom_##insn, flags, CODE_FOR_ ## icode, \
233 N2_FTYPE_OP ## nop args }
235 /* Arithmetic and math functions; 2 or 3 operand FP operations. */
236 #define N2FPU_OP2(mode) (mode, mode)
237 #define N2FPU_OP3(mode) (mode, mode, mode)
238 #define N2FPU_INSN_DEF(code, icode, nop, flags, m, M) \
239 N2FPU_INSN_DEF_BASE (f ## code ## m, nop, flags, \
240 icode ## m ## f ## nop, N2FPU_OP ## nop (M ## F))
241 #define N2FPU_INSN_SF(code, nop, flags) \
242 N2FPU_INSN_DEF (code, code, nop, flags, s, S)
243 #define N2FPU_INSN_DF(code, nop, flags) \
244 N2FPU_INSN_DEF (code, code, nop, flags | N2F_DF, d, D)
246 /* Compare instructions, 3 operand FP operation with a SI result. */
247 #define N2FPU_CMP_DEF(code, flags, m, M) \
248 N2FPU_INSN_DEF_BASE (fcmp ## code ## m, 3, flags, \
249 nios2_s ## code ## m ## f, (SI, M ## F, M ## F))
250 #define N2FPU_CMP_SF(code) N2FPU_CMP_DEF (code, 0, s, S)
251 #define N2FPU_CMP_DF(code) N2FPU_CMP_DEF (code, N2F_DF, d, D)
253 /* The order of definition needs to be maintained consistent with
254 enum n2fpu_code in nios2-opts.h. */
255 struct nios2_fpu_insn_info nios2_fpu_insn[] =
257 /* Single precision instructions. */
258 N2FPU_INSN_SF (add, 3, 0),
259 N2FPU_INSN_SF (sub, 3, 0),
260 N2FPU_INSN_SF (mul, 3, 0),
261 N2FPU_INSN_SF (div, 3, 0),
262 /* Due to textual difference between min/max and smin/smax. */
263 N2FPU_INSN_DEF (min, smin, 3, N2F_FINITE, s, S),
264 N2FPU_INSN_DEF (max, smax, 3, N2F_FINITE, s, S),
265 N2FPU_INSN_SF (neg, 2, 0),
266 N2FPU_INSN_SF (abs, 2, 0),
267 N2FPU_INSN_SF (sqrt, 2, 0),
268 N2FPU_INSN_SF (sin, 2, N2F_UNSAFE),
269 N2FPU_INSN_SF (cos, 2, N2F_UNSAFE),
270 N2FPU_INSN_SF (tan, 2, N2F_UNSAFE),
271 N2FPU_INSN_SF (atan, 2, N2F_UNSAFE),
272 N2FPU_INSN_SF (exp, 2, N2F_UNSAFE),
273 N2FPU_INSN_SF (log, 2, N2F_UNSAFE),
274 /* Single precision compares. */
275 N2FPU_CMP_SF (eq), N2FPU_CMP_SF (ne),
276 N2FPU_CMP_SF (lt), N2FPU_CMP_SF (le),
277 N2FPU_CMP_SF (gt), N2FPU_CMP_SF (ge),
279 /* Double precision instructions. */
280 N2FPU_INSN_DF (add, 3, 0),
281 N2FPU_INSN_DF (sub, 3, 0),
282 N2FPU_INSN_DF (mul, 3, 0),
283 N2FPU_INSN_DF (div, 3, 0),
284 /* Due to textual difference between min/max and smin/smax. */
285 N2FPU_INSN_DEF (min, smin, 3, N2F_FINITE, d, D),
286 N2FPU_INSN_DEF (max, smax, 3, N2F_FINITE, d, D),
287 N2FPU_INSN_DF (neg, 2, 0),
288 N2FPU_INSN_DF (abs, 2, 0),
289 N2FPU_INSN_DF (sqrt, 2, 0),
290 N2FPU_INSN_DF (sin, 2, N2F_UNSAFE),
291 N2FPU_INSN_DF (cos, 2, N2F_UNSAFE),
292 N2FPU_INSN_DF (tan, 2, N2F_UNSAFE),
293 N2FPU_INSN_DF (atan, 2, N2F_UNSAFE),
294 N2FPU_INSN_DF (exp, 2, N2F_UNSAFE),
295 N2FPU_INSN_DF (log, 2, N2F_UNSAFE),
296 /* Double precision compares. */
297 N2FPU_CMP_DF (eq), N2FPU_CMP_DF (ne),
298 N2FPU_CMP_DF (lt), N2FPU_CMP_DF (le),
299 N2FPU_CMP_DF (gt), N2FPU_CMP_DF (ge),
301 /* Conversion instructions. */
302 N2FPU_INSN_DEF_BASE (floatis, 2, 0, floatsisf2, (SF, SI)),
303 N2FPU_INSN_DEF_BASE (floatus, 2, 0, floatunssisf2, (SF, UI)),
304 N2FPU_INSN_DEF_BASE (floatid, 2, 0, floatsidf2, (DF, SI)),
305 N2FPU_INSN_DEF_BASE (floatud, 2, 0, floatunssidf2, (DF, UI)),
306 N2FPU_INSN_DEF_BASE (round, 2, N2F_NO_ERRNO, lroundsfsi2, (SI, SF)),
307 N2FPU_INSN_DEF_BASE (fixsi, 2, 0, fix_truncsfsi2, (SI, SF)),
308 N2FPU_INSN_DEF_BASE (fixsu, 2, 0, fixuns_truncsfsi2, (UI, SF)),
309 N2FPU_INSN_DEF_BASE (fixdi, 2, 0, fix_truncdfsi2, (SI, DF)),
310 N2FPU_INSN_DEF_BASE (fixdu, 2, 0, fixuns_truncdfsi2, (UI, DF)),
311 N2FPU_INSN_DEF_BASE (fextsd, 2, 0, extendsfdf2, (DF, SF)),
312 N2FPU_INSN_DEF_BASE (ftruncds, 2, 0, truncdfsf2, (SF, DF)),
314 /* X, Y access instructions. */
315 N2FPU_INSN_DEF_BASE (fwrx, 2, N2F_DFREQ, nios2_fwrx, (VOID, DF)),
316 N2FPU_INSN_DEF_BASE (fwry, 2, N2F_DFREQ, nios2_fwry, (VOID, SF)),
317 N2FPU_INSN_DEF_BASE (frdxlo, 1, N2F_DFREQ, nios2_frdxlo, (SF)),
318 N2FPU_INSN_DEF_BASE (frdxhi, 1, N2F_DFREQ, nios2_frdxhi, (SF)),
319 N2FPU_INSN_DEF_BASE (frdy, 1, N2F_DFREQ, nios2_frdy, (SF))
322 /* Some macros for ease of access. */
323 #define N2FPU(code) nios2_fpu_insn[(int) code]
324 #define N2FPU_ENABLED_P(code) (N2FPU_N(code) >= 0)
325 #define N2FPU_N(code) (*N2FPU(code).optvar)
326 #define N2FPU_NAME(code) (N2FPU(code).name)
327 #define N2FPU_ICODE(code) (N2FPU(code).icode)
328 #define N2FPU_FTCODE(code) (N2FPU(code).ftcode)
329 #define N2FPU_FINITE_P(code) (N2FPU(code).flags & N2F_FINITE)
330 #define N2FPU_UNSAFE_P(code) (N2FPU(code).flags & N2F_UNSAFE)
331 #define N2FPU_NO_ERRNO_P(code) (N2FPU(code).flags & N2F_NO_ERRNO)
332 #define N2FPU_DOUBLE_P(code) (N2FPU(code).flags & N2F_DF)
333 #define N2FPU_DOUBLE_REQUIRED_P(code) (N2FPU(code).flags & N2F_DFREQ)
335 /* Same as above, but for cases where using only the op part is shorter. */
336 #define N2FPU_OP(op) N2FPU(n2fpu_ ## op)
337 #define N2FPU_OP_NAME(op) N2FPU_NAME(n2fpu_ ## op)
338 #define N2FPU_OP_ENABLED_P(op) N2FPU_ENABLED_P(n2fpu_ ## op)
340 /* Export the FPU insn enabled predicate to nios2.md. */
341 bool
342 nios2_fpu_insn_enabled (enum n2fpu_code code)
344 return N2FPU_ENABLED_P (code);
347 /* Return true if COND comparison for mode MODE is enabled under current
348 settings. */
350 static bool
351 nios2_fpu_compare_enabled (enum rtx_code cond, machine_mode mode)
353 if (mode == SFmode)
354 switch (cond)
356 case EQ: return N2FPU_OP_ENABLED_P (fcmpeqs);
357 case NE: return N2FPU_OP_ENABLED_P (fcmpnes);
358 case GT: return N2FPU_OP_ENABLED_P (fcmpgts);
359 case GE: return N2FPU_OP_ENABLED_P (fcmpges);
360 case LT: return N2FPU_OP_ENABLED_P (fcmplts);
361 case LE: return N2FPU_OP_ENABLED_P (fcmples);
362 default: break;
364 else if (mode == DFmode)
365 switch (cond)
367 case EQ: return N2FPU_OP_ENABLED_P (fcmpeqd);
368 case NE: return N2FPU_OP_ENABLED_P (fcmpned);
369 case GT: return N2FPU_OP_ENABLED_P (fcmpgtd);
370 case GE: return N2FPU_OP_ENABLED_P (fcmpged);
371 case LT: return N2FPU_OP_ENABLED_P (fcmpltd);
372 case LE: return N2FPU_OP_ENABLED_P (fcmpled);
373 default: break;
375 return false;
378 /* Stack layout and calling conventions. */
380 #define NIOS2_STACK_ALIGN(LOC) \
381 (((LOC) + ((PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT) - 1)) \
382 & ~((PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT) - 1))
384 /* Return the bytes needed to compute the frame pointer from the current
385 stack pointer. */
386 static int
387 nios2_compute_frame_layout (void)
389 unsigned int regno;
390 unsigned int save_mask = 0;
391 int total_size;
392 int var_size;
393 int out_args_size;
394 int save_reg_size;
396 if (cfun->machine->initialized)
397 return cfun->machine->total_size;
399 var_size = NIOS2_STACK_ALIGN (get_frame_size ());
400 out_args_size = NIOS2_STACK_ALIGN (crtl->outgoing_args_size);
401 total_size = var_size + out_args_size;
403 /* Calculate space needed for gp registers. */
404 save_reg_size = 0;
405 for (regno = 0; regno <= LAST_GP_REG; regno++)
406 if (prologue_saved_reg_p (regno))
408 save_mask |= 1 << regno;
409 save_reg_size += 4;
412 /* If we call eh_return, we need to save the EH data registers. */
413 if (crtl->calls_eh_return)
415 unsigned i;
416 unsigned r;
418 for (i = 0; (r = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; i++)
419 if (!(save_mask & (1 << r)))
421 save_mask |= 1 << r;
422 save_reg_size += 4;
426 cfun->machine->fp_save_offset = 0;
427 if (save_mask & (1 << HARD_FRAME_POINTER_REGNUM))
429 int fp_save_offset = 0;
430 for (regno = 0; regno < HARD_FRAME_POINTER_REGNUM; regno++)
431 if (save_mask & (1 << regno))
432 fp_save_offset += 4;
434 cfun->machine->fp_save_offset = fp_save_offset;
437 save_reg_size = NIOS2_STACK_ALIGN (save_reg_size);
438 total_size += save_reg_size;
439 total_size += NIOS2_STACK_ALIGN (crtl->args.pretend_args_size);
441 /* Save other computed information. */
442 cfun->machine->save_mask = save_mask;
443 cfun->machine->total_size = total_size;
444 cfun->machine->var_size = var_size;
445 cfun->machine->args_size = out_args_size;
446 cfun->machine->save_reg_size = save_reg_size;
447 cfun->machine->initialized = reload_completed;
448 cfun->machine->save_regs_offset = out_args_size + var_size;
450 return total_size;
453 /* Generate save/restore of register REGNO at SP + OFFSET. Used by the
454 prologue/epilogue expand routines. */
455 static void
456 save_reg (int regno, unsigned offset)
458 rtx reg = gen_rtx_REG (SImode, regno);
459 rtx addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
460 gen_int_mode (offset, Pmode));
461 rtx insn = emit_move_insn (gen_frame_mem (Pmode, addr), reg);
462 RTX_FRAME_RELATED_P (insn) = 1;
465 static void
466 restore_reg (int regno, unsigned offset)
468 rtx reg = gen_rtx_REG (SImode, regno);
469 rtx addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
470 gen_int_mode (offset, Pmode));
471 rtx insn = emit_move_insn (reg, gen_frame_mem (Pmode, addr));
472 /* Tag epilogue unwind note. */
473 add_reg_note (insn, REG_CFA_RESTORE, reg);
474 RTX_FRAME_RELATED_P (insn) = 1;
477 /* Emit conditional trap for checking stack limit. */
478 static void
479 nios2_emit_stack_limit_check (void)
481 if (REG_P (stack_limit_rtx))
482 emit_insn (gen_ctrapsi4 (gen_rtx_LTU (VOIDmode, stack_pointer_rtx,
483 stack_limit_rtx),
484 stack_pointer_rtx, stack_limit_rtx, GEN_INT (3)));
485 else
486 sorry ("only register based stack limit is supported");
489 /* Temp regno used inside prologue/epilogue. */
490 #define TEMP_REG_NUM 8
492 void
493 nios2_expand_prologue (void)
495 unsigned int regno;
496 int total_frame_size, save_offset;
497 int sp_offset; /* offset from base_reg to final stack value. */
498 int save_regs_base; /* offset from base_reg to register save area. */
499 rtx insn;
501 total_frame_size = nios2_compute_frame_layout ();
503 if (flag_stack_usage_info)
504 current_function_static_stack_size = total_frame_size;
506 /* Decrement the stack pointer. */
507 if (!SMALL_INT (total_frame_size))
509 /* We need an intermediary point, this will point at the spill block. */
510 insn = emit_insn
511 (gen_add2_insn (stack_pointer_rtx,
512 gen_int_mode (cfun->machine->save_regs_offset
513 - total_frame_size, Pmode)));
514 RTX_FRAME_RELATED_P (insn) = 1;
515 save_regs_base = 0;
516 sp_offset = -cfun->machine->save_regs_offset;
518 else if (total_frame_size)
520 insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
521 gen_int_mode (-total_frame_size,
522 Pmode)));
523 RTX_FRAME_RELATED_P (insn) = 1;
524 save_regs_base = cfun->machine->save_regs_offset;
525 sp_offset = 0;
527 else
528 save_regs_base = sp_offset = 0;
530 if (crtl->limit_stack)
531 nios2_emit_stack_limit_check ();
533 save_offset = save_regs_base + cfun->machine->save_reg_size;
535 for (regno = LAST_GP_REG; regno > 0; regno--)
536 if (cfun->machine->save_mask & (1 << regno))
538 save_offset -= 4;
539 save_reg (regno, save_offset);
542 if (frame_pointer_needed)
544 int fp_save_offset = save_regs_base + cfun->machine->fp_save_offset;
545 insn = emit_insn (gen_add3_insn (hard_frame_pointer_rtx,
546 stack_pointer_rtx,
547 gen_int_mode (fp_save_offset, Pmode)));
548 RTX_FRAME_RELATED_P (insn) = 1;
551 if (sp_offset)
553 rtx sp_adjust
554 = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
555 plus_constant (Pmode, stack_pointer_rtx, sp_offset));
556 if (SMALL_INT (sp_offset))
557 insn = emit_insn (sp_adjust);
558 else
560 rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
561 emit_move_insn (tmp, gen_int_mode (sp_offset, Pmode));
562 insn = emit_insn (gen_add2_insn (stack_pointer_rtx, tmp));
563 /* Attach the sp_adjust as a note indicating what happened. */
564 add_reg_note (insn, REG_FRAME_RELATED_EXPR, sp_adjust);
566 RTX_FRAME_RELATED_P (insn) = 1;
568 if (crtl->limit_stack)
569 nios2_emit_stack_limit_check ();
572 /* Load the PIC register if needed. */
573 if (crtl->uses_pic_offset_table)
574 nios2_load_pic_register ();
576 /* If we are profiling, make sure no instructions are scheduled before
577 the call to mcount. */
578 if (crtl->profile)
579 emit_insn (gen_blockage ());
582 void
583 nios2_expand_epilogue (bool sibcall_p)
585 rtx insn, cfa_adj;
586 int total_frame_size;
587 int sp_adjust, save_offset;
588 unsigned int regno;
590 if (!sibcall_p && nios2_can_use_return_insn ())
592 emit_jump_insn (gen_return ());
593 return;
596 emit_insn (gen_blockage ());
598 total_frame_size = nios2_compute_frame_layout ();
599 if (frame_pointer_needed)
601 /* Recover the stack pointer. */
602 insn = emit_insn (gen_add3_insn
603 (stack_pointer_rtx, hard_frame_pointer_rtx,
604 gen_int_mode (-cfun->machine->fp_save_offset, Pmode)));
605 cfa_adj = plus_constant (Pmode, stack_pointer_rtx,
606 (total_frame_size
607 - cfun->machine->save_regs_offset));
608 add_reg_note (insn, REG_CFA_DEF_CFA, cfa_adj);
609 RTX_FRAME_RELATED_P (insn) = 1;
611 save_offset = 0;
612 sp_adjust = total_frame_size - cfun->machine->save_regs_offset;
614 else if (!SMALL_INT (total_frame_size))
616 rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
617 emit_move_insn (tmp, gen_int_mode (cfun->machine->save_regs_offset,
618 Pmode));
619 insn = emit_insn (gen_add2_insn (stack_pointer_rtx, tmp));
620 cfa_adj = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
621 plus_constant (Pmode, stack_pointer_rtx,
622 cfun->machine->save_regs_offset));
623 add_reg_note (insn, REG_CFA_ADJUST_CFA, cfa_adj);
624 RTX_FRAME_RELATED_P (insn) = 1;
625 save_offset = 0;
626 sp_adjust = total_frame_size - cfun->machine->save_regs_offset;
628 else
630 save_offset = cfun->machine->save_regs_offset;
631 sp_adjust = total_frame_size;
634 save_offset += cfun->machine->save_reg_size;
636 for (regno = LAST_GP_REG; regno > 0; regno--)
637 if (cfun->machine->save_mask & (1 << regno))
639 save_offset -= 4;
640 restore_reg (regno, save_offset);
643 if (sp_adjust)
645 insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
646 gen_int_mode (sp_adjust, Pmode)));
647 cfa_adj = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
648 plus_constant (Pmode, stack_pointer_rtx,
649 sp_adjust));
650 add_reg_note (insn, REG_CFA_ADJUST_CFA, cfa_adj);
651 RTX_FRAME_RELATED_P (insn) = 1;
654 /* Add in the __builtin_eh_return stack adjustment. */
655 if (crtl->calls_eh_return)
656 emit_insn (gen_add2_insn (stack_pointer_rtx, EH_RETURN_STACKADJ_RTX));
658 if (!sibcall_p)
659 emit_jump_insn (gen_simple_return ());
662 /* Implement RETURN_ADDR_RTX. Note, we do not support moving
663 back to a previous frame. */
665 nios2_get_return_address (int count)
667 if (count != 0)
668 return const0_rtx;
670 return get_hard_reg_initial_val (Pmode, RA_REGNO);
673 /* Emit code to change the current function's return address to
674 ADDRESS. SCRATCH is available as a scratch register, if needed.
675 ADDRESS and SCRATCH are both word-mode GPRs. */
676 void
677 nios2_set_return_address (rtx address, rtx scratch)
679 nios2_compute_frame_layout ();
680 if (cfun->machine->save_mask & (1 << RA_REGNO))
682 unsigned offset = cfun->machine->save_reg_size - 4;
683 rtx base;
685 if (frame_pointer_needed)
686 base = hard_frame_pointer_rtx;
687 else
689 base = stack_pointer_rtx;
690 offset += cfun->machine->save_regs_offset;
692 if (!SMALL_INT (offset))
694 emit_move_insn (scratch, gen_int_mode (offset, Pmode));
695 emit_insn (gen_add2_insn (scratch, base));
696 base = scratch;
697 offset = 0;
700 if (offset)
701 base = plus_constant (Pmode, base, offset);
702 emit_move_insn (gen_rtx_MEM (Pmode, base), address);
704 else
705 emit_move_insn (gen_rtx_REG (Pmode, RA_REGNO), address);
708 /* Implement FUNCTION_PROFILER macro. */
709 void
710 nios2_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
712 fprintf (file, "\tmov\tr8, ra\n");
713 if (flag_pic == 1)
715 fprintf (file, "\tnextpc\tr2\n");
716 fprintf (file, "\t1: movhi\tr3, %%hiadj(_gp_got - 1b)\n");
717 fprintf (file, "\taddi\tr3, r3, %%lo(_gp_got - 1b)\n");
718 fprintf (file, "\tadd\tr2, r2, r3\n");
719 fprintf (file, "\tldw\tr2, %%call(_mcount)(r2)\n");
720 fprintf (file, "\tcallr\tr2\n");
722 else if (flag_pic == 2)
724 fprintf (file, "\tnextpc\tr2\n");
725 fprintf (file, "\t1: movhi\tr3, %%hiadj(_gp_got - 1b)\n");
726 fprintf (file, "\taddi\tr3, r3, %%lo(_gp_got - 1b)\n");
727 fprintf (file, "\tadd\tr2, r2, r3\n");
728 fprintf (file, "\tmovhi\tr3, %%call_hiadj(_mcount)\n");
729 fprintf (file, "\taddi\tr3, r3, %%call_lo(_mcount)\n");
730 fprintf (file, "\tadd\tr3, r2, r3\n");
731 fprintf (file, "\tldw\tr2, 0(r3)\n");
732 fprintf (file, "\tcallr\tr2\n");
734 else
735 fprintf (file, "\tcall\t_mcount\n");
736 fprintf (file, "\tmov\tra, r8\n");
739 /* Dump stack layout. */
740 static void
741 nios2_dump_frame_layout (FILE *file)
743 fprintf (file, "\t%s Current Frame Info\n", ASM_COMMENT_START);
744 fprintf (file, "\t%s total_size = %d\n", ASM_COMMENT_START,
745 cfun->machine->total_size);
746 fprintf (file, "\t%s var_size = %d\n", ASM_COMMENT_START,
747 cfun->machine->var_size);
748 fprintf (file, "\t%s args_size = %d\n", ASM_COMMENT_START,
749 cfun->machine->args_size);
750 fprintf (file, "\t%s save_reg_size = %d\n", ASM_COMMENT_START,
751 cfun->machine->save_reg_size);
752 fprintf (file, "\t%s initialized = %d\n", ASM_COMMENT_START,
753 cfun->machine->initialized);
754 fprintf (file, "\t%s save_regs_offset = %d\n", ASM_COMMENT_START,
755 cfun->machine->save_regs_offset);
756 fprintf (file, "\t%s is_leaf = %d\n", ASM_COMMENT_START,
757 crtl->is_leaf);
758 fprintf (file, "\t%s frame_pointer_needed = %d\n", ASM_COMMENT_START,
759 frame_pointer_needed);
760 fprintf (file, "\t%s pretend_args_size = %d\n", ASM_COMMENT_START,
761 crtl->args.pretend_args_size);
764 /* Return true if REGNO should be saved in the prologue. */
765 static bool
766 prologue_saved_reg_p (unsigned regno)
768 gcc_assert (GP_REG_P (regno));
770 if (df_regs_ever_live_p (regno) && !call_used_regs[regno])
771 return true;
773 if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
774 return true;
776 if (regno == PIC_OFFSET_TABLE_REGNUM && crtl->uses_pic_offset_table)
777 return true;
779 if (regno == RA_REGNO && df_regs_ever_live_p (RA_REGNO))
780 return true;
782 return false;
785 /* Implement TARGET_CAN_ELIMINATE. */
786 static bool
787 nios2_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
789 if (to == STACK_POINTER_REGNUM)
790 return !frame_pointer_needed;
791 return true;
794 /* Implement INITIAL_ELIMINATION_OFFSET macro. */
796 nios2_initial_elimination_offset (int from, int to)
798 int offset;
800 nios2_compute_frame_layout ();
802 /* Set OFFSET to the offset from the stack pointer. */
803 switch (from)
805 case FRAME_POINTER_REGNUM:
806 offset = cfun->machine->args_size;
807 break;
809 case ARG_POINTER_REGNUM:
810 offset = cfun->machine->total_size;
811 offset -= crtl->args.pretend_args_size;
812 break;
814 default:
815 gcc_unreachable ();
818 /* If we are asked for the frame pointer offset, then adjust OFFSET
819 by the offset from the frame pointer to the stack pointer. */
820 if (to == HARD_FRAME_POINTER_REGNUM)
821 offset -= (cfun->machine->save_regs_offset
822 + cfun->machine->fp_save_offset);
824 return offset;
827 /* Return nonzero if this function is known to have a null epilogue.
828 This allows the optimizer to omit jumps to jumps if no stack
829 was created. */
831 nios2_can_use_return_insn (void)
833 if (!reload_completed || crtl->profile)
834 return 0;
836 return nios2_compute_frame_layout () == 0;
840 /* Check and signal some warnings/errors on FPU insn options. */
841 static void
842 nios2_custom_check_insns (void)
844 unsigned int i, j;
845 bool errors = false;
847 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
848 if (N2FPU_ENABLED_P (i) && N2FPU_DOUBLE_P (i))
850 for (j = 0; j < ARRAY_SIZE (nios2_fpu_insn); j++)
851 if (N2FPU_DOUBLE_REQUIRED_P (j) && ! N2FPU_ENABLED_P (j))
853 error ("switch %<-mcustom-%s%> is required for double "
854 "precision floating point", N2FPU_NAME (j));
855 errors = true;
857 break;
860 /* Warn if the user has certain exotic operations that won't get used
861 without -funsafe-math-optimizations. See expand_builtin () in
862 builtins.c. */
863 if (!flag_unsafe_math_optimizations)
864 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
865 if (N2FPU_ENABLED_P (i) && N2FPU_UNSAFE_P (i))
866 warning (0, "switch %<-mcustom-%s%> has no effect unless "
867 "-funsafe-math-optimizations is specified", N2FPU_NAME (i));
869 /* Warn if the user is trying to use -mcustom-fmins et. al, that won't
870 get used without -ffinite-math-only. See fold_builtin_fmin_fmax ()
871 in builtins.c. */
872 if (!flag_finite_math_only)
873 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
874 if (N2FPU_ENABLED_P (i) && N2FPU_FINITE_P (i))
875 warning (0, "switch %<-mcustom-%s%> has no effect unless "
876 "-ffinite-math-only is specified", N2FPU_NAME (i));
878 /* Warn if the user is trying to use a custom rounding instruction
879 that won't get used without -fno-math-errno. See
880 expand_builtin_int_roundingfn_2 () in builtins.c. */
881 if (flag_errno_math)
882 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
883 if (N2FPU_ENABLED_P (i) && N2FPU_NO_ERRNO_P (i))
884 warning (0, "switch %<-mcustom-%s%> has no effect unless "
885 "-fno-math-errno is specified", N2FPU_NAME (i));
887 if (errors || custom_code_conflict)
888 fatal_error (input_location,
889 "conflicting use of -mcustom switches, target attributes, "
890 "and/or __builtin_custom_ functions");
893 static void
894 nios2_set_fpu_custom_code (enum n2fpu_code code, int n, bool override_p)
896 if (override_p || N2FPU_N (code) == -1)
897 N2FPU_N (code) = n;
898 nios2_register_custom_code (n, CCS_FPU, (int) code);
901 /* Type to represent a standard FPU config. */
902 struct nios2_fpu_config
904 const char *name;
905 bool set_sp_constants;
906 int code[n2fpu_code_num];
909 #define NIOS2_FPU_CONFIG_NUM 3
910 static struct nios2_fpu_config custom_fpu_config[NIOS2_FPU_CONFIG_NUM];
912 static void
913 nios2_init_fpu_configs (void)
915 struct nios2_fpu_config* cfg;
916 int i = 0;
917 #define NEXT_FPU_CONFIG \
918 do { \
919 cfg = &custom_fpu_config[i++]; \
920 memset (cfg, -1, sizeof (struct nios2_fpu_config));\
921 } while (0)
923 NEXT_FPU_CONFIG;
924 cfg->name = "60-1";
925 cfg->set_sp_constants = true;
926 cfg->code[n2fpu_fmuls] = 252;
927 cfg->code[n2fpu_fadds] = 253;
928 cfg->code[n2fpu_fsubs] = 254;
930 NEXT_FPU_CONFIG;
931 cfg->name = "60-2";
932 cfg->set_sp_constants = true;
933 cfg->code[n2fpu_fmuls] = 252;
934 cfg->code[n2fpu_fadds] = 253;
935 cfg->code[n2fpu_fsubs] = 254;
936 cfg->code[n2fpu_fdivs] = 255;
938 NEXT_FPU_CONFIG;
939 cfg->name = "72-3";
940 cfg->set_sp_constants = true;
941 cfg->code[n2fpu_floatus] = 243;
942 cfg->code[n2fpu_fixsi] = 244;
943 cfg->code[n2fpu_floatis] = 245;
944 cfg->code[n2fpu_fcmpgts] = 246;
945 cfg->code[n2fpu_fcmples] = 249;
946 cfg->code[n2fpu_fcmpeqs] = 250;
947 cfg->code[n2fpu_fcmpnes] = 251;
948 cfg->code[n2fpu_fmuls] = 252;
949 cfg->code[n2fpu_fadds] = 253;
950 cfg->code[n2fpu_fsubs] = 254;
951 cfg->code[n2fpu_fdivs] = 255;
953 #undef NEXT_FPU_CONFIG
954 gcc_assert (i == NIOS2_FPU_CONFIG_NUM);
957 static struct nios2_fpu_config *
958 nios2_match_custom_fpu_cfg (const char *cfgname, const char *endp)
960 int i;
961 for (i = 0; i < NIOS2_FPU_CONFIG_NUM; i++)
963 bool match = !(endp != NULL
964 ? strncmp (custom_fpu_config[i].name, cfgname,
965 endp - cfgname)
966 : strcmp (custom_fpu_config[i].name, cfgname));
967 if (match)
968 return &custom_fpu_config[i];
970 return NULL;
973 /* Use CFGNAME to lookup FPU config, ENDP if not NULL marks end of string.
974 OVERRIDE is true if loaded config codes should overwrite current state. */
975 static void
976 nios2_handle_custom_fpu_cfg (const char *cfgname, const char *endp,
977 bool override)
979 struct nios2_fpu_config *cfg = nios2_match_custom_fpu_cfg (cfgname, endp);
980 if (cfg)
982 unsigned int i;
983 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
984 if (cfg->code[i] >= 0)
985 nios2_set_fpu_custom_code ((enum n2fpu_code) i, cfg->code[i],
986 override);
987 if (cfg->set_sp_constants)
988 flag_single_precision_constant = 1;
990 else
991 warning (0, "ignoring unrecognized switch %<-mcustom-fpu-cfg%> "
992 "value %<%s%>", cfgname);
994 /* Guard against errors in the standard configurations. */
995 nios2_custom_check_insns ();
998 /* Check individual FPU insn options, and register custom code. */
999 static void
1000 nios2_handle_custom_fpu_insn_option (int fpu_insn_index)
1002 int param = N2FPU_N (fpu_insn_index);
1004 if (0 <= param && param <= 255)
1005 nios2_register_custom_code (param, CCS_FPU, fpu_insn_index);
1007 /* Valid values are 0-255, but also allow -1 so that the
1008 -mno-custom-<opt> switches work. */
1009 else if (param != -1)
1010 error ("switch %<-mcustom-%s%> value %d must be between 0 and 255",
1011 N2FPU_NAME (fpu_insn_index), param);
1014 /* Allocate a chunk of memory for per-function machine-dependent data. */
1015 static struct machine_function *
1016 nios2_init_machine_status (void)
1018 return ggc_cleared_alloc<machine_function> ();
1021 /* Implement TARGET_OPTION_OVERRIDE. */
1022 static void
1023 nios2_option_override (void)
1025 unsigned int i;
1027 #ifdef SUBTARGET_OVERRIDE_OPTIONS
1028 SUBTARGET_OVERRIDE_OPTIONS;
1029 #endif
1031 /* Check for unsupported options. */
1032 if (flag_pic && !TARGET_LINUX_ABI)
1033 sorry ("position-independent code requires the Linux ABI");
1035 /* Function to allocate machine-dependent function status. */
1036 init_machine_status = &nios2_init_machine_status;
1038 nios2_section_threshold
1039 = (global_options_set.x_g_switch_value
1040 ? g_switch_value : NIOS2_DEFAULT_GVALUE);
1042 if (nios2_gpopt_option == gpopt_unspecified)
1044 /* Default to -mgpopt unless -fpic or -fPIC. */
1045 if (flag_pic)
1046 nios2_gpopt_option = gpopt_none;
1047 else
1048 nios2_gpopt_option = gpopt_local;
1051 /* If we don't have mul, we don't have mulx either! */
1052 if (!TARGET_HAS_MUL && TARGET_HAS_MULX)
1053 target_flags &= ~MASK_HAS_MULX;
1055 /* Initialize default FPU configurations. */
1056 nios2_init_fpu_configs ();
1058 /* Set up default handling for floating point custom instructions.
1060 Putting things in this order means that the -mcustom-fpu-cfg=
1061 switch will always be overridden by individual -mcustom-fadds=
1062 switches, regardless of the order in which they were specified
1063 on the command line.
1065 This behavior of prioritization of individual -mcustom-<insn>=
1066 options before the -mcustom-fpu-cfg= switch is maintained for
1067 compatibility. */
1068 if (nios2_custom_fpu_cfg_string && *nios2_custom_fpu_cfg_string)
1069 nios2_handle_custom_fpu_cfg (nios2_custom_fpu_cfg_string, NULL, false);
1071 /* Handle options for individual FPU insns. */
1072 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
1073 nios2_handle_custom_fpu_insn_option (i);
1075 nios2_custom_check_insns ();
1077 /* Save the initial options in case the user does function specific
1078 options. */
1079 target_option_default_node = target_option_current_node
1080 = build_target_option_node (&global_options);
1084 /* Return true if CST is a constant within range of movi/movui/movhi. */
1085 static bool
1086 nios2_simple_const_p (const_rtx cst)
1088 HOST_WIDE_INT val = INTVAL (cst);
1089 return SMALL_INT (val) || SMALL_INT_UNSIGNED (val) || UPPER16_INT (val);
1092 /* Compute a (partial) cost for rtx X. Return true if the complete
1093 cost has been computed, and false if subexpressions should be
1094 scanned. In either case, *TOTAL contains the cost result. */
1095 static bool
1096 nios2_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
1097 int opno ATTRIBUTE_UNUSED,
1098 int *total, bool speed ATTRIBUTE_UNUSED)
1100 switch (code)
1102 case CONST_INT:
1103 if (INTVAL (x) == 0)
1105 *total = COSTS_N_INSNS (0);
1106 return true;
1108 else if (nios2_simple_const_p (x))
1110 *total = COSTS_N_INSNS (2);
1111 return true;
1113 else
1115 *total = COSTS_N_INSNS (4);
1116 return true;
1119 case LABEL_REF:
1120 case SYMBOL_REF:
1121 case CONST:
1122 case CONST_DOUBLE:
1124 *total = COSTS_N_INSNS (4);
1125 return true;
1128 case AND:
1130 /* Recognize 'nor' insn pattern. */
1131 if (GET_CODE (XEXP (x, 0)) == NOT
1132 && GET_CODE (XEXP (x, 1)) == NOT)
1134 *total = COSTS_N_INSNS (1);
1135 return true;
1137 return false;
1140 case MULT:
1142 *total = COSTS_N_INSNS (1);
1143 return false;
1145 case SIGN_EXTEND:
1147 *total = COSTS_N_INSNS (3);
1148 return false;
1150 case ZERO_EXTEND:
1152 *total = COSTS_N_INSNS (1);
1153 return false;
1156 default:
1157 return false;
1161 /* Implement TARGET_PREFERRED_RELOAD_CLASS. */
1162 static reg_class_t
1163 nios2_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, reg_class_t regclass)
1165 return regclass == NO_REGS ? GENERAL_REGS : regclass;
1168 /* Emit a call to __tls_get_addr. TI is the argument to this function.
1169 RET is an RTX for the return value location. The entire insn sequence
1170 is returned. */
1171 static GTY(()) rtx nios2_tls_symbol;
1173 static rtx
1174 nios2_call_tls_get_addr (rtx ti)
1176 rtx arg = gen_rtx_REG (Pmode, FIRST_ARG_REGNO);
1177 rtx ret = gen_rtx_REG (Pmode, FIRST_RETVAL_REGNO);
1178 rtx fn, insn;
1180 if (!nios2_tls_symbol)
1181 nios2_tls_symbol = init_one_libfunc ("__tls_get_addr");
1183 emit_move_insn (arg, ti);
1184 fn = gen_rtx_MEM (QImode, nios2_tls_symbol);
1185 insn = emit_call_insn (gen_call_value (ret, fn, const0_rtx));
1186 RTL_CONST_CALL_P (insn) = 1;
1187 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), ret);
1188 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), arg);
1190 return ret;
1193 /* Return true for large offsets requiring hiadj/lo relocation pairs. */
1194 static bool
1195 nios2_large_offset_p (int unspec)
1197 gcc_assert (nios2_unspec_reloc_name (unspec) != NULL);
1199 if (flag_pic == 2
1200 /* FIXME: TLS GOT offset relocations will eventually also get this
1201 treatment, after binutils support for those are also completed. */
1202 && (unspec == UNSPEC_PIC_SYM || unspec == UNSPEC_PIC_CALL_SYM))
1203 return true;
1205 /* 'gotoff' offsets are always hiadj/lo. */
1206 if (unspec == UNSPEC_PIC_GOTOFF_SYM)
1207 return true;
1209 return false;
1212 /* Return true for conforming unspec relocations. Also used in
1213 constraints.md and predicates.md. */
1214 bool
1215 nios2_unspec_reloc_p (rtx op)
1217 return (GET_CODE (op) == CONST
1218 && GET_CODE (XEXP (op, 0)) == UNSPEC
1219 && ! nios2_large_offset_p (XINT (XEXP (op, 0), 1)));
1222 /* Helper to generate unspec constant. */
1223 static rtx
1224 nios2_unspec_offset (rtx loc, int unspec)
1226 return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, loc),
1227 unspec));
1230 /* Generate GOT pointer based address with large offset. */
1231 static rtx
1232 nios2_large_got_address (rtx offset)
1234 rtx addr = gen_reg_rtx (Pmode);
1235 emit_insn (gen_add3_insn (addr, pic_offset_table_rtx,
1236 force_reg (Pmode, offset)));
1237 return addr;
1240 /* Generate a GOT pointer based address. */
1241 static rtx
1242 nios2_got_address (rtx loc, int unspec)
1244 rtx offset = nios2_unspec_offset (loc, unspec);
1245 crtl->uses_pic_offset_table = 1;
1247 if (nios2_large_offset_p (unspec))
1248 return nios2_large_got_address (offset);
1250 return gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset);
1253 /* Generate the code to access LOC, a thread local SYMBOL_REF. The
1254 return value will be a valid address and move_operand (either a REG
1255 or a LO_SUM). */
1256 static rtx
1257 nios2_legitimize_tls_address (rtx loc)
1259 rtx tmp, mem, tp;
1260 enum tls_model model = SYMBOL_REF_TLS_MODEL (loc);
1262 switch (model)
1264 case TLS_MODEL_GLOBAL_DYNAMIC:
1265 tmp = gen_reg_rtx (Pmode);
1266 emit_move_insn (tmp, nios2_got_address (loc, UNSPEC_ADD_TLS_GD));
1267 return nios2_call_tls_get_addr (tmp);
1269 case TLS_MODEL_LOCAL_DYNAMIC:
1270 tmp = gen_reg_rtx (Pmode);
1271 emit_move_insn (tmp, nios2_got_address (loc, UNSPEC_ADD_TLS_LDM));
1272 return gen_rtx_PLUS (Pmode, nios2_call_tls_get_addr (tmp),
1273 nios2_unspec_offset (loc, UNSPEC_ADD_TLS_LDO));
1275 case TLS_MODEL_INITIAL_EXEC:
1276 tmp = gen_reg_rtx (Pmode);
1277 mem = gen_const_mem (Pmode, nios2_got_address (loc, UNSPEC_LOAD_TLS_IE));
1278 emit_move_insn (tmp, mem);
1279 tp = gen_rtx_REG (Pmode, TP_REGNO);
1280 return gen_rtx_PLUS (Pmode, tp, tmp);
1282 case TLS_MODEL_LOCAL_EXEC:
1283 tp = gen_rtx_REG (Pmode, TP_REGNO);
1284 return gen_rtx_PLUS (Pmode, tp,
1285 nios2_unspec_offset (loc, UNSPEC_ADD_TLS_LE));
1286 default:
1287 gcc_unreachable ();
1291 /* Divide Support
1293 If -O3 is used, we want to output a table lookup for
1294 divides between small numbers (both num and den >= 0
1295 and < 0x10). The overhead of this method in the worst
1296 case is 40 bytes in the text section (10 insns) and
1297 256 bytes in the data section. Additional divides do
1298 not incur additional penalties in the data section.
1300 Code speed is improved for small divides by about 5x
1301 when using this method in the worse case (~9 cycles
1302 vs ~45). And in the worst case divides not within the
1303 table are penalized by about 10% (~5 cycles vs ~45).
1304 However in the typical case the penalty is not as bad
1305 because doing the long divide in only 45 cycles is
1306 quite optimistic.
1308 ??? would be nice to have some benchmarks other
1309 than Dhrystone to back this up.
1311 This bit of expansion is to create this instruction
1312 sequence as rtl.
1313 or $8, $4, $5
1314 slli $9, $4, 4
1315 cmpgeui $3, $8, 16
1316 beq $3, $0, .L3
1317 or $10, $9, $5
1318 add $12, $11, divide_table
1319 ldbu $2, 0($12)
1320 br .L1
1321 .L3:
1322 call slow_div
1323 .L1:
1324 # continue here with result in $2
1326 ??? Ideally I would like the libcall block to contain all
1327 of this code, but I don't know how to do that. What it
1328 means is that if the divide can be eliminated, it may not
1329 completely disappear.
1331 ??? The __divsi3_table label should ideally be moved out
1332 of this block and into a global. If it is placed into the
1333 sdata section we can save even more cycles by doing things
1334 gp relative. */
1335 void
1336 nios2_emit_expensive_div (rtx *operands, machine_mode mode)
1338 rtx or_result, shift_left_result;
1339 rtx lookup_value;
1340 rtx_code_label *lab1, *lab3;
1341 rtx insns;
1342 rtx libfunc;
1343 rtx final_result;
1344 rtx tmp;
1345 rtx table;
1347 /* It may look a little generic, but only SImode is supported for now. */
1348 gcc_assert (mode == SImode);
1349 libfunc = optab_libfunc (sdiv_optab, SImode);
1351 lab1 = gen_label_rtx ();
1352 lab3 = gen_label_rtx ();
1354 or_result = expand_simple_binop (SImode, IOR,
1355 operands[1], operands[2],
1356 0, 0, OPTAB_LIB_WIDEN);
1358 emit_cmp_and_jump_insns (or_result, GEN_INT (15), GTU, 0,
1359 GET_MODE (or_result), 0, lab3);
1360 JUMP_LABEL (get_last_insn ()) = lab3;
1362 shift_left_result = expand_simple_binop (SImode, ASHIFT,
1363 operands[1], GEN_INT (4),
1364 0, 0, OPTAB_LIB_WIDEN);
1366 lookup_value = expand_simple_binop (SImode, IOR,
1367 shift_left_result, operands[2],
1368 0, 0, OPTAB_LIB_WIDEN);
1369 table = gen_rtx_PLUS (SImode, lookup_value,
1370 gen_rtx_SYMBOL_REF (SImode, "__divsi3_table"));
1371 convert_move (operands[0], gen_rtx_MEM (QImode, table), 1);
1373 tmp = emit_jump_insn (gen_jump (lab1));
1374 JUMP_LABEL (tmp) = lab1;
1375 emit_barrier ();
1377 emit_label (lab3);
1378 LABEL_NUSES (lab3) = 1;
1380 start_sequence ();
1381 final_result = emit_library_call_value (libfunc, NULL_RTX,
1382 LCT_CONST, SImode, 2,
1383 operands[1], SImode,
1384 operands[2], SImode);
1386 insns = get_insns ();
1387 end_sequence ();
1388 emit_libcall_block (insns, operands[0], final_result,
1389 gen_rtx_DIV (SImode, operands[1], operands[2]));
1391 emit_label (lab1);
1392 LABEL_NUSES (lab1) = 1;
1396 /* Branches and compares. */
1398 /* Return in *ALT_CODE and *ALT_OP, an alternate equivalent constant
1399 comparison, e.g. >= 1 into > 0. */
1400 static void
1401 nios2_alternate_compare_const (enum rtx_code code, rtx op,
1402 enum rtx_code *alt_code, rtx *alt_op,
1403 machine_mode mode)
1405 HOST_WIDE_INT opval = INTVAL (op);
1406 enum rtx_code scode = signed_condition (code);
1407 bool dec_p = (scode == LT || scode == GE);
1409 if (code == EQ || code == NE)
1411 *alt_code = code;
1412 *alt_op = op;
1413 return;
1416 *alt_op = (dec_p
1417 ? gen_int_mode (opval - 1, mode)
1418 : gen_int_mode (opval + 1, mode));
1420 /* The required conversion between [>,>=] and [<,<=] is captured
1421 by a reverse + swap of condition codes. */
1422 *alt_code = reverse_condition (swap_condition (code));
1425 /* Test if the incremented/decremented value crosses the over/underflow
1426 boundary. Supposedly, such boundary cases should already be transformed
1427 into always-true/false or EQ conditions, so use an assertion here. */
1428 unsigned HOST_WIDE_INT alt_opval = INTVAL (*alt_op);
1429 if (code == scode)
1430 alt_opval ^= (1 << (GET_MODE_BITSIZE (mode) - 1));
1431 alt_opval &= GET_MODE_MASK (mode);
1432 gcc_assert (dec_p ? alt_opval != GET_MODE_MASK (mode) : alt_opval != 0);
1436 /* Return true if the constant comparison is supported by nios2. */
1437 static bool
1438 nios2_valid_compare_const_p (enum rtx_code code, rtx op)
1440 switch (code)
1442 case EQ: case NE: case GE: case LT:
1443 return SMALL_INT (INTVAL (op));
1444 case GEU: case LTU:
1445 return SMALL_INT_UNSIGNED (INTVAL (op));
1446 default:
1447 return false;
1451 /* Checks if the FPU comparison in *CMP, *OP1, and *OP2 can be supported in
1452 the current configuration. Perform modifications if MODIFY_P is true.
1453 Returns true if FPU compare can be done. */
1455 bool
1456 nios2_validate_fpu_compare (machine_mode mode, rtx *cmp, rtx *op1, rtx *op2,
1457 bool modify_p)
1459 bool rev_p = false;
1460 enum rtx_code code = GET_CODE (*cmp);
1462 if (!nios2_fpu_compare_enabled (code, mode))
1464 code = swap_condition (code);
1465 if (nios2_fpu_compare_enabled (code, mode))
1466 rev_p = true;
1467 else
1468 return false;
1471 if (modify_p)
1473 if (rev_p)
1475 rtx tmp = *op1;
1476 *op1 = *op2;
1477 *op2 = tmp;
1479 *op1 = force_reg (mode, *op1);
1480 *op2 = force_reg (mode, *op2);
1481 *cmp = gen_rtx_fmt_ee (code, mode, *op1, *op2);
1483 return true;
1486 /* Checks and modifies the comparison in *CMP, *OP1, and *OP2 into valid
1487 nios2 supported form. Returns true if success. */
1488 bool
1489 nios2_validate_compare (machine_mode mode, rtx *cmp, rtx *op1, rtx *op2)
1491 enum rtx_code code = GET_CODE (*cmp);
1492 enum rtx_code alt_code;
1493 rtx alt_op2;
1495 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
1496 return nios2_validate_fpu_compare (mode, cmp, op1, op2, true);
1498 if (!reg_or_0_operand (*op2, mode))
1500 /* Create alternate constant compare. */
1501 nios2_alternate_compare_const (code, *op2, &alt_code, &alt_op2, mode);
1503 /* If alterate op2 is zero(0), we can use it directly, possibly
1504 swapping the compare code. */
1505 if (alt_op2 == const0_rtx)
1507 code = alt_code;
1508 *op2 = alt_op2;
1509 goto check_rebuild_cmp;
1512 /* Check if either constant compare can be used. */
1513 if (nios2_valid_compare_const_p (code, *op2))
1514 return true;
1515 else if (nios2_valid_compare_const_p (alt_code, alt_op2))
1517 code = alt_code;
1518 *op2 = alt_op2;
1519 goto rebuild_cmp;
1522 /* We have to force op2 into a register now. Try to pick one
1523 with a lower cost. */
1524 if (! nios2_simple_const_p (*op2)
1525 && nios2_simple_const_p (alt_op2))
1527 code = alt_code;
1528 *op2 = alt_op2;
1530 *op2 = force_reg (SImode, *op2);
1532 check_rebuild_cmp:
1533 if (code == GT || code == GTU || code == LE || code == LEU)
1535 rtx t = *op1; *op1 = *op2; *op2 = t;
1536 code = swap_condition (code);
1538 rebuild_cmp:
1539 *cmp = gen_rtx_fmt_ee (code, mode, *op1, *op2);
1540 return true;
1544 /* Addressing Modes. */
1546 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
1547 static bool
1548 nios2_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
1550 rtx base, offset;
1551 split_const (x, &base, &offset);
1552 return GET_CODE (base) != SYMBOL_REF || !SYMBOL_REF_TLS_MODEL (base);
1555 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
1556 static bool
1557 nios2_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
1559 return nios2_legitimate_constant_p (mode, x) == false;
1562 /* Return true if register REGNO is a valid base register.
1563 STRICT_P is true if REG_OK_STRICT is in effect. */
1565 bool
1566 nios2_regno_ok_for_base_p (int regno, bool strict_p)
1568 if (!HARD_REGISTER_NUM_P (regno))
1570 if (!strict_p)
1571 return true;
1573 if (!reg_renumber)
1574 return false;
1576 regno = reg_renumber[regno];
1579 /* The fake registers will be eliminated to either the stack or
1580 hard frame pointer, both of which are usually valid base registers.
1581 Reload deals with the cases where the eliminated form isn't valid. */
1582 return (GP_REG_P (regno)
1583 || regno == FRAME_POINTER_REGNUM
1584 || regno == ARG_POINTER_REGNUM);
1587 /* Return true if the address expression formed by BASE + OFFSET is
1588 valid. */
1589 static bool
1590 nios2_valid_addr_expr_p (rtx base, rtx offset, bool strict_p)
1592 if (!strict_p && GET_CODE (base) == SUBREG)
1593 base = SUBREG_REG (base);
1594 return (REG_P (base)
1595 && nios2_regno_ok_for_base_p (REGNO (base), strict_p)
1596 && (offset == NULL_RTX
1597 || const_arith_operand (offset, Pmode)
1598 || nios2_unspec_reloc_p (offset)));
1601 /* Implement TARGET_LEGITIMATE_ADDRESS_P. */
1602 static bool
1603 nios2_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
1604 rtx operand, bool strict_p)
1606 switch (GET_CODE (operand))
1608 /* Direct. */
1609 case SYMBOL_REF:
1610 if (SYMBOL_REF_TLS_MODEL (operand))
1611 return false;
1613 if (nios2_symbol_ref_in_small_data_p (operand))
1614 return true;
1616 /* Else, fall through. */
1617 case LABEL_REF:
1618 case CONST_INT:
1619 case CONST:
1620 case CONST_DOUBLE:
1621 return false;
1623 /* Register indirect. */
1624 case REG:
1625 return nios2_regno_ok_for_base_p (REGNO (operand), strict_p);
1627 /* Register indirect with displacement. */
1628 case PLUS:
1630 rtx op0 = XEXP (operand, 0);
1631 rtx op1 = XEXP (operand, 1);
1633 return (nios2_valid_addr_expr_p (op0, op1, strict_p)
1634 || nios2_valid_addr_expr_p (op1, op0, strict_p));
1637 default:
1638 break;
1640 return false;
1643 /* Return true if SECTION is a small section name. */
1644 static bool
1645 nios2_small_section_name_p (const char *section)
1647 return (strcmp (section, ".sbss") == 0
1648 || strncmp (section, ".sbss.", 6) == 0
1649 || strcmp (section, ".sdata") == 0
1650 || strncmp (section, ".sdata.", 7) == 0);
1653 /* Return true if EXP should be placed in the small data section. */
1654 static bool
1655 nios2_in_small_data_p (const_tree exp)
1657 /* We want to merge strings, so we never consider them small data. */
1658 if (TREE_CODE (exp) == STRING_CST)
1659 return false;
1661 if (TREE_CODE (exp) == VAR_DECL)
1663 if (DECL_SECTION_NAME (exp))
1665 const char *section = DECL_SECTION_NAME (exp);
1666 if (nios2_small_section_name_p (section))
1667 return true;
1669 else
1671 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
1673 /* If this is an incomplete type with size 0, then we can't put it
1674 in sdata because it might be too big when completed. */
1675 if (size > 0
1676 && (unsigned HOST_WIDE_INT) size <= nios2_section_threshold)
1677 return true;
1681 return false;
1684 /* Return true if symbol is in small data section. */
1686 bool
1687 nios2_symbol_ref_in_small_data_p (rtx sym)
1689 tree decl;
1691 gcc_assert (GET_CODE (sym) == SYMBOL_REF);
1692 decl = SYMBOL_REF_DECL (sym);
1694 /* TLS variables are not accessed through the GP. */
1695 if (SYMBOL_REF_TLS_MODEL (sym) != 0)
1696 return false;
1698 /* If the user has explicitly placed the symbol in a small data section
1699 via an attribute, generate gp-relative addressing even if the symbol
1700 is external, weak, or larger than we'd automatically put in the
1701 small data section. OTOH, if the symbol is located in some
1702 non-small-data section, we can't use gp-relative accesses on it
1703 unless the user has requested gpopt_data or gpopt_all. */
1705 switch (nios2_gpopt_option)
1707 case gpopt_none:
1708 /* Don't generate a gp-relative addressing mode if that's been
1709 disabled. */
1710 return false;
1712 case gpopt_local:
1713 /* Use GP-relative addressing for small data symbols that are
1714 not external or weak, plus any symbols that have explicitly
1715 been placed in a small data section. */
1716 if (decl && DECL_SECTION_NAME (decl))
1717 return nios2_small_section_name_p (DECL_SECTION_NAME (decl));
1718 return (SYMBOL_REF_SMALL_P (sym)
1719 && !SYMBOL_REF_EXTERNAL_P (sym)
1720 && !(decl && DECL_WEAK (decl)));
1722 case gpopt_global:
1723 /* Use GP-relative addressing for small data symbols, even if
1724 they are external or weak. Note that SYMBOL_REF_SMALL_P
1725 is also true of symbols that have explicitly been placed
1726 in a small data section. */
1727 return SYMBOL_REF_SMALL_P (sym);
1729 case gpopt_data:
1730 /* Use GP-relative addressing for all data symbols regardless
1731 of the object size, but not for code symbols. This option
1732 is equivalent to the user asserting that the entire data
1733 section is accessible from the GP. */
1734 return !SYMBOL_REF_FUNCTION_P (sym);
1736 case gpopt_all:
1737 /* Use GP-relative addressing for everything, including code.
1738 Effectively, the user has asserted that the entire program
1739 fits within the 64K range of the GP offset. */
1740 return true;
1742 default:
1743 /* We shouldn't get here. */
1744 return false;
1748 /* Implement TARGET_SECTION_TYPE_FLAGS. */
1750 static unsigned int
1751 nios2_section_type_flags (tree decl, const char *name, int reloc)
1753 unsigned int flags;
1755 flags = default_section_type_flags (decl, name, reloc);
1757 if (nios2_small_section_name_p (name))
1758 flags |= SECTION_SMALL;
1760 return flags;
1763 /* Return true if SYMBOL_REF X binds locally. */
1765 static bool
1766 nios2_symbol_binds_local_p (const_rtx x)
1768 return (SYMBOL_REF_DECL (x)
1769 ? targetm.binds_local_p (SYMBOL_REF_DECL (x))
1770 : SYMBOL_REF_LOCAL_P (x));
1773 /* Position independent code related. */
1775 /* Emit code to load the PIC register. */
1776 static void
1777 nios2_load_pic_register (void)
1779 rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
1781 emit_insn (gen_load_got_register (pic_offset_table_rtx, tmp));
1782 emit_insn (gen_add3_insn (pic_offset_table_rtx, pic_offset_table_rtx, tmp));
1785 /* Generate a PIC address as a MEM rtx. */
1786 static rtx
1787 nios2_load_pic_address (rtx sym, int unspec)
1789 if (flag_pic == 2
1790 && GET_CODE (sym) == SYMBOL_REF
1791 && nios2_symbol_binds_local_p (sym))
1792 /* Under -fPIC, generate a GOTOFF address for local symbols. */
1793 return nios2_got_address (sym, UNSPEC_PIC_GOTOFF_SYM);
1795 return gen_const_mem (Pmode, nios2_got_address (sym, unspec));
1798 /* Nonzero if the constant value X is a legitimate general operand
1799 when generating PIC code. It is given that flag_pic is on and
1800 that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
1801 bool
1802 nios2_legitimate_pic_operand_p (rtx x)
1804 if (GET_CODE (x) == CONST
1805 && GET_CODE (XEXP (x, 0)) == UNSPEC
1806 && nios2_large_offset_p (XINT (XEXP (x, 0), 1)))
1807 return true;
1809 return ! (GET_CODE (x) == SYMBOL_REF
1810 || GET_CODE (x) == LABEL_REF || GET_CODE (x) == CONST);
1813 /* Return TRUE if X is a thread-local symbol. */
1814 static bool
1815 nios2_tls_symbol_p (rtx x)
1817 return (targetm.have_tls && GET_CODE (x) == SYMBOL_REF
1818 && SYMBOL_REF_TLS_MODEL (x) != 0);
1821 /* Legitimize addresses that are CONSTANT_P expressions. */
1822 static rtx
1823 nios2_legitimize_constant_address (rtx addr)
1825 rtx base, offset;
1826 split_const (addr, &base, &offset);
1828 if (nios2_tls_symbol_p (base))
1829 base = nios2_legitimize_tls_address (base);
1830 else if (flag_pic)
1831 base = nios2_load_pic_address (base, UNSPEC_PIC_SYM);
1832 else
1833 return addr;
1835 if (offset != const0_rtx)
1837 gcc_assert (can_create_pseudo_p ());
1838 return gen_rtx_PLUS (Pmode, force_reg (Pmode, base),
1839 (CONST_INT_P (offset)
1840 ? (SMALL_INT (INTVAL (offset))
1841 ? offset : force_reg (Pmode, offset))
1842 : offset));
1844 return base;
1847 /* Implement TARGET_LEGITIMIZE_ADDRESS. */
1848 static rtx
1849 nios2_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
1850 machine_mode mode ATTRIBUTE_UNUSED)
1852 if (CONSTANT_P (x))
1853 return nios2_legitimize_constant_address (x);
1855 /* For the TLS LE (Local Exec) model, the compiler may try to
1856 combine constant offsets with unspec relocs, creating address RTXs
1857 looking like this:
1858 (plus:SI (reg:SI 23 r23)
1859 (const:SI
1860 (plus:SI
1861 (unspec:SI [(symbol_ref:SI ("var"))] UNSPEC_ADD_TLS_LE)
1862 (const_int 48 [0x30]))))
1864 This usually happens when 'var' is a thread-local struct variable,
1865 and access of a field in var causes the addend.
1867 We typically want this combining, so transform the above into this
1868 form, which is allowed:
1869 (plus:SI (reg:SI 23 r23)
1870 (const:SI
1871 (unspec:SI
1872 [(const:SI
1873 (plus:SI (symbol_ref:SI ("var"))
1874 (const_int 48 [0x30])))] UNSPEC_ADD_TLS_LE)))
1876 Which will be output as '%tls_le(var+48)(r23)' in assembly. */
1877 if (GET_CODE (x) == PLUS
1878 && GET_CODE (XEXP (x, 0)) == REG
1879 && GET_CODE (XEXP (x, 1)) == CONST)
1881 rtx unspec, offset, reg = XEXP (x, 0);
1882 split_const (XEXP (x, 1), &unspec, &offset);
1883 if (GET_CODE (unspec) == UNSPEC
1884 && !nios2_large_offset_p (XINT (unspec, 1))
1885 && offset != const0_rtx)
1887 unspec = copy_rtx (unspec);
1888 XVECEXP (unspec, 0, 0)
1889 = plus_constant (Pmode, XVECEXP (unspec, 0, 0), INTVAL (offset));
1890 x = gen_rtx_PLUS (Pmode, reg, gen_rtx_CONST (Pmode, unspec));
1894 return x;
1897 static rtx
1898 nios2_delegitimize_address (rtx x)
1900 x = delegitimize_mem_from_attrs (x);
1902 if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
1904 switch (XINT (XEXP (x, 0), 1))
1906 case UNSPEC_PIC_SYM:
1907 case UNSPEC_PIC_CALL_SYM:
1908 case UNSPEC_PIC_GOTOFF_SYM:
1909 case UNSPEC_ADD_TLS_GD:
1910 case UNSPEC_ADD_TLS_LDM:
1911 case UNSPEC_LOAD_TLS_IE:
1912 case UNSPEC_ADD_TLS_LE:
1913 x = XVECEXP (XEXP (x, 0), 0, 0);
1914 gcc_assert (GET_CODE (x) == SYMBOL_REF);
1915 break;
1918 return x;
1921 /* Main expander function for RTL moves. */
1923 nios2_emit_move_sequence (rtx *operands, machine_mode mode)
1925 rtx to = operands[0];
1926 rtx from = operands[1];
1928 if (!register_operand (to, mode) && !reg_or_0_operand (from, mode))
1930 gcc_assert (can_create_pseudo_p ());
1931 from = copy_to_mode_reg (mode, from);
1934 if (GET_CODE (from) == SYMBOL_REF || GET_CODE (from) == LABEL_REF
1935 || (GET_CODE (from) == CONST
1936 && GET_CODE (XEXP (from, 0)) != UNSPEC))
1937 from = nios2_legitimize_constant_address (from);
1939 operands[0] = to;
1940 operands[1] = from;
1941 return 0;
1944 /* The function with address *ADDR is being called. If the address
1945 needs to be loaded from the GOT, emit the instruction to do so and
1946 update *ADDR to point to the rtx for the loaded value. */
1947 void
1948 nios2_adjust_call_address (rtx *call_op)
1950 rtx addr;
1951 gcc_assert (MEM_P (*call_op));
1952 addr = XEXP (*call_op, 0);
1953 if (flag_pic && CONSTANT_P (addr))
1955 rtx reg = gen_reg_rtx (Pmode);
1956 emit_move_insn (reg, nios2_load_pic_address (addr, UNSPEC_PIC_CALL_SYM));
1957 XEXP (*call_op, 0) = reg;
1962 /* Output assembly language related definitions. */
1964 /* Print the operand OP to file stream FILE modified by LETTER.
1965 LETTER can be one of:
1967 i: print "i" if OP is an immediate, except 0
1968 o: print "io" if OP is volatile
1969 z: for const0_rtx print $0 instead of 0
1970 H: for %hiadj
1971 L: for %lo
1972 U: for upper half of 32 bit value
1973 D: for the upper 32-bits of a 64-bit double value
1974 R: prints reverse condition.
1976 static void
1977 nios2_print_operand (FILE *file, rtx op, int letter)
1980 switch (letter)
1982 case 'i':
1983 if (CONSTANT_P (op) && op != const0_rtx)
1984 fprintf (file, "i");
1985 return;
1987 case 'o':
1988 if (GET_CODE (op) == MEM
1989 && ((MEM_VOLATILE_P (op) && TARGET_BYPASS_CACHE_VOLATILE)
1990 || TARGET_BYPASS_CACHE))
1991 fprintf (file, "io");
1992 return;
1994 default:
1995 break;
1998 if (comparison_operator (op, VOIDmode))
2000 enum rtx_code cond = GET_CODE (op);
2001 if (letter == 0)
2003 fprintf (file, "%s", GET_RTX_NAME (cond));
2004 return;
2006 if (letter == 'R')
2008 fprintf (file, "%s", GET_RTX_NAME (reverse_condition (cond)));
2009 return;
2013 switch (GET_CODE (op))
2015 case REG:
2016 if (letter == 0 || letter == 'z')
2018 fprintf (file, "%s", reg_names[REGNO (op)]);
2019 return;
2021 else if (letter == 'D')
2023 fprintf (file, "%s", reg_names[REGNO (op)+1]);
2024 return;
2026 break;
2028 case CONST_INT:
2029 if (INTVAL (op) == 0 && letter == 'z')
2031 fprintf (file, "zero");
2032 return;
2035 if (letter == 'U')
2037 HOST_WIDE_INT val = INTVAL (op);
2038 val = (val >> 16) & 0xFFFF;
2039 output_addr_const (file, gen_int_mode (val, SImode));
2040 return;
2042 /* Else, fall through. */
2044 case CONST:
2045 case LABEL_REF:
2046 case SYMBOL_REF:
2047 case CONST_DOUBLE:
2048 if (letter == 0 || letter == 'z')
2050 output_addr_const (file, op);
2051 return;
2053 else if (letter == 'H' || letter == 'L')
2055 fprintf (file, "%%");
2056 if (GET_CODE (op) == CONST
2057 && GET_CODE (XEXP (op, 0)) == UNSPEC)
2059 rtx unspec = XEXP (op, 0);
2060 int unspec_reloc = XINT (unspec, 1);
2061 gcc_assert (nios2_large_offset_p (unspec_reloc));
2062 fprintf (file, "%s_", nios2_unspec_reloc_name (unspec_reloc));
2063 op = XVECEXP (unspec, 0, 0);
2065 fprintf (file, letter == 'H' ? "hiadj(" : "lo(");
2066 output_addr_const (file, op);
2067 fprintf (file, ")");
2068 return;
2070 break;
2072 case SUBREG:
2073 case MEM:
2074 if (letter == 0)
2076 output_address (op);
2077 return;
2079 break;
2081 case CODE_LABEL:
2082 if (letter == 0)
2084 output_addr_const (file, op);
2085 return;
2087 break;
2089 default:
2090 break;
2093 output_operand_lossage ("Unsupported operand for code '%c'", letter);
2094 gcc_unreachable ();
2097 /* Return true if this is a GP-relative accessible reference. */
2098 static bool
2099 gprel_constant_p (rtx op)
2101 if (GET_CODE (op) == SYMBOL_REF
2102 && nios2_symbol_ref_in_small_data_p (op))
2103 return true;
2104 else if (GET_CODE (op) == CONST
2105 && GET_CODE (XEXP (op, 0)) == PLUS)
2106 return gprel_constant_p (XEXP (XEXP (op, 0), 0));
2108 return false;
2111 /* Return the name string for a supported unspec reloc offset. */
2112 static const char *
2113 nios2_unspec_reloc_name (int unspec)
2115 switch (unspec)
2117 case UNSPEC_PIC_SYM:
2118 return "got";
2119 case UNSPEC_PIC_CALL_SYM:
2120 return "call";
2121 case UNSPEC_PIC_GOTOFF_SYM:
2122 return "gotoff";
2123 case UNSPEC_LOAD_TLS_IE:
2124 return "tls_ie";
2125 case UNSPEC_ADD_TLS_LE:
2126 return "tls_le";
2127 case UNSPEC_ADD_TLS_GD:
2128 return "tls_gd";
2129 case UNSPEC_ADD_TLS_LDM:
2130 return "tls_ldm";
2131 case UNSPEC_ADD_TLS_LDO:
2132 return "tls_ldo";
2133 default:
2134 return NULL;
2138 /* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */
2139 static bool
2140 nios2_output_addr_const_extra (FILE *file, rtx op)
2142 const char *name;
2143 gcc_assert (GET_CODE (op) == UNSPEC);
2145 /* Support for printing out const unspec relocations. */
2146 name = nios2_unspec_reloc_name (XINT (op, 1));
2147 if (name)
2149 fprintf (file, "%%%s(", name);
2150 output_addr_const (file, XVECEXP (op, 0, 0));
2151 fprintf (file, ")");
2152 return true;
2154 return false;
2157 /* Implement TARGET_PRINT_OPERAND_ADDRESS. */
2158 static void
2159 nios2_print_operand_address (FILE *file, rtx op)
2161 switch (GET_CODE (op))
2163 case CONST:
2164 case CONST_INT:
2165 case LABEL_REF:
2166 case CONST_DOUBLE:
2167 case SYMBOL_REF:
2168 if (gprel_constant_p (op))
2170 fprintf (file, "%%gprel(");
2171 output_addr_const (file, op);
2172 fprintf (file, ")(%s)", reg_names[GP_REGNO]);
2173 return;
2176 break;
2178 case PLUS:
2180 rtx op0 = XEXP (op, 0);
2181 rtx op1 = XEXP (op, 1);
2183 if (REG_P (op0) && CONSTANT_P (op1))
2185 output_addr_const (file, op1);
2186 fprintf (file, "(%s)", reg_names[REGNO (op0)]);
2187 return;
2189 else if (REG_P (op1) && CONSTANT_P (op0))
2191 output_addr_const (file, op0);
2192 fprintf (file, "(%s)", reg_names[REGNO (op1)]);
2193 return;
2196 break;
2198 case REG:
2199 fprintf (file, "0(%s)", reg_names[REGNO (op)]);
2200 return;
2202 case MEM:
2204 rtx base = XEXP (op, 0);
2205 nios2_print_operand_address (file, base);
2206 return;
2208 default:
2209 break;
2212 fprintf (stderr, "Missing way to print address\n");
2213 debug_rtx (op);
2214 gcc_unreachable ();
2217 /* Implement TARGET_ASM_OUTPUT_DWARF_DTPREL. */
2218 static void
2219 nios2_output_dwarf_dtprel (FILE *file, int size, rtx x)
2221 gcc_assert (size == 4);
2222 fprintf (file, "\t.4byte\t%%tls_ldo(");
2223 output_addr_const (file, x);
2224 fprintf (file, ")");
2227 /* Implemet TARGET_ASM_FILE_END. */
2229 static void
2230 nios2_asm_file_end (void)
2232 /* The Nios II Linux stack is mapped non-executable by default, so add a
2233 .note.GNU-stack section for switching to executable stacks only when
2234 trampolines are generated. */
2235 if (TARGET_LINUX_ABI && trampolines_created)
2236 file_end_indicate_exec_stack ();
2239 /* Implement TARGET_ASM_FUNCTION_PROLOGUE. */
2240 static void
2241 nios2_asm_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
2243 if (flag_verbose_asm || flag_debug_asm)
2245 nios2_compute_frame_layout ();
2246 nios2_dump_frame_layout (file);
2250 /* Emit assembly of custom FPU instructions. */
2251 const char *
2252 nios2_fpu_insn_asm (enum n2fpu_code code)
2254 static char buf[256];
2255 const char *op1, *op2, *op3;
2256 int ln = 256, n = 0;
2258 int N = N2FPU_N (code);
2259 int num_operands = N2FPU (code).num_operands;
2260 const char *insn_name = N2FPU_NAME (code);
2261 tree ftype = nios2_ftype (N2FPU_FTCODE (code));
2262 machine_mode dst_mode = TYPE_MODE (TREE_TYPE (ftype));
2263 machine_mode src_mode = TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (ftype)));
2265 /* Prepare X register for DF input operands. */
2266 if (GET_MODE_SIZE (src_mode) == 8 && num_operands == 3)
2267 n = snprintf (buf, ln, "custom\t%d, zero, %%1, %%D1 # fwrx %%1\n\t",
2268 N2FPU_N (n2fpu_fwrx));
2270 if (src_mode == SFmode)
2272 if (dst_mode == VOIDmode)
2274 /* The fwry case. */
2275 op1 = op3 = "zero";
2276 op2 = "%0";
2277 num_operands -= 1;
2279 else
2281 op1 = (dst_mode == DFmode ? "%D0" : "%0");
2282 op2 = "%1";
2283 op3 = (num_operands == 2 ? "zero" : "%2");
2286 else if (src_mode == DFmode)
2288 if (dst_mode == VOIDmode)
2290 /* The fwrx case. */
2291 op1 = "zero";
2292 op2 = "%0";
2293 op3 = "%D0";
2294 num_operands -= 1;
2296 else
2298 op1 = (dst_mode == DFmode ? "%D0" : "%0");
2299 op2 = (num_operands == 2 ? "%1" : "%2");
2300 op3 = (num_operands == 2 ? "%D1" : "%D2");
2303 else if (src_mode == VOIDmode)
2305 /* frdxlo, frdxhi, frdy cases. */
2306 gcc_assert (dst_mode == SFmode);
2307 op1 = "%0";
2308 op2 = op3 = "zero";
2310 else if (src_mode == SImode)
2312 /* Conversion operators. */
2313 gcc_assert (num_operands == 2);
2314 op1 = (dst_mode == DFmode ? "%D0" : "%0");
2315 op2 = "%1";
2316 op3 = "zero";
2318 else
2319 gcc_unreachable ();
2321 /* Main instruction string. */
2322 n += snprintf (buf + n, ln - n, "custom\t%d, %s, %s, %s # %s %%0%s%s",
2323 N, op1, op2, op3, insn_name,
2324 (num_operands >= 2 ? ", %1" : ""),
2325 (num_operands == 3 ? ", %2" : ""));
2327 /* Extraction of Y register for DF results. */
2328 if (dst_mode == DFmode)
2329 snprintf (buf + n, ln - n, "\n\tcustom\t%d, %%0, zero, zero # frdy %%0",
2330 N2FPU_N (n2fpu_frdy));
2331 return buf;
2336 /* Function argument related. */
2338 /* Define where to put the arguments to a function. Value is zero to
2339 push the argument on the stack, or a hard register in which to
2340 store the argument.
2342 MODE is the argument's machine mode.
2343 TYPE is the data type of the argument (as a tree).
2344 This is null for libcalls where that information may
2345 not be available.
2346 CUM is a variable of type CUMULATIVE_ARGS which gives info about
2347 the preceding args and about the function being called.
2348 NAMED is nonzero if this argument is a named parameter
2349 (otherwise it is an extra parameter matching an ellipsis). */
2351 static rtx
2352 nios2_function_arg (cumulative_args_t cum_v, machine_mode mode,
2353 const_tree type ATTRIBUTE_UNUSED,
2354 bool named ATTRIBUTE_UNUSED)
2356 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2357 rtx return_rtx = NULL_RTX;
2359 if (cum->regs_used < NUM_ARG_REGS)
2360 return_rtx = gen_rtx_REG (mode, FIRST_ARG_REGNO + cum->regs_used);
2362 return return_rtx;
2365 /* Return number of bytes, at the beginning of the argument, that must be
2366 put in registers. 0 is the argument is entirely in registers or entirely
2367 in memory. */
2369 static int
2370 nios2_arg_partial_bytes (cumulative_args_t cum_v,
2371 machine_mode mode, tree type ATTRIBUTE_UNUSED,
2372 bool named ATTRIBUTE_UNUSED)
2374 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2375 HOST_WIDE_INT param_size;
2377 if (mode == BLKmode)
2379 param_size = int_size_in_bytes (type);
2380 gcc_assert (param_size >= 0);
2382 else
2383 param_size = GET_MODE_SIZE (mode);
2385 /* Convert to words (round up). */
2386 param_size = (UNITS_PER_WORD - 1 + param_size) / UNITS_PER_WORD;
2388 if (cum->regs_used < NUM_ARG_REGS
2389 && cum->regs_used + param_size > NUM_ARG_REGS)
2390 return (NUM_ARG_REGS - cum->regs_used) * UNITS_PER_WORD;
2392 return 0;
2395 /* Update the data in CUM to advance over an argument of mode MODE
2396 and data type TYPE; TYPE is null for libcalls where that information
2397 may not be available. */
2399 static void
2400 nios2_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
2401 const_tree type ATTRIBUTE_UNUSED,
2402 bool named ATTRIBUTE_UNUSED)
2404 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2405 HOST_WIDE_INT param_size;
2407 if (mode == BLKmode)
2409 param_size = int_size_in_bytes (type);
2410 gcc_assert (param_size >= 0);
2412 else
2413 param_size = GET_MODE_SIZE (mode);
2415 /* Convert to words (round up). */
2416 param_size = (UNITS_PER_WORD - 1 + param_size) / UNITS_PER_WORD;
2418 if (cum->regs_used + param_size > NUM_ARG_REGS)
2419 cum->regs_used = NUM_ARG_REGS;
2420 else
2421 cum->regs_used += param_size;
2424 enum direction
2425 nios2_function_arg_padding (machine_mode mode, const_tree type)
2427 /* On little-endian targets, the first byte of every stack argument
2428 is passed in the first byte of the stack slot. */
2429 if (!BYTES_BIG_ENDIAN)
2430 return upward;
2432 /* Otherwise, integral types are padded downward: the last byte of a
2433 stack argument is passed in the last byte of the stack slot. */
2434 if (type != 0
2435 ? INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)
2436 : GET_MODE_CLASS (mode) == MODE_INT)
2437 return downward;
2439 /* Arguments smaller than a stack slot are padded downward. */
2440 if (mode != BLKmode)
2441 return (GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY) ? upward : downward;
2443 return ((int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT))
2444 ? upward : downward);
2447 enum direction
2448 nios2_block_reg_padding (machine_mode mode, tree type,
2449 int first ATTRIBUTE_UNUSED)
2451 return nios2_function_arg_padding (mode, type);
2454 /* Emit RTL insns to initialize the variable parts of a trampoline.
2455 FNADDR is an RTX for the address of the function's pure code.
2456 CXT is an RTX for the static chain value for the function.
2457 On Nios II, we handle this by a library call. */
2458 static void
2459 nios2_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
2461 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
2462 rtx ctx_reg = force_reg (Pmode, cxt);
2463 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
2465 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
2466 LCT_NORMAL, VOIDmode, 3, addr, Pmode, fnaddr, Pmode,
2467 ctx_reg, Pmode);
2470 /* Implement TARGET_FUNCTION_VALUE. */
2471 static rtx
2472 nios2_function_value (const_tree ret_type, const_tree fn ATTRIBUTE_UNUSED,
2473 bool outgoing ATTRIBUTE_UNUSED)
2475 return gen_rtx_REG (TYPE_MODE (ret_type), FIRST_RETVAL_REGNO);
2478 /* Implement TARGET_LIBCALL_VALUE. */
2479 static rtx
2480 nios2_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
2482 return gen_rtx_REG (mode, FIRST_RETVAL_REGNO);
2485 /* Implement TARGET_FUNCTION_VALUE_REGNO_P. */
2486 static bool
2487 nios2_function_value_regno_p (const unsigned int regno)
2489 return regno == FIRST_RETVAL_REGNO;
2492 /* Implement TARGET_RETURN_IN_MEMORY. */
2493 static bool
2494 nios2_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
2496 return (int_size_in_bytes (type) > (2 * UNITS_PER_WORD)
2497 || int_size_in_bytes (type) == -1);
2500 /* TODO: It may be possible to eliminate the copyback and implement
2501 own va_arg type. */
2502 static void
2503 nios2_setup_incoming_varargs (cumulative_args_t cum_v,
2504 machine_mode mode, tree type,
2505 int *pretend_size, int second_time)
2507 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2508 CUMULATIVE_ARGS local_cum;
2509 cumulative_args_t local_cum_v = pack_cumulative_args (&local_cum);
2510 int regs_to_push;
2511 int pret_size;
2513 local_cum = *cum;
2514 nios2_function_arg_advance (local_cum_v, mode, type, 1);
2516 regs_to_push = NUM_ARG_REGS - local_cum.regs_used;
2518 if (!second_time && regs_to_push > 0)
2520 rtx ptr = virtual_incoming_args_rtx;
2521 rtx mem = gen_rtx_MEM (BLKmode, ptr);
2522 emit_insn (gen_blockage ());
2523 move_block_from_reg (local_cum.regs_used + FIRST_ARG_REGNO, mem,
2524 regs_to_push);
2525 emit_insn (gen_blockage ());
2528 pret_size = regs_to_push * UNITS_PER_WORD;
2529 if (pret_size)
2530 *pretend_size = pret_size;
2535 /* Init FPU builtins. */
2536 static void
2537 nios2_init_fpu_builtins (int start_code)
2539 tree fndecl;
2540 char builtin_name[64] = "__builtin_custom_";
2541 unsigned int i, n = strlen ("__builtin_custom_");
2543 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
2545 snprintf (builtin_name + n, sizeof (builtin_name) - n,
2546 "%s", N2FPU_NAME (i));
2547 fndecl =
2548 add_builtin_function (builtin_name, nios2_ftype (N2FPU_FTCODE (i)),
2549 start_code + i, BUILT_IN_MD, NULL, NULL_TREE);
2550 nios2_register_builtin_fndecl (start_code + i, fndecl);
2554 /* Helper function for expanding FPU builtins. */
2555 static rtx
2556 nios2_expand_fpu_builtin (tree exp, unsigned int code, rtx target)
2558 struct expand_operand ops[MAX_RECOG_OPERANDS];
2559 enum insn_code icode = N2FPU_ICODE (code);
2560 int nargs, argno, opno = 0;
2561 int num_operands = N2FPU (code).num_operands;
2562 machine_mode dst_mode = TYPE_MODE (TREE_TYPE (exp));
2563 bool has_target_p = (dst_mode != VOIDmode);
2565 if (N2FPU_N (code) < 0)
2566 fatal_error (input_location,
2567 "Cannot call %<__builtin_custom_%s%> without specifying switch"
2568 " %<-mcustom-%s%>", N2FPU_NAME (code), N2FPU_NAME (code));
2569 if (has_target_p)
2570 create_output_operand (&ops[opno++], target, dst_mode);
2571 else
2572 /* Subtract away the count of the VOID return, mainly for fwrx/fwry. */
2573 num_operands -= 1;
2574 nargs = call_expr_nargs (exp);
2575 for (argno = 0; argno < nargs; argno++)
2577 tree arg = CALL_EXPR_ARG (exp, argno);
2578 create_input_operand (&ops[opno++], expand_normal (arg),
2579 TYPE_MODE (TREE_TYPE (arg)));
2581 if (!maybe_expand_insn (icode, num_operands, ops))
2583 error ("invalid argument to built-in function");
2584 return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
2586 return has_target_p ? ops[0].value : const0_rtx;
2589 /* Nios II has custom instruction built-in functions of the forms:
2590 __builtin_custom_n
2591 __builtin_custom_nX
2592 __builtin_custom_nXX
2593 __builtin_custom_Xn
2594 __builtin_custom_XnX
2595 __builtin_custom_XnXX
2597 where each X could be either 'i' (int), 'f' (float), or 'p' (void*).
2598 Therefore with 0-1 return values, and 0-2 arguments, we have a
2599 total of (3 + 1) * (1 + 3 + 9) == 52 custom builtin functions.
2601 #define NUM_CUSTOM_BUILTINS ((3 + 1) * (1 + 3 + 9))
2602 static char custom_builtin_name[NUM_CUSTOM_BUILTINS][5];
2604 static void
2605 nios2_init_custom_builtins (int start_code)
2607 tree builtin_ftype, ret_type, fndecl;
2608 char builtin_name[32] = "__builtin_custom_";
2609 int n = strlen ("__builtin_custom_");
2610 int builtin_code = 0;
2611 int lhs, rhs1, rhs2;
2613 struct { tree type; const char *c; } op[4];
2614 /* z */ op[0].c = ""; op[0].type = NULL_TREE;
2615 /* f */ op[1].c = "f"; op[1].type = float_type_node;
2616 /* i */ op[2].c = "i"; op[2].type = integer_type_node;
2617 /* p */ op[3].c = "p"; op[3].type = ptr_type_node;
2619 /* We enumerate through the possible operand types to create all the
2620 __builtin_custom_XnXX function tree types. Note that these may slightly
2621 overlap with the function types created for other fixed builtins. */
2623 for (lhs = 0; lhs < 4; lhs++)
2624 for (rhs1 = 0; rhs1 < 4; rhs1++)
2625 for (rhs2 = 0; rhs2 < 4; rhs2++)
2627 if (rhs1 == 0 && rhs2 != 0)
2628 continue;
2629 ret_type = (op[lhs].type ? op[lhs].type : void_type_node);
2630 builtin_ftype
2631 = build_function_type_list (ret_type, integer_type_node,
2632 op[rhs1].type, op[rhs2].type,
2633 NULL_TREE);
2634 snprintf (builtin_name + n, 32 - n, "%sn%s%s",
2635 op[lhs].c, op[rhs1].c, op[rhs2].c);
2636 /* Save copy of parameter string into custom_builtin_name[]. */
2637 strncpy (custom_builtin_name[builtin_code], builtin_name + n, 5);
2638 fndecl =
2639 add_builtin_function (builtin_name, builtin_ftype,
2640 start_code + builtin_code,
2641 BUILT_IN_MD, NULL, NULL_TREE);
2642 nios2_register_builtin_fndecl (start_code + builtin_code, fndecl);
2643 builtin_code += 1;
2647 /* Helper function for expanding custom builtins. */
2648 static rtx
2649 nios2_expand_custom_builtin (tree exp, unsigned int index, rtx target)
2651 bool has_target_p = (TREE_TYPE (exp) != void_type_node);
2652 machine_mode tmode = VOIDmode;
2653 int nargs, argno;
2654 rtx value, insn, unspec_args[3];
2655 tree arg;
2657 /* XnXX form. */
2658 if (has_target_p)
2660 tmode = TYPE_MODE (TREE_TYPE (exp));
2661 if (!target || GET_MODE (target) != tmode
2662 || !REG_P (target))
2663 target = gen_reg_rtx (tmode);
2666 nargs = call_expr_nargs (exp);
2667 for (argno = 0; argno < nargs; argno++)
2669 arg = CALL_EXPR_ARG (exp, argno);
2670 value = expand_normal (arg);
2671 unspec_args[argno] = value;
2672 if (argno == 0)
2674 if (!custom_insn_opcode (value, VOIDmode))
2675 error ("custom instruction opcode must be compile time "
2676 "constant in the range 0-255 for __builtin_custom_%s",
2677 custom_builtin_name[index]);
2679 else
2680 /* For other arguments, force into a register. */
2681 unspec_args[argno] = force_reg (TYPE_MODE (TREE_TYPE (arg)),
2682 unspec_args[argno]);
2684 /* Fill remaining unspec operands with zero. */
2685 for (; argno < 3; argno++)
2686 unspec_args[argno] = const0_rtx;
2688 insn = (has_target_p
2689 ? gen_rtx_SET (VOIDmode, target,
2690 gen_rtx_UNSPEC_VOLATILE (tmode,
2691 gen_rtvec_v (3, unspec_args),
2692 UNSPECV_CUSTOM_XNXX))
2693 : gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec_v (3, unspec_args),
2694 UNSPECV_CUSTOM_NXX));
2695 emit_insn (insn);
2696 return has_target_p ? target : const0_rtx;
2702 /* Main definition of built-in functions. Nios II has a small number of fixed
2703 builtins, plus a large number of FPU insn builtins, and builtins for
2704 generating custom instructions. */
2706 struct nios2_builtin_desc
2708 enum insn_code icode;
2709 enum nios2_ftcode ftype;
2710 const char *name;
2713 #define N2_BUILTINS \
2714 N2_BUILTIN_DEF (sync, N2_FTYPE_VOID_VOID) \
2715 N2_BUILTIN_DEF (ldbio, N2_FTYPE_SI_CVPTR) \
2716 N2_BUILTIN_DEF (ldbuio, N2_FTYPE_UI_CVPTR) \
2717 N2_BUILTIN_DEF (ldhio, N2_FTYPE_SI_CVPTR) \
2718 N2_BUILTIN_DEF (ldhuio, N2_FTYPE_UI_CVPTR) \
2719 N2_BUILTIN_DEF (ldwio, N2_FTYPE_SI_CVPTR) \
2720 N2_BUILTIN_DEF (stbio, N2_FTYPE_VOID_VPTR_SI) \
2721 N2_BUILTIN_DEF (sthio, N2_FTYPE_VOID_VPTR_SI) \
2722 N2_BUILTIN_DEF (stwio, N2_FTYPE_VOID_VPTR_SI) \
2723 N2_BUILTIN_DEF (rdctl, N2_FTYPE_SI_SI) \
2724 N2_BUILTIN_DEF (wrctl, N2_FTYPE_VOID_SI_SI)
2726 enum nios2_builtin_code {
2727 #define N2_BUILTIN_DEF(name, ftype) NIOS2_BUILTIN_ ## name,
2728 N2_BUILTINS
2729 #undef N2_BUILTIN_DEF
2730 NUM_FIXED_NIOS2_BUILTINS
2733 static const struct nios2_builtin_desc nios2_builtins[] = {
2734 #define N2_BUILTIN_DEF(name, ftype) \
2735 { CODE_FOR_ ## name, ftype, "__builtin_" #name },
2736 N2_BUILTINS
2737 #undef N2_BUILTIN_DEF
2740 /* Start/ends of FPU/custom insn builtin index ranges. */
2741 static unsigned int nios2_fpu_builtin_base;
2742 static unsigned int nios2_custom_builtin_base;
2743 static unsigned int nios2_custom_builtin_end;
2745 /* Implement TARGET_INIT_BUILTINS. */
2746 static void
2747 nios2_init_builtins (void)
2749 unsigned int i;
2751 /* Initialize fixed builtins. */
2752 for (i = 0; i < ARRAY_SIZE (nios2_builtins); i++)
2754 const struct nios2_builtin_desc *d = &nios2_builtins[i];
2755 tree fndecl =
2756 add_builtin_function (d->name, nios2_ftype (d->ftype), i,
2757 BUILT_IN_MD, NULL, NULL);
2758 nios2_register_builtin_fndecl (i, fndecl);
2761 /* Initialize FPU builtins. */
2762 nios2_fpu_builtin_base = ARRAY_SIZE (nios2_builtins);
2763 nios2_init_fpu_builtins (nios2_fpu_builtin_base);
2765 /* Initialize custom insn builtins. */
2766 nios2_custom_builtin_base
2767 = nios2_fpu_builtin_base + ARRAY_SIZE (nios2_fpu_insn);
2768 nios2_custom_builtin_end
2769 = nios2_custom_builtin_base + NUM_CUSTOM_BUILTINS;
2770 nios2_init_custom_builtins (nios2_custom_builtin_base);
2773 /* Array of fndecls for TARGET_BUILTIN_DECL. */
2774 #define NIOS2_NUM_BUILTINS \
2775 (ARRAY_SIZE (nios2_builtins) + ARRAY_SIZE (nios2_fpu_insn) + NUM_CUSTOM_BUILTINS)
2776 static GTY(()) tree nios2_builtin_decls[NIOS2_NUM_BUILTINS];
2778 static void
2779 nios2_register_builtin_fndecl (unsigned code, tree fndecl)
2781 nios2_builtin_decls[code] = fndecl;
2784 /* Implement TARGET_BUILTIN_DECL. */
2785 static tree
2786 nios2_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
2788 gcc_assert (nios2_custom_builtin_end == ARRAY_SIZE (nios2_builtin_decls));
2790 if (code >= nios2_custom_builtin_end)
2791 return error_mark_node;
2793 if (code >= nios2_fpu_builtin_base
2794 && code < nios2_custom_builtin_base
2795 && ! N2FPU_ENABLED_P (code - nios2_fpu_builtin_base))
2796 return error_mark_node;
2798 return nios2_builtin_decls[code];
2802 /* Low-level built-in expand routine. */
2803 static rtx
2804 nios2_expand_builtin_insn (const struct nios2_builtin_desc *d, int n,
2805 struct expand_operand *ops, bool has_target_p)
2807 if (maybe_expand_insn (d->icode, n, ops))
2808 return has_target_p ? ops[0].value : const0_rtx;
2809 else
2811 error ("invalid argument to built-in function %s", d->name);
2812 return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
2816 /* Expand ldio/stio form load-store instruction builtins. */
2817 static rtx
2818 nios2_expand_ldstio_builtin (tree exp, rtx target,
2819 const struct nios2_builtin_desc *d)
2821 bool has_target_p;
2822 rtx addr, mem, val;
2823 struct expand_operand ops[MAX_RECOG_OPERANDS];
2824 machine_mode mode = insn_data[d->icode].operand[0].mode;
2826 addr = expand_normal (CALL_EXPR_ARG (exp, 0));
2827 mem = gen_rtx_MEM (mode, addr);
2829 if (insn_data[d->icode].operand[0].allows_mem)
2831 /* stxio. */
2832 val = expand_normal (CALL_EXPR_ARG (exp, 1));
2833 if (CONST_INT_P (val))
2834 val = force_reg (mode, gen_int_mode (INTVAL (val), mode));
2835 val = simplify_gen_subreg (mode, val, GET_MODE (val), 0);
2836 create_output_operand (&ops[0], mem, mode);
2837 create_input_operand (&ops[1], val, mode);
2838 has_target_p = false;
2840 else
2842 /* ldxio. */
2843 create_output_operand (&ops[0], target, mode);
2844 create_input_operand (&ops[1], mem, mode);
2845 has_target_p = true;
2847 return nios2_expand_builtin_insn (d, 2, ops, has_target_p);
2850 /* Expand rdctl/wrctl builtins. */
2851 static rtx
2852 nios2_expand_rdwrctl_builtin (tree exp, rtx target,
2853 const struct nios2_builtin_desc *d)
2855 bool has_target_p = (insn_data[d->icode].operand[0].predicate
2856 == register_operand);
2857 rtx ctlcode = expand_normal (CALL_EXPR_ARG (exp, 0));
2858 struct expand_operand ops[MAX_RECOG_OPERANDS];
2859 if (!rdwrctl_operand (ctlcode, VOIDmode))
2861 error ("Control register number must be in range 0-31 for %s",
2862 d->name);
2863 return has_target_p ? gen_reg_rtx (SImode) : const0_rtx;
2865 if (has_target_p)
2867 create_output_operand (&ops[0], target, SImode);
2868 create_integer_operand (&ops[1], INTVAL (ctlcode));
2870 else
2872 rtx val = expand_normal (CALL_EXPR_ARG (exp, 1));
2873 create_integer_operand (&ops[0], INTVAL (ctlcode));
2874 create_input_operand (&ops[1], val, SImode);
2876 return nios2_expand_builtin_insn (d, 2, ops, has_target_p);
2879 /* Implement TARGET_EXPAND_BUILTIN. Expand an expression EXP that calls
2880 a built-in function, with result going to TARGET if that's convenient
2881 (and in mode MODE if that's convenient).
2882 SUBTARGET may be used as the target for computing one of EXP's operands.
2883 IGNORE is nonzero if the value is to be ignored. */
2885 static rtx
2886 nios2_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
2887 machine_mode mode ATTRIBUTE_UNUSED,
2888 int ignore ATTRIBUTE_UNUSED)
2890 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2891 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
2893 if (fcode < nios2_fpu_builtin_base)
2895 const struct nios2_builtin_desc *d = &nios2_builtins[fcode];
2897 switch (fcode)
2899 case NIOS2_BUILTIN_sync:
2900 emit_insn (gen_sync ());
2901 return const0_rtx;
2903 case NIOS2_BUILTIN_ldbio:
2904 case NIOS2_BUILTIN_ldbuio:
2905 case NIOS2_BUILTIN_ldhio:
2906 case NIOS2_BUILTIN_ldhuio:
2907 case NIOS2_BUILTIN_ldwio:
2908 case NIOS2_BUILTIN_stbio:
2909 case NIOS2_BUILTIN_sthio:
2910 case NIOS2_BUILTIN_stwio:
2911 return nios2_expand_ldstio_builtin (exp, target, d);
2913 case NIOS2_BUILTIN_rdctl:
2914 case NIOS2_BUILTIN_wrctl:
2915 return nios2_expand_rdwrctl_builtin (exp, target, d);
2917 default:
2918 gcc_unreachable ();
2921 else if (fcode < nios2_custom_builtin_base)
2922 /* FPU builtin range. */
2923 return nios2_expand_fpu_builtin (exp, fcode - nios2_fpu_builtin_base,
2924 target);
2925 else if (fcode < nios2_custom_builtin_end)
2926 /* Custom insn builtin range. */
2927 return nios2_expand_custom_builtin (exp, fcode - nios2_custom_builtin_base,
2928 target);
2929 else
2930 gcc_unreachable ();
2933 /* Implement TARGET_INIT_LIBFUNCS. */
2934 static void
2935 nios2_init_libfuncs (void)
2937 /* For Linux, we have access to kernel support for atomic operations. */
2938 if (TARGET_LINUX_ABI)
2939 init_sync_libfuncs (UNITS_PER_WORD);
2944 /* Register a custom code use, and signal error if a conflict was found. */
2945 static void
2946 nios2_register_custom_code (unsigned int N, enum nios2_ccs_code status,
2947 int index)
2949 gcc_assert (N <= 255);
2951 if (status == CCS_FPU)
2953 if (custom_code_status[N] == CCS_FPU && index != custom_code_index[N])
2955 custom_code_conflict = true;
2956 error ("switch %<-mcustom-%s%> conflicts with switch %<-mcustom-%s%>",
2957 N2FPU_NAME (custom_code_index[N]), N2FPU_NAME (index));
2959 else if (custom_code_status[N] == CCS_BUILTIN_CALL)
2961 custom_code_conflict = true;
2962 error ("call to %<__builtin_custom_%s%> conflicts with switch "
2963 "%<-mcustom-%s%>", custom_builtin_name[custom_code_index[N]],
2964 N2FPU_NAME (index));
2967 else if (status == CCS_BUILTIN_CALL)
2969 if (custom_code_status[N] == CCS_FPU)
2971 custom_code_conflict = true;
2972 error ("call to %<__builtin_custom_%s%> conflicts with switch "
2973 "%<-mcustom-%s%>", custom_builtin_name[index],
2974 N2FPU_NAME (custom_code_index[N]));
2976 else
2978 /* Note that code conflicts between different __builtin_custom_xnxx
2979 calls are not checked. */
2982 else
2983 gcc_unreachable ();
2985 custom_code_status[N] = status;
2986 custom_code_index[N] = index;
2989 /* Mark a custom code as not in use. */
2990 static void
2991 nios2_deregister_custom_code (unsigned int N)
2993 if (N <= 255)
2995 custom_code_status[N] = CCS_UNUSED;
2996 custom_code_index[N] = 0;
3000 /* Target attributes can affect per-function option state, so we need to
3001 save/restore the custom code tracking info using the
3002 TARGET_OPTION_SAVE/TARGET_OPTION_RESTORE hooks. */
3004 static void
3005 nios2_option_save (struct cl_target_option *ptr,
3006 struct gcc_options *opts ATTRIBUTE_UNUSED)
3008 unsigned int i;
3009 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
3010 ptr->saved_fpu_custom_code[i] = N2FPU_N (i);
3011 memcpy (ptr->saved_custom_code_status, custom_code_status,
3012 sizeof (custom_code_status));
3013 memcpy (ptr->saved_custom_code_index, custom_code_index,
3014 sizeof (custom_code_index));
3017 static void
3018 nios2_option_restore (struct gcc_options *opts ATTRIBUTE_UNUSED,
3019 struct cl_target_option *ptr)
3021 unsigned int i;
3022 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
3023 N2FPU_N (i) = ptr->saved_fpu_custom_code[i];
3024 memcpy (custom_code_status, ptr->saved_custom_code_status,
3025 sizeof (custom_code_status));
3026 memcpy (custom_code_index, ptr->saved_custom_code_index,
3027 sizeof (custom_code_index));
3030 /* Inner function to process the attribute((target(...))), take an argument and
3031 set the current options from the argument. If we have a list, recursively
3032 go over the list. */
3034 static bool
3035 nios2_valid_target_attribute_rec (tree args)
3037 if (TREE_CODE (args) == TREE_LIST)
3039 bool ret = true;
3040 for (; args; args = TREE_CHAIN (args))
3041 if (TREE_VALUE (args)
3042 && !nios2_valid_target_attribute_rec (TREE_VALUE (args)))
3043 ret = false;
3044 return ret;
3046 else if (TREE_CODE (args) == STRING_CST)
3048 char *argstr = ASTRDUP (TREE_STRING_POINTER (args));
3049 while (argstr && *argstr != '\0')
3051 bool no_opt = false, end_p = false;
3052 char *eq = NULL, *p;
3053 while (ISSPACE (*argstr))
3054 argstr++;
3055 p = argstr;
3056 while (*p != '\0' && *p != ',')
3058 if (!eq && *p == '=')
3059 eq = p;
3060 ++p;
3062 if (*p == '\0')
3063 end_p = true;
3064 else
3065 *p = '\0';
3066 if (eq) *eq = '\0';
3068 if (!strncmp (argstr, "no-", 3))
3070 no_opt = true;
3071 argstr += 3;
3073 if (!strncmp (argstr, "custom-fpu-cfg", 14))
3075 char *end_eq = p;
3076 if (no_opt)
3078 error ("custom-fpu-cfg option does not support %<no-%>");
3079 return false;
3081 if (!eq)
3083 error ("custom-fpu-cfg option requires configuration"
3084 " argument");
3085 return false;
3087 /* Increment and skip whitespace. */
3088 while (ISSPACE (*(++eq))) ;
3089 /* Decrement and skip to before any trailing whitespace. */
3090 while (ISSPACE (*(--end_eq))) ;
3092 nios2_handle_custom_fpu_cfg (eq, end_eq + 1, true);
3094 else if (!strncmp (argstr, "custom-", 7))
3096 int code = -1;
3097 unsigned int i;
3098 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
3099 if (!strncmp (argstr + 7, N2FPU_NAME (i),
3100 strlen (N2FPU_NAME (i))))
3102 /* Found insn. */
3103 code = i;
3104 break;
3106 if (code >= 0)
3108 if (no_opt)
3110 if (eq)
3112 error ("%<no-custom-%s%> does not accept arguments",
3113 N2FPU_NAME (code));
3114 return false;
3116 /* Disable option by setting to -1. */
3117 nios2_deregister_custom_code (N2FPU_N (code));
3118 N2FPU_N (code) = -1;
3120 else
3122 char *t;
3123 if (eq)
3124 while (ISSPACE (*(++eq))) ;
3125 if (!eq || eq == p)
3127 error ("%<custom-%s=%> requires argument",
3128 N2FPU_NAME (code));
3129 return false;
3131 for (t = eq; t != p; ++t)
3133 if (ISSPACE (*t))
3134 continue;
3135 if (!ISDIGIT (*t))
3137 error ("`custom-%s=' argument requires "
3138 "numeric digits", N2FPU_NAME (code));
3139 return false;
3142 /* Set option to argument. */
3143 N2FPU_N (code) = atoi (eq);
3144 nios2_handle_custom_fpu_insn_option (code);
3147 else
3149 error ("%<custom-%s=%> is not recognised as FPU instruction",
3150 argstr + 7);
3151 return false;
3154 else
3156 error ("%<%s%> is unknown", argstr);
3157 return false;
3160 if (end_p)
3161 break;
3162 else
3163 argstr = p + 1;
3165 return true;
3167 else
3168 gcc_unreachable ();
3171 /* Return a TARGET_OPTION_NODE tree of the target options listed or NULL. */
3173 static tree
3174 nios2_valid_target_attribute_tree (tree args)
3176 if (!nios2_valid_target_attribute_rec (args))
3177 return NULL_TREE;
3178 nios2_custom_check_insns ();
3179 return build_target_option_node (&global_options);
3182 /* Hook to validate attribute((target("string"))). */
3184 static bool
3185 nios2_valid_target_attribute_p (tree fndecl, tree ARG_UNUSED (name),
3186 tree args, int ARG_UNUSED (flags))
3188 struct cl_target_option cur_target;
3189 bool ret = true;
3190 tree old_optimize = build_optimization_node (&global_options);
3191 tree new_target, new_optimize;
3192 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
3194 /* If the function changed the optimization levels as well as setting target
3195 options, start with the optimizations specified. */
3196 if (func_optimize && func_optimize != old_optimize)
3197 cl_optimization_restore (&global_options,
3198 TREE_OPTIMIZATION (func_optimize));
3200 /* The target attributes may also change some optimization flags, so update
3201 the optimization options if necessary. */
3202 cl_target_option_save (&cur_target, &global_options);
3203 new_target = nios2_valid_target_attribute_tree (args);
3204 new_optimize = build_optimization_node (&global_options);
3206 if (!new_target)
3207 ret = false;
3209 else if (fndecl)
3211 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
3213 if (old_optimize != new_optimize)
3214 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
3217 cl_target_option_restore (&global_options, &cur_target);
3219 if (old_optimize != new_optimize)
3220 cl_optimization_restore (&global_options,
3221 TREE_OPTIMIZATION (old_optimize));
3222 return ret;
3225 /* Remember the last target of nios2_set_current_function. */
3226 static GTY(()) tree nios2_previous_fndecl;
3228 /* Establish appropriate back-end context for processing the function
3229 FNDECL. The argument might be NULL to indicate processing at top
3230 level, outside of any function scope. */
3231 static void
3232 nios2_set_current_function (tree fndecl)
3234 tree old_tree = (nios2_previous_fndecl
3235 ? DECL_FUNCTION_SPECIFIC_TARGET (nios2_previous_fndecl)
3236 : NULL_TREE);
3238 tree new_tree = (fndecl
3239 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
3240 : NULL_TREE);
3242 if (fndecl && fndecl != nios2_previous_fndecl)
3244 nios2_previous_fndecl = fndecl;
3245 if (old_tree == new_tree)
3248 else if (new_tree)
3250 cl_target_option_restore (&global_options,
3251 TREE_TARGET_OPTION (new_tree));
3252 target_reinit ();
3255 else if (old_tree)
3257 struct cl_target_option *def
3258 = TREE_TARGET_OPTION (target_option_current_node);
3260 cl_target_option_restore (&global_options, def);
3261 target_reinit ();
3266 /* Hook to validate the current #pragma GCC target and set the FPU custom
3267 code option state. If ARGS is NULL, then POP_TARGET is used to reset
3268 the options. */
3269 static bool
3270 nios2_pragma_target_parse (tree args, tree pop_target)
3272 tree cur_tree;
3273 if (! args)
3275 cur_tree = ((pop_target)
3276 ? pop_target
3277 : target_option_default_node);
3278 cl_target_option_restore (&global_options,
3279 TREE_TARGET_OPTION (cur_tree));
3281 else
3283 cur_tree = nios2_valid_target_attribute_tree (args);
3284 if (!cur_tree)
3285 return false;
3288 target_option_current_node = cur_tree;
3289 return true;
3292 /* Implement TARGET_MERGE_DECL_ATTRIBUTES.
3293 We are just using this hook to add some additional error checking to
3294 the default behavior. GCC does not provide a target hook for merging
3295 the target options, and only correctly handles merging empty vs non-empty
3296 option data; see merge_decls() in c-decl.c.
3297 So here we require either that at least one of the decls has empty
3298 target options, or that the target options/data be identical. */
3299 static tree
3300 nios2_merge_decl_attributes (tree olddecl, tree newdecl)
3302 tree oldopts = lookup_attribute ("target", DECL_ATTRIBUTES (olddecl));
3303 tree newopts = lookup_attribute ("target", DECL_ATTRIBUTES (newdecl));
3304 if (newopts && oldopts && newopts != oldopts)
3306 tree oldtree = DECL_FUNCTION_SPECIFIC_TARGET (olddecl);
3307 tree newtree = DECL_FUNCTION_SPECIFIC_TARGET (newdecl);
3308 if (oldtree && newtree && oldtree != newtree)
3310 struct cl_target_option *olddata = TREE_TARGET_OPTION (oldtree);
3311 struct cl_target_option *newdata = TREE_TARGET_OPTION (newtree);
3312 if (olddata != newdata
3313 && memcmp (olddata, newdata, sizeof (struct cl_target_option)))
3314 error ("%qE redeclared with conflicting %qs attributes",
3315 DECL_NAME (newdecl), "target");
3318 return merge_attributes (DECL_ATTRIBUTES (olddecl),
3319 DECL_ATTRIBUTES (newdecl));
3323 /* Initialize the GCC target structure. */
3324 #undef TARGET_ASM_FUNCTION_PROLOGUE
3325 #define TARGET_ASM_FUNCTION_PROLOGUE nios2_asm_function_prologue
3327 #undef TARGET_IN_SMALL_DATA_P
3328 #define TARGET_IN_SMALL_DATA_P nios2_in_small_data_p
3330 #undef TARGET_SECTION_TYPE_FLAGS
3331 #define TARGET_SECTION_TYPE_FLAGS nios2_section_type_flags
3333 #undef TARGET_INIT_BUILTINS
3334 #define TARGET_INIT_BUILTINS nios2_init_builtins
3335 #undef TARGET_EXPAND_BUILTIN
3336 #define TARGET_EXPAND_BUILTIN nios2_expand_builtin
3337 #undef TARGET_BUILTIN_DECL
3338 #define TARGET_BUILTIN_DECL nios2_builtin_decl
3340 #undef TARGET_INIT_LIBFUNCS
3341 #define TARGET_INIT_LIBFUNCS nios2_init_libfuncs
3343 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
3344 #define TARGET_FUNCTION_OK_FOR_SIBCALL hook_bool_tree_tree_true
3346 #undef TARGET_CAN_ELIMINATE
3347 #define TARGET_CAN_ELIMINATE nios2_can_eliminate
3349 #undef TARGET_FUNCTION_ARG
3350 #define TARGET_FUNCTION_ARG nios2_function_arg
3352 #undef TARGET_FUNCTION_ARG_ADVANCE
3353 #define TARGET_FUNCTION_ARG_ADVANCE nios2_function_arg_advance
3355 #undef TARGET_ARG_PARTIAL_BYTES
3356 #define TARGET_ARG_PARTIAL_BYTES nios2_arg_partial_bytes
3358 #undef TARGET_TRAMPOLINE_INIT
3359 #define TARGET_TRAMPOLINE_INIT nios2_trampoline_init
3361 #undef TARGET_FUNCTION_VALUE
3362 #define TARGET_FUNCTION_VALUE nios2_function_value
3364 #undef TARGET_LIBCALL_VALUE
3365 #define TARGET_LIBCALL_VALUE nios2_libcall_value
3367 #undef TARGET_FUNCTION_VALUE_REGNO_P
3368 #define TARGET_FUNCTION_VALUE_REGNO_P nios2_function_value_regno_p
3370 #undef TARGET_RETURN_IN_MEMORY
3371 #define TARGET_RETURN_IN_MEMORY nios2_return_in_memory
3373 #undef TARGET_PROMOTE_PROTOTYPES
3374 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
3376 #undef TARGET_SETUP_INCOMING_VARARGS
3377 #define TARGET_SETUP_INCOMING_VARARGS nios2_setup_incoming_varargs
3379 #undef TARGET_MUST_PASS_IN_STACK
3380 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
3382 #undef TARGET_LEGITIMATE_CONSTANT_P
3383 #define TARGET_LEGITIMATE_CONSTANT_P nios2_legitimate_constant_p
3385 #undef TARGET_LEGITIMIZE_ADDRESS
3386 #define TARGET_LEGITIMIZE_ADDRESS nios2_legitimize_address
3388 #undef TARGET_DELEGITIMIZE_ADDRESS
3389 #define TARGET_DELEGITIMIZE_ADDRESS nios2_delegitimize_address
3391 #undef TARGET_LEGITIMATE_ADDRESS_P
3392 #define TARGET_LEGITIMATE_ADDRESS_P nios2_legitimate_address_p
3394 #undef TARGET_PREFERRED_RELOAD_CLASS
3395 #define TARGET_PREFERRED_RELOAD_CLASS nios2_preferred_reload_class
3397 #undef TARGET_RTX_COSTS
3398 #define TARGET_RTX_COSTS nios2_rtx_costs
3400 #undef TARGET_HAVE_TLS
3401 #define TARGET_HAVE_TLS TARGET_LINUX_ABI
3403 #undef TARGET_CANNOT_FORCE_CONST_MEM
3404 #define TARGET_CANNOT_FORCE_CONST_MEM nios2_cannot_force_const_mem
3406 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
3407 #define TARGET_ASM_OUTPUT_DWARF_DTPREL nios2_output_dwarf_dtprel
3409 #undef TARGET_PRINT_OPERAND
3410 #define TARGET_PRINT_OPERAND nios2_print_operand
3412 #undef TARGET_PRINT_OPERAND_ADDRESS
3413 #define TARGET_PRINT_OPERAND_ADDRESS nios2_print_operand_address
3415 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
3416 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA nios2_output_addr_const_extra
3418 #undef TARGET_ASM_FILE_END
3419 #define TARGET_ASM_FILE_END nios2_asm_file_end
3421 #undef TARGET_OPTION_OVERRIDE
3422 #define TARGET_OPTION_OVERRIDE nios2_option_override
3424 #undef TARGET_OPTION_SAVE
3425 #define TARGET_OPTION_SAVE nios2_option_save
3427 #undef TARGET_OPTION_RESTORE
3428 #define TARGET_OPTION_RESTORE nios2_option_restore
3430 #undef TARGET_SET_CURRENT_FUNCTION
3431 #define TARGET_SET_CURRENT_FUNCTION nios2_set_current_function
3433 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
3434 #define TARGET_OPTION_VALID_ATTRIBUTE_P nios2_valid_target_attribute_p
3436 #undef TARGET_OPTION_PRAGMA_PARSE
3437 #define TARGET_OPTION_PRAGMA_PARSE nios2_pragma_target_parse
3439 #undef TARGET_MERGE_DECL_ATTRIBUTES
3440 #define TARGET_MERGE_DECL_ATTRIBUTES nios2_merge_decl_attributes
3442 struct gcc_target targetm = TARGET_INITIALIZER;
3444 #include "gt-nios2.h"