gcc/
[official-gcc.git] / gcc / config / nios2 / nios2.c
blobd83c393ed604e8be1b291de1fafbdee001d55a4d
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 static rtx
493 nios2_emit_add_constant (rtx reg, HOST_WIDE_INT immed)
495 rtx insn;
496 if (SMALL_INT (immed))
497 insn = emit_insn (gen_add2_insn (reg, gen_int_mode (immed, Pmode)));
498 else
500 rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
501 emit_move_insn (tmp, gen_int_mode (immed, Pmode));
502 insn = emit_insn (gen_add2_insn (reg, tmp));
504 return insn;
507 void
508 nios2_expand_prologue (void)
510 unsigned int regno;
511 int total_frame_size, save_offset;
512 int sp_offset; /* offset from base_reg to final stack value. */
513 int save_regs_base; /* offset from base_reg to register save area. */
514 rtx insn;
516 total_frame_size = nios2_compute_frame_layout ();
518 if (flag_stack_usage_info)
519 current_function_static_stack_size = total_frame_size;
521 /* Decrement the stack pointer. */
522 if (!SMALL_INT (total_frame_size))
524 /* We need an intermediary point, this will point at the spill block. */
525 insn = emit_insn
526 (gen_add2_insn (stack_pointer_rtx,
527 gen_int_mode (cfun->machine->save_regs_offset
528 - total_frame_size, Pmode)));
529 RTX_FRAME_RELATED_P (insn) = 1;
530 save_regs_base = 0;
531 sp_offset = -cfun->machine->save_regs_offset;
533 else if (total_frame_size)
535 insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
536 gen_int_mode (-total_frame_size,
537 Pmode)));
538 RTX_FRAME_RELATED_P (insn) = 1;
539 save_regs_base = cfun->machine->save_regs_offset;
540 sp_offset = 0;
542 else
543 save_regs_base = sp_offset = 0;
545 if (crtl->limit_stack)
546 nios2_emit_stack_limit_check ();
548 save_offset = save_regs_base + cfun->machine->save_reg_size;
550 for (regno = LAST_GP_REG; regno > 0; regno--)
551 if (cfun->machine->save_mask & (1 << regno))
553 save_offset -= 4;
554 save_reg (regno, save_offset);
557 if (frame_pointer_needed)
559 int fp_save_offset = save_regs_base + cfun->machine->fp_save_offset;
560 insn = emit_insn (gen_add3_insn (hard_frame_pointer_rtx,
561 stack_pointer_rtx,
562 gen_int_mode (fp_save_offset, Pmode)));
563 RTX_FRAME_RELATED_P (insn) = 1;
566 if (sp_offset)
568 rtx sp_adjust
569 = gen_rtx_SET (stack_pointer_rtx,
570 plus_constant (Pmode, stack_pointer_rtx, sp_offset));
571 if (SMALL_INT (sp_offset))
572 insn = emit_insn (sp_adjust);
573 else
575 rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
576 emit_move_insn (tmp, gen_int_mode (sp_offset, Pmode));
577 insn = emit_insn (gen_add2_insn (stack_pointer_rtx, tmp));
578 /* Attach the sp_adjust as a note indicating what happened. */
579 add_reg_note (insn, REG_FRAME_RELATED_EXPR, sp_adjust);
581 RTX_FRAME_RELATED_P (insn) = 1;
583 if (crtl->limit_stack)
584 nios2_emit_stack_limit_check ();
587 /* Load the PIC register if needed. */
588 if (crtl->uses_pic_offset_table)
589 nios2_load_pic_register ();
591 /* If we are profiling, make sure no instructions are scheduled before
592 the call to mcount. */
593 if (crtl->profile)
594 emit_insn (gen_blockage ());
597 void
598 nios2_expand_epilogue (bool sibcall_p)
600 rtx insn, cfa_adj;
601 int total_frame_size;
602 int sp_adjust, save_offset;
603 unsigned int regno;
605 if (!sibcall_p && nios2_can_use_return_insn ())
607 emit_jump_insn (gen_return ());
608 return;
611 emit_insn (gen_blockage ());
613 total_frame_size = nios2_compute_frame_layout ();
614 if (frame_pointer_needed)
616 /* Recover the stack pointer. */
617 insn = emit_insn (gen_add3_insn
618 (stack_pointer_rtx, hard_frame_pointer_rtx,
619 gen_int_mode (-cfun->machine->fp_save_offset, Pmode)));
620 cfa_adj = plus_constant (Pmode, stack_pointer_rtx,
621 (total_frame_size
622 - cfun->machine->save_regs_offset));
623 add_reg_note (insn, REG_CFA_DEF_CFA, cfa_adj);
624 RTX_FRAME_RELATED_P (insn) = 1;
626 save_offset = 0;
627 sp_adjust = total_frame_size - cfun->machine->save_regs_offset;
629 else if (!SMALL_INT (total_frame_size))
631 rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
632 emit_move_insn (tmp, gen_int_mode (cfun->machine->save_regs_offset,
633 Pmode));
634 insn = emit_insn (gen_add2_insn (stack_pointer_rtx, tmp));
635 cfa_adj = gen_rtx_SET (stack_pointer_rtx,
636 plus_constant (Pmode, stack_pointer_rtx,
637 cfun->machine->save_regs_offset));
638 add_reg_note (insn, REG_CFA_ADJUST_CFA, cfa_adj);
639 RTX_FRAME_RELATED_P (insn) = 1;
640 save_offset = 0;
641 sp_adjust = total_frame_size - cfun->machine->save_regs_offset;
643 else
645 save_offset = cfun->machine->save_regs_offset;
646 sp_adjust = total_frame_size;
649 save_offset += cfun->machine->save_reg_size;
651 for (regno = LAST_GP_REG; regno > 0; regno--)
652 if (cfun->machine->save_mask & (1 << regno))
654 save_offset -= 4;
655 restore_reg (regno, save_offset);
658 if (sp_adjust)
660 insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
661 gen_int_mode (sp_adjust, Pmode)));
662 cfa_adj = gen_rtx_SET (stack_pointer_rtx,
663 plus_constant (Pmode, stack_pointer_rtx,
664 sp_adjust));
665 add_reg_note (insn, REG_CFA_ADJUST_CFA, cfa_adj);
666 RTX_FRAME_RELATED_P (insn) = 1;
669 /* Add in the __builtin_eh_return stack adjustment. */
670 if (crtl->calls_eh_return)
671 emit_insn (gen_add2_insn (stack_pointer_rtx, EH_RETURN_STACKADJ_RTX));
673 if (!sibcall_p)
674 emit_jump_insn (gen_simple_return ());
677 /* Implement RETURN_ADDR_RTX. Note, we do not support moving
678 back to a previous frame. */
680 nios2_get_return_address (int count)
682 if (count != 0)
683 return const0_rtx;
685 return get_hard_reg_initial_val (Pmode, RA_REGNO);
688 /* Emit code to change the current function's return address to
689 ADDRESS. SCRATCH is available as a scratch register, if needed.
690 ADDRESS and SCRATCH are both word-mode GPRs. */
691 void
692 nios2_set_return_address (rtx address, rtx scratch)
694 nios2_compute_frame_layout ();
695 if (cfun->machine->save_mask & (1 << RA_REGNO))
697 unsigned offset = cfun->machine->save_reg_size - 4;
698 rtx base;
700 if (frame_pointer_needed)
701 base = hard_frame_pointer_rtx;
702 else
704 base = stack_pointer_rtx;
705 offset += cfun->machine->save_regs_offset;
707 if (!SMALL_INT (offset))
709 emit_move_insn (scratch, gen_int_mode (offset, Pmode));
710 emit_insn (gen_add2_insn (scratch, base));
711 base = scratch;
712 offset = 0;
715 if (offset)
716 base = plus_constant (Pmode, base, offset);
717 emit_move_insn (gen_rtx_MEM (Pmode, base), address);
719 else
720 emit_move_insn (gen_rtx_REG (Pmode, RA_REGNO), address);
723 /* Implement FUNCTION_PROFILER macro. */
724 void
725 nios2_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
727 fprintf (file, "\tmov\tr8, ra\n");
728 if (flag_pic == 1)
730 fprintf (file, "\tnextpc\tr2\n");
731 fprintf (file, "\t1: movhi\tr3, %%hiadj(_gp_got - 1b)\n");
732 fprintf (file, "\taddi\tr3, r3, %%lo(_gp_got - 1b)\n");
733 fprintf (file, "\tadd\tr2, r2, r3\n");
734 fprintf (file, "\tldw\tr2, %%call(_mcount)(r2)\n");
735 fprintf (file, "\tcallr\tr2\n");
737 else if (flag_pic == 2)
739 fprintf (file, "\tnextpc\tr2\n");
740 fprintf (file, "\t1: movhi\tr3, %%hiadj(_gp_got - 1b)\n");
741 fprintf (file, "\taddi\tr3, r3, %%lo(_gp_got - 1b)\n");
742 fprintf (file, "\tadd\tr2, r2, r3\n");
743 fprintf (file, "\tmovhi\tr3, %%call_hiadj(_mcount)\n");
744 fprintf (file, "\taddi\tr3, r3, %%call_lo(_mcount)\n");
745 fprintf (file, "\tadd\tr3, r2, r3\n");
746 fprintf (file, "\tldw\tr2, 0(r3)\n");
747 fprintf (file, "\tcallr\tr2\n");
749 else
750 fprintf (file, "\tcall\t_mcount\n");
751 fprintf (file, "\tmov\tra, r8\n");
754 /* Dump stack layout. */
755 static void
756 nios2_dump_frame_layout (FILE *file)
758 fprintf (file, "\t%s Current Frame Info\n", ASM_COMMENT_START);
759 fprintf (file, "\t%s total_size = %d\n", ASM_COMMENT_START,
760 cfun->machine->total_size);
761 fprintf (file, "\t%s var_size = %d\n", ASM_COMMENT_START,
762 cfun->machine->var_size);
763 fprintf (file, "\t%s args_size = %d\n", ASM_COMMENT_START,
764 cfun->machine->args_size);
765 fprintf (file, "\t%s save_reg_size = %d\n", ASM_COMMENT_START,
766 cfun->machine->save_reg_size);
767 fprintf (file, "\t%s initialized = %d\n", ASM_COMMENT_START,
768 cfun->machine->initialized);
769 fprintf (file, "\t%s save_regs_offset = %d\n", ASM_COMMENT_START,
770 cfun->machine->save_regs_offset);
771 fprintf (file, "\t%s is_leaf = %d\n", ASM_COMMENT_START,
772 crtl->is_leaf);
773 fprintf (file, "\t%s frame_pointer_needed = %d\n", ASM_COMMENT_START,
774 frame_pointer_needed);
775 fprintf (file, "\t%s pretend_args_size = %d\n", ASM_COMMENT_START,
776 crtl->args.pretend_args_size);
779 /* Return true if REGNO should be saved in the prologue. */
780 static bool
781 prologue_saved_reg_p (unsigned regno)
783 gcc_assert (GP_REG_P (regno));
785 if (df_regs_ever_live_p (regno) && !call_used_regs[regno])
786 return true;
788 if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
789 return true;
791 if (regno == PIC_OFFSET_TABLE_REGNUM && crtl->uses_pic_offset_table)
792 return true;
794 if (regno == RA_REGNO && df_regs_ever_live_p (RA_REGNO))
795 return true;
797 return false;
800 /* Implement TARGET_CAN_ELIMINATE. */
801 static bool
802 nios2_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
804 if (to == STACK_POINTER_REGNUM)
805 return !frame_pointer_needed;
806 return true;
809 /* Implement INITIAL_ELIMINATION_OFFSET macro. */
811 nios2_initial_elimination_offset (int from, int to)
813 int offset;
815 nios2_compute_frame_layout ();
817 /* Set OFFSET to the offset from the stack pointer. */
818 switch (from)
820 case FRAME_POINTER_REGNUM:
821 offset = cfun->machine->args_size;
822 break;
824 case ARG_POINTER_REGNUM:
825 offset = cfun->machine->total_size;
826 offset -= crtl->args.pretend_args_size;
827 break;
829 default:
830 gcc_unreachable ();
833 /* If we are asked for the frame pointer offset, then adjust OFFSET
834 by the offset from the frame pointer to the stack pointer. */
835 if (to == HARD_FRAME_POINTER_REGNUM)
836 offset -= (cfun->machine->save_regs_offset
837 + cfun->machine->fp_save_offset);
839 return offset;
842 /* Return nonzero if this function is known to have a null epilogue.
843 This allows the optimizer to omit jumps to jumps if no stack
844 was created. */
846 nios2_can_use_return_insn (void)
848 if (!reload_completed || crtl->profile)
849 return 0;
851 return nios2_compute_frame_layout () == 0;
855 /* Check and signal some warnings/errors on FPU insn options. */
856 static void
857 nios2_custom_check_insns (void)
859 unsigned int i, j;
860 bool errors = false;
862 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
863 if (N2FPU_ENABLED_P (i) && N2FPU_DOUBLE_P (i))
865 for (j = 0; j < ARRAY_SIZE (nios2_fpu_insn); j++)
866 if (N2FPU_DOUBLE_REQUIRED_P (j) && ! N2FPU_ENABLED_P (j))
868 error ("switch %<-mcustom-%s%> is required for double "
869 "precision floating point", N2FPU_NAME (j));
870 errors = true;
872 break;
875 /* Warn if the user has certain exotic operations that won't get used
876 without -funsafe-math-optimizations. See expand_builtin () in
877 builtins.c. */
878 if (!flag_unsafe_math_optimizations)
879 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
880 if (N2FPU_ENABLED_P (i) && N2FPU_UNSAFE_P (i))
881 warning (0, "switch %<-mcustom-%s%> has no effect unless "
882 "-funsafe-math-optimizations is specified", N2FPU_NAME (i));
884 /* Warn if the user is trying to use -mcustom-fmins et. al, that won't
885 get used without -ffinite-math-only. See fold_builtin_fmin_fmax ()
886 in builtins.c. */
887 if (!flag_finite_math_only)
888 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
889 if (N2FPU_ENABLED_P (i) && N2FPU_FINITE_P (i))
890 warning (0, "switch %<-mcustom-%s%> has no effect unless "
891 "-ffinite-math-only is specified", N2FPU_NAME (i));
893 /* Warn if the user is trying to use a custom rounding instruction
894 that won't get used without -fno-math-errno. See
895 expand_builtin_int_roundingfn_2 () in builtins.c. */
896 if (flag_errno_math)
897 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
898 if (N2FPU_ENABLED_P (i) && N2FPU_NO_ERRNO_P (i))
899 warning (0, "switch %<-mcustom-%s%> has no effect unless "
900 "-fno-math-errno is specified", N2FPU_NAME (i));
902 if (errors || custom_code_conflict)
903 fatal_error (input_location,
904 "conflicting use of -mcustom switches, target attributes, "
905 "and/or __builtin_custom_ functions");
908 static void
909 nios2_set_fpu_custom_code (enum n2fpu_code code, int n, bool override_p)
911 if (override_p || N2FPU_N (code) == -1)
912 N2FPU_N (code) = n;
913 nios2_register_custom_code (n, CCS_FPU, (int) code);
916 /* Type to represent a standard FPU config. */
917 struct nios2_fpu_config
919 const char *name;
920 bool set_sp_constants;
921 int code[n2fpu_code_num];
924 #define NIOS2_FPU_CONFIG_NUM 3
925 static struct nios2_fpu_config custom_fpu_config[NIOS2_FPU_CONFIG_NUM];
927 static void
928 nios2_init_fpu_configs (void)
930 struct nios2_fpu_config* cfg;
931 int i = 0;
932 #define NEXT_FPU_CONFIG \
933 do { \
934 cfg = &custom_fpu_config[i++]; \
935 memset (cfg, -1, sizeof (struct nios2_fpu_config));\
936 } while (0)
938 NEXT_FPU_CONFIG;
939 cfg->name = "60-1";
940 cfg->set_sp_constants = true;
941 cfg->code[n2fpu_fmuls] = 252;
942 cfg->code[n2fpu_fadds] = 253;
943 cfg->code[n2fpu_fsubs] = 254;
945 NEXT_FPU_CONFIG;
946 cfg->name = "60-2";
947 cfg->set_sp_constants = true;
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 NEXT_FPU_CONFIG;
954 cfg->name = "72-3";
955 cfg->set_sp_constants = true;
956 cfg->code[n2fpu_floatus] = 243;
957 cfg->code[n2fpu_fixsi] = 244;
958 cfg->code[n2fpu_floatis] = 245;
959 cfg->code[n2fpu_fcmpgts] = 246;
960 cfg->code[n2fpu_fcmples] = 249;
961 cfg->code[n2fpu_fcmpeqs] = 250;
962 cfg->code[n2fpu_fcmpnes] = 251;
963 cfg->code[n2fpu_fmuls] = 252;
964 cfg->code[n2fpu_fadds] = 253;
965 cfg->code[n2fpu_fsubs] = 254;
966 cfg->code[n2fpu_fdivs] = 255;
968 #undef NEXT_FPU_CONFIG
969 gcc_assert (i == NIOS2_FPU_CONFIG_NUM);
972 static struct nios2_fpu_config *
973 nios2_match_custom_fpu_cfg (const char *cfgname, const char *endp)
975 int i;
976 for (i = 0; i < NIOS2_FPU_CONFIG_NUM; i++)
978 bool match = !(endp != NULL
979 ? strncmp (custom_fpu_config[i].name, cfgname,
980 endp - cfgname)
981 : strcmp (custom_fpu_config[i].name, cfgname));
982 if (match)
983 return &custom_fpu_config[i];
985 return NULL;
988 /* Use CFGNAME to lookup FPU config, ENDP if not NULL marks end of string.
989 OVERRIDE is true if loaded config codes should overwrite current state. */
990 static void
991 nios2_handle_custom_fpu_cfg (const char *cfgname, const char *endp,
992 bool override)
994 struct nios2_fpu_config *cfg = nios2_match_custom_fpu_cfg (cfgname, endp);
995 if (cfg)
997 unsigned int i;
998 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
999 if (cfg->code[i] >= 0)
1000 nios2_set_fpu_custom_code ((enum n2fpu_code) i, cfg->code[i],
1001 override);
1002 if (cfg->set_sp_constants)
1003 flag_single_precision_constant = 1;
1005 else
1006 warning (0, "ignoring unrecognized switch %<-mcustom-fpu-cfg%> "
1007 "value %<%s%>", cfgname);
1009 /* Guard against errors in the standard configurations. */
1010 nios2_custom_check_insns ();
1013 /* Check individual FPU insn options, and register custom code. */
1014 static void
1015 nios2_handle_custom_fpu_insn_option (int fpu_insn_index)
1017 int param = N2FPU_N (fpu_insn_index);
1019 if (0 <= param && param <= 255)
1020 nios2_register_custom_code (param, CCS_FPU, fpu_insn_index);
1022 /* Valid values are 0-255, but also allow -1 so that the
1023 -mno-custom-<opt> switches work. */
1024 else if (param != -1)
1025 error ("switch %<-mcustom-%s%> value %d must be between 0 and 255",
1026 N2FPU_NAME (fpu_insn_index), param);
1029 /* Allocate a chunk of memory for per-function machine-dependent data. */
1030 static struct machine_function *
1031 nios2_init_machine_status (void)
1033 return ggc_cleared_alloc<machine_function> ();
1036 /* Implement TARGET_OPTION_OVERRIDE. */
1037 static void
1038 nios2_option_override (void)
1040 unsigned int i;
1042 #ifdef SUBTARGET_OVERRIDE_OPTIONS
1043 SUBTARGET_OVERRIDE_OPTIONS;
1044 #endif
1046 /* Check for unsupported options. */
1047 if (flag_pic && !TARGET_LINUX_ABI)
1048 sorry ("position-independent code requires the Linux ABI");
1050 /* Function to allocate machine-dependent function status. */
1051 init_machine_status = &nios2_init_machine_status;
1053 nios2_section_threshold
1054 = (global_options_set.x_g_switch_value
1055 ? g_switch_value : NIOS2_DEFAULT_GVALUE);
1057 if (nios2_gpopt_option == gpopt_unspecified)
1059 /* Default to -mgpopt unless -fpic or -fPIC. */
1060 if (flag_pic)
1061 nios2_gpopt_option = gpopt_none;
1062 else
1063 nios2_gpopt_option = gpopt_local;
1066 /* If we don't have mul, we don't have mulx either! */
1067 if (!TARGET_HAS_MUL && TARGET_HAS_MULX)
1068 target_flags &= ~MASK_HAS_MULX;
1070 /* Initialize default FPU configurations. */
1071 nios2_init_fpu_configs ();
1073 /* Set up default handling for floating point custom instructions.
1075 Putting things in this order means that the -mcustom-fpu-cfg=
1076 switch will always be overridden by individual -mcustom-fadds=
1077 switches, regardless of the order in which they were specified
1078 on the command line.
1080 This behavior of prioritization of individual -mcustom-<insn>=
1081 options before the -mcustom-fpu-cfg= switch is maintained for
1082 compatibility. */
1083 if (nios2_custom_fpu_cfg_string && *nios2_custom_fpu_cfg_string)
1084 nios2_handle_custom_fpu_cfg (nios2_custom_fpu_cfg_string, NULL, false);
1086 /* Handle options for individual FPU insns. */
1087 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
1088 nios2_handle_custom_fpu_insn_option (i);
1090 nios2_custom_check_insns ();
1092 /* Save the initial options in case the user does function specific
1093 options. */
1094 target_option_default_node = target_option_current_node
1095 = build_target_option_node (&global_options);
1099 /* Return true if CST is a constant within range of movi/movui/movhi. */
1100 static bool
1101 nios2_simple_const_p (const_rtx cst)
1103 HOST_WIDE_INT val = INTVAL (cst);
1104 return SMALL_INT (val) || SMALL_INT_UNSIGNED (val) || UPPER16_INT (val);
1107 /* Compute a (partial) cost for rtx X. Return true if the complete
1108 cost has been computed, and false if subexpressions should be
1109 scanned. In either case, *TOTAL contains the cost result. */
1110 static bool
1111 nios2_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
1112 int opno ATTRIBUTE_UNUSED,
1113 int *total, bool speed ATTRIBUTE_UNUSED)
1115 switch (code)
1117 case CONST_INT:
1118 if (INTVAL (x) == 0)
1120 *total = COSTS_N_INSNS (0);
1121 return true;
1123 else if (nios2_simple_const_p (x))
1125 *total = COSTS_N_INSNS (2);
1126 return true;
1128 else
1130 *total = COSTS_N_INSNS (4);
1131 return true;
1134 case LABEL_REF:
1135 case SYMBOL_REF:
1136 case CONST:
1137 case CONST_DOUBLE:
1139 *total = COSTS_N_INSNS (4);
1140 return true;
1143 case AND:
1145 /* Recognize 'nor' insn pattern. */
1146 if (GET_CODE (XEXP (x, 0)) == NOT
1147 && GET_CODE (XEXP (x, 1)) == NOT)
1149 *total = COSTS_N_INSNS (1);
1150 return true;
1152 return false;
1155 case MULT:
1157 *total = COSTS_N_INSNS (1);
1158 return false;
1160 case SIGN_EXTEND:
1162 *total = COSTS_N_INSNS (3);
1163 return false;
1165 case ZERO_EXTEND:
1167 *total = COSTS_N_INSNS (1);
1168 return false;
1171 default:
1172 return false;
1176 /* Implement TARGET_PREFERRED_RELOAD_CLASS. */
1177 static reg_class_t
1178 nios2_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, reg_class_t regclass)
1180 return regclass == NO_REGS ? GENERAL_REGS : regclass;
1183 /* Emit a call to __tls_get_addr. TI is the argument to this function.
1184 RET is an RTX for the return value location. The entire insn sequence
1185 is returned. */
1186 static GTY(()) rtx nios2_tls_symbol;
1188 static rtx
1189 nios2_call_tls_get_addr (rtx ti)
1191 rtx arg = gen_rtx_REG (Pmode, FIRST_ARG_REGNO);
1192 rtx ret = gen_rtx_REG (Pmode, FIRST_RETVAL_REGNO);
1193 rtx fn, insn;
1195 if (!nios2_tls_symbol)
1196 nios2_tls_symbol = init_one_libfunc ("__tls_get_addr");
1198 emit_move_insn (arg, ti);
1199 fn = gen_rtx_MEM (QImode, nios2_tls_symbol);
1200 insn = emit_call_insn (gen_call_value (ret, fn, const0_rtx));
1201 RTL_CONST_CALL_P (insn) = 1;
1202 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), ret);
1203 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), arg);
1205 return ret;
1208 /* Return true for large offsets requiring hiadj/lo relocation pairs. */
1209 static bool
1210 nios2_large_offset_p (int unspec)
1212 gcc_assert (nios2_unspec_reloc_name (unspec) != NULL);
1214 if (flag_pic == 2
1215 /* FIXME: TLS GOT offset relocations will eventually also get this
1216 treatment, after binutils support for those are also completed. */
1217 && (unspec == UNSPEC_PIC_SYM || unspec == UNSPEC_PIC_CALL_SYM))
1218 return true;
1220 /* 'gotoff' offsets are always hiadj/lo. */
1221 if (unspec == UNSPEC_PIC_GOTOFF_SYM)
1222 return true;
1224 return false;
1227 /* Return true for conforming unspec relocations. Also used in
1228 constraints.md and predicates.md. */
1229 bool
1230 nios2_unspec_reloc_p (rtx op)
1232 return (GET_CODE (op) == CONST
1233 && GET_CODE (XEXP (op, 0)) == UNSPEC
1234 && ! nios2_large_offset_p (XINT (XEXP (op, 0), 1)));
1237 /* Helper to generate unspec constant. */
1238 static rtx
1239 nios2_unspec_offset (rtx loc, int unspec)
1241 return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, loc),
1242 unspec));
1245 /* Generate GOT pointer based address with large offset. */
1246 static rtx
1247 nios2_large_got_address (rtx offset, rtx tmp)
1249 if (!tmp)
1250 tmp = gen_reg_rtx (Pmode);
1251 emit_move_insn (tmp, offset);
1252 return gen_rtx_PLUS (Pmode, tmp, pic_offset_table_rtx);
1255 /* Generate a GOT pointer based address. */
1256 static rtx
1257 nios2_got_address (rtx loc, int unspec)
1259 rtx offset = nios2_unspec_offset (loc, unspec);
1260 crtl->uses_pic_offset_table = 1;
1262 if (nios2_large_offset_p (unspec))
1263 return force_reg (Pmode, nios2_large_got_address (offset, NULL_RTX));
1265 return gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset);
1268 /* Generate the code to access LOC, a thread local SYMBOL_REF. The
1269 return value will be a valid address and move_operand (either a REG
1270 or a LO_SUM). */
1271 static rtx
1272 nios2_legitimize_tls_address (rtx loc)
1274 rtx tmp, mem, tp;
1275 enum tls_model model = SYMBOL_REF_TLS_MODEL (loc);
1277 switch (model)
1279 case TLS_MODEL_GLOBAL_DYNAMIC:
1280 tmp = gen_reg_rtx (Pmode);
1281 emit_move_insn (tmp, nios2_got_address (loc, UNSPEC_ADD_TLS_GD));
1282 return nios2_call_tls_get_addr (tmp);
1284 case TLS_MODEL_LOCAL_DYNAMIC:
1285 tmp = gen_reg_rtx (Pmode);
1286 emit_move_insn (tmp, nios2_got_address (loc, UNSPEC_ADD_TLS_LDM));
1287 return gen_rtx_PLUS (Pmode, nios2_call_tls_get_addr (tmp),
1288 nios2_unspec_offset (loc, UNSPEC_ADD_TLS_LDO));
1290 case TLS_MODEL_INITIAL_EXEC:
1291 tmp = gen_reg_rtx (Pmode);
1292 mem = gen_const_mem (Pmode, nios2_got_address (loc, UNSPEC_LOAD_TLS_IE));
1293 emit_move_insn (tmp, mem);
1294 tp = gen_rtx_REG (Pmode, TP_REGNO);
1295 return gen_rtx_PLUS (Pmode, tp, tmp);
1297 case TLS_MODEL_LOCAL_EXEC:
1298 tp = gen_rtx_REG (Pmode, TP_REGNO);
1299 return gen_rtx_PLUS (Pmode, tp,
1300 nios2_unspec_offset (loc, UNSPEC_ADD_TLS_LE));
1301 default:
1302 gcc_unreachable ();
1306 /* Divide Support
1308 If -O3 is used, we want to output a table lookup for
1309 divides between small numbers (both num and den >= 0
1310 and < 0x10). The overhead of this method in the worst
1311 case is 40 bytes in the text section (10 insns) and
1312 256 bytes in the data section. Additional divides do
1313 not incur additional penalties in the data section.
1315 Code speed is improved for small divides by about 5x
1316 when using this method in the worse case (~9 cycles
1317 vs ~45). And in the worst case divides not within the
1318 table are penalized by about 10% (~5 cycles vs ~45).
1319 However in the typical case the penalty is not as bad
1320 because doing the long divide in only 45 cycles is
1321 quite optimistic.
1323 ??? would be nice to have some benchmarks other
1324 than Dhrystone to back this up.
1326 This bit of expansion is to create this instruction
1327 sequence as rtl.
1328 or $8, $4, $5
1329 slli $9, $4, 4
1330 cmpgeui $3, $8, 16
1331 beq $3, $0, .L3
1332 or $10, $9, $5
1333 add $12, $11, divide_table
1334 ldbu $2, 0($12)
1335 br .L1
1336 .L3:
1337 call slow_div
1338 .L1:
1339 # continue here with result in $2
1341 ??? Ideally I would like the libcall block to contain all
1342 of this code, but I don't know how to do that. What it
1343 means is that if the divide can be eliminated, it may not
1344 completely disappear.
1346 ??? The __divsi3_table label should ideally be moved out
1347 of this block and into a global. If it is placed into the
1348 sdata section we can save even more cycles by doing things
1349 gp relative. */
1350 void
1351 nios2_emit_expensive_div (rtx *operands, machine_mode mode)
1353 rtx or_result, shift_left_result;
1354 rtx lookup_value;
1355 rtx_code_label *lab1, *lab3;
1356 rtx insns;
1357 rtx libfunc;
1358 rtx final_result;
1359 rtx tmp;
1360 rtx table;
1362 /* It may look a little generic, but only SImode is supported for now. */
1363 gcc_assert (mode == SImode);
1364 libfunc = optab_libfunc (sdiv_optab, SImode);
1366 lab1 = gen_label_rtx ();
1367 lab3 = gen_label_rtx ();
1369 or_result = expand_simple_binop (SImode, IOR,
1370 operands[1], operands[2],
1371 0, 0, OPTAB_LIB_WIDEN);
1373 emit_cmp_and_jump_insns (or_result, GEN_INT (15), GTU, 0,
1374 GET_MODE (or_result), 0, lab3);
1375 JUMP_LABEL (get_last_insn ()) = lab3;
1377 shift_left_result = expand_simple_binop (SImode, ASHIFT,
1378 operands[1], GEN_INT (4),
1379 0, 0, OPTAB_LIB_WIDEN);
1381 lookup_value = expand_simple_binop (SImode, IOR,
1382 shift_left_result, operands[2],
1383 0, 0, OPTAB_LIB_WIDEN);
1384 table = gen_rtx_PLUS (SImode, lookup_value,
1385 gen_rtx_SYMBOL_REF (SImode, "__divsi3_table"));
1386 convert_move (operands[0], gen_rtx_MEM (QImode, table), 1);
1388 tmp = emit_jump_insn (gen_jump (lab1));
1389 JUMP_LABEL (tmp) = lab1;
1390 emit_barrier ();
1392 emit_label (lab3);
1393 LABEL_NUSES (lab3) = 1;
1395 start_sequence ();
1396 final_result = emit_library_call_value (libfunc, NULL_RTX,
1397 LCT_CONST, SImode, 2,
1398 operands[1], SImode,
1399 operands[2], SImode);
1401 insns = get_insns ();
1402 end_sequence ();
1403 emit_libcall_block (insns, operands[0], final_result,
1404 gen_rtx_DIV (SImode, operands[1], operands[2]));
1406 emit_label (lab1);
1407 LABEL_NUSES (lab1) = 1;
1411 /* Branches and compares. */
1413 /* Return in *ALT_CODE and *ALT_OP, an alternate equivalent constant
1414 comparison, e.g. >= 1 into > 0. */
1415 static void
1416 nios2_alternate_compare_const (enum rtx_code code, rtx op,
1417 enum rtx_code *alt_code, rtx *alt_op,
1418 machine_mode mode)
1420 HOST_WIDE_INT opval = INTVAL (op);
1421 enum rtx_code scode = signed_condition (code);
1422 bool dec_p = (scode == LT || scode == GE);
1424 if (code == EQ || code == NE)
1426 *alt_code = code;
1427 *alt_op = op;
1428 return;
1431 *alt_op = (dec_p
1432 ? gen_int_mode (opval - 1, mode)
1433 : gen_int_mode (opval + 1, mode));
1435 /* The required conversion between [>,>=] and [<,<=] is captured
1436 by a reverse + swap of condition codes. */
1437 *alt_code = reverse_condition (swap_condition (code));
1440 /* Test if the incremented/decremented value crosses the over/underflow
1441 boundary. Supposedly, such boundary cases should already be transformed
1442 into always-true/false or EQ conditions, so use an assertion here. */
1443 unsigned HOST_WIDE_INT alt_opval = INTVAL (*alt_op);
1444 if (code == scode)
1445 alt_opval ^= (1 << (GET_MODE_BITSIZE (mode) - 1));
1446 alt_opval &= GET_MODE_MASK (mode);
1447 gcc_assert (dec_p ? alt_opval != GET_MODE_MASK (mode) : alt_opval != 0);
1451 /* Return true if the constant comparison is supported by nios2. */
1452 static bool
1453 nios2_valid_compare_const_p (enum rtx_code code, rtx op)
1455 switch (code)
1457 case EQ: case NE: case GE: case LT:
1458 return SMALL_INT (INTVAL (op));
1459 case GEU: case LTU:
1460 return SMALL_INT_UNSIGNED (INTVAL (op));
1461 default:
1462 return false;
1466 /* Checks if the FPU comparison in *CMP, *OP1, and *OP2 can be supported in
1467 the current configuration. Perform modifications if MODIFY_P is true.
1468 Returns true if FPU compare can be done. */
1470 bool
1471 nios2_validate_fpu_compare (machine_mode mode, rtx *cmp, rtx *op1, rtx *op2,
1472 bool modify_p)
1474 bool rev_p = false;
1475 enum rtx_code code = GET_CODE (*cmp);
1477 if (!nios2_fpu_compare_enabled (code, mode))
1479 code = swap_condition (code);
1480 if (nios2_fpu_compare_enabled (code, mode))
1481 rev_p = true;
1482 else
1483 return false;
1486 if (modify_p)
1488 if (rev_p)
1490 rtx tmp = *op1;
1491 *op1 = *op2;
1492 *op2 = tmp;
1494 *op1 = force_reg (mode, *op1);
1495 *op2 = force_reg (mode, *op2);
1496 *cmp = gen_rtx_fmt_ee (code, mode, *op1, *op2);
1498 return true;
1501 /* Checks and modifies the comparison in *CMP, *OP1, and *OP2 into valid
1502 nios2 supported form. Returns true if success. */
1503 bool
1504 nios2_validate_compare (machine_mode mode, rtx *cmp, rtx *op1, rtx *op2)
1506 enum rtx_code code = GET_CODE (*cmp);
1507 enum rtx_code alt_code;
1508 rtx alt_op2;
1510 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
1511 return nios2_validate_fpu_compare (mode, cmp, op1, op2, true);
1513 if (!reg_or_0_operand (*op2, mode))
1515 /* Create alternate constant compare. */
1516 nios2_alternate_compare_const (code, *op2, &alt_code, &alt_op2, mode);
1518 /* If alterate op2 is zero(0), we can use it directly, possibly
1519 swapping the compare code. */
1520 if (alt_op2 == const0_rtx)
1522 code = alt_code;
1523 *op2 = alt_op2;
1524 goto check_rebuild_cmp;
1527 /* Check if either constant compare can be used. */
1528 if (nios2_valid_compare_const_p (code, *op2))
1529 return true;
1530 else if (nios2_valid_compare_const_p (alt_code, alt_op2))
1532 code = alt_code;
1533 *op2 = alt_op2;
1534 goto rebuild_cmp;
1537 /* We have to force op2 into a register now. Try to pick one
1538 with a lower cost. */
1539 if (! nios2_simple_const_p (*op2)
1540 && nios2_simple_const_p (alt_op2))
1542 code = alt_code;
1543 *op2 = alt_op2;
1545 *op2 = force_reg (SImode, *op2);
1547 check_rebuild_cmp:
1548 if (code == GT || code == GTU || code == LE || code == LEU)
1550 rtx t = *op1; *op1 = *op2; *op2 = t;
1551 code = swap_condition (code);
1553 rebuild_cmp:
1554 *cmp = gen_rtx_fmt_ee (code, mode, *op1, *op2);
1555 return true;
1559 /* Addressing Modes. */
1561 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
1562 static bool
1563 nios2_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
1565 rtx base, offset;
1566 split_const (x, &base, &offset);
1567 return GET_CODE (base) != SYMBOL_REF || !SYMBOL_REF_TLS_MODEL (base);
1570 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
1571 static bool
1572 nios2_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
1574 return nios2_legitimate_constant_p (mode, x) == false;
1577 /* Return true if register REGNO is a valid base register.
1578 STRICT_P is true if REG_OK_STRICT is in effect. */
1580 bool
1581 nios2_regno_ok_for_base_p (int regno, bool strict_p)
1583 if (!HARD_REGISTER_NUM_P (regno))
1585 if (!strict_p)
1586 return true;
1588 if (!reg_renumber)
1589 return false;
1591 regno = reg_renumber[regno];
1594 /* The fake registers will be eliminated to either the stack or
1595 hard frame pointer, both of which are usually valid base registers.
1596 Reload deals with the cases where the eliminated form isn't valid. */
1597 return (GP_REG_P (regno)
1598 || regno == FRAME_POINTER_REGNUM
1599 || regno == ARG_POINTER_REGNUM);
1602 /* Return true if the address expression formed by BASE + OFFSET is
1603 valid. */
1604 static bool
1605 nios2_valid_addr_expr_p (rtx base, rtx offset, bool strict_p)
1607 if (!strict_p && GET_CODE (base) == SUBREG)
1608 base = SUBREG_REG (base);
1609 return (REG_P (base)
1610 && nios2_regno_ok_for_base_p (REGNO (base), strict_p)
1611 && (offset == NULL_RTX
1612 || const_arith_operand (offset, Pmode)
1613 || nios2_unspec_reloc_p (offset)));
1616 /* Implement TARGET_LEGITIMATE_ADDRESS_P. */
1617 static bool
1618 nios2_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
1619 rtx operand, bool strict_p)
1621 switch (GET_CODE (operand))
1623 /* Direct. */
1624 case SYMBOL_REF:
1625 if (SYMBOL_REF_TLS_MODEL (operand))
1626 return false;
1628 if (nios2_symbol_ref_in_small_data_p (operand))
1629 return true;
1631 /* Else, fall through. */
1632 case LABEL_REF:
1633 case CONST_INT:
1634 case CONST:
1635 case CONST_DOUBLE:
1636 return false;
1638 /* Register indirect. */
1639 case REG:
1640 return nios2_regno_ok_for_base_p (REGNO (operand), strict_p);
1642 /* Register indirect with displacement. */
1643 case PLUS:
1645 rtx op0 = XEXP (operand, 0);
1646 rtx op1 = XEXP (operand, 1);
1648 return (nios2_valid_addr_expr_p (op0, op1, strict_p)
1649 || nios2_valid_addr_expr_p (op1, op0, strict_p));
1652 default:
1653 break;
1655 return false;
1658 /* Return true if SECTION is a small section name. */
1659 static bool
1660 nios2_small_section_name_p (const char *section)
1662 return (strcmp (section, ".sbss") == 0
1663 || strncmp (section, ".sbss.", 6) == 0
1664 || strcmp (section, ".sdata") == 0
1665 || strncmp (section, ".sdata.", 7) == 0);
1668 /* Return true if EXP should be placed in the small data section. */
1669 static bool
1670 nios2_in_small_data_p (const_tree exp)
1672 /* We want to merge strings, so we never consider them small data. */
1673 if (TREE_CODE (exp) == STRING_CST)
1674 return false;
1676 if (TREE_CODE (exp) == VAR_DECL)
1678 if (DECL_SECTION_NAME (exp))
1680 const char *section = DECL_SECTION_NAME (exp);
1681 if (nios2_small_section_name_p (section))
1682 return true;
1684 else
1686 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
1688 /* If this is an incomplete type with size 0, then we can't put it
1689 in sdata because it might be too big when completed. */
1690 if (size > 0
1691 && (unsigned HOST_WIDE_INT) size <= nios2_section_threshold)
1692 return true;
1696 return false;
1699 /* Return true if symbol is in small data section. */
1701 bool
1702 nios2_symbol_ref_in_small_data_p (rtx sym)
1704 tree decl;
1706 gcc_assert (GET_CODE (sym) == SYMBOL_REF);
1707 decl = SYMBOL_REF_DECL (sym);
1709 /* TLS variables are not accessed through the GP. */
1710 if (SYMBOL_REF_TLS_MODEL (sym) != 0)
1711 return false;
1713 /* If the user has explicitly placed the symbol in a small data section
1714 via an attribute, generate gp-relative addressing even if the symbol
1715 is external, weak, or larger than we'd automatically put in the
1716 small data section. OTOH, if the symbol is located in some
1717 non-small-data section, we can't use gp-relative accesses on it
1718 unless the user has requested gpopt_data or gpopt_all. */
1720 switch (nios2_gpopt_option)
1722 case gpopt_none:
1723 /* Don't generate a gp-relative addressing mode if that's been
1724 disabled. */
1725 return false;
1727 case gpopt_local:
1728 /* Use GP-relative addressing for small data symbols that are
1729 not external or weak, plus any symbols that have explicitly
1730 been placed in a small data section. */
1731 if (decl && DECL_SECTION_NAME (decl))
1732 return nios2_small_section_name_p (DECL_SECTION_NAME (decl));
1733 return (SYMBOL_REF_SMALL_P (sym)
1734 && !SYMBOL_REF_EXTERNAL_P (sym)
1735 && !(decl && DECL_WEAK (decl)));
1737 case gpopt_global:
1738 /* Use GP-relative addressing for small data symbols, even if
1739 they are external or weak. Note that SYMBOL_REF_SMALL_P
1740 is also true of symbols that have explicitly been placed
1741 in a small data section. */
1742 return SYMBOL_REF_SMALL_P (sym);
1744 case gpopt_data:
1745 /* Use GP-relative addressing for all data symbols regardless
1746 of the object size, but not for code symbols. This option
1747 is equivalent to the user asserting that the entire data
1748 section is accessible from the GP. */
1749 return !SYMBOL_REF_FUNCTION_P (sym);
1751 case gpopt_all:
1752 /* Use GP-relative addressing for everything, including code.
1753 Effectively, the user has asserted that the entire program
1754 fits within the 64K range of the GP offset. */
1755 return true;
1757 default:
1758 /* We shouldn't get here. */
1759 return false;
1763 /* Implement TARGET_SECTION_TYPE_FLAGS. */
1765 static unsigned int
1766 nios2_section_type_flags (tree decl, const char *name, int reloc)
1768 unsigned int flags;
1770 flags = default_section_type_flags (decl, name, reloc);
1772 if (nios2_small_section_name_p (name))
1773 flags |= SECTION_SMALL;
1775 return flags;
1778 /* Return true if SYMBOL_REF X binds locally. */
1780 static bool
1781 nios2_symbol_binds_local_p (const_rtx x)
1783 return (SYMBOL_REF_DECL (x)
1784 ? targetm.binds_local_p (SYMBOL_REF_DECL (x))
1785 : SYMBOL_REF_LOCAL_P (x));
1788 /* Position independent code related. */
1790 /* Emit code to load the PIC register. */
1791 static void
1792 nios2_load_pic_register (void)
1794 rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
1796 emit_insn (gen_load_got_register (pic_offset_table_rtx, tmp));
1797 emit_insn (gen_add3_insn (pic_offset_table_rtx, pic_offset_table_rtx, tmp));
1800 /* Generate a PIC address as a MEM rtx. */
1801 static rtx
1802 nios2_load_pic_address (rtx sym, int unspec, rtx tmp)
1804 if (flag_pic == 2
1805 && GET_CODE (sym) == SYMBOL_REF
1806 && nios2_symbol_binds_local_p (sym))
1807 /* Under -fPIC, generate a GOTOFF address for local symbols. */
1809 rtx offset = nios2_unspec_offset (sym, UNSPEC_PIC_GOTOFF_SYM);
1810 crtl->uses_pic_offset_table = 1;
1811 return nios2_large_got_address (offset, tmp);
1814 return gen_const_mem (Pmode, nios2_got_address (sym, unspec));
1817 /* Nonzero if the constant value X is a legitimate general operand
1818 when generating PIC code. It is given that flag_pic is on and
1819 that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
1820 bool
1821 nios2_legitimate_pic_operand_p (rtx x)
1823 if (GET_CODE (x) == CONST
1824 && GET_CODE (XEXP (x, 0)) == UNSPEC
1825 && nios2_large_offset_p (XINT (XEXP (x, 0), 1)))
1826 return true;
1828 return ! (GET_CODE (x) == SYMBOL_REF
1829 || GET_CODE (x) == LABEL_REF || GET_CODE (x) == CONST);
1832 /* Return TRUE if X is a thread-local symbol. */
1833 static bool
1834 nios2_tls_symbol_p (rtx x)
1836 return (targetm.have_tls && GET_CODE (x) == SYMBOL_REF
1837 && SYMBOL_REF_TLS_MODEL (x) != 0);
1840 /* Legitimize addresses that are CONSTANT_P expressions. */
1841 static rtx
1842 nios2_legitimize_constant_address (rtx addr)
1844 rtx base, offset;
1845 split_const (addr, &base, &offset);
1847 if (nios2_tls_symbol_p (base))
1848 base = nios2_legitimize_tls_address (base);
1849 else if (flag_pic)
1850 base = nios2_load_pic_address (base, UNSPEC_PIC_SYM, NULL_RTX);
1851 else
1852 return addr;
1854 if (offset != const0_rtx)
1856 gcc_assert (can_create_pseudo_p ());
1857 return gen_rtx_PLUS (Pmode, force_reg (Pmode, base),
1858 (CONST_INT_P (offset)
1859 ? (SMALL_INT (INTVAL (offset))
1860 ? offset : force_reg (Pmode, offset))
1861 : offset));
1863 return base;
1866 /* Implement TARGET_LEGITIMIZE_ADDRESS. */
1867 static rtx
1868 nios2_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
1869 machine_mode mode ATTRIBUTE_UNUSED)
1871 if (CONSTANT_P (x))
1872 return nios2_legitimize_constant_address (x);
1874 /* For the TLS LE (Local Exec) model, the compiler may try to
1875 combine constant offsets with unspec relocs, creating address RTXs
1876 looking like this:
1877 (plus:SI (reg:SI 23 r23)
1878 (const:SI
1879 (plus:SI
1880 (unspec:SI [(symbol_ref:SI ("var"))] UNSPEC_ADD_TLS_LE)
1881 (const_int 48 [0x30]))))
1883 This usually happens when 'var' is a thread-local struct variable,
1884 and access of a field in var causes the addend.
1886 We typically want this combining, so transform the above into this
1887 form, which is allowed:
1888 (plus:SI (reg:SI 23 r23)
1889 (const:SI
1890 (unspec:SI
1891 [(const:SI
1892 (plus:SI (symbol_ref:SI ("var"))
1893 (const_int 48 [0x30])))] UNSPEC_ADD_TLS_LE)))
1895 Which will be output as '%tls_le(var+48)(r23)' in assembly. */
1896 if (GET_CODE (x) == PLUS
1897 && GET_CODE (XEXP (x, 0)) == REG
1898 && GET_CODE (XEXP (x, 1)) == CONST)
1900 rtx unspec, offset, reg = XEXP (x, 0);
1901 split_const (XEXP (x, 1), &unspec, &offset);
1902 if (GET_CODE (unspec) == UNSPEC
1903 && !nios2_large_offset_p (XINT (unspec, 1))
1904 && offset != const0_rtx)
1906 unspec = copy_rtx (unspec);
1907 XVECEXP (unspec, 0, 0)
1908 = plus_constant (Pmode, XVECEXP (unspec, 0, 0), INTVAL (offset));
1909 x = gen_rtx_PLUS (Pmode, reg, gen_rtx_CONST (Pmode, unspec));
1913 return x;
1916 static rtx
1917 nios2_delegitimize_address (rtx x)
1919 x = delegitimize_mem_from_attrs (x);
1921 if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
1923 switch (XINT (XEXP (x, 0), 1))
1925 case UNSPEC_PIC_SYM:
1926 case UNSPEC_PIC_CALL_SYM:
1927 case UNSPEC_PIC_GOTOFF_SYM:
1928 case UNSPEC_ADD_TLS_GD:
1929 case UNSPEC_ADD_TLS_LDM:
1930 case UNSPEC_LOAD_TLS_IE:
1931 case UNSPEC_ADD_TLS_LE:
1932 x = XVECEXP (XEXP (x, 0), 0, 0);
1933 gcc_assert (GET_CODE (x) == SYMBOL_REF);
1934 break;
1937 return x;
1940 /* Main expander function for RTL moves. */
1942 nios2_emit_move_sequence (rtx *operands, machine_mode mode)
1944 rtx to = operands[0];
1945 rtx from = operands[1];
1947 if (!register_operand (to, mode) && !reg_or_0_operand (from, mode))
1949 gcc_assert (can_create_pseudo_p ());
1950 from = copy_to_mode_reg (mode, from);
1953 if (GET_CODE (from) == SYMBOL_REF || GET_CODE (from) == LABEL_REF
1954 || (GET_CODE (from) == CONST
1955 && GET_CODE (XEXP (from, 0)) != UNSPEC))
1956 from = nios2_legitimize_constant_address (from);
1958 operands[0] = to;
1959 operands[1] = from;
1960 return 0;
1963 /* The function with address *ADDR is being called. If the address
1964 needs to be loaded from the GOT, emit the instruction to do so and
1965 update *ADDR to point to the rtx for the loaded value.
1966 If REG != NULL_RTX, it is used as the target/scratch register in the
1967 GOT address calculation. */
1968 void
1969 nios2_adjust_call_address (rtx *call_op, rtx reg)
1971 if (MEM_P (*call_op))
1972 call_op = &XEXP (*call_op, 0);
1974 rtx addr = *call_op;
1975 if (flag_pic && CONSTANT_P (addr))
1977 rtx tmp = reg ? reg : NULL_RTX;
1978 if (!reg)
1979 reg = gen_reg_rtx (Pmode);
1980 addr = nios2_load_pic_address (addr, UNSPEC_PIC_CALL_SYM, tmp);
1981 emit_insn (gen_rtx_SET (reg, addr));
1982 *call_op = reg;
1987 /* Output assembly language related definitions. */
1989 /* Print the operand OP to file stream FILE modified by LETTER.
1990 LETTER can be one of:
1992 i: print "i" if OP is an immediate, except 0
1993 o: print "io" if OP is volatile
1994 z: for const0_rtx print $0 instead of 0
1995 H: for %hiadj
1996 L: for %lo
1997 U: for upper half of 32 bit value
1998 D: for the upper 32-bits of a 64-bit double value
1999 R: prints reverse condition.
2001 static void
2002 nios2_print_operand (FILE *file, rtx op, int letter)
2005 switch (letter)
2007 case 'i':
2008 if (CONSTANT_P (op) && op != const0_rtx)
2009 fprintf (file, "i");
2010 return;
2012 case 'o':
2013 if (GET_CODE (op) == MEM
2014 && ((MEM_VOLATILE_P (op) && TARGET_BYPASS_CACHE_VOLATILE)
2015 || TARGET_BYPASS_CACHE))
2016 fprintf (file, "io");
2017 return;
2019 default:
2020 break;
2023 if (comparison_operator (op, VOIDmode))
2025 enum rtx_code cond = GET_CODE (op);
2026 if (letter == 0)
2028 fprintf (file, "%s", GET_RTX_NAME (cond));
2029 return;
2031 if (letter == 'R')
2033 fprintf (file, "%s", GET_RTX_NAME (reverse_condition (cond)));
2034 return;
2038 switch (GET_CODE (op))
2040 case REG:
2041 if (letter == 0 || letter == 'z')
2043 fprintf (file, "%s", reg_names[REGNO (op)]);
2044 return;
2046 else if (letter == 'D')
2048 fprintf (file, "%s", reg_names[REGNO (op)+1]);
2049 return;
2051 break;
2053 case CONST_INT:
2054 if (INTVAL (op) == 0 && letter == 'z')
2056 fprintf (file, "zero");
2057 return;
2060 if (letter == 'U')
2062 HOST_WIDE_INT val = INTVAL (op);
2063 val = (val >> 16) & 0xFFFF;
2064 output_addr_const (file, gen_int_mode (val, SImode));
2065 return;
2067 /* Else, fall through. */
2069 case CONST:
2070 case LABEL_REF:
2071 case SYMBOL_REF:
2072 case CONST_DOUBLE:
2073 if (letter == 0 || letter == 'z')
2075 output_addr_const (file, op);
2076 return;
2078 else if (letter == 'H' || letter == 'L')
2080 fprintf (file, "%%");
2081 if (GET_CODE (op) == CONST
2082 && GET_CODE (XEXP (op, 0)) == UNSPEC)
2084 rtx unspec = XEXP (op, 0);
2085 int unspec_reloc = XINT (unspec, 1);
2086 gcc_assert (nios2_large_offset_p (unspec_reloc));
2087 fprintf (file, "%s_", nios2_unspec_reloc_name (unspec_reloc));
2088 op = XVECEXP (unspec, 0, 0);
2090 fprintf (file, letter == 'H' ? "hiadj(" : "lo(");
2091 output_addr_const (file, op);
2092 fprintf (file, ")");
2093 return;
2095 break;
2097 case SUBREG:
2098 case MEM:
2099 if (letter == 0)
2101 output_address (op);
2102 return;
2104 break;
2106 case CODE_LABEL:
2107 if (letter == 0)
2109 output_addr_const (file, op);
2110 return;
2112 break;
2114 default:
2115 break;
2118 output_operand_lossage ("Unsupported operand for code '%c'", letter);
2119 gcc_unreachable ();
2122 /* Return true if this is a GP-relative accessible reference. */
2123 static bool
2124 gprel_constant_p (rtx op)
2126 if (GET_CODE (op) == SYMBOL_REF
2127 && nios2_symbol_ref_in_small_data_p (op))
2128 return true;
2129 else if (GET_CODE (op) == CONST
2130 && GET_CODE (XEXP (op, 0)) == PLUS)
2131 return gprel_constant_p (XEXP (XEXP (op, 0), 0));
2133 return false;
2136 /* Return the name string for a supported unspec reloc offset. */
2137 static const char *
2138 nios2_unspec_reloc_name (int unspec)
2140 switch (unspec)
2142 case UNSPEC_PIC_SYM:
2143 return "got";
2144 case UNSPEC_PIC_CALL_SYM:
2145 return "call";
2146 case UNSPEC_PIC_GOTOFF_SYM:
2147 return "gotoff";
2148 case UNSPEC_LOAD_TLS_IE:
2149 return "tls_ie";
2150 case UNSPEC_ADD_TLS_LE:
2151 return "tls_le";
2152 case UNSPEC_ADD_TLS_GD:
2153 return "tls_gd";
2154 case UNSPEC_ADD_TLS_LDM:
2155 return "tls_ldm";
2156 case UNSPEC_ADD_TLS_LDO:
2157 return "tls_ldo";
2158 default:
2159 return NULL;
2163 /* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */
2164 static bool
2165 nios2_output_addr_const_extra (FILE *file, rtx op)
2167 const char *name;
2168 gcc_assert (GET_CODE (op) == UNSPEC);
2170 /* Support for printing out const unspec relocations. */
2171 name = nios2_unspec_reloc_name (XINT (op, 1));
2172 if (name)
2174 fprintf (file, "%%%s(", name);
2175 output_addr_const (file, XVECEXP (op, 0, 0));
2176 fprintf (file, ")");
2177 return true;
2179 return false;
2182 /* Implement TARGET_PRINT_OPERAND_ADDRESS. */
2183 static void
2184 nios2_print_operand_address (FILE *file, rtx op)
2186 switch (GET_CODE (op))
2188 case CONST:
2189 case CONST_INT:
2190 case LABEL_REF:
2191 case CONST_DOUBLE:
2192 case SYMBOL_REF:
2193 if (gprel_constant_p (op))
2195 fprintf (file, "%%gprel(");
2196 output_addr_const (file, op);
2197 fprintf (file, ")(%s)", reg_names[GP_REGNO]);
2198 return;
2201 break;
2203 case PLUS:
2205 rtx op0 = XEXP (op, 0);
2206 rtx op1 = XEXP (op, 1);
2208 if (REG_P (op0) && CONSTANT_P (op1))
2210 output_addr_const (file, op1);
2211 fprintf (file, "(%s)", reg_names[REGNO (op0)]);
2212 return;
2214 else if (REG_P (op1) && CONSTANT_P (op0))
2216 output_addr_const (file, op0);
2217 fprintf (file, "(%s)", reg_names[REGNO (op1)]);
2218 return;
2221 break;
2223 case REG:
2224 fprintf (file, "0(%s)", reg_names[REGNO (op)]);
2225 return;
2227 case MEM:
2229 rtx base = XEXP (op, 0);
2230 nios2_print_operand_address (file, base);
2231 return;
2233 default:
2234 break;
2237 fprintf (stderr, "Missing way to print address\n");
2238 debug_rtx (op);
2239 gcc_unreachable ();
2242 /* Implement TARGET_ASM_OUTPUT_DWARF_DTPREL. */
2243 static void
2244 nios2_output_dwarf_dtprel (FILE *file, int size, rtx x)
2246 gcc_assert (size == 4);
2247 fprintf (file, "\t.4byte\t%%tls_ldo(");
2248 output_addr_const (file, x);
2249 fprintf (file, ")");
2252 /* Implemet TARGET_ASM_FILE_END. */
2254 static void
2255 nios2_asm_file_end (void)
2257 /* The Nios II Linux stack is mapped non-executable by default, so add a
2258 .note.GNU-stack section for switching to executable stacks only when
2259 trampolines are generated. */
2260 if (TARGET_LINUX_ABI && trampolines_created)
2261 file_end_indicate_exec_stack ();
2264 /* Implement TARGET_ASM_FUNCTION_PROLOGUE. */
2265 static void
2266 nios2_asm_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
2268 if (flag_verbose_asm || flag_debug_asm)
2270 nios2_compute_frame_layout ();
2271 nios2_dump_frame_layout (file);
2275 /* Emit assembly of custom FPU instructions. */
2276 const char *
2277 nios2_fpu_insn_asm (enum n2fpu_code code)
2279 static char buf[256];
2280 const char *op1, *op2, *op3;
2281 int ln = 256, n = 0;
2283 int N = N2FPU_N (code);
2284 int num_operands = N2FPU (code).num_operands;
2285 const char *insn_name = N2FPU_NAME (code);
2286 tree ftype = nios2_ftype (N2FPU_FTCODE (code));
2287 machine_mode dst_mode = TYPE_MODE (TREE_TYPE (ftype));
2288 machine_mode src_mode = TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (ftype)));
2290 /* Prepare X register for DF input operands. */
2291 if (GET_MODE_SIZE (src_mode) == 8 && num_operands == 3)
2292 n = snprintf (buf, ln, "custom\t%d, zero, %%1, %%D1 # fwrx %%1\n\t",
2293 N2FPU_N (n2fpu_fwrx));
2295 if (src_mode == SFmode)
2297 if (dst_mode == VOIDmode)
2299 /* The fwry case. */
2300 op1 = op3 = "zero";
2301 op2 = "%0";
2302 num_operands -= 1;
2304 else
2306 op1 = (dst_mode == DFmode ? "%D0" : "%0");
2307 op2 = "%1";
2308 op3 = (num_operands == 2 ? "zero" : "%2");
2311 else if (src_mode == DFmode)
2313 if (dst_mode == VOIDmode)
2315 /* The fwrx case. */
2316 op1 = "zero";
2317 op2 = "%0";
2318 op3 = "%D0";
2319 num_operands -= 1;
2321 else
2323 op1 = (dst_mode == DFmode ? "%D0" : "%0");
2324 op2 = (num_operands == 2 ? "%1" : "%2");
2325 op3 = (num_operands == 2 ? "%D1" : "%D2");
2328 else if (src_mode == VOIDmode)
2330 /* frdxlo, frdxhi, frdy cases. */
2331 gcc_assert (dst_mode == SFmode);
2332 op1 = "%0";
2333 op2 = op3 = "zero";
2335 else if (src_mode == SImode)
2337 /* Conversion operators. */
2338 gcc_assert (num_operands == 2);
2339 op1 = (dst_mode == DFmode ? "%D0" : "%0");
2340 op2 = "%1";
2341 op3 = "zero";
2343 else
2344 gcc_unreachable ();
2346 /* Main instruction string. */
2347 n += snprintf (buf + n, ln - n, "custom\t%d, %s, %s, %s # %s %%0%s%s",
2348 N, op1, op2, op3, insn_name,
2349 (num_operands >= 2 ? ", %1" : ""),
2350 (num_operands == 3 ? ", %2" : ""));
2352 /* Extraction of Y register for DF results. */
2353 if (dst_mode == DFmode)
2354 snprintf (buf + n, ln - n, "\n\tcustom\t%d, %%0, zero, zero # frdy %%0",
2355 N2FPU_N (n2fpu_frdy));
2356 return buf;
2361 /* Function argument related. */
2363 /* Define where to put the arguments to a function. Value is zero to
2364 push the argument on the stack, or a hard register in which to
2365 store the argument.
2367 MODE is the argument's machine mode.
2368 TYPE is the data type of the argument (as a tree).
2369 This is null for libcalls where that information may
2370 not be available.
2371 CUM is a variable of type CUMULATIVE_ARGS which gives info about
2372 the preceding args and about the function being called.
2373 NAMED is nonzero if this argument is a named parameter
2374 (otherwise it is an extra parameter matching an ellipsis). */
2376 static rtx
2377 nios2_function_arg (cumulative_args_t cum_v, machine_mode mode,
2378 const_tree type ATTRIBUTE_UNUSED,
2379 bool named ATTRIBUTE_UNUSED)
2381 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2382 rtx return_rtx = NULL_RTX;
2384 if (cum->regs_used < NUM_ARG_REGS)
2385 return_rtx = gen_rtx_REG (mode, FIRST_ARG_REGNO + cum->regs_used);
2387 return return_rtx;
2390 /* Return number of bytes, at the beginning of the argument, that must be
2391 put in registers. 0 is the argument is entirely in registers or entirely
2392 in memory. */
2394 static int
2395 nios2_arg_partial_bytes (cumulative_args_t cum_v,
2396 machine_mode mode, tree type ATTRIBUTE_UNUSED,
2397 bool named ATTRIBUTE_UNUSED)
2399 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2400 HOST_WIDE_INT param_size;
2402 if (mode == BLKmode)
2404 param_size = int_size_in_bytes (type);
2405 gcc_assert (param_size >= 0);
2407 else
2408 param_size = GET_MODE_SIZE (mode);
2410 /* Convert to words (round up). */
2411 param_size = (UNITS_PER_WORD - 1 + param_size) / UNITS_PER_WORD;
2413 if (cum->regs_used < NUM_ARG_REGS
2414 && cum->regs_used + param_size > NUM_ARG_REGS)
2415 return (NUM_ARG_REGS - cum->regs_used) * UNITS_PER_WORD;
2417 return 0;
2420 /* Update the data in CUM to advance over an argument of mode MODE
2421 and data type TYPE; TYPE is null for libcalls where that information
2422 may not be available. */
2424 static void
2425 nios2_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
2426 const_tree type ATTRIBUTE_UNUSED,
2427 bool named ATTRIBUTE_UNUSED)
2429 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2430 HOST_WIDE_INT param_size;
2432 if (mode == BLKmode)
2434 param_size = int_size_in_bytes (type);
2435 gcc_assert (param_size >= 0);
2437 else
2438 param_size = GET_MODE_SIZE (mode);
2440 /* Convert to words (round up). */
2441 param_size = (UNITS_PER_WORD - 1 + param_size) / UNITS_PER_WORD;
2443 if (cum->regs_used + param_size > NUM_ARG_REGS)
2444 cum->regs_used = NUM_ARG_REGS;
2445 else
2446 cum->regs_used += param_size;
2449 enum direction
2450 nios2_function_arg_padding (machine_mode mode, const_tree type)
2452 /* On little-endian targets, the first byte of every stack argument
2453 is passed in the first byte of the stack slot. */
2454 if (!BYTES_BIG_ENDIAN)
2455 return upward;
2457 /* Otherwise, integral types are padded downward: the last byte of a
2458 stack argument is passed in the last byte of the stack slot. */
2459 if (type != 0
2460 ? INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)
2461 : GET_MODE_CLASS (mode) == MODE_INT)
2462 return downward;
2464 /* Arguments smaller than a stack slot are padded downward. */
2465 if (mode != BLKmode)
2466 return (GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY) ? upward : downward;
2468 return ((int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT))
2469 ? upward : downward);
2472 enum direction
2473 nios2_block_reg_padding (machine_mode mode, tree type,
2474 int first ATTRIBUTE_UNUSED)
2476 return nios2_function_arg_padding (mode, type);
2479 /* Emit RTL insns to initialize the variable parts of a trampoline.
2480 FNADDR is an RTX for the address of the function's pure code.
2481 CXT is an RTX for the static chain value for the function.
2482 On Nios II, we handle this by a library call. */
2483 static void
2484 nios2_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
2486 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
2487 rtx ctx_reg = force_reg (Pmode, cxt);
2488 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
2490 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
2491 LCT_NORMAL, VOIDmode, 3, addr, Pmode, fnaddr, Pmode,
2492 ctx_reg, Pmode);
2495 /* Implement TARGET_FUNCTION_VALUE. */
2496 static rtx
2497 nios2_function_value (const_tree ret_type, const_tree fn ATTRIBUTE_UNUSED,
2498 bool outgoing ATTRIBUTE_UNUSED)
2500 return gen_rtx_REG (TYPE_MODE (ret_type), FIRST_RETVAL_REGNO);
2503 /* Implement TARGET_LIBCALL_VALUE. */
2504 static rtx
2505 nios2_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
2507 return gen_rtx_REG (mode, FIRST_RETVAL_REGNO);
2510 /* Implement TARGET_FUNCTION_VALUE_REGNO_P. */
2511 static bool
2512 nios2_function_value_regno_p (const unsigned int regno)
2514 return regno == FIRST_RETVAL_REGNO;
2517 /* Implement TARGET_RETURN_IN_MEMORY. */
2518 static bool
2519 nios2_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
2521 return (int_size_in_bytes (type) > (2 * UNITS_PER_WORD)
2522 || int_size_in_bytes (type) == -1);
2525 /* TODO: It may be possible to eliminate the copyback and implement
2526 own va_arg type. */
2527 static void
2528 nios2_setup_incoming_varargs (cumulative_args_t cum_v,
2529 machine_mode mode, tree type,
2530 int *pretend_size, int second_time)
2532 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2533 CUMULATIVE_ARGS local_cum;
2534 cumulative_args_t local_cum_v = pack_cumulative_args (&local_cum);
2535 int regs_to_push;
2536 int pret_size;
2538 local_cum = *cum;
2539 nios2_function_arg_advance (local_cum_v, mode, type, 1);
2541 regs_to_push = NUM_ARG_REGS - local_cum.regs_used;
2543 if (!second_time && regs_to_push > 0)
2545 rtx ptr = virtual_incoming_args_rtx;
2546 rtx mem = gen_rtx_MEM (BLKmode, ptr);
2547 emit_insn (gen_blockage ());
2548 move_block_from_reg (local_cum.regs_used + FIRST_ARG_REGNO, mem,
2549 regs_to_push);
2550 emit_insn (gen_blockage ());
2553 pret_size = regs_to_push * UNITS_PER_WORD;
2554 if (pret_size)
2555 *pretend_size = pret_size;
2560 /* Init FPU builtins. */
2561 static void
2562 nios2_init_fpu_builtins (int start_code)
2564 tree fndecl;
2565 char builtin_name[64] = "__builtin_custom_";
2566 unsigned int i, n = strlen ("__builtin_custom_");
2568 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
2570 snprintf (builtin_name + n, sizeof (builtin_name) - n,
2571 "%s", N2FPU_NAME (i));
2572 fndecl =
2573 add_builtin_function (builtin_name, nios2_ftype (N2FPU_FTCODE (i)),
2574 start_code + i, BUILT_IN_MD, NULL, NULL_TREE);
2575 nios2_register_builtin_fndecl (start_code + i, fndecl);
2579 /* Helper function for expanding FPU builtins. */
2580 static rtx
2581 nios2_expand_fpu_builtin (tree exp, unsigned int code, rtx target)
2583 struct expand_operand ops[MAX_RECOG_OPERANDS];
2584 enum insn_code icode = N2FPU_ICODE (code);
2585 int nargs, argno, opno = 0;
2586 int num_operands = N2FPU (code).num_operands;
2587 machine_mode dst_mode = TYPE_MODE (TREE_TYPE (exp));
2588 bool has_target_p = (dst_mode != VOIDmode);
2590 if (N2FPU_N (code) < 0)
2591 fatal_error (input_location,
2592 "Cannot call %<__builtin_custom_%s%> without specifying switch"
2593 " %<-mcustom-%s%>", N2FPU_NAME (code), N2FPU_NAME (code));
2594 if (has_target_p)
2595 create_output_operand (&ops[opno++], target, dst_mode);
2596 else
2597 /* Subtract away the count of the VOID return, mainly for fwrx/fwry. */
2598 num_operands -= 1;
2599 nargs = call_expr_nargs (exp);
2600 for (argno = 0; argno < nargs; argno++)
2602 tree arg = CALL_EXPR_ARG (exp, argno);
2603 create_input_operand (&ops[opno++], expand_normal (arg),
2604 TYPE_MODE (TREE_TYPE (arg)));
2606 if (!maybe_expand_insn (icode, num_operands, ops))
2608 error ("invalid argument to built-in function");
2609 return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
2611 return has_target_p ? ops[0].value : const0_rtx;
2614 /* Nios II has custom instruction built-in functions of the forms:
2615 __builtin_custom_n
2616 __builtin_custom_nX
2617 __builtin_custom_nXX
2618 __builtin_custom_Xn
2619 __builtin_custom_XnX
2620 __builtin_custom_XnXX
2622 where each X could be either 'i' (int), 'f' (float), or 'p' (void*).
2623 Therefore with 0-1 return values, and 0-2 arguments, we have a
2624 total of (3 + 1) * (1 + 3 + 9) == 52 custom builtin functions.
2626 #define NUM_CUSTOM_BUILTINS ((3 + 1) * (1 + 3 + 9))
2627 static char custom_builtin_name[NUM_CUSTOM_BUILTINS][5];
2629 static void
2630 nios2_init_custom_builtins (int start_code)
2632 tree builtin_ftype, ret_type, fndecl;
2633 char builtin_name[32] = "__builtin_custom_";
2634 int n = strlen ("__builtin_custom_");
2635 int builtin_code = 0;
2636 int lhs, rhs1, rhs2;
2638 struct { tree type; const char *c; } op[4];
2639 /* z */ op[0].c = ""; op[0].type = NULL_TREE;
2640 /* f */ op[1].c = "f"; op[1].type = float_type_node;
2641 /* i */ op[2].c = "i"; op[2].type = integer_type_node;
2642 /* p */ op[3].c = "p"; op[3].type = ptr_type_node;
2644 /* We enumerate through the possible operand types to create all the
2645 __builtin_custom_XnXX function tree types. Note that these may slightly
2646 overlap with the function types created for other fixed builtins. */
2648 for (lhs = 0; lhs < 4; lhs++)
2649 for (rhs1 = 0; rhs1 < 4; rhs1++)
2650 for (rhs2 = 0; rhs2 < 4; rhs2++)
2652 if (rhs1 == 0 && rhs2 != 0)
2653 continue;
2654 ret_type = (op[lhs].type ? op[lhs].type : void_type_node);
2655 builtin_ftype
2656 = build_function_type_list (ret_type, integer_type_node,
2657 op[rhs1].type, op[rhs2].type,
2658 NULL_TREE);
2659 snprintf (builtin_name + n, 32 - n, "%sn%s%s",
2660 op[lhs].c, op[rhs1].c, op[rhs2].c);
2661 /* Save copy of parameter string into custom_builtin_name[]. */
2662 strncpy (custom_builtin_name[builtin_code], builtin_name + n, 5);
2663 fndecl =
2664 add_builtin_function (builtin_name, builtin_ftype,
2665 start_code + builtin_code,
2666 BUILT_IN_MD, NULL, NULL_TREE);
2667 nios2_register_builtin_fndecl (start_code + builtin_code, fndecl);
2668 builtin_code += 1;
2672 /* Helper function for expanding custom builtins. */
2673 static rtx
2674 nios2_expand_custom_builtin (tree exp, unsigned int index, rtx target)
2676 bool has_target_p = (TREE_TYPE (exp) != void_type_node);
2677 machine_mode tmode = VOIDmode;
2678 int nargs, argno;
2679 rtx value, insn, unspec_args[3];
2680 tree arg;
2682 /* XnXX form. */
2683 if (has_target_p)
2685 tmode = TYPE_MODE (TREE_TYPE (exp));
2686 if (!target || GET_MODE (target) != tmode
2687 || !REG_P (target))
2688 target = gen_reg_rtx (tmode);
2691 nargs = call_expr_nargs (exp);
2692 for (argno = 0; argno < nargs; argno++)
2694 arg = CALL_EXPR_ARG (exp, argno);
2695 value = expand_normal (arg);
2696 unspec_args[argno] = value;
2697 if (argno == 0)
2699 if (!custom_insn_opcode (value, VOIDmode))
2700 error ("custom instruction opcode must be compile time "
2701 "constant in the range 0-255 for __builtin_custom_%s",
2702 custom_builtin_name[index]);
2704 else
2705 /* For other arguments, force into a register. */
2706 unspec_args[argno] = force_reg (TYPE_MODE (TREE_TYPE (arg)),
2707 unspec_args[argno]);
2709 /* Fill remaining unspec operands with zero. */
2710 for (; argno < 3; argno++)
2711 unspec_args[argno] = const0_rtx;
2713 insn = (has_target_p
2714 ? gen_rtx_SET (target,
2715 gen_rtx_UNSPEC_VOLATILE (tmode,
2716 gen_rtvec_v (3, unspec_args),
2717 UNSPECV_CUSTOM_XNXX))
2718 : gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec_v (3, unspec_args),
2719 UNSPECV_CUSTOM_NXX));
2720 emit_insn (insn);
2721 return has_target_p ? target : const0_rtx;
2727 /* Main definition of built-in functions. Nios II has a small number of fixed
2728 builtins, plus a large number of FPU insn builtins, and builtins for
2729 generating custom instructions. */
2731 struct nios2_builtin_desc
2733 enum insn_code icode;
2734 enum nios2_ftcode ftype;
2735 const char *name;
2738 #define N2_BUILTINS \
2739 N2_BUILTIN_DEF (sync, N2_FTYPE_VOID_VOID) \
2740 N2_BUILTIN_DEF (ldbio, N2_FTYPE_SI_CVPTR) \
2741 N2_BUILTIN_DEF (ldbuio, N2_FTYPE_UI_CVPTR) \
2742 N2_BUILTIN_DEF (ldhio, N2_FTYPE_SI_CVPTR) \
2743 N2_BUILTIN_DEF (ldhuio, N2_FTYPE_UI_CVPTR) \
2744 N2_BUILTIN_DEF (ldwio, N2_FTYPE_SI_CVPTR) \
2745 N2_BUILTIN_DEF (stbio, N2_FTYPE_VOID_VPTR_SI) \
2746 N2_BUILTIN_DEF (sthio, N2_FTYPE_VOID_VPTR_SI) \
2747 N2_BUILTIN_DEF (stwio, N2_FTYPE_VOID_VPTR_SI) \
2748 N2_BUILTIN_DEF (rdctl, N2_FTYPE_SI_SI) \
2749 N2_BUILTIN_DEF (wrctl, N2_FTYPE_VOID_SI_SI)
2751 enum nios2_builtin_code {
2752 #define N2_BUILTIN_DEF(name, ftype) NIOS2_BUILTIN_ ## name,
2753 N2_BUILTINS
2754 #undef N2_BUILTIN_DEF
2755 NUM_FIXED_NIOS2_BUILTINS
2758 static const struct nios2_builtin_desc nios2_builtins[] = {
2759 #define N2_BUILTIN_DEF(name, ftype) \
2760 { CODE_FOR_ ## name, ftype, "__builtin_" #name },
2761 N2_BUILTINS
2762 #undef N2_BUILTIN_DEF
2765 /* Start/ends of FPU/custom insn builtin index ranges. */
2766 static unsigned int nios2_fpu_builtin_base;
2767 static unsigned int nios2_custom_builtin_base;
2768 static unsigned int nios2_custom_builtin_end;
2770 /* Implement TARGET_INIT_BUILTINS. */
2771 static void
2772 nios2_init_builtins (void)
2774 unsigned int i;
2776 /* Initialize fixed builtins. */
2777 for (i = 0; i < ARRAY_SIZE (nios2_builtins); i++)
2779 const struct nios2_builtin_desc *d = &nios2_builtins[i];
2780 tree fndecl =
2781 add_builtin_function (d->name, nios2_ftype (d->ftype), i,
2782 BUILT_IN_MD, NULL, NULL);
2783 nios2_register_builtin_fndecl (i, fndecl);
2786 /* Initialize FPU builtins. */
2787 nios2_fpu_builtin_base = ARRAY_SIZE (nios2_builtins);
2788 nios2_init_fpu_builtins (nios2_fpu_builtin_base);
2790 /* Initialize custom insn builtins. */
2791 nios2_custom_builtin_base
2792 = nios2_fpu_builtin_base + ARRAY_SIZE (nios2_fpu_insn);
2793 nios2_custom_builtin_end
2794 = nios2_custom_builtin_base + NUM_CUSTOM_BUILTINS;
2795 nios2_init_custom_builtins (nios2_custom_builtin_base);
2798 /* Array of fndecls for TARGET_BUILTIN_DECL. */
2799 #define NIOS2_NUM_BUILTINS \
2800 (ARRAY_SIZE (nios2_builtins) + ARRAY_SIZE (nios2_fpu_insn) + NUM_CUSTOM_BUILTINS)
2801 static GTY(()) tree nios2_builtin_decls[NIOS2_NUM_BUILTINS];
2803 static void
2804 nios2_register_builtin_fndecl (unsigned code, tree fndecl)
2806 nios2_builtin_decls[code] = fndecl;
2809 /* Implement TARGET_BUILTIN_DECL. */
2810 static tree
2811 nios2_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
2813 gcc_assert (nios2_custom_builtin_end == ARRAY_SIZE (nios2_builtin_decls));
2815 if (code >= nios2_custom_builtin_end)
2816 return error_mark_node;
2818 if (code >= nios2_fpu_builtin_base
2819 && code < nios2_custom_builtin_base
2820 && ! N2FPU_ENABLED_P (code - nios2_fpu_builtin_base))
2821 return error_mark_node;
2823 return nios2_builtin_decls[code];
2827 /* Low-level built-in expand routine. */
2828 static rtx
2829 nios2_expand_builtin_insn (const struct nios2_builtin_desc *d, int n,
2830 struct expand_operand *ops, bool has_target_p)
2832 if (maybe_expand_insn (d->icode, n, ops))
2833 return has_target_p ? ops[0].value : const0_rtx;
2834 else
2836 error ("invalid argument to built-in function %s", d->name);
2837 return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
2841 /* Expand ldio/stio form load-store instruction builtins. */
2842 static rtx
2843 nios2_expand_ldstio_builtin (tree exp, rtx target,
2844 const struct nios2_builtin_desc *d)
2846 bool has_target_p;
2847 rtx addr, mem, val;
2848 struct expand_operand ops[MAX_RECOG_OPERANDS];
2849 machine_mode mode = insn_data[d->icode].operand[0].mode;
2851 addr = expand_normal (CALL_EXPR_ARG (exp, 0));
2852 mem = gen_rtx_MEM (mode, addr);
2854 if (insn_data[d->icode].operand[0].allows_mem)
2856 /* stxio. */
2857 val = expand_normal (CALL_EXPR_ARG (exp, 1));
2858 if (CONST_INT_P (val))
2859 val = force_reg (mode, gen_int_mode (INTVAL (val), mode));
2860 val = simplify_gen_subreg (mode, val, GET_MODE (val), 0);
2861 create_output_operand (&ops[0], mem, mode);
2862 create_input_operand (&ops[1], val, mode);
2863 has_target_p = false;
2865 else
2867 /* ldxio. */
2868 create_output_operand (&ops[0], target, mode);
2869 create_input_operand (&ops[1], mem, mode);
2870 has_target_p = true;
2872 return nios2_expand_builtin_insn (d, 2, ops, has_target_p);
2875 /* Expand rdctl/wrctl builtins. */
2876 static rtx
2877 nios2_expand_rdwrctl_builtin (tree exp, rtx target,
2878 const struct nios2_builtin_desc *d)
2880 bool has_target_p = (insn_data[d->icode].operand[0].predicate
2881 == register_operand);
2882 rtx ctlcode = expand_normal (CALL_EXPR_ARG (exp, 0));
2883 struct expand_operand ops[MAX_RECOG_OPERANDS];
2884 if (!rdwrctl_operand (ctlcode, VOIDmode))
2886 error ("Control register number must be in range 0-31 for %s",
2887 d->name);
2888 return has_target_p ? gen_reg_rtx (SImode) : const0_rtx;
2890 if (has_target_p)
2892 create_output_operand (&ops[0], target, SImode);
2893 create_integer_operand (&ops[1], INTVAL (ctlcode));
2895 else
2897 rtx val = expand_normal (CALL_EXPR_ARG (exp, 1));
2898 create_integer_operand (&ops[0], INTVAL (ctlcode));
2899 create_input_operand (&ops[1], val, SImode);
2901 return nios2_expand_builtin_insn (d, 2, ops, has_target_p);
2904 /* Implement TARGET_EXPAND_BUILTIN. Expand an expression EXP that calls
2905 a built-in function, with result going to TARGET if that's convenient
2906 (and in mode MODE if that's convenient).
2907 SUBTARGET may be used as the target for computing one of EXP's operands.
2908 IGNORE is nonzero if the value is to be ignored. */
2910 static rtx
2911 nios2_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
2912 machine_mode mode ATTRIBUTE_UNUSED,
2913 int ignore ATTRIBUTE_UNUSED)
2915 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2916 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
2918 if (fcode < nios2_fpu_builtin_base)
2920 const struct nios2_builtin_desc *d = &nios2_builtins[fcode];
2922 switch (fcode)
2924 case NIOS2_BUILTIN_sync:
2925 emit_insn (gen_sync ());
2926 return const0_rtx;
2928 case NIOS2_BUILTIN_ldbio:
2929 case NIOS2_BUILTIN_ldbuio:
2930 case NIOS2_BUILTIN_ldhio:
2931 case NIOS2_BUILTIN_ldhuio:
2932 case NIOS2_BUILTIN_ldwio:
2933 case NIOS2_BUILTIN_stbio:
2934 case NIOS2_BUILTIN_sthio:
2935 case NIOS2_BUILTIN_stwio:
2936 return nios2_expand_ldstio_builtin (exp, target, d);
2938 case NIOS2_BUILTIN_rdctl:
2939 case NIOS2_BUILTIN_wrctl:
2940 return nios2_expand_rdwrctl_builtin (exp, target, d);
2942 default:
2943 gcc_unreachable ();
2946 else if (fcode < nios2_custom_builtin_base)
2947 /* FPU builtin range. */
2948 return nios2_expand_fpu_builtin (exp, fcode - nios2_fpu_builtin_base,
2949 target);
2950 else if (fcode < nios2_custom_builtin_end)
2951 /* Custom insn builtin range. */
2952 return nios2_expand_custom_builtin (exp, fcode - nios2_custom_builtin_base,
2953 target);
2954 else
2955 gcc_unreachable ();
2958 /* Implement TARGET_INIT_LIBFUNCS. */
2959 static void
2960 nios2_init_libfuncs (void)
2962 /* For Linux, we have access to kernel support for atomic operations. */
2963 if (TARGET_LINUX_ABI)
2964 init_sync_libfuncs (UNITS_PER_WORD);
2969 /* Register a custom code use, and signal error if a conflict was found. */
2970 static void
2971 nios2_register_custom_code (unsigned int N, enum nios2_ccs_code status,
2972 int index)
2974 gcc_assert (N <= 255);
2976 if (status == CCS_FPU)
2978 if (custom_code_status[N] == CCS_FPU && index != custom_code_index[N])
2980 custom_code_conflict = true;
2981 error ("switch %<-mcustom-%s%> conflicts with switch %<-mcustom-%s%>",
2982 N2FPU_NAME (custom_code_index[N]), N2FPU_NAME (index));
2984 else if (custom_code_status[N] == CCS_BUILTIN_CALL)
2986 custom_code_conflict = true;
2987 error ("call to %<__builtin_custom_%s%> conflicts with switch "
2988 "%<-mcustom-%s%>", custom_builtin_name[custom_code_index[N]],
2989 N2FPU_NAME (index));
2992 else if (status == CCS_BUILTIN_CALL)
2994 if (custom_code_status[N] == CCS_FPU)
2996 custom_code_conflict = true;
2997 error ("call to %<__builtin_custom_%s%> conflicts with switch "
2998 "%<-mcustom-%s%>", custom_builtin_name[index],
2999 N2FPU_NAME (custom_code_index[N]));
3001 else
3003 /* Note that code conflicts between different __builtin_custom_xnxx
3004 calls are not checked. */
3007 else
3008 gcc_unreachable ();
3010 custom_code_status[N] = status;
3011 custom_code_index[N] = index;
3014 /* Mark a custom code as not in use. */
3015 static void
3016 nios2_deregister_custom_code (unsigned int N)
3018 if (N <= 255)
3020 custom_code_status[N] = CCS_UNUSED;
3021 custom_code_index[N] = 0;
3025 /* Target attributes can affect per-function option state, so we need to
3026 save/restore the custom code tracking info using the
3027 TARGET_OPTION_SAVE/TARGET_OPTION_RESTORE hooks. */
3029 static void
3030 nios2_option_save (struct cl_target_option *ptr,
3031 struct gcc_options *opts ATTRIBUTE_UNUSED)
3033 unsigned int i;
3034 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
3035 ptr->saved_fpu_custom_code[i] = N2FPU_N (i);
3036 memcpy (ptr->saved_custom_code_status, custom_code_status,
3037 sizeof (custom_code_status));
3038 memcpy (ptr->saved_custom_code_index, custom_code_index,
3039 sizeof (custom_code_index));
3042 static void
3043 nios2_option_restore (struct gcc_options *opts ATTRIBUTE_UNUSED,
3044 struct cl_target_option *ptr)
3046 unsigned int i;
3047 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
3048 N2FPU_N (i) = ptr->saved_fpu_custom_code[i];
3049 memcpy (custom_code_status, ptr->saved_custom_code_status,
3050 sizeof (custom_code_status));
3051 memcpy (custom_code_index, ptr->saved_custom_code_index,
3052 sizeof (custom_code_index));
3055 /* Inner function to process the attribute((target(...))), take an argument and
3056 set the current options from the argument. If we have a list, recursively
3057 go over the list. */
3059 static bool
3060 nios2_valid_target_attribute_rec (tree args)
3062 if (TREE_CODE (args) == TREE_LIST)
3064 bool ret = true;
3065 for (; args; args = TREE_CHAIN (args))
3066 if (TREE_VALUE (args)
3067 && !nios2_valid_target_attribute_rec (TREE_VALUE (args)))
3068 ret = false;
3069 return ret;
3071 else if (TREE_CODE (args) == STRING_CST)
3073 char *argstr = ASTRDUP (TREE_STRING_POINTER (args));
3074 while (argstr && *argstr != '\0')
3076 bool no_opt = false, end_p = false;
3077 char *eq = NULL, *p;
3078 while (ISSPACE (*argstr))
3079 argstr++;
3080 p = argstr;
3081 while (*p != '\0' && *p != ',')
3083 if (!eq && *p == '=')
3084 eq = p;
3085 ++p;
3087 if (*p == '\0')
3088 end_p = true;
3089 else
3090 *p = '\0';
3091 if (eq) *eq = '\0';
3093 if (!strncmp (argstr, "no-", 3))
3095 no_opt = true;
3096 argstr += 3;
3098 if (!strncmp (argstr, "custom-fpu-cfg", 14))
3100 char *end_eq = p;
3101 if (no_opt)
3103 error ("custom-fpu-cfg option does not support %<no-%>");
3104 return false;
3106 if (!eq)
3108 error ("custom-fpu-cfg option requires configuration"
3109 " argument");
3110 return false;
3112 /* Increment and skip whitespace. */
3113 while (ISSPACE (*(++eq))) ;
3114 /* Decrement and skip to before any trailing whitespace. */
3115 while (ISSPACE (*(--end_eq))) ;
3117 nios2_handle_custom_fpu_cfg (eq, end_eq + 1, true);
3119 else if (!strncmp (argstr, "custom-", 7))
3121 int code = -1;
3122 unsigned int i;
3123 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
3124 if (!strncmp (argstr + 7, N2FPU_NAME (i),
3125 strlen (N2FPU_NAME (i))))
3127 /* Found insn. */
3128 code = i;
3129 break;
3131 if (code >= 0)
3133 if (no_opt)
3135 if (eq)
3137 error ("%<no-custom-%s%> does not accept arguments",
3138 N2FPU_NAME (code));
3139 return false;
3141 /* Disable option by setting to -1. */
3142 nios2_deregister_custom_code (N2FPU_N (code));
3143 N2FPU_N (code) = -1;
3145 else
3147 char *t;
3148 if (eq)
3149 while (ISSPACE (*(++eq))) ;
3150 if (!eq || eq == p)
3152 error ("%<custom-%s=%> requires argument",
3153 N2FPU_NAME (code));
3154 return false;
3156 for (t = eq; t != p; ++t)
3158 if (ISSPACE (*t))
3159 continue;
3160 if (!ISDIGIT (*t))
3162 error ("`custom-%s=' argument requires "
3163 "numeric digits", N2FPU_NAME (code));
3164 return false;
3167 /* Set option to argument. */
3168 N2FPU_N (code) = atoi (eq);
3169 nios2_handle_custom_fpu_insn_option (code);
3172 else
3174 error ("%<custom-%s=%> is not recognised as FPU instruction",
3175 argstr + 7);
3176 return false;
3179 else
3181 error ("%<%s%> is unknown", argstr);
3182 return false;
3185 if (end_p)
3186 break;
3187 else
3188 argstr = p + 1;
3190 return true;
3192 else
3193 gcc_unreachable ();
3196 /* Return a TARGET_OPTION_NODE tree of the target options listed or NULL. */
3198 static tree
3199 nios2_valid_target_attribute_tree (tree args)
3201 if (!nios2_valid_target_attribute_rec (args))
3202 return NULL_TREE;
3203 nios2_custom_check_insns ();
3204 return build_target_option_node (&global_options);
3207 /* Hook to validate attribute((target("string"))). */
3209 static bool
3210 nios2_valid_target_attribute_p (tree fndecl, tree ARG_UNUSED (name),
3211 tree args, int ARG_UNUSED (flags))
3213 struct cl_target_option cur_target;
3214 bool ret = true;
3215 tree old_optimize = build_optimization_node (&global_options);
3216 tree new_target, new_optimize;
3217 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
3219 /* If the function changed the optimization levels as well as setting target
3220 options, start with the optimizations specified. */
3221 if (func_optimize && func_optimize != old_optimize)
3222 cl_optimization_restore (&global_options,
3223 TREE_OPTIMIZATION (func_optimize));
3225 /* The target attributes may also change some optimization flags, so update
3226 the optimization options if necessary. */
3227 cl_target_option_save (&cur_target, &global_options);
3228 new_target = nios2_valid_target_attribute_tree (args);
3229 new_optimize = build_optimization_node (&global_options);
3231 if (!new_target)
3232 ret = false;
3234 else if (fndecl)
3236 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
3238 if (old_optimize != new_optimize)
3239 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
3242 cl_target_option_restore (&global_options, &cur_target);
3244 if (old_optimize != new_optimize)
3245 cl_optimization_restore (&global_options,
3246 TREE_OPTIMIZATION (old_optimize));
3247 return ret;
3250 /* Remember the last target of nios2_set_current_function. */
3251 static GTY(()) tree nios2_previous_fndecl;
3253 /* Establish appropriate back-end context for processing the function
3254 FNDECL. The argument might be NULL to indicate processing at top
3255 level, outside of any function scope. */
3256 static void
3257 nios2_set_current_function (tree fndecl)
3259 tree old_tree = (nios2_previous_fndecl
3260 ? DECL_FUNCTION_SPECIFIC_TARGET (nios2_previous_fndecl)
3261 : NULL_TREE);
3263 tree new_tree = (fndecl
3264 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
3265 : NULL_TREE);
3267 if (fndecl && fndecl != nios2_previous_fndecl)
3269 nios2_previous_fndecl = fndecl;
3270 if (old_tree == new_tree)
3273 else if (new_tree)
3275 cl_target_option_restore (&global_options,
3276 TREE_TARGET_OPTION (new_tree));
3277 target_reinit ();
3280 else if (old_tree)
3282 struct cl_target_option *def
3283 = TREE_TARGET_OPTION (target_option_current_node);
3285 cl_target_option_restore (&global_options, def);
3286 target_reinit ();
3291 /* Hook to validate the current #pragma GCC target and set the FPU custom
3292 code option state. If ARGS is NULL, then POP_TARGET is used to reset
3293 the options. */
3294 static bool
3295 nios2_pragma_target_parse (tree args, tree pop_target)
3297 tree cur_tree;
3298 if (! args)
3300 cur_tree = ((pop_target)
3301 ? pop_target
3302 : target_option_default_node);
3303 cl_target_option_restore (&global_options,
3304 TREE_TARGET_OPTION (cur_tree));
3306 else
3308 cur_tree = nios2_valid_target_attribute_tree (args);
3309 if (!cur_tree)
3310 return false;
3313 target_option_current_node = cur_tree;
3314 return true;
3317 /* Implement TARGET_MERGE_DECL_ATTRIBUTES.
3318 We are just using this hook to add some additional error checking to
3319 the default behavior. GCC does not provide a target hook for merging
3320 the target options, and only correctly handles merging empty vs non-empty
3321 option data; see merge_decls() in c-decl.c.
3322 So here we require either that at least one of the decls has empty
3323 target options, or that the target options/data be identical. */
3324 static tree
3325 nios2_merge_decl_attributes (tree olddecl, tree newdecl)
3327 tree oldopts = lookup_attribute ("target", DECL_ATTRIBUTES (olddecl));
3328 tree newopts = lookup_attribute ("target", DECL_ATTRIBUTES (newdecl));
3329 if (newopts && oldopts && newopts != oldopts)
3331 tree oldtree = DECL_FUNCTION_SPECIFIC_TARGET (olddecl);
3332 tree newtree = DECL_FUNCTION_SPECIFIC_TARGET (newdecl);
3333 if (oldtree && newtree && oldtree != newtree)
3335 struct cl_target_option *olddata = TREE_TARGET_OPTION (oldtree);
3336 struct cl_target_option *newdata = TREE_TARGET_OPTION (newtree);
3337 if (olddata != newdata
3338 && memcmp (olddata, newdata, sizeof (struct cl_target_option)))
3339 error ("%qE redeclared with conflicting %qs attributes",
3340 DECL_NAME (newdecl), "target");
3343 return merge_attributes (DECL_ATTRIBUTES (olddecl),
3344 DECL_ATTRIBUTES (newdecl));
3347 /* Implement TARGET_ASM_OUTPUT_MI_THUNK. */
3348 static void
3349 nios2_asm_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
3350 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
3351 tree function)
3353 rtx this_rtx, funexp;
3354 rtx_insn *insn;
3356 /* Pretend to be a post-reload pass while generating rtl. */
3357 reload_completed = 1;
3359 if (flag_pic)
3360 nios2_load_pic_register ();
3362 /* Mark the end of the (empty) prologue. */
3363 emit_note (NOTE_INSN_PROLOGUE_END);
3365 /* Find the "this" pointer. If the function returns a structure,
3366 the structure return pointer is in $5. */
3367 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
3368 this_rtx = gen_rtx_REG (Pmode, FIRST_ARG_REGNO + 1);
3369 else
3370 this_rtx = gen_rtx_REG (Pmode, FIRST_ARG_REGNO);
3372 /* Add DELTA to THIS_RTX. */
3373 nios2_emit_add_constant (this_rtx, delta);
3375 /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX. */
3376 if (vcall_offset)
3378 rtx tmp;
3380 tmp = gen_rtx_REG (Pmode, 2);
3381 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
3382 nios2_emit_add_constant (tmp, vcall_offset);
3383 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
3384 emit_insn (gen_add2_insn (this_rtx, tmp));
3387 /* Generate a tail call to the target function. */
3388 if (!TREE_USED (function))
3390 assemble_external (function);
3391 TREE_USED (function) = 1;
3393 funexp = XEXP (DECL_RTL (function), 0);
3394 /* Function address needs to be constructed under PIC,
3395 provide r2 to use here. */
3396 nios2_adjust_call_address (&funexp, gen_rtx_REG (Pmode, 2));
3397 insn = emit_call_insn (gen_sibcall_internal (funexp, const0_rtx));
3398 SIBLING_CALL_P (insn) = 1;
3400 /* Run just enough of rest_of_compilation to get the insns emitted.
3401 There's not really enough bulk here to make other passes such as
3402 instruction scheduling worth while. Note that use_thunk calls
3403 assemble_start_function and assemble_end_function. */
3404 insn = get_insns ();
3405 shorten_branches (insn);
3406 final_start_function (insn, file, 1);
3407 final (insn, file, 1);
3408 final_end_function ();
3410 /* Stop pretending to be a post-reload pass. */
3411 reload_completed = 0;
3415 /* Initialize the GCC target structure. */
3416 #undef TARGET_ASM_FUNCTION_PROLOGUE
3417 #define TARGET_ASM_FUNCTION_PROLOGUE nios2_asm_function_prologue
3419 #undef TARGET_IN_SMALL_DATA_P
3420 #define TARGET_IN_SMALL_DATA_P nios2_in_small_data_p
3422 #undef TARGET_SECTION_TYPE_FLAGS
3423 #define TARGET_SECTION_TYPE_FLAGS nios2_section_type_flags
3425 #undef TARGET_INIT_BUILTINS
3426 #define TARGET_INIT_BUILTINS nios2_init_builtins
3427 #undef TARGET_EXPAND_BUILTIN
3428 #define TARGET_EXPAND_BUILTIN nios2_expand_builtin
3429 #undef TARGET_BUILTIN_DECL
3430 #define TARGET_BUILTIN_DECL nios2_builtin_decl
3432 #undef TARGET_INIT_LIBFUNCS
3433 #define TARGET_INIT_LIBFUNCS nios2_init_libfuncs
3435 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
3436 #define TARGET_FUNCTION_OK_FOR_SIBCALL hook_bool_tree_tree_true
3438 #undef TARGET_CAN_ELIMINATE
3439 #define TARGET_CAN_ELIMINATE nios2_can_eliminate
3441 #undef TARGET_FUNCTION_ARG
3442 #define TARGET_FUNCTION_ARG nios2_function_arg
3444 #undef TARGET_FUNCTION_ARG_ADVANCE
3445 #define TARGET_FUNCTION_ARG_ADVANCE nios2_function_arg_advance
3447 #undef TARGET_ARG_PARTIAL_BYTES
3448 #define TARGET_ARG_PARTIAL_BYTES nios2_arg_partial_bytes
3450 #undef TARGET_TRAMPOLINE_INIT
3451 #define TARGET_TRAMPOLINE_INIT nios2_trampoline_init
3453 #undef TARGET_FUNCTION_VALUE
3454 #define TARGET_FUNCTION_VALUE nios2_function_value
3456 #undef TARGET_LIBCALL_VALUE
3457 #define TARGET_LIBCALL_VALUE nios2_libcall_value
3459 #undef TARGET_FUNCTION_VALUE_REGNO_P
3460 #define TARGET_FUNCTION_VALUE_REGNO_P nios2_function_value_regno_p
3462 #undef TARGET_RETURN_IN_MEMORY
3463 #define TARGET_RETURN_IN_MEMORY nios2_return_in_memory
3465 #undef TARGET_PROMOTE_PROTOTYPES
3466 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
3468 #undef TARGET_SETUP_INCOMING_VARARGS
3469 #define TARGET_SETUP_INCOMING_VARARGS nios2_setup_incoming_varargs
3471 #undef TARGET_MUST_PASS_IN_STACK
3472 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
3474 #undef TARGET_LEGITIMATE_CONSTANT_P
3475 #define TARGET_LEGITIMATE_CONSTANT_P nios2_legitimate_constant_p
3477 #undef TARGET_LEGITIMIZE_ADDRESS
3478 #define TARGET_LEGITIMIZE_ADDRESS nios2_legitimize_address
3480 #undef TARGET_DELEGITIMIZE_ADDRESS
3481 #define TARGET_DELEGITIMIZE_ADDRESS nios2_delegitimize_address
3483 #undef TARGET_LEGITIMATE_ADDRESS_P
3484 #define TARGET_LEGITIMATE_ADDRESS_P nios2_legitimate_address_p
3486 #undef TARGET_PREFERRED_RELOAD_CLASS
3487 #define TARGET_PREFERRED_RELOAD_CLASS nios2_preferred_reload_class
3489 #undef TARGET_RTX_COSTS
3490 #define TARGET_RTX_COSTS nios2_rtx_costs
3492 #undef TARGET_HAVE_TLS
3493 #define TARGET_HAVE_TLS TARGET_LINUX_ABI
3495 #undef TARGET_CANNOT_FORCE_CONST_MEM
3496 #define TARGET_CANNOT_FORCE_CONST_MEM nios2_cannot_force_const_mem
3498 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
3499 #define TARGET_ASM_OUTPUT_DWARF_DTPREL nios2_output_dwarf_dtprel
3501 #undef TARGET_PRINT_OPERAND
3502 #define TARGET_PRINT_OPERAND nios2_print_operand
3504 #undef TARGET_PRINT_OPERAND_ADDRESS
3505 #define TARGET_PRINT_OPERAND_ADDRESS nios2_print_operand_address
3507 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
3508 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA nios2_output_addr_const_extra
3510 #undef TARGET_ASM_FILE_END
3511 #define TARGET_ASM_FILE_END nios2_asm_file_end
3513 #undef TARGET_OPTION_OVERRIDE
3514 #define TARGET_OPTION_OVERRIDE nios2_option_override
3516 #undef TARGET_OPTION_SAVE
3517 #define TARGET_OPTION_SAVE nios2_option_save
3519 #undef TARGET_OPTION_RESTORE
3520 #define TARGET_OPTION_RESTORE nios2_option_restore
3522 #undef TARGET_SET_CURRENT_FUNCTION
3523 #define TARGET_SET_CURRENT_FUNCTION nios2_set_current_function
3525 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
3526 #define TARGET_OPTION_VALID_ATTRIBUTE_P nios2_valid_target_attribute_p
3528 #undef TARGET_OPTION_PRAGMA_PARSE
3529 #define TARGET_OPTION_PRAGMA_PARSE nios2_pragma_target_parse
3531 #undef TARGET_MERGE_DECL_ATTRIBUTES
3532 #define TARGET_MERGE_DECL_ATTRIBUTES nios2_merge_decl_attributes
3534 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
3535 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK \
3536 hook_bool_const_tree_hwi_hwi_const_tree_true
3538 #undef TARGET_ASM_OUTPUT_MI_THUNK
3539 #define TARGET_ASM_OUTPUT_MI_THUNK nios2_asm_output_mi_thunk
3541 struct gcc_target targetm = TARGET_INITIALIZER;
3543 #include "gt-nios2.h"