]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/nios2/nios2.c
tree-core.h: Include symtab.h.
[thirdparty/gcc.git] / gcc / config / nios2 / nios2.c
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.
6
7 This file is part of GCC.
8
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.
13
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.
18
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/>. */
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "backend.h"
27 #include "tree.h"
28 #include "rtl.h"
29 #include "df.h"
30 #include "alias.h"
31 #include "fold-const.h"
32 #include "regs.h"
33 #include "insn-config.h"
34 #include "conditions.h"
35 #include "output.h"
36 #include "insn-attr.h"
37 #include "flags.h"
38 #include "recog.h"
39 #include "expmed.h"
40 #include "dojump.h"
41 #include "explow.h"
42 #include "calls.h"
43 #include "emit-rtl.h"
44 #include "varasm.h"
45 #include "stmt.h"
46 #include "expr.h"
47 #include "insn-codes.h"
48 #include "optabs.h"
49 #include "cfgrtl.h"
50 #include "cfganal.h"
51 #include "lcm.h"
52 #include "cfgbuild.h"
53 #include "cfgcleanup.h"
54 #include "diagnostic-core.h"
55 #include "toplev.h"
56 #include "target.h"
57 #include "tm_p.h"
58 #include "langhooks.h"
59 #include "debug.h"
60 #include "reload.h"
61 #include "stor-layout.h"
62 #include "builtins.h"
63
64 /* This file should be included last. */
65 #include "target-def.h"
66
67 /* Forward function declarations. */
68 static bool prologue_saved_reg_p (unsigned);
69 static void nios2_load_pic_register (void);
70 static void nios2_register_custom_code (unsigned int, enum nios2_ccs_code, int);
71 static const char *nios2_unspec_reloc_name (int);
72 static void nios2_register_builtin_fndecl (unsigned, tree);
73
74 /* Threshold for data being put into the small data/bss area, instead
75 of the normal data area (references to the small data/bss area take
76 1 instruction, and use the global pointer, references to the normal
77 data area takes 2 instructions). */
78 unsigned HOST_WIDE_INT nios2_section_threshold = NIOS2_DEFAULT_GVALUE;
79
80 struct GTY (()) machine_function
81 {
82 /* Current frame information, to be filled in by nios2_compute_frame_layout
83 with register save masks, and offsets for the current function. */
84
85 /* Mask of registers to save. */
86 unsigned int save_mask;
87 /* Number of bytes that the entire frame takes up. */
88 int total_size;
89 /* Number of bytes that variables take up. */
90 int var_size;
91 /* Number of bytes that outgoing arguments take up. */
92 int args_size;
93 /* Number of bytes needed to store registers in frame. */
94 int save_reg_size;
95 /* Offset from new stack pointer to store registers. */
96 int save_regs_offset;
97 /* Offset from save_regs_offset to store frame pointer register. */
98 int fp_save_offset;
99 /* != 0 if frame layout already calculated. */
100 int initialized;
101 };
102
103 /* State to track the assignment of custom codes to FPU/custom builtins. */
104 static enum nios2_ccs_code custom_code_status[256];
105 static int custom_code_index[256];
106 /* Set to true if any conflicts (re-use of a code between 0-255) are found. */
107 static bool custom_code_conflict = false;
108
109 \f
110 /* Definition of builtin function types for nios2. */
111
112 #define N2_FTYPES \
113 N2_FTYPE(1, (SF)) \
114 N2_FTYPE(1, (VOID)) \
115 N2_FTYPE(2, (DF, DF)) \
116 N2_FTYPE(3, (DF, DF, DF)) \
117 N2_FTYPE(2, (DF, SF)) \
118 N2_FTYPE(2, (DF, SI)) \
119 N2_FTYPE(2, (DF, UI)) \
120 N2_FTYPE(2, (SF, DF)) \
121 N2_FTYPE(2, (SF, SF)) \
122 N2_FTYPE(3, (SF, SF, SF)) \
123 N2_FTYPE(2, (SF, SI)) \
124 N2_FTYPE(2, (SF, UI)) \
125 N2_FTYPE(2, (SI, CVPTR)) \
126 N2_FTYPE(2, (SI, DF)) \
127 N2_FTYPE(3, (SI, DF, DF)) \
128 N2_FTYPE(2, (SI, SF)) \
129 N2_FTYPE(3, (SI, SF, SF)) \
130 N2_FTYPE(2, (SI, SI)) \
131 N2_FTYPE(2, (UI, CVPTR)) \
132 N2_FTYPE(2, (UI, DF)) \
133 N2_FTYPE(2, (UI, SF)) \
134 N2_FTYPE(2, (VOID, DF)) \
135 N2_FTYPE(2, (VOID, SF)) \
136 N2_FTYPE(3, (VOID, SI, SI)) \
137 N2_FTYPE(3, (VOID, VPTR, SI))
138
139 #define N2_FTYPE_OP1(R) N2_FTYPE_ ## R ## _VOID
140 #define N2_FTYPE_OP2(R, A1) N2_FTYPE_ ## R ## _ ## A1
141 #define N2_FTYPE_OP3(R, A1, A2) N2_FTYPE_ ## R ## _ ## A1 ## _ ## A2
142
143 /* Expand ftcode enumeration. */
144 enum nios2_ftcode {
145 #define N2_FTYPE(N,ARGS) N2_FTYPE_OP ## N ARGS,
146 N2_FTYPES
147 #undef N2_FTYPE
148 N2_FTYPE_MAX
149 };
150
151 /* Return the tree function type, based on the ftcode. */
152 static tree
153 nios2_ftype (enum nios2_ftcode ftcode)
154 {
155 static tree types[(int) N2_FTYPE_MAX];
156
157 tree N2_TYPE_SF = float_type_node;
158 tree N2_TYPE_DF = double_type_node;
159 tree N2_TYPE_SI = integer_type_node;
160 tree N2_TYPE_UI = unsigned_type_node;
161 tree N2_TYPE_VOID = void_type_node;
162
163 static const_tree N2_TYPE_CVPTR, N2_TYPE_VPTR;
164 if (!N2_TYPE_CVPTR)
165 {
166 /* const volatile void *. */
167 N2_TYPE_CVPTR
168 = build_pointer_type (build_qualified_type (void_type_node,
169 (TYPE_QUAL_CONST
170 | TYPE_QUAL_VOLATILE)));
171 /* volatile void *. */
172 N2_TYPE_VPTR
173 = build_pointer_type (build_qualified_type (void_type_node,
174 TYPE_QUAL_VOLATILE));
175 }
176 if (types[(int) ftcode] == NULL_TREE)
177 switch (ftcode)
178 {
179 #define N2_FTYPE_ARGS1(R) N2_TYPE_ ## R
180 #define N2_FTYPE_ARGS2(R,A1) N2_TYPE_ ## R, N2_TYPE_ ## A1
181 #define N2_FTYPE_ARGS3(R,A1,A2) N2_TYPE_ ## R, N2_TYPE_ ## A1, N2_TYPE_ ## A2
182 #define N2_FTYPE(N,ARGS) \
183 case N2_FTYPE_OP ## N ARGS: \
184 types[(int) ftcode] \
185 = build_function_type_list (N2_FTYPE_ARGS ## N ARGS, NULL_TREE); \
186 break;
187 N2_FTYPES
188 #undef N2_FTYPE
189 default: gcc_unreachable ();
190 }
191 return types[(int) ftcode];
192 }
193
194 \f
195 /* Definition of FPU instruction descriptions. */
196
197 struct nios2_fpu_insn_info
198 {
199 const char *name;
200 int num_operands, *optvar;
201 int opt, no_opt;
202 #define N2F_DF 0x1
203 #define N2F_DFREQ 0x2
204 #define N2F_UNSAFE 0x4
205 #define N2F_FINITE 0x8
206 #define N2F_NO_ERRNO 0x10
207 unsigned int flags;
208 enum insn_code icode;
209 enum nios2_ftcode ftcode;
210 };
211
212 /* Base macro for defining FPU instructions. */
213 #define N2FPU_INSN_DEF_BASE(insn, nop, flags, icode, args) \
214 { #insn, nop, &nios2_custom_ ## insn, OPT_mcustom_##insn##_, \
215 OPT_mno_custom_##insn, flags, CODE_FOR_ ## icode, \
216 N2_FTYPE_OP ## nop args }
217
218 /* Arithmetic and math functions; 2 or 3 operand FP operations. */
219 #define N2FPU_OP2(mode) (mode, mode)
220 #define N2FPU_OP3(mode) (mode, mode, mode)
221 #define N2FPU_INSN_DEF(code, icode, nop, flags, m, M) \
222 N2FPU_INSN_DEF_BASE (f ## code ## m, nop, flags, \
223 icode ## m ## f ## nop, N2FPU_OP ## nop (M ## F))
224 #define N2FPU_INSN_SF(code, nop, flags) \
225 N2FPU_INSN_DEF (code, code, nop, flags, s, S)
226 #define N2FPU_INSN_DF(code, nop, flags) \
227 N2FPU_INSN_DEF (code, code, nop, flags | N2F_DF, d, D)
228
229 /* Compare instructions, 3 operand FP operation with a SI result. */
230 #define N2FPU_CMP_DEF(code, flags, m, M) \
231 N2FPU_INSN_DEF_BASE (fcmp ## code ## m, 3, flags, \
232 nios2_s ## code ## m ## f, (SI, M ## F, M ## F))
233 #define N2FPU_CMP_SF(code) N2FPU_CMP_DEF (code, 0, s, S)
234 #define N2FPU_CMP_DF(code) N2FPU_CMP_DEF (code, N2F_DF, d, D)
235
236 /* The order of definition needs to be maintained consistent with
237 enum n2fpu_code in nios2-opts.h. */
238 struct nios2_fpu_insn_info nios2_fpu_insn[] =
239 {
240 /* Single precision instructions. */
241 N2FPU_INSN_SF (add, 3, 0),
242 N2FPU_INSN_SF (sub, 3, 0),
243 N2FPU_INSN_SF (mul, 3, 0),
244 N2FPU_INSN_SF (div, 3, 0),
245 /* Due to textual difference between min/max and smin/smax. */
246 N2FPU_INSN_DEF (min, smin, 3, N2F_FINITE, s, S),
247 N2FPU_INSN_DEF (max, smax, 3, N2F_FINITE, s, S),
248 N2FPU_INSN_SF (neg, 2, 0),
249 N2FPU_INSN_SF (abs, 2, 0),
250 N2FPU_INSN_SF (sqrt, 2, 0),
251 N2FPU_INSN_SF (sin, 2, N2F_UNSAFE),
252 N2FPU_INSN_SF (cos, 2, N2F_UNSAFE),
253 N2FPU_INSN_SF (tan, 2, N2F_UNSAFE),
254 N2FPU_INSN_SF (atan, 2, N2F_UNSAFE),
255 N2FPU_INSN_SF (exp, 2, N2F_UNSAFE),
256 N2FPU_INSN_SF (log, 2, N2F_UNSAFE),
257 /* Single precision compares. */
258 N2FPU_CMP_SF (eq), N2FPU_CMP_SF (ne),
259 N2FPU_CMP_SF (lt), N2FPU_CMP_SF (le),
260 N2FPU_CMP_SF (gt), N2FPU_CMP_SF (ge),
261
262 /* Double precision instructions. */
263 N2FPU_INSN_DF (add, 3, 0),
264 N2FPU_INSN_DF (sub, 3, 0),
265 N2FPU_INSN_DF (mul, 3, 0),
266 N2FPU_INSN_DF (div, 3, 0),
267 /* Due to textual difference between min/max and smin/smax. */
268 N2FPU_INSN_DEF (min, smin, 3, N2F_FINITE, d, D),
269 N2FPU_INSN_DEF (max, smax, 3, N2F_FINITE, d, D),
270 N2FPU_INSN_DF (neg, 2, 0),
271 N2FPU_INSN_DF (abs, 2, 0),
272 N2FPU_INSN_DF (sqrt, 2, 0),
273 N2FPU_INSN_DF (sin, 2, N2F_UNSAFE),
274 N2FPU_INSN_DF (cos, 2, N2F_UNSAFE),
275 N2FPU_INSN_DF (tan, 2, N2F_UNSAFE),
276 N2FPU_INSN_DF (atan, 2, N2F_UNSAFE),
277 N2FPU_INSN_DF (exp, 2, N2F_UNSAFE),
278 N2FPU_INSN_DF (log, 2, N2F_UNSAFE),
279 /* Double precision compares. */
280 N2FPU_CMP_DF (eq), N2FPU_CMP_DF (ne),
281 N2FPU_CMP_DF (lt), N2FPU_CMP_DF (le),
282 N2FPU_CMP_DF (gt), N2FPU_CMP_DF (ge),
283
284 /* Conversion instructions. */
285 N2FPU_INSN_DEF_BASE (floatis, 2, 0, floatsisf2, (SF, SI)),
286 N2FPU_INSN_DEF_BASE (floatus, 2, 0, floatunssisf2, (SF, UI)),
287 N2FPU_INSN_DEF_BASE (floatid, 2, 0, floatsidf2, (DF, SI)),
288 N2FPU_INSN_DEF_BASE (floatud, 2, 0, floatunssidf2, (DF, UI)),
289 N2FPU_INSN_DEF_BASE (round, 2, N2F_NO_ERRNO, lroundsfsi2, (SI, SF)),
290 N2FPU_INSN_DEF_BASE (fixsi, 2, 0, fix_truncsfsi2, (SI, SF)),
291 N2FPU_INSN_DEF_BASE (fixsu, 2, 0, fixuns_truncsfsi2, (UI, SF)),
292 N2FPU_INSN_DEF_BASE (fixdi, 2, 0, fix_truncdfsi2, (SI, DF)),
293 N2FPU_INSN_DEF_BASE (fixdu, 2, 0, fixuns_truncdfsi2, (UI, DF)),
294 N2FPU_INSN_DEF_BASE (fextsd, 2, 0, extendsfdf2, (DF, SF)),
295 N2FPU_INSN_DEF_BASE (ftruncds, 2, 0, truncdfsf2, (SF, DF)),
296
297 /* X, Y access instructions. */
298 N2FPU_INSN_DEF_BASE (fwrx, 2, N2F_DFREQ, nios2_fwrx, (VOID, DF)),
299 N2FPU_INSN_DEF_BASE (fwry, 2, N2F_DFREQ, nios2_fwry, (VOID, SF)),
300 N2FPU_INSN_DEF_BASE (frdxlo, 1, N2F_DFREQ, nios2_frdxlo, (SF)),
301 N2FPU_INSN_DEF_BASE (frdxhi, 1, N2F_DFREQ, nios2_frdxhi, (SF)),
302 N2FPU_INSN_DEF_BASE (frdy, 1, N2F_DFREQ, nios2_frdy, (SF))
303 };
304
305 /* Some macros for ease of access. */
306 #define N2FPU(code) nios2_fpu_insn[(int) code]
307 #define N2FPU_ENABLED_P(code) (N2FPU_N(code) >= 0)
308 #define N2FPU_N(code) (*N2FPU(code).optvar)
309 #define N2FPU_NAME(code) (N2FPU(code).name)
310 #define N2FPU_ICODE(code) (N2FPU(code).icode)
311 #define N2FPU_FTCODE(code) (N2FPU(code).ftcode)
312 #define N2FPU_FINITE_P(code) (N2FPU(code).flags & N2F_FINITE)
313 #define N2FPU_UNSAFE_P(code) (N2FPU(code).flags & N2F_UNSAFE)
314 #define N2FPU_NO_ERRNO_P(code) (N2FPU(code).flags & N2F_NO_ERRNO)
315 #define N2FPU_DOUBLE_P(code) (N2FPU(code).flags & N2F_DF)
316 #define N2FPU_DOUBLE_REQUIRED_P(code) (N2FPU(code).flags & N2F_DFREQ)
317
318 /* Same as above, but for cases where using only the op part is shorter. */
319 #define N2FPU_OP(op) N2FPU(n2fpu_ ## op)
320 #define N2FPU_OP_NAME(op) N2FPU_NAME(n2fpu_ ## op)
321 #define N2FPU_OP_ENABLED_P(op) N2FPU_ENABLED_P(n2fpu_ ## op)
322
323 /* Export the FPU insn enabled predicate to nios2.md. */
324 bool
325 nios2_fpu_insn_enabled (enum n2fpu_code code)
326 {
327 return N2FPU_ENABLED_P (code);
328 }
329
330 /* Return true if COND comparison for mode MODE is enabled under current
331 settings. */
332
333 static bool
334 nios2_fpu_compare_enabled (enum rtx_code cond, machine_mode mode)
335 {
336 if (mode == SFmode)
337 switch (cond)
338 {
339 case EQ: return N2FPU_OP_ENABLED_P (fcmpeqs);
340 case NE: return N2FPU_OP_ENABLED_P (fcmpnes);
341 case GT: return N2FPU_OP_ENABLED_P (fcmpgts);
342 case GE: return N2FPU_OP_ENABLED_P (fcmpges);
343 case LT: return N2FPU_OP_ENABLED_P (fcmplts);
344 case LE: return N2FPU_OP_ENABLED_P (fcmples);
345 default: break;
346 }
347 else if (mode == DFmode)
348 switch (cond)
349 {
350 case EQ: return N2FPU_OP_ENABLED_P (fcmpeqd);
351 case NE: return N2FPU_OP_ENABLED_P (fcmpned);
352 case GT: return N2FPU_OP_ENABLED_P (fcmpgtd);
353 case GE: return N2FPU_OP_ENABLED_P (fcmpged);
354 case LT: return N2FPU_OP_ENABLED_P (fcmpltd);
355 case LE: return N2FPU_OP_ENABLED_P (fcmpled);
356 default: break;
357 }
358 return false;
359 }
360
361 /* Stack layout and calling conventions. */
362
363 #define NIOS2_STACK_ALIGN(LOC) \
364 (((LOC) + ((PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT) - 1)) \
365 & ~((PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT) - 1))
366
367 /* Return the bytes needed to compute the frame pointer from the current
368 stack pointer. */
369 static int
370 nios2_compute_frame_layout (void)
371 {
372 unsigned int regno;
373 unsigned int save_mask = 0;
374 int total_size;
375 int var_size;
376 int out_args_size;
377 int save_reg_size;
378
379 if (cfun->machine->initialized)
380 return cfun->machine->total_size;
381
382 var_size = NIOS2_STACK_ALIGN (get_frame_size ());
383 out_args_size = NIOS2_STACK_ALIGN (crtl->outgoing_args_size);
384 total_size = var_size + out_args_size;
385
386 /* Calculate space needed for gp registers. */
387 save_reg_size = 0;
388 for (regno = 0; regno <= LAST_GP_REG; regno++)
389 if (prologue_saved_reg_p (regno))
390 {
391 save_mask |= 1 << regno;
392 save_reg_size += 4;
393 }
394
395 /* If we call eh_return, we need to save the EH data registers. */
396 if (crtl->calls_eh_return)
397 {
398 unsigned i;
399 unsigned r;
400
401 for (i = 0; (r = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; i++)
402 if (!(save_mask & (1 << r)))
403 {
404 save_mask |= 1 << r;
405 save_reg_size += 4;
406 }
407 }
408
409 cfun->machine->fp_save_offset = 0;
410 if (save_mask & (1 << HARD_FRAME_POINTER_REGNUM))
411 {
412 int fp_save_offset = 0;
413 for (regno = 0; regno < HARD_FRAME_POINTER_REGNUM; regno++)
414 if (save_mask & (1 << regno))
415 fp_save_offset += 4;
416
417 cfun->machine->fp_save_offset = fp_save_offset;
418 }
419
420 save_reg_size = NIOS2_STACK_ALIGN (save_reg_size);
421 total_size += save_reg_size;
422 total_size += NIOS2_STACK_ALIGN (crtl->args.pretend_args_size);
423
424 /* Save other computed information. */
425 cfun->machine->save_mask = save_mask;
426 cfun->machine->total_size = total_size;
427 cfun->machine->var_size = var_size;
428 cfun->machine->args_size = out_args_size;
429 cfun->machine->save_reg_size = save_reg_size;
430 cfun->machine->initialized = reload_completed;
431 cfun->machine->save_regs_offset = out_args_size + var_size;
432
433 return total_size;
434 }
435
436 /* Generate save/restore of register REGNO at SP + OFFSET. Used by the
437 prologue/epilogue expand routines. */
438 static void
439 save_reg (int regno, unsigned offset)
440 {
441 rtx reg = gen_rtx_REG (SImode, regno);
442 rtx addr = plus_constant (Pmode, stack_pointer_rtx, offset, false);
443 rtx_insn *insn = emit_move_insn (gen_frame_mem (Pmode, addr), reg);
444 RTX_FRAME_RELATED_P (insn) = 1;
445 }
446
447 static void
448 restore_reg (int regno, unsigned offset)
449 {
450 rtx reg = gen_rtx_REG (SImode, regno);
451 rtx addr = plus_constant (Pmode, stack_pointer_rtx, offset, false);
452 rtx_insn *insn = emit_move_insn (reg, gen_frame_mem (Pmode, addr));
453 /* Tag epilogue unwind note. */
454 add_reg_note (insn, REG_CFA_RESTORE, reg);
455 RTX_FRAME_RELATED_P (insn) = 1;
456 }
457
458 /* Emit conditional trap for checking stack limit. */
459 static void
460 nios2_emit_stack_limit_check (void)
461 {
462 if (REG_P (stack_limit_rtx))
463 emit_insn (gen_ctrapsi4 (gen_rtx_LTU (VOIDmode, stack_pointer_rtx,
464 stack_limit_rtx),
465 stack_pointer_rtx, stack_limit_rtx, GEN_INT (3)));
466 else
467 sorry ("only register based stack limit is supported");
468 }
469
470 /* Temp regno used inside prologue/epilogue. */
471 #define TEMP_REG_NUM 8
472
473 static rtx_insn *
474 nios2_emit_add_constant (rtx reg, HOST_WIDE_INT immed)
475 {
476 rtx_insn *insn;
477 if (SMALL_INT (immed))
478 insn = emit_insn (gen_add2_insn (reg, gen_int_mode (immed, Pmode)));
479 else
480 {
481 rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
482 emit_move_insn (tmp, gen_int_mode (immed, Pmode));
483 insn = emit_insn (gen_add2_insn (reg, tmp));
484 }
485 return insn;
486 }
487
488 void
489 nios2_expand_prologue (void)
490 {
491 unsigned int regno;
492 int total_frame_size, save_offset;
493 int sp_offset; /* offset from base_reg to final stack value. */
494 int save_regs_base; /* offset from base_reg to register save area. */
495 rtx_insn *insn;
496
497 total_frame_size = nios2_compute_frame_layout ();
498
499 if (flag_stack_usage_info)
500 current_function_static_stack_size = total_frame_size;
501
502 /* Decrement the stack pointer. */
503 if (!SMALL_INT (total_frame_size))
504 {
505 /* We need an intermediary point, this will point at the spill block. */
506 insn = emit_insn
507 (gen_add2_insn (stack_pointer_rtx,
508 gen_int_mode (cfun->machine->save_regs_offset
509 - total_frame_size, Pmode)));
510 RTX_FRAME_RELATED_P (insn) = 1;
511 save_regs_base = 0;
512 sp_offset = -cfun->machine->save_regs_offset;
513 }
514 else if (total_frame_size)
515 {
516 insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
517 gen_int_mode (-total_frame_size,
518 Pmode)));
519 RTX_FRAME_RELATED_P (insn) = 1;
520 save_regs_base = cfun->machine->save_regs_offset;
521 sp_offset = 0;
522 }
523 else
524 save_regs_base = sp_offset = 0;
525
526 if (crtl->limit_stack)
527 nios2_emit_stack_limit_check ();
528
529 save_offset = save_regs_base + cfun->machine->save_reg_size;
530
531 for (regno = LAST_GP_REG; regno > 0; regno--)
532 if (cfun->machine->save_mask & (1 << regno))
533 {
534 save_offset -= 4;
535 save_reg (regno, save_offset);
536 }
537
538 if (frame_pointer_needed)
539 {
540 int fp_save_offset = save_regs_base + cfun->machine->fp_save_offset;
541 insn = emit_insn (gen_add3_insn (hard_frame_pointer_rtx,
542 stack_pointer_rtx,
543 gen_int_mode (fp_save_offset, Pmode)));
544 RTX_FRAME_RELATED_P (insn) = 1;
545 }
546
547 if (sp_offset)
548 {
549 rtx sp_adjust
550 = gen_rtx_SET (stack_pointer_rtx,
551 plus_constant (Pmode, stack_pointer_rtx, sp_offset));
552 if (SMALL_INT (sp_offset))
553 insn = emit_insn (sp_adjust);
554 else
555 {
556 rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
557 emit_move_insn (tmp, gen_int_mode (sp_offset, Pmode));
558 insn = emit_insn (gen_add2_insn (stack_pointer_rtx, tmp));
559 /* Attach the sp_adjust as a note indicating what happened. */
560 add_reg_note (insn, REG_FRAME_RELATED_EXPR, sp_adjust);
561 }
562 RTX_FRAME_RELATED_P (insn) = 1;
563
564 if (crtl->limit_stack)
565 nios2_emit_stack_limit_check ();
566 }
567
568 /* Load the PIC register if needed. */
569 if (crtl->uses_pic_offset_table)
570 nios2_load_pic_register ();
571
572 /* If we are profiling, make sure no instructions are scheduled before
573 the call to mcount. */
574 if (crtl->profile)
575 emit_insn (gen_blockage ());
576 }
577
578 void
579 nios2_expand_epilogue (bool sibcall_p)
580 {
581 rtx_insn *insn;
582 rtx cfa_adj;
583 int total_frame_size;
584 int sp_adjust, save_offset;
585 unsigned int regno;
586
587 if (!sibcall_p && nios2_can_use_return_insn ())
588 {
589 emit_jump_insn (gen_return ());
590 return;
591 }
592
593 emit_insn (gen_blockage ());
594
595 total_frame_size = nios2_compute_frame_layout ();
596 if (frame_pointer_needed)
597 {
598 /* Recover the stack pointer. */
599 insn = emit_insn (gen_add3_insn
600 (stack_pointer_rtx, hard_frame_pointer_rtx,
601 gen_int_mode (-cfun->machine->fp_save_offset, Pmode)));
602 cfa_adj = plus_constant (Pmode, stack_pointer_rtx,
603 (total_frame_size
604 - cfun->machine->save_regs_offset));
605 add_reg_note (insn, REG_CFA_DEF_CFA, cfa_adj);
606 RTX_FRAME_RELATED_P (insn) = 1;
607
608 save_offset = 0;
609 sp_adjust = total_frame_size - cfun->machine->save_regs_offset;
610 }
611 else if (!SMALL_INT (total_frame_size))
612 {
613 rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
614 emit_move_insn (tmp, gen_int_mode (cfun->machine->save_regs_offset,
615 Pmode));
616 insn = emit_insn (gen_add2_insn (stack_pointer_rtx, tmp));
617 cfa_adj = gen_rtx_SET (stack_pointer_rtx,
618 plus_constant (Pmode, stack_pointer_rtx,
619 cfun->machine->save_regs_offset));
620 add_reg_note (insn, REG_CFA_ADJUST_CFA, cfa_adj);
621 RTX_FRAME_RELATED_P (insn) = 1;
622 save_offset = 0;
623 sp_adjust = total_frame_size - cfun->machine->save_regs_offset;
624 }
625 else
626 {
627 save_offset = cfun->machine->save_regs_offset;
628 sp_adjust = total_frame_size;
629 }
630
631 save_offset += cfun->machine->save_reg_size;
632
633 for (regno = LAST_GP_REG; regno > 0; regno--)
634 if (cfun->machine->save_mask & (1 << regno))
635 {
636 save_offset -= 4;
637 restore_reg (regno, save_offset);
638 }
639
640 if (sp_adjust)
641 {
642 insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
643 gen_int_mode (sp_adjust, Pmode)));
644 cfa_adj = gen_rtx_SET (stack_pointer_rtx,
645 plus_constant (Pmode, stack_pointer_rtx,
646 sp_adjust));
647 add_reg_note (insn, REG_CFA_ADJUST_CFA, cfa_adj);
648 RTX_FRAME_RELATED_P (insn) = 1;
649 }
650
651 /* Add in the __builtin_eh_return stack adjustment. */
652 if (crtl->calls_eh_return)
653 emit_insn (gen_add2_insn (stack_pointer_rtx, EH_RETURN_STACKADJ_RTX));
654
655 if (!sibcall_p)
656 emit_jump_insn (gen_simple_return ());
657 }
658
659 /* Implement RETURN_ADDR_RTX. Note, we do not support moving
660 back to a previous frame. */
661 rtx
662 nios2_get_return_address (int count)
663 {
664 if (count != 0)
665 return const0_rtx;
666
667 return get_hard_reg_initial_val (Pmode, RA_REGNO);
668 }
669
670 /* Emit code to change the current function's return address to
671 ADDRESS. SCRATCH is available as a scratch register, if needed.
672 ADDRESS and SCRATCH are both word-mode GPRs. */
673 void
674 nios2_set_return_address (rtx address, rtx scratch)
675 {
676 nios2_compute_frame_layout ();
677 if (cfun->machine->save_mask & (1 << RA_REGNO))
678 {
679 unsigned offset = cfun->machine->save_reg_size - 4;
680 rtx base;
681
682 if (frame_pointer_needed)
683 base = hard_frame_pointer_rtx;
684 else
685 {
686 base = stack_pointer_rtx;
687 offset += cfun->machine->save_regs_offset;
688
689 if (!SMALL_INT (offset))
690 {
691 emit_move_insn (scratch, gen_int_mode (offset, Pmode));
692 emit_insn (gen_add2_insn (scratch, base));
693 base = scratch;
694 offset = 0;
695 }
696 }
697 if (offset)
698 base = plus_constant (Pmode, base, offset);
699 emit_move_insn (gen_rtx_MEM (Pmode, base), address);
700 }
701 else
702 emit_move_insn (gen_rtx_REG (Pmode, RA_REGNO), address);
703 }
704
705 /* Implement FUNCTION_PROFILER macro. */
706 void
707 nios2_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
708 {
709 fprintf (file, "\tmov\tr8, ra\n");
710 if (flag_pic == 1)
711 {
712 fprintf (file, "\tnextpc\tr2\n");
713 fprintf (file, "\t1: movhi\tr3, %%hiadj(_gp_got - 1b)\n");
714 fprintf (file, "\taddi\tr3, r3, %%lo(_gp_got - 1b)\n");
715 fprintf (file, "\tadd\tr2, r2, r3\n");
716 fprintf (file, "\tldw\tr2, %%call(_mcount)(r2)\n");
717 fprintf (file, "\tcallr\tr2\n");
718 }
719 else if (flag_pic == 2)
720 {
721 fprintf (file, "\tnextpc\tr2\n");
722 fprintf (file, "\t1: movhi\tr3, %%hiadj(_gp_got - 1b)\n");
723 fprintf (file, "\taddi\tr3, r3, %%lo(_gp_got - 1b)\n");
724 fprintf (file, "\tadd\tr2, r2, r3\n");
725 fprintf (file, "\tmovhi\tr3, %%call_hiadj(_mcount)\n");
726 fprintf (file, "\taddi\tr3, r3, %%call_lo(_mcount)\n");
727 fprintf (file, "\tadd\tr3, r2, r3\n");
728 fprintf (file, "\tldw\tr2, 0(r3)\n");
729 fprintf (file, "\tcallr\tr2\n");
730 }
731 else
732 fprintf (file, "\tcall\t_mcount\n");
733 fprintf (file, "\tmov\tra, r8\n");
734 }
735
736 /* Dump stack layout. */
737 static void
738 nios2_dump_frame_layout (FILE *file)
739 {
740 fprintf (file, "\t%s Current Frame Info\n", ASM_COMMENT_START);
741 fprintf (file, "\t%s total_size = %d\n", ASM_COMMENT_START,
742 cfun->machine->total_size);
743 fprintf (file, "\t%s var_size = %d\n", ASM_COMMENT_START,
744 cfun->machine->var_size);
745 fprintf (file, "\t%s args_size = %d\n", ASM_COMMENT_START,
746 cfun->machine->args_size);
747 fprintf (file, "\t%s save_reg_size = %d\n", ASM_COMMENT_START,
748 cfun->machine->save_reg_size);
749 fprintf (file, "\t%s initialized = %d\n", ASM_COMMENT_START,
750 cfun->machine->initialized);
751 fprintf (file, "\t%s save_regs_offset = %d\n", ASM_COMMENT_START,
752 cfun->machine->save_regs_offset);
753 fprintf (file, "\t%s is_leaf = %d\n", ASM_COMMENT_START,
754 crtl->is_leaf);
755 fprintf (file, "\t%s frame_pointer_needed = %d\n", ASM_COMMENT_START,
756 frame_pointer_needed);
757 fprintf (file, "\t%s pretend_args_size = %d\n", ASM_COMMENT_START,
758 crtl->args.pretend_args_size);
759 }
760
761 /* Return true if REGNO should be saved in the prologue. */
762 static bool
763 prologue_saved_reg_p (unsigned regno)
764 {
765 gcc_assert (GP_REG_P (regno));
766
767 if (df_regs_ever_live_p (regno) && !call_used_regs[regno])
768 return true;
769
770 if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
771 return true;
772
773 if (regno == PIC_OFFSET_TABLE_REGNUM && crtl->uses_pic_offset_table)
774 return true;
775
776 if (regno == RA_REGNO && df_regs_ever_live_p (RA_REGNO))
777 return true;
778
779 return false;
780 }
781
782 /* Implement TARGET_CAN_ELIMINATE. */
783 static bool
784 nios2_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
785 {
786 if (to == STACK_POINTER_REGNUM)
787 return !frame_pointer_needed;
788 return true;
789 }
790
791 /* Implement INITIAL_ELIMINATION_OFFSET macro. */
792 int
793 nios2_initial_elimination_offset (int from, int to)
794 {
795 int offset;
796
797 nios2_compute_frame_layout ();
798
799 /* Set OFFSET to the offset from the stack pointer. */
800 switch (from)
801 {
802 case FRAME_POINTER_REGNUM:
803 offset = cfun->machine->args_size;
804 break;
805
806 case ARG_POINTER_REGNUM:
807 offset = cfun->machine->total_size;
808 offset -= crtl->args.pretend_args_size;
809 break;
810
811 default:
812 gcc_unreachable ();
813 }
814
815 /* If we are asked for the frame pointer offset, then adjust OFFSET
816 by the offset from the frame pointer to the stack pointer. */
817 if (to == HARD_FRAME_POINTER_REGNUM)
818 offset -= (cfun->machine->save_regs_offset
819 + cfun->machine->fp_save_offset);
820
821 return offset;
822 }
823
824 /* Return nonzero if this function is known to have a null epilogue.
825 This allows the optimizer to omit jumps to jumps if no stack
826 was created. */
827 int
828 nios2_can_use_return_insn (void)
829 {
830 if (!reload_completed || crtl->profile)
831 return 0;
832
833 return nios2_compute_frame_layout () == 0;
834 }
835
836 \f
837 /* Check and signal some warnings/errors on FPU insn options. */
838 static void
839 nios2_custom_check_insns (void)
840 {
841 unsigned int i, j;
842 bool errors = false;
843
844 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
845 if (N2FPU_ENABLED_P (i) && N2FPU_DOUBLE_P (i))
846 {
847 for (j = 0; j < ARRAY_SIZE (nios2_fpu_insn); j++)
848 if (N2FPU_DOUBLE_REQUIRED_P (j) && ! N2FPU_ENABLED_P (j))
849 {
850 error ("switch %<-mcustom-%s%> is required for double "
851 "precision floating point", N2FPU_NAME (j));
852 errors = true;
853 }
854 break;
855 }
856
857 /* Warn if the user has certain exotic operations that won't get used
858 without -funsafe-math-optimizations. See expand_builtin () in
859 builtins.c. */
860 if (!flag_unsafe_math_optimizations)
861 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
862 if (N2FPU_ENABLED_P (i) && N2FPU_UNSAFE_P (i))
863 warning (0, "switch %<-mcustom-%s%> has no effect unless "
864 "-funsafe-math-optimizations is specified", N2FPU_NAME (i));
865
866 /* Warn if the user is trying to use -mcustom-fmins et. al, that won't
867 get used without -ffinite-math-only. See fold_builtin_fmin_fmax ()
868 in builtins.c. */
869 if (!flag_finite_math_only)
870 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
871 if (N2FPU_ENABLED_P (i) && N2FPU_FINITE_P (i))
872 warning (0, "switch %<-mcustom-%s%> has no effect unless "
873 "-ffinite-math-only is specified", N2FPU_NAME (i));
874
875 /* Warn if the user is trying to use a custom rounding instruction
876 that won't get used without -fno-math-errno. See
877 expand_builtin_int_roundingfn_2 () in builtins.c. */
878 if (flag_errno_math)
879 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
880 if (N2FPU_ENABLED_P (i) && N2FPU_NO_ERRNO_P (i))
881 warning (0, "switch %<-mcustom-%s%> has no effect unless "
882 "-fno-math-errno is specified", N2FPU_NAME (i));
883
884 if (errors || custom_code_conflict)
885 fatal_error (input_location,
886 "conflicting use of -mcustom switches, target attributes, "
887 "and/or __builtin_custom_ functions");
888 }
889
890 static void
891 nios2_set_fpu_custom_code (enum n2fpu_code code, int n, bool override_p)
892 {
893 if (override_p || N2FPU_N (code) == -1)
894 N2FPU_N (code) = n;
895 nios2_register_custom_code (n, CCS_FPU, (int) code);
896 }
897
898 /* Type to represent a standard FPU config. */
899 struct nios2_fpu_config
900 {
901 const char *name;
902 bool set_sp_constants;
903 int code[n2fpu_code_num];
904 };
905
906 #define NIOS2_FPU_CONFIG_NUM 3
907 static struct nios2_fpu_config custom_fpu_config[NIOS2_FPU_CONFIG_NUM];
908
909 static void
910 nios2_init_fpu_configs (void)
911 {
912 struct nios2_fpu_config* cfg;
913 int i = 0;
914 #define NEXT_FPU_CONFIG \
915 do { \
916 cfg = &custom_fpu_config[i++]; \
917 memset (cfg, -1, sizeof (struct nios2_fpu_config));\
918 } while (0)
919
920 NEXT_FPU_CONFIG;
921 cfg->name = "60-1";
922 cfg->set_sp_constants = true;
923 cfg->code[n2fpu_fmuls] = 252;
924 cfg->code[n2fpu_fadds] = 253;
925 cfg->code[n2fpu_fsubs] = 254;
926
927 NEXT_FPU_CONFIG;
928 cfg->name = "60-2";
929 cfg->set_sp_constants = true;
930 cfg->code[n2fpu_fmuls] = 252;
931 cfg->code[n2fpu_fadds] = 253;
932 cfg->code[n2fpu_fsubs] = 254;
933 cfg->code[n2fpu_fdivs] = 255;
934
935 NEXT_FPU_CONFIG;
936 cfg->name = "72-3";
937 cfg->set_sp_constants = true;
938 cfg->code[n2fpu_floatus] = 243;
939 cfg->code[n2fpu_fixsi] = 244;
940 cfg->code[n2fpu_floatis] = 245;
941 cfg->code[n2fpu_fcmpgts] = 246;
942 cfg->code[n2fpu_fcmples] = 249;
943 cfg->code[n2fpu_fcmpeqs] = 250;
944 cfg->code[n2fpu_fcmpnes] = 251;
945 cfg->code[n2fpu_fmuls] = 252;
946 cfg->code[n2fpu_fadds] = 253;
947 cfg->code[n2fpu_fsubs] = 254;
948 cfg->code[n2fpu_fdivs] = 255;
949
950 #undef NEXT_FPU_CONFIG
951 gcc_assert (i == NIOS2_FPU_CONFIG_NUM);
952 }
953
954 static struct nios2_fpu_config *
955 nios2_match_custom_fpu_cfg (const char *cfgname, const char *endp)
956 {
957 int i;
958 for (i = 0; i < NIOS2_FPU_CONFIG_NUM; i++)
959 {
960 bool match = !(endp != NULL
961 ? strncmp (custom_fpu_config[i].name, cfgname,
962 endp - cfgname)
963 : strcmp (custom_fpu_config[i].name, cfgname));
964 if (match)
965 return &custom_fpu_config[i];
966 }
967 return NULL;
968 }
969
970 /* Use CFGNAME to lookup FPU config, ENDP if not NULL marks end of string.
971 OVERRIDE is true if loaded config codes should overwrite current state. */
972 static void
973 nios2_handle_custom_fpu_cfg (const char *cfgname, const char *endp,
974 bool override)
975 {
976 struct nios2_fpu_config *cfg = nios2_match_custom_fpu_cfg (cfgname, endp);
977 if (cfg)
978 {
979 unsigned int i;
980 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
981 if (cfg->code[i] >= 0)
982 nios2_set_fpu_custom_code ((enum n2fpu_code) i, cfg->code[i],
983 override);
984 if (cfg->set_sp_constants)
985 flag_single_precision_constant = 1;
986 }
987 else
988 warning (0, "ignoring unrecognized switch %<-mcustom-fpu-cfg%> "
989 "value %<%s%>", cfgname);
990
991 /* Guard against errors in the standard configurations. */
992 nios2_custom_check_insns ();
993 }
994
995 /* Check individual FPU insn options, and register custom code. */
996 static void
997 nios2_handle_custom_fpu_insn_option (int fpu_insn_index)
998 {
999 int param = N2FPU_N (fpu_insn_index);
1000
1001 if (0 <= param && param <= 255)
1002 nios2_register_custom_code (param, CCS_FPU, fpu_insn_index);
1003
1004 /* Valid values are 0-255, but also allow -1 so that the
1005 -mno-custom-<opt> switches work. */
1006 else if (param != -1)
1007 error ("switch %<-mcustom-%s%> value %d must be between 0 and 255",
1008 N2FPU_NAME (fpu_insn_index), param);
1009 }
1010
1011 /* Allocate a chunk of memory for per-function machine-dependent data. */
1012 static struct machine_function *
1013 nios2_init_machine_status (void)
1014 {
1015 return ggc_cleared_alloc<machine_function> ();
1016 }
1017
1018 /* Implement TARGET_OPTION_OVERRIDE. */
1019 static void
1020 nios2_option_override (void)
1021 {
1022 unsigned int i;
1023
1024 #ifdef SUBTARGET_OVERRIDE_OPTIONS
1025 SUBTARGET_OVERRIDE_OPTIONS;
1026 #endif
1027
1028 /* Check for unsupported options. */
1029 if (flag_pic && !TARGET_LINUX_ABI)
1030 sorry ("position-independent code requires the Linux ABI");
1031
1032 /* Function to allocate machine-dependent function status. */
1033 init_machine_status = &nios2_init_machine_status;
1034
1035 nios2_section_threshold
1036 = (global_options_set.x_g_switch_value
1037 ? g_switch_value : NIOS2_DEFAULT_GVALUE);
1038
1039 if (nios2_gpopt_option == gpopt_unspecified)
1040 {
1041 /* Default to -mgpopt unless -fpic or -fPIC. */
1042 if (flag_pic)
1043 nios2_gpopt_option = gpopt_none;
1044 else
1045 nios2_gpopt_option = gpopt_local;
1046 }
1047
1048 /* If we don't have mul, we don't have mulx either! */
1049 if (!TARGET_HAS_MUL && TARGET_HAS_MULX)
1050 target_flags &= ~MASK_HAS_MULX;
1051
1052 /* Initialize default FPU configurations. */
1053 nios2_init_fpu_configs ();
1054
1055 /* Set up default handling for floating point custom instructions.
1056
1057 Putting things in this order means that the -mcustom-fpu-cfg=
1058 switch will always be overridden by individual -mcustom-fadds=
1059 switches, regardless of the order in which they were specified
1060 on the command line.
1061
1062 This behavior of prioritization of individual -mcustom-<insn>=
1063 options before the -mcustom-fpu-cfg= switch is maintained for
1064 compatibility. */
1065 if (nios2_custom_fpu_cfg_string && *nios2_custom_fpu_cfg_string)
1066 nios2_handle_custom_fpu_cfg (nios2_custom_fpu_cfg_string, NULL, false);
1067
1068 /* Handle options for individual FPU insns. */
1069 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
1070 nios2_handle_custom_fpu_insn_option (i);
1071
1072 nios2_custom_check_insns ();
1073
1074 /* Save the initial options in case the user does function specific
1075 options. */
1076 target_option_default_node = target_option_current_node
1077 = build_target_option_node (&global_options);
1078 }
1079
1080 \f
1081 /* Return true if CST is a constant within range of movi/movui/movhi. */
1082 static bool
1083 nios2_simple_const_p (const_rtx cst)
1084 {
1085 HOST_WIDE_INT val = INTVAL (cst);
1086 return SMALL_INT (val) || SMALL_INT_UNSIGNED (val) || UPPER16_INT (val);
1087 }
1088
1089 /* Compute a (partial) cost for rtx X. Return true if the complete
1090 cost has been computed, and false if subexpressions should be
1091 scanned. In either case, *TOTAL contains the cost result. */
1092 static bool
1093 nios2_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
1094 int opno ATTRIBUTE_UNUSED,
1095 int *total, bool speed ATTRIBUTE_UNUSED)
1096 {
1097 switch (code)
1098 {
1099 case CONST_INT:
1100 if (INTVAL (x) == 0)
1101 {
1102 *total = COSTS_N_INSNS (0);
1103 return true;
1104 }
1105 else if (nios2_simple_const_p (x))
1106 {
1107 *total = COSTS_N_INSNS (2);
1108 return true;
1109 }
1110 else
1111 {
1112 *total = COSTS_N_INSNS (4);
1113 return true;
1114 }
1115
1116 case LABEL_REF:
1117 case SYMBOL_REF:
1118 case CONST:
1119 case CONST_DOUBLE:
1120 {
1121 *total = COSTS_N_INSNS (4);
1122 return true;
1123 }
1124
1125 case AND:
1126 {
1127 /* Recognize 'nor' insn pattern. */
1128 if (GET_CODE (XEXP (x, 0)) == NOT
1129 && GET_CODE (XEXP (x, 1)) == NOT)
1130 {
1131 *total = COSTS_N_INSNS (1);
1132 return true;
1133 }
1134 return false;
1135 }
1136
1137 case MULT:
1138 {
1139 *total = COSTS_N_INSNS (1);
1140 return false;
1141 }
1142 case SIGN_EXTEND:
1143 {
1144 *total = COSTS_N_INSNS (3);
1145 return false;
1146 }
1147 case ZERO_EXTEND:
1148 {
1149 *total = COSTS_N_INSNS (1);
1150 return false;
1151 }
1152
1153 default:
1154 return false;
1155 }
1156 }
1157
1158 /* Implement TARGET_PREFERRED_RELOAD_CLASS. */
1159 static reg_class_t
1160 nios2_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, reg_class_t regclass)
1161 {
1162 return regclass == NO_REGS ? GENERAL_REGS : regclass;
1163 }
1164
1165 /* Emit a call to __tls_get_addr. TI is the argument to this function.
1166 RET is an RTX for the return value location. The entire insn sequence
1167 is returned. */
1168 static GTY(()) rtx nios2_tls_symbol;
1169
1170 static rtx
1171 nios2_call_tls_get_addr (rtx ti)
1172 {
1173 rtx arg = gen_rtx_REG (Pmode, FIRST_ARG_REGNO);
1174 rtx ret = gen_rtx_REG (Pmode, FIRST_RETVAL_REGNO);
1175 rtx fn;
1176 rtx_insn *insn;
1177
1178 if (!nios2_tls_symbol)
1179 nios2_tls_symbol = init_one_libfunc ("__tls_get_addr");
1180
1181 emit_move_insn (arg, ti);
1182 fn = gen_rtx_MEM (QImode, nios2_tls_symbol);
1183 insn = emit_call_insn (gen_call_value (ret, fn, const0_rtx));
1184 RTL_CONST_CALL_P (insn) = 1;
1185 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), ret);
1186 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), arg);
1187
1188 return ret;
1189 }
1190
1191 /* Return true for large offsets requiring hiadj/lo relocation pairs. */
1192 static bool
1193 nios2_large_offset_p (int unspec)
1194 {
1195 gcc_assert (nios2_unspec_reloc_name (unspec) != NULL);
1196
1197 if (flag_pic == 2
1198 /* FIXME: TLS GOT offset relocations will eventually also get this
1199 treatment, after binutils support for those are also completed. */
1200 && (unspec == UNSPEC_PIC_SYM || unspec == UNSPEC_PIC_CALL_SYM))
1201 return true;
1202
1203 /* 'gotoff' offsets are always hiadj/lo. */
1204 if (unspec == UNSPEC_PIC_GOTOFF_SYM)
1205 return true;
1206
1207 return false;
1208 }
1209
1210 /* Return true for conforming unspec relocations. Also used in
1211 constraints.md and predicates.md. */
1212 bool
1213 nios2_unspec_reloc_p (rtx op)
1214 {
1215 return (GET_CODE (op) == CONST
1216 && GET_CODE (XEXP (op, 0)) == UNSPEC
1217 && ! nios2_large_offset_p (XINT (XEXP (op, 0), 1)));
1218 }
1219
1220 /* Helper to generate unspec constant. */
1221 static rtx
1222 nios2_unspec_offset (rtx loc, int unspec)
1223 {
1224 return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, loc),
1225 unspec));
1226 }
1227
1228 /* Generate GOT pointer based address with large offset. */
1229 static rtx
1230 nios2_large_got_address (rtx offset, rtx tmp)
1231 {
1232 if (!tmp)
1233 tmp = gen_reg_rtx (Pmode);
1234 emit_move_insn (tmp, offset);
1235 return gen_rtx_PLUS (Pmode, tmp, pic_offset_table_rtx);
1236 }
1237
1238 /* Generate a GOT pointer based address. */
1239 static rtx
1240 nios2_got_address (rtx loc, int unspec)
1241 {
1242 rtx offset = nios2_unspec_offset (loc, unspec);
1243 crtl->uses_pic_offset_table = 1;
1244
1245 if (nios2_large_offset_p (unspec))
1246 return force_reg (Pmode, nios2_large_got_address (offset, NULL_RTX));
1247
1248 return gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset);
1249 }
1250
1251 /* Generate the code to access LOC, a thread local SYMBOL_REF. The
1252 return value will be a valid address and move_operand (either a REG
1253 or a LO_SUM). */
1254 static rtx
1255 nios2_legitimize_tls_address (rtx loc)
1256 {
1257 rtx tmp, mem, tp;
1258 enum tls_model model = SYMBOL_REF_TLS_MODEL (loc);
1259
1260 switch (model)
1261 {
1262 case TLS_MODEL_GLOBAL_DYNAMIC:
1263 tmp = gen_reg_rtx (Pmode);
1264 emit_move_insn (tmp, nios2_got_address (loc, UNSPEC_ADD_TLS_GD));
1265 return nios2_call_tls_get_addr (tmp);
1266
1267 case TLS_MODEL_LOCAL_DYNAMIC:
1268 tmp = gen_reg_rtx (Pmode);
1269 emit_move_insn (tmp, nios2_got_address (loc, UNSPEC_ADD_TLS_LDM));
1270 return gen_rtx_PLUS (Pmode, nios2_call_tls_get_addr (tmp),
1271 nios2_unspec_offset (loc, UNSPEC_ADD_TLS_LDO));
1272
1273 case TLS_MODEL_INITIAL_EXEC:
1274 tmp = gen_reg_rtx (Pmode);
1275 mem = gen_const_mem (Pmode, nios2_got_address (loc, UNSPEC_LOAD_TLS_IE));
1276 emit_move_insn (tmp, mem);
1277 tp = gen_rtx_REG (Pmode, TP_REGNO);
1278 return gen_rtx_PLUS (Pmode, tp, tmp);
1279
1280 case TLS_MODEL_LOCAL_EXEC:
1281 tp = gen_rtx_REG (Pmode, TP_REGNO);
1282 return gen_rtx_PLUS (Pmode, tp,
1283 nios2_unspec_offset (loc, UNSPEC_ADD_TLS_LE));
1284 default:
1285 gcc_unreachable ();
1286 }
1287 }
1288
1289 /* Divide Support
1290
1291 If -O3 is used, we want to output a table lookup for
1292 divides between small numbers (both num and den >= 0
1293 and < 0x10). The overhead of this method in the worst
1294 case is 40 bytes in the text section (10 insns) and
1295 256 bytes in the data section. Additional divides do
1296 not incur additional penalties in the data section.
1297
1298 Code speed is improved for small divides by about 5x
1299 when using this method in the worse case (~9 cycles
1300 vs ~45). And in the worst case divides not within the
1301 table are penalized by about 10% (~5 cycles vs ~45).
1302 However in the typical case the penalty is not as bad
1303 because doing the long divide in only 45 cycles is
1304 quite optimistic.
1305
1306 ??? would be nice to have some benchmarks other
1307 than Dhrystone to back this up.
1308
1309 This bit of expansion is to create this instruction
1310 sequence as rtl.
1311 or $8, $4, $5
1312 slli $9, $4, 4
1313 cmpgeui $3, $8, 16
1314 beq $3, $0, .L3
1315 or $10, $9, $5
1316 add $12, $11, divide_table
1317 ldbu $2, 0($12)
1318 br .L1
1319 .L3:
1320 call slow_div
1321 .L1:
1322 # continue here with result in $2
1323
1324 ??? Ideally I would like the libcall block to contain all
1325 of this code, but I don't know how to do that. What it
1326 means is that if the divide can be eliminated, it may not
1327 completely disappear.
1328
1329 ??? The __divsi3_table label should ideally be moved out
1330 of this block and into a global. If it is placed into the
1331 sdata section we can save even more cycles by doing things
1332 gp relative. */
1333 void
1334 nios2_emit_expensive_div (rtx *operands, machine_mode mode)
1335 {
1336 rtx or_result, shift_left_result;
1337 rtx lookup_value;
1338 rtx_code_label *lab1, *lab3;
1339 rtx_insn *insns;
1340 rtx libfunc;
1341 rtx final_result;
1342 rtx_insn *tmp;
1343 rtx table;
1344
1345 /* It may look a little generic, but only SImode is supported for now. */
1346 gcc_assert (mode == SImode);
1347 libfunc = optab_libfunc (sdiv_optab, SImode);
1348
1349 lab1 = gen_label_rtx ();
1350 lab3 = gen_label_rtx ();
1351
1352 or_result = expand_simple_binop (SImode, IOR,
1353 operands[1], operands[2],
1354 0, 0, OPTAB_LIB_WIDEN);
1355
1356 emit_cmp_and_jump_insns (or_result, GEN_INT (15), GTU, 0,
1357 GET_MODE (or_result), 0, lab3);
1358 JUMP_LABEL (get_last_insn ()) = lab3;
1359
1360 shift_left_result = expand_simple_binop (SImode, ASHIFT,
1361 operands[1], GEN_INT (4),
1362 0, 0, OPTAB_LIB_WIDEN);
1363
1364 lookup_value = expand_simple_binop (SImode, IOR,
1365 shift_left_result, operands[2],
1366 0, 0, OPTAB_LIB_WIDEN);
1367 table = gen_rtx_PLUS (SImode, lookup_value,
1368 gen_rtx_SYMBOL_REF (SImode, "__divsi3_table"));
1369 convert_move (operands[0], gen_rtx_MEM (QImode, table), 1);
1370
1371 tmp = emit_jump_insn (gen_jump (lab1));
1372 JUMP_LABEL (tmp) = lab1;
1373 emit_barrier ();
1374
1375 emit_label (lab3);
1376 LABEL_NUSES (lab3) = 1;
1377
1378 start_sequence ();
1379 final_result = emit_library_call_value (libfunc, NULL_RTX,
1380 LCT_CONST, SImode, 2,
1381 operands[1], SImode,
1382 operands[2], SImode);
1383
1384 insns = get_insns ();
1385 end_sequence ();
1386 emit_libcall_block (insns, operands[0], final_result,
1387 gen_rtx_DIV (SImode, operands[1], operands[2]));
1388
1389 emit_label (lab1);
1390 LABEL_NUSES (lab1) = 1;
1391 }
1392
1393 \f
1394 /* Branches and compares. */
1395
1396 /* Return in *ALT_CODE and *ALT_OP, an alternate equivalent constant
1397 comparison, e.g. >= 1 into > 0. */
1398 static void
1399 nios2_alternate_compare_const (enum rtx_code code, rtx op,
1400 enum rtx_code *alt_code, rtx *alt_op,
1401 machine_mode mode)
1402 {
1403 HOST_WIDE_INT opval = INTVAL (op);
1404 enum rtx_code scode = signed_condition (code);
1405 bool dec_p = (scode == LT || scode == GE);
1406
1407 if (code == EQ || code == NE)
1408 {
1409 *alt_code = code;
1410 *alt_op = op;
1411 return;
1412 }
1413
1414 *alt_op = (dec_p
1415 ? gen_int_mode (opval - 1, mode)
1416 : gen_int_mode (opval + 1, mode));
1417
1418 /* The required conversion between [>,>=] and [<,<=] is captured
1419 by a reverse + swap of condition codes. */
1420 *alt_code = reverse_condition (swap_condition (code));
1421
1422 {
1423 /* Test if the incremented/decremented value crosses the over/underflow
1424 boundary. Supposedly, such boundary cases should already be transformed
1425 into always-true/false or EQ conditions, so use an assertion here. */
1426 unsigned HOST_WIDE_INT alt_opval = INTVAL (*alt_op);
1427 if (code == scode)
1428 alt_opval ^= (1 << (GET_MODE_BITSIZE (mode) - 1));
1429 alt_opval &= GET_MODE_MASK (mode);
1430 gcc_assert (dec_p ? alt_opval != GET_MODE_MASK (mode) : alt_opval != 0);
1431 }
1432 }
1433
1434 /* Return true if the constant comparison is supported by nios2. */
1435 static bool
1436 nios2_valid_compare_const_p (enum rtx_code code, rtx op)
1437 {
1438 switch (code)
1439 {
1440 case EQ: case NE: case GE: case LT:
1441 return SMALL_INT (INTVAL (op));
1442 case GEU: case LTU:
1443 return SMALL_INT_UNSIGNED (INTVAL (op));
1444 default:
1445 return false;
1446 }
1447 }
1448
1449 /* Checks if the FPU comparison in *CMP, *OP1, and *OP2 can be supported in
1450 the current configuration. Perform modifications if MODIFY_P is true.
1451 Returns true if FPU compare can be done. */
1452
1453 bool
1454 nios2_validate_fpu_compare (machine_mode mode, rtx *cmp, rtx *op1, rtx *op2,
1455 bool modify_p)
1456 {
1457 bool rev_p = false;
1458 enum rtx_code code = GET_CODE (*cmp);
1459
1460 if (!nios2_fpu_compare_enabled (code, mode))
1461 {
1462 code = swap_condition (code);
1463 if (nios2_fpu_compare_enabled (code, mode))
1464 rev_p = true;
1465 else
1466 return false;
1467 }
1468
1469 if (modify_p)
1470 {
1471 if (rev_p)
1472 {
1473 rtx tmp = *op1;
1474 *op1 = *op2;
1475 *op2 = tmp;
1476 }
1477 *op1 = force_reg (mode, *op1);
1478 *op2 = force_reg (mode, *op2);
1479 *cmp = gen_rtx_fmt_ee (code, mode, *op1, *op2);
1480 }
1481 return true;
1482 }
1483
1484 /* Checks and modifies the comparison in *CMP, *OP1, and *OP2 into valid
1485 nios2 supported form. Returns true if success. */
1486 bool
1487 nios2_validate_compare (machine_mode mode, rtx *cmp, rtx *op1, rtx *op2)
1488 {
1489 enum rtx_code code = GET_CODE (*cmp);
1490 enum rtx_code alt_code;
1491 rtx alt_op2;
1492
1493 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
1494 return nios2_validate_fpu_compare (mode, cmp, op1, op2, true);
1495
1496 if (!reg_or_0_operand (*op2, mode))
1497 {
1498 /* Create alternate constant compare. */
1499 nios2_alternate_compare_const (code, *op2, &alt_code, &alt_op2, mode);
1500
1501 /* If alterate op2 is zero(0), we can use it directly, possibly
1502 swapping the compare code. */
1503 if (alt_op2 == const0_rtx)
1504 {
1505 code = alt_code;
1506 *op2 = alt_op2;
1507 goto check_rebuild_cmp;
1508 }
1509
1510 /* Check if either constant compare can be used. */
1511 if (nios2_valid_compare_const_p (code, *op2))
1512 return true;
1513 else if (nios2_valid_compare_const_p (alt_code, alt_op2))
1514 {
1515 code = alt_code;
1516 *op2 = alt_op2;
1517 goto rebuild_cmp;
1518 }
1519
1520 /* We have to force op2 into a register now. Try to pick one
1521 with a lower cost. */
1522 if (! nios2_simple_const_p (*op2)
1523 && nios2_simple_const_p (alt_op2))
1524 {
1525 code = alt_code;
1526 *op2 = alt_op2;
1527 }
1528 *op2 = force_reg (SImode, *op2);
1529 }
1530 check_rebuild_cmp:
1531 if (code == GT || code == GTU || code == LE || code == LEU)
1532 {
1533 rtx t = *op1; *op1 = *op2; *op2 = t;
1534 code = swap_condition (code);
1535 }
1536 rebuild_cmp:
1537 *cmp = gen_rtx_fmt_ee (code, mode, *op1, *op2);
1538 return true;
1539 }
1540
1541
1542 /* Addressing Modes. */
1543
1544 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
1545 static bool
1546 nios2_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
1547 {
1548 rtx base, offset;
1549 split_const (x, &base, &offset);
1550 return GET_CODE (base) != SYMBOL_REF || !SYMBOL_REF_TLS_MODEL (base);
1551 }
1552
1553 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
1554 static bool
1555 nios2_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
1556 {
1557 return nios2_legitimate_constant_p (mode, x) == false;
1558 }
1559
1560 /* Return true if register REGNO is a valid base register.
1561 STRICT_P is true if REG_OK_STRICT is in effect. */
1562
1563 bool
1564 nios2_regno_ok_for_base_p (int regno, bool strict_p)
1565 {
1566 if (!HARD_REGISTER_NUM_P (regno))
1567 {
1568 if (!strict_p)
1569 return true;
1570
1571 if (!reg_renumber)
1572 return false;
1573
1574 regno = reg_renumber[regno];
1575 }
1576
1577 /* The fake registers will be eliminated to either the stack or
1578 hard frame pointer, both of which are usually valid base registers.
1579 Reload deals with the cases where the eliminated form isn't valid. */
1580 return (GP_REG_P (regno)
1581 || regno == FRAME_POINTER_REGNUM
1582 || regno == ARG_POINTER_REGNUM);
1583 }
1584
1585 /* Return true if the address expression formed by BASE + OFFSET is
1586 valid. */
1587 static bool
1588 nios2_valid_addr_expr_p (rtx base, rtx offset, bool strict_p)
1589 {
1590 if (!strict_p && GET_CODE (base) == SUBREG)
1591 base = SUBREG_REG (base);
1592 return (REG_P (base)
1593 && nios2_regno_ok_for_base_p (REGNO (base), strict_p)
1594 && (offset == NULL_RTX
1595 || const_arith_operand (offset, Pmode)
1596 || nios2_unspec_reloc_p (offset)));
1597 }
1598
1599 /* Implement TARGET_LEGITIMATE_ADDRESS_P. */
1600 static bool
1601 nios2_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
1602 rtx operand, bool strict_p)
1603 {
1604 switch (GET_CODE (operand))
1605 {
1606 /* Direct. */
1607 case SYMBOL_REF:
1608 if (SYMBOL_REF_TLS_MODEL (operand))
1609 return false;
1610
1611 /* Else, fall through. */
1612 case CONST:
1613 if (gprel_constant_p (operand))
1614 return true;
1615
1616 /* Else, fall through. */
1617 case LABEL_REF:
1618 case CONST_INT:
1619 case CONST_DOUBLE:
1620 return false;
1621
1622 /* Register indirect. */
1623 case REG:
1624 return nios2_regno_ok_for_base_p (REGNO (operand), strict_p);
1625
1626 /* Register indirect with displacement. */
1627 case PLUS:
1628 {
1629 rtx op0 = XEXP (operand, 0);
1630 rtx op1 = XEXP (operand, 1);
1631
1632 return (nios2_valid_addr_expr_p (op0, op1, strict_p)
1633 || nios2_valid_addr_expr_p (op1, op0, strict_p));
1634 }
1635
1636 default:
1637 break;
1638 }
1639 return false;
1640 }
1641
1642 /* Return true if SECTION is a small section name. */
1643 static bool
1644 nios2_small_section_name_p (const char *section)
1645 {
1646 return (strcmp (section, ".sbss") == 0
1647 || strncmp (section, ".sbss.", 6) == 0
1648 || strcmp (section, ".sdata") == 0
1649 || strncmp (section, ".sdata.", 7) == 0);
1650 }
1651
1652 /* Return true if EXP should be placed in the small data section. */
1653 static bool
1654 nios2_in_small_data_p (const_tree exp)
1655 {
1656 /* We want to merge strings, so we never consider them small data. */
1657 if (TREE_CODE (exp) == STRING_CST)
1658 return false;
1659
1660 if (TREE_CODE (exp) == VAR_DECL)
1661 {
1662 if (DECL_SECTION_NAME (exp))
1663 {
1664 const char *section = DECL_SECTION_NAME (exp);
1665 if (nios2_small_section_name_p (section))
1666 return true;
1667 }
1668 else
1669 {
1670 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
1671
1672 /* If this is an incomplete type with size 0, then we can't put it
1673 in sdata because it might be too big when completed. */
1674 if (size > 0
1675 && (unsigned HOST_WIDE_INT) size <= nios2_section_threshold)
1676 return true;
1677 }
1678 }
1679
1680 return false;
1681 }
1682
1683 /* Return true if symbol is in small data section. */
1684
1685 static bool
1686 nios2_symbol_ref_in_small_data_p (rtx sym)
1687 {
1688 tree decl;
1689
1690 gcc_assert (GET_CODE (sym) == SYMBOL_REF);
1691 decl = SYMBOL_REF_DECL (sym);
1692
1693 /* TLS variables are not accessed through the GP. */
1694 if (SYMBOL_REF_TLS_MODEL (sym) != 0)
1695 return false;
1696
1697 /* If the user has explicitly placed the symbol in a small data section
1698 via an attribute, generate gp-relative addressing even if the symbol
1699 is external, weak, or larger than we'd automatically put in the
1700 small data section. OTOH, if the symbol is located in some
1701 non-small-data section, we can't use gp-relative accesses on it
1702 unless the user has requested gpopt_data or gpopt_all. */
1703
1704 switch (nios2_gpopt_option)
1705 {
1706 case gpopt_none:
1707 /* Don't generate a gp-relative addressing mode if that's been
1708 disabled. */
1709 return false;
1710
1711 case gpopt_local:
1712 /* Use GP-relative addressing for small data symbols that are
1713 not external or weak, plus any symbols that have explicitly
1714 been placed in a small data section. */
1715 if (decl && DECL_SECTION_NAME (decl))
1716 return nios2_small_section_name_p (DECL_SECTION_NAME (decl));
1717 return (SYMBOL_REF_SMALL_P (sym)
1718 && !SYMBOL_REF_EXTERNAL_P (sym)
1719 && !(decl && DECL_WEAK (decl)));
1720
1721 case gpopt_global:
1722 /* Use GP-relative addressing for small data symbols, even if
1723 they are external or weak. Note that SYMBOL_REF_SMALL_P
1724 is also true of symbols that have explicitly been placed
1725 in a small data section. */
1726 return SYMBOL_REF_SMALL_P (sym);
1727
1728 case gpopt_data:
1729 /* Use GP-relative addressing for all data symbols regardless
1730 of the object size, but not for code symbols. This option
1731 is equivalent to the user asserting that the entire data
1732 section is accessible from the GP. */
1733 return !SYMBOL_REF_FUNCTION_P (sym);
1734
1735 case gpopt_all:
1736 /* Use GP-relative addressing for everything, including code.
1737 Effectively, the user has asserted that the entire program
1738 fits within the 64K range of the GP offset. */
1739 return true;
1740
1741 default:
1742 /* We shouldn't get here. */
1743 return false;
1744 }
1745 }
1746
1747 /* Implement TARGET_SECTION_TYPE_FLAGS. */
1748
1749 static unsigned int
1750 nios2_section_type_flags (tree decl, const char *name, int reloc)
1751 {
1752 unsigned int flags;
1753
1754 flags = default_section_type_flags (decl, name, reloc);
1755
1756 if (nios2_small_section_name_p (name))
1757 flags |= SECTION_SMALL;
1758
1759 return flags;
1760 }
1761
1762 /* Return true if SYMBOL_REF X binds locally. */
1763
1764 static bool
1765 nios2_symbol_binds_local_p (const_rtx x)
1766 {
1767 return (SYMBOL_REF_DECL (x)
1768 ? targetm.binds_local_p (SYMBOL_REF_DECL (x))
1769 : SYMBOL_REF_LOCAL_P (x));
1770 }
1771
1772 /* Position independent code related. */
1773
1774 /* Emit code to load the PIC register. */
1775 static void
1776 nios2_load_pic_register (void)
1777 {
1778 rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
1779
1780 emit_insn (gen_load_got_register (pic_offset_table_rtx, tmp));
1781 emit_insn (gen_add3_insn (pic_offset_table_rtx, pic_offset_table_rtx, tmp));
1782 }
1783
1784 /* Generate a PIC address as a MEM rtx. */
1785 static rtx
1786 nios2_load_pic_address (rtx sym, int unspec, rtx tmp)
1787 {
1788 if (flag_pic == 2
1789 && GET_CODE (sym) == SYMBOL_REF
1790 && nios2_symbol_binds_local_p (sym))
1791 /* Under -fPIC, generate a GOTOFF address for local symbols. */
1792 {
1793 rtx offset = nios2_unspec_offset (sym, UNSPEC_PIC_GOTOFF_SYM);
1794 crtl->uses_pic_offset_table = 1;
1795 return nios2_large_got_address (offset, tmp);
1796 }
1797
1798 return gen_const_mem (Pmode, nios2_got_address (sym, unspec));
1799 }
1800
1801 /* Nonzero if the constant value X is a legitimate general operand
1802 when generating PIC code. It is given that flag_pic is on and
1803 that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
1804 bool
1805 nios2_legitimate_pic_operand_p (rtx x)
1806 {
1807 if (GET_CODE (x) == CONST
1808 && GET_CODE (XEXP (x, 0)) == UNSPEC
1809 && nios2_large_offset_p (XINT (XEXP (x, 0), 1)))
1810 return true;
1811
1812 return ! (GET_CODE (x) == SYMBOL_REF
1813 || GET_CODE (x) == LABEL_REF || GET_CODE (x) == CONST);
1814 }
1815
1816 /* Return TRUE if X is a thread-local symbol. */
1817 static bool
1818 nios2_tls_symbol_p (rtx x)
1819 {
1820 return (targetm.have_tls && GET_CODE (x) == SYMBOL_REF
1821 && SYMBOL_REF_TLS_MODEL (x) != 0);
1822 }
1823
1824 /* Legitimize addresses that are CONSTANT_P expressions. */
1825 static rtx
1826 nios2_legitimize_constant_address (rtx addr)
1827 {
1828 rtx base, offset;
1829 split_const (addr, &base, &offset);
1830
1831 if (nios2_tls_symbol_p (base))
1832 base = nios2_legitimize_tls_address (base);
1833 else if (flag_pic)
1834 base = nios2_load_pic_address (base, UNSPEC_PIC_SYM, NULL_RTX);
1835 else
1836 return addr;
1837
1838 if (offset != const0_rtx)
1839 {
1840 gcc_assert (can_create_pseudo_p ());
1841 return gen_rtx_PLUS (Pmode, force_reg (Pmode, base),
1842 (CONST_INT_P (offset)
1843 ? (SMALL_INT (INTVAL (offset))
1844 ? offset : force_reg (Pmode, offset))
1845 : offset));
1846 }
1847 return base;
1848 }
1849
1850 /* Implement TARGET_LEGITIMIZE_ADDRESS. */
1851 static rtx
1852 nios2_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
1853 machine_mode mode ATTRIBUTE_UNUSED)
1854 {
1855 if (CONSTANT_P (x))
1856 return nios2_legitimize_constant_address (x);
1857
1858 /* For the TLS LE (Local Exec) model, the compiler may try to
1859 combine constant offsets with unspec relocs, creating address RTXs
1860 looking like this:
1861 (plus:SI (reg:SI 23 r23)
1862 (const:SI
1863 (plus:SI
1864 (unspec:SI [(symbol_ref:SI ("var"))] UNSPEC_ADD_TLS_LE)
1865 (const_int 48 [0x30]))))
1866
1867 This usually happens when 'var' is a thread-local struct variable,
1868 and access of a field in var causes the addend.
1869
1870 We typically want this combining, so transform the above into this
1871 form, which is allowed:
1872 (plus:SI (reg:SI 23 r23)
1873 (const:SI
1874 (unspec:SI
1875 [(const:SI
1876 (plus:SI (symbol_ref:SI ("var"))
1877 (const_int 48 [0x30])))] UNSPEC_ADD_TLS_LE)))
1878
1879 Which will be output as '%tls_le(var+48)(r23)' in assembly. */
1880 if (GET_CODE (x) == PLUS
1881 && GET_CODE (XEXP (x, 0)) == REG
1882 && GET_CODE (XEXP (x, 1)) == CONST)
1883 {
1884 rtx unspec, offset, reg = XEXP (x, 0);
1885 split_const (XEXP (x, 1), &unspec, &offset);
1886 if (GET_CODE (unspec) == UNSPEC
1887 && !nios2_large_offset_p (XINT (unspec, 1))
1888 && offset != const0_rtx)
1889 {
1890 unspec = copy_rtx (unspec);
1891 XVECEXP (unspec, 0, 0)
1892 = plus_constant (Pmode, XVECEXP (unspec, 0, 0), INTVAL (offset));
1893 x = gen_rtx_PLUS (Pmode, reg, gen_rtx_CONST (Pmode, unspec));
1894 }
1895 }
1896
1897 return x;
1898 }
1899
1900 static rtx
1901 nios2_delegitimize_address (rtx x)
1902 {
1903 x = delegitimize_mem_from_attrs (x);
1904
1905 if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
1906 {
1907 switch (XINT (XEXP (x, 0), 1))
1908 {
1909 case UNSPEC_PIC_SYM:
1910 case UNSPEC_PIC_CALL_SYM:
1911 case UNSPEC_PIC_GOTOFF_SYM:
1912 case UNSPEC_ADD_TLS_GD:
1913 case UNSPEC_ADD_TLS_LDM:
1914 case UNSPEC_LOAD_TLS_IE:
1915 case UNSPEC_ADD_TLS_LE:
1916 x = XVECEXP (XEXP (x, 0), 0, 0);
1917 gcc_assert (CONSTANT_P (x));
1918 break;
1919 }
1920 }
1921 return x;
1922 }
1923
1924 /* Main expander function for RTL moves. */
1925 bool
1926 nios2_emit_move_sequence (rtx *operands, machine_mode mode)
1927 {
1928 rtx to = operands[0];
1929 rtx from = operands[1];
1930
1931 if (!register_operand (to, mode) && !reg_or_0_operand (from, mode))
1932 {
1933 gcc_assert (can_create_pseudo_p ());
1934 from = copy_to_mode_reg (mode, from);
1935 }
1936
1937 if (GET_CODE (from) == SYMBOL_REF || GET_CODE (from) == LABEL_REF
1938 || (GET_CODE (from) == CONST
1939 && GET_CODE (XEXP (from, 0)) != UNSPEC))
1940 from = nios2_legitimize_constant_address (from);
1941
1942 operands[0] = to;
1943 operands[1] = from;
1944 return false;
1945 }
1946
1947 /* The function with address *ADDR is being called. If the address
1948 needs to be loaded from the GOT, emit the instruction to do so and
1949 update *ADDR to point to the rtx for the loaded value.
1950 If REG != NULL_RTX, it is used as the target/scratch register in the
1951 GOT address calculation. */
1952 void
1953 nios2_adjust_call_address (rtx *call_op, rtx reg)
1954 {
1955 if (MEM_P (*call_op))
1956 call_op = &XEXP (*call_op, 0);
1957
1958 rtx addr = *call_op;
1959 if (flag_pic && CONSTANT_P (addr))
1960 {
1961 rtx tmp = reg ? reg : NULL_RTX;
1962 if (!reg)
1963 reg = gen_reg_rtx (Pmode);
1964 addr = nios2_load_pic_address (addr, UNSPEC_PIC_CALL_SYM, tmp);
1965 emit_insn (gen_rtx_SET (reg, addr));
1966 *call_op = reg;
1967 }
1968 }
1969
1970 \f
1971 /* Output assembly language related definitions. */
1972
1973 /* Print the operand OP to file stream FILE modified by LETTER.
1974 LETTER can be one of:
1975
1976 i: print "i" if OP is an immediate, except 0
1977 o: print "io" if OP is volatile
1978 z: for const0_rtx print $0 instead of 0
1979 H: for %hiadj
1980 L: for %lo
1981 U: for upper half of 32 bit value
1982 D: for the upper 32-bits of a 64-bit double value
1983 R: prints reverse condition.
1984 */
1985 static void
1986 nios2_print_operand (FILE *file, rtx op, int letter)
1987 {
1988
1989 switch (letter)
1990 {
1991 case 'i':
1992 if (CONSTANT_P (op) && op != const0_rtx)
1993 fprintf (file, "i");
1994 return;
1995
1996 case 'o':
1997 if (GET_CODE (op) == MEM
1998 && ((MEM_VOLATILE_P (op) && TARGET_BYPASS_CACHE_VOLATILE)
1999 || TARGET_BYPASS_CACHE))
2000 fprintf (file, "io");
2001 return;
2002
2003 default:
2004 break;
2005 }
2006
2007 if (comparison_operator (op, VOIDmode))
2008 {
2009 enum rtx_code cond = GET_CODE (op);
2010 if (letter == 0)
2011 {
2012 fprintf (file, "%s", GET_RTX_NAME (cond));
2013 return;
2014 }
2015 if (letter == 'R')
2016 {
2017 fprintf (file, "%s", GET_RTX_NAME (reverse_condition (cond)));
2018 return;
2019 }
2020 }
2021
2022 switch (GET_CODE (op))
2023 {
2024 case REG:
2025 if (letter == 0 || letter == 'z')
2026 {
2027 fprintf (file, "%s", reg_names[REGNO (op)]);
2028 return;
2029 }
2030 else if (letter == 'D')
2031 {
2032 fprintf (file, "%s", reg_names[REGNO (op)+1]);
2033 return;
2034 }
2035 break;
2036
2037 case CONST_INT:
2038 if (INTVAL (op) == 0 && letter == 'z')
2039 {
2040 fprintf (file, "zero");
2041 return;
2042 }
2043
2044 if (letter == 'U')
2045 {
2046 HOST_WIDE_INT val = INTVAL (op);
2047 val = (val >> 16) & 0xFFFF;
2048 output_addr_const (file, gen_int_mode (val, SImode));
2049 return;
2050 }
2051 /* Else, fall through. */
2052
2053 case CONST:
2054 case LABEL_REF:
2055 case SYMBOL_REF:
2056 case CONST_DOUBLE:
2057 if (letter == 0 || letter == 'z')
2058 {
2059 output_addr_const (file, op);
2060 return;
2061 }
2062 else if (letter == 'H' || letter == 'L')
2063 {
2064 fprintf (file, "%%");
2065 if (GET_CODE (op) == CONST
2066 && GET_CODE (XEXP (op, 0)) == UNSPEC)
2067 {
2068 rtx unspec = XEXP (op, 0);
2069 int unspec_reloc = XINT (unspec, 1);
2070 gcc_assert (nios2_large_offset_p (unspec_reloc));
2071 fprintf (file, "%s_", nios2_unspec_reloc_name (unspec_reloc));
2072 op = XVECEXP (unspec, 0, 0);
2073 }
2074 fprintf (file, letter == 'H' ? "hiadj(" : "lo(");
2075 output_addr_const (file, op);
2076 fprintf (file, ")");
2077 return;
2078 }
2079 break;
2080
2081 case SUBREG:
2082 case MEM:
2083 if (letter == 0)
2084 {
2085 output_address (op);
2086 return;
2087 }
2088 break;
2089
2090 case CODE_LABEL:
2091 if (letter == 0)
2092 {
2093 output_addr_const (file, op);
2094 return;
2095 }
2096 break;
2097
2098 default:
2099 break;
2100 }
2101
2102 output_operand_lossage ("Unsupported operand for code '%c'", letter);
2103 gcc_unreachable ();
2104 }
2105
2106 /* Return true if this is a GP-relative accessible reference. */
2107 bool
2108 gprel_constant_p (rtx op)
2109 {
2110 if (GET_CODE (op) == SYMBOL_REF
2111 && nios2_symbol_ref_in_small_data_p (op))
2112 return true;
2113 else if (GET_CODE (op) == CONST
2114 && GET_CODE (XEXP (op, 0)) == PLUS)
2115 return gprel_constant_p (XEXP (XEXP (op, 0), 0));
2116
2117 return false;
2118 }
2119
2120 /* Return the name string for a supported unspec reloc offset. */
2121 static const char *
2122 nios2_unspec_reloc_name (int unspec)
2123 {
2124 switch (unspec)
2125 {
2126 case UNSPEC_PIC_SYM:
2127 return "got";
2128 case UNSPEC_PIC_CALL_SYM:
2129 return "call";
2130 case UNSPEC_PIC_GOTOFF_SYM:
2131 return "gotoff";
2132 case UNSPEC_LOAD_TLS_IE:
2133 return "tls_ie";
2134 case UNSPEC_ADD_TLS_LE:
2135 return "tls_le";
2136 case UNSPEC_ADD_TLS_GD:
2137 return "tls_gd";
2138 case UNSPEC_ADD_TLS_LDM:
2139 return "tls_ldm";
2140 case UNSPEC_ADD_TLS_LDO:
2141 return "tls_ldo";
2142 default:
2143 return NULL;
2144 }
2145 }
2146
2147 /* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */
2148 static bool
2149 nios2_output_addr_const_extra (FILE *file, rtx op)
2150 {
2151 const char *name;
2152 gcc_assert (GET_CODE (op) == UNSPEC);
2153
2154 /* Support for printing out const unspec relocations. */
2155 name = nios2_unspec_reloc_name (XINT (op, 1));
2156 if (name)
2157 {
2158 fprintf (file, "%%%s(", name);
2159 output_addr_const (file, XVECEXP (op, 0, 0));
2160 fprintf (file, ")");
2161 return true;
2162 }
2163 return false;
2164 }
2165
2166 /* Implement TARGET_PRINT_OPERAND_ADDRESS. */
2167 static void
2168 nios2_print_operand_address (FILE *file, rtx op)
2169 {
2170 switch (GET_CODE (op))
2171 {
2172 case CONST:
2173 case CONST_INT:
2174 case LABEL_REF:
2175 case CONST_DOUBLE:
2176 case SYMBOL_REF:
2177 if (gprel_constant_p (op))
2178 {
2179 fprintf (file, "%%gprel(");
2180 output_addr_const (file, op);
2181 fprintf (file, ")(%s)", reg_names[GP_REGNO]);
2182 return;
2183 }
2184
2185 break;
2186
2187 case PLUS:
2188 {
2189 rtx op0 = XEXP (op, 0);
2190 rtx op1 = XEXP (op, 1);
2191
2192 if (REG_P (op0) && CONSTANT_P (op1))
2193 {
2194 output_addr_const (file, op1);
2195 fprintf (file, "(%s)", reg_names[REGNO (op0)]);
2196 return;
2197 }
2198 else if (REG_P (op1) && CONSTANT_P (op0))
2199 {
2200 output_addr_const (file, op0);
2201 fprintf (file, "(%s)", reg_names[REGNO (op1)]);
2202 return;
2203 }
2204 }
2205 break;
2206
2207 case REG:
2208 fprintf (file, "0(%s)", reg_names[REGNO (op)]);
2209 return;
2210
2211 case MEM:
2212 {
2213 rtx base = XEXP (op, 0);
2214 nios2_print_operand_address (file, base);
2215 return;
2216 }
2217 default:
2218 break;
2219 }
2220
2221 fprintf (stderr, "Missing way to print address\n");
2222 debug_rtx (op);
2223 gcc_unreachable ();
2224 }
2225
2226 /* Implement TARGET_ASM_OUTPUT_DWARF_DTPREL. */
2227 static void
2228 nios2_output_dwarf_dtprel (FILE *file, int size, rtx x)
2229 {
2230 gcc_assert (size == 4);
2231 fprintf (file, "\t.4byte\t%%tls_ldo(");
2232 output_addr_const (file, x);
2233 fprintf (file, ")");
2234 }
2235
2236 /* Implemet TARGET_ASM_FILE_END. */
2237
2238 static void
2239 nios2_asm_file_end (void)
2240 {
2241 /* The Nios II Linux stack is mapped non-executable by default, so add a
2242 .note.GNU-stack section for switching to executable stacks only when
2243 trampolines are generated. */
2244 if (TARGET_LINUX_ABI && trampolines_created)
2245 file_end_indicate_exec_stack ();
2246 }
2247
2248 /* Implement TARGET_ASM_FUNCTION_PROLOGUE. */
2249 static void
2250 nios2_asm_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
2251 {
2252 if (flag_verbose_asm || flag_debug_asm)
2253 {
2254 nios2_compute_frame_layout ();
2255 nios2_dump_frame_layout (file);
2256 }
2257 }
2258
2259 /* Emit assembly of custom FPU instructions. */
2260 const char *
2261 nios2_fpu_insn_asm (enum n2fpu_code code)
2262 {
2263 static char buf[256];
2264 const char *op1, *op2, *op3;
2265 int ln = 256, n = 0;
2266
2267 int N = N2FPU_N (code);
2268 int num_operands = N2FPU (code).num_operands;
2269 const char *insn_name = N2FPU_NAME (code);
2270 tree ftype = nios2_ftype (N2FPU_FTCODE (code));
2271 machine_mode dst_mode = TYPE_MODE (TREE_TYPE (ftype));
2272 machine_mode src_mode = TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (ftype)));
2273
2274 /* Prepare X register for DF input operands. */
2275 if (GET_MODE_SIZE (src_mode) == 8 && num_operands == 3)
2276 n = snprintf (buf, ln, "custom\t%d, zero, %%1, %%D1 # fwrx %%1\n\t",
2277 N2FPU_N (n2fpu_fwrx));
2278
2279 if (src_mode == SFmode)
2280 {
2281 if (dst_mode == VOIDmode)
2282 {
2283 /* The fwry case. */
2284 op1 = op3 = "zero";
2285 op2 = "%0";
2286 num_operands -= 1;
2287 }
2288 else
2289 {
2290 op1 = (dst_mode == DFmode ? "%D0" : "%0");
2291 op2 = "%1";
2292 op3 = (num_operands == 2 ? "zero" : "%2");
2293 }
2294 }
2295 else if (src_mode == DFmode)
2296 {
2297 if (dst_mode == VOIDmode)
2298 {
2299 /* The fwrx case. */
2300 op1 = "zero";
2301 op2 = "%0";
2302 op3 = "%D0";
2303 num_operands -= 1;
2304 }
2305 else
2306 {
2307 op1 = (dst_mode == DFmode ? "%D0" : "%0");
2308 op2 = (num_operands == 2 ? "%1" : "%2");
2309 op3 = (num_operands == 2 ? "%D1" : "%D2");
2310 }
2311 }
2312 else if (src_mode == VOIDmode)
2313 {
2314 /* frdxlo, frdxhi, frdy cases. */
2315 gcc_assert (dst_mode == SFmode);
2316 op1 = "%0";
2317 op2 = op3 = "zero";
2318 }
2319 else if (src_mode == SImode)
2320 {
2321 /* Conversion operators. */
2322 gcc_assert (num_operands == 2);
2323 op1 = (dst_mode == DFmode ? "%D0" : "%0");
2324 op2 = "%1";
2325 op3 = "zero";
2326 }
2327 else
2328 gcc_unreachable ();
2329
2330 /* Main instruction string. */
2331 n += snprintf (buf + n, ln - n, "custom\t%d, %s, %s, %s # %s %%0%s%s",
2332 N, op1, op2, op3, insn_name,
2333 (num_operands >= 2 ? ", %1" : ""),
2334 (num_operands == 3 ? ", %2" : ""));
2335
2336 /* Extraction of Y register for DF results. */
2337 if (dst_mode == DFmode)
2338 snprintf (buf + n, ln - n, "\n\tcustom\t%d, %%0, zero, zero # frdy %%0",
2339 N2FPU_N (n2fpu_frdy));
2340 return buf;
2341 }
2342
2343 \f
2344
2345 /* Function argument related. */
2346
2347 /* Define where to put the arguments to a function. Value is zero to
2348 push the argument on the stack, or a hard register in which to
2349 store the argument.
2350
2351 MODE is the argument's machine mode.
2352 TYPE is the data type of the argument (as a tree).
2353 This is null for libcalls where that information may
2354 not be available.
2355 CUM is a variable of type CUMULATIVE_ARGS which gives info about
2356 the preceding args and about the function being called.
2357 NAMED is nonzero if this argument is a named parameter
2358 (otherwise it is an extra parameter matching an ellipsis). */
2359
2360 static rtx
2361 nios2_function_arg (cumulative_args_t cum_v, machine_mode mode,
2362 const_tree type ATTRIBUTE_UNUSED,
2363 bool named ATTRIBUTE_UNUSED)
2364 {
2365 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2366 rtx return_rtx = NULL_RTX;
2367
2368 if (cum->regs_used < NUM_ARG_REGS)
2369 return_rtx = gen_rtx_REG (mode, FIRST_ARG_REGNO + cum->regs_used);
2370
2371 return return_rtx;
2372 }
2373
2374 /* Return number of bytes, at the beginning of the argument, that must be
2375 put in registers. 0 is the argument is entirely in registers or entirely
2376 in memory. */
2377
2378 static int
2379 nios2_arg_partial_bytes (cumulative_args_t cum_v,
2380 machine_mode mode, tree type ATTRIBUTE_UNUSED,
2381 bool named ATTRIBUTE_UNUSED)
2382 {
2383 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2384 HOST_WIDE_INT param_size;
2385
2386 if (mode == BLKmode)
2387 {
2388 param_size = int_size_in_bytes (type);
2389 gcc_assert (param_size >= 0);
2390 }
2391 else
2392 param_size = GET_MODE_SIZE (mode);
2393
2394 /* Convert to words (round up). */
2395 param_size = (UNITS_PER_WORD - 1 + param_size) / UNITS_PER_WORD;
2396
2397 if (cum->regs_used < NUM_ARG_REGS
2398 && cum->regs_used + param_size > NUM_ARG_REGS)
2399 return (NUM_ARG_REGS - cum->regs_used) * UNITS_PER_WORD;
2400
2401 return 0;
2402 }
2403
2404 /* Update the data in CUM to advance over an argument of mode MODE
2405 and data type TYPE; TYPE is null for libcalls where that information
2406 may not be available. */
2407
2408 static void
2409 nios2_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
2410 const_tree type ATTRIBUTE_UNUSED,
2411 bool named ATTRIBUTE_UNUSED)
2412 {
2413 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2414 HOST_WIDE_INT param_size;
2415
2416 if (mode == BLKmode)
2417 {
2418 param_size = int_size_in_bytes (type);
2419 gcc_assert (param_size >= 0);
2420 }
2421 else
2422 param_size = GET_MODE_SIZE (mode);
2423
2424 /* Convert to words (round up). */
2425 param_size = (UNITS_PER_WORD - 1 + param_size) / UNITS_PER_WORD;
2426
2427 if (cum->regs_used + param_size > NUM_ARG_REGS)
2428 cum->regs_used = NUM_ARG_REGS;
2429 else
2430 cum->regs_used += param_size;
2431 }
2432
2433 enum direction
2434 nios2_function_arg_padding (machine_mode mode, const_tree type)
2435 {
2436 /* On little-endian targets, the first byte of every stack argument
2437 is passed in the first byte of the stack slot. */
2438 if (!BYTES_BIG_ENDIAN)
2439 return upward;
2440
2441 /* Otherwise, integral types are padded downward: the last byte of a
2442 stack argument is passed in the last byte of the stack slot. */
2443 if (type != 0
2444 ? INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)
2445 : GET_MODE_CLASS (mode) == MODE_INT)
2446 return downward;
2447
2448 /* Arguments smaller than a stack slot are padded downward. */
2449 if (mode != BLKmode)
2450 return (GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY) ? upward : downward;
2451
2452 return ((int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT))
2453 ? upward : downward);
2454 }
2455
2456 enum direction
2457 nios2_block_reg_padding (machine_mode mode, tree type,
2458 int first ATTRIBUTE_UNUSED)
2459 {
2460 return nios2_function_arg_padding (mode, type);
2461 }
2462
2463 /* Emit RTL insns to initialize the variable parts of a trampoline.
2464 FNADDR is an RTX for the address of the function's pure code.
2465 CXT is an RTX for the static chain value for the function.
2466 On Nios II, we handle this by a library call. */
2467 static void
2468 nios2_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
2469 {
2470 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
2471 rtx ctx_reg = force_reg (Pmode, cxt);
2472 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
2473
2474 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
2475 LCT_NORMAL, VOIDmode, 3, addr, Pmode, fnaddr, Pmode,
2476 ctx_reg, Pmode);
2477 }
2478
2479 /* Implement TARGET_FUNCTION_VALUE. */
2480 static rtx
2481 nios2_function_value (const_tree ret_type, const_tree fn ATTRIBUTE_UNUSED,
2482 bool outgoing ATTRIBUTE_UNUSED)
2483 {
2484 return gen_rtx_REG (TYPE_MODE (ret_type), FIRST_RETVAL_REGNO);
2485 }
2486
2487 /* Implement TARGET_LIBCALL_VALUE. */
2488 static rtx
2489 nios2_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
2490 {
2491 return gen_rtx_REG (mode, FIRST_RETVAL_REGNO);
2492 }
2493
2494 /* Implement TARGET_FUNCTION_VALUE_REGNO_P. */
2495 static bool
2496 nios2_function_value_regno_p (const unsigned int regno)
2497 {
2498 return regno == FIRST_RETVAL_REGNO;
2499 }
2500
2501 /* Implement TARGET_RETURN_IN_MEMORY. */
2502 static bool
2503 nios2_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
2504 {
2505 return (int_size_in_bytes (type) > (2 * UNITS_PER_WORD)
2506 || int_size_in_bytes (type) == -1);
2507 }
2508
2509 /* TODO: It may be possible to eliminate the copyback and implement
2510 own va_arg type. */
2511 static void
2512 nios2_setup_incoming_varargs (cumulative_args_t cum_v,
2513 machine_mode mode, tree type,
2514 int *pretend_size, int second_time)
2515 {
2516 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2517 CUMULATIVE_ARGS local_cum;
2518 cumulative_args_t local_cum_v = pack_cumulative_args (&local_cum);
2519 int regs_to_push;
2520 int pret_size;
2521
2522 local_cum = *cum;
2523 nios2_function_arg_advance (local_cum_v, mode, type, 1);
2524
2525 regs_to_push = NUM_ARG_REGS - local_cum.regs_used;
2526
2527 if (!second_time && regs_to_push > 0)
2528 {
2529 rtx ptr = virtual_incoming_args_rtx;
2530 rtx mem = gen_rtx_MEM (BLKmode, ptr);
2531 emit_insn (gen_blockage ());
2532 move_block_from_reg (local_cum.regs_used + FIRST_ARG_REGNO, mem,
2533 regs_to_push);
2534 emit_insn (gen_blockage ());
2535 }
2536
2537 pret_size = regs_to_push * UNITS_PER_WORD;
2538 if (pret_size)
2539 *pretend_size = pret_size;
2540 }
2541
2542 \f
2543
2544 /* Init FPU builtins. */
2545 static void
2546 nios2_init_fpu_builtins (int start_code)
2547 {
2548 tree fndecl;
2549 char builtin_name[64] = "__builtin_custom_";
2550 unsigned int i, n = strlen ("__builtin_custom_");
2551
2552 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
2553 {
2554 snprintf (builtin_name + n, sizeof (builtin_name) - n,
2555 "%s", N2FPU_NAME (i));
2556 fndecl =
2557 add_builtin_function (builtin_name, nios2_ftype (N2FPU_FTCODE (i)),
2558 start_code + i, BUILT_IN_MD, NULL, NULL_TREE);
2559 nios2_register_builtin_fndecl (start_code + i, fndecl);
2560 }
2561 }
2562
2563 /* Helper function for expanding FPU builtins. */
2564 static rtx
2565 nios2_expand_fpu_builtin (tree exp, unsigned int code, rtx target)
2566 {
2567 struct expand_operand ops[MAX_RECOG_OPERANDS];
2568 enum insn_code icode = N2FPU_ICODE (code);
2569 int nargs, argno, opno = 0;
2570 int num_operands = N2FPU (code).num_operands;
2571 machine_mode dst_mode = TYPE_MODE (TREE_TYPE (exp));
2572 bool has_target_p = (dst_mode != VOIDmode);
2573
2574 if (N2FPU_N (code) < 0)
2575 fatal_error (input_location,
2576 "Cannot call %<__builtin_custom_%s%> without specifying switch"
2577 " %<-mcustom-%s%>", N2FPU_NAME (code), N2FPU_NAME (code));
2578 if (has_target_p)
2579 create_output_operand (&ops[opno++], target, dst_mode);
2580 else
2581 /* Subtract away the count of the VOID return, mainly for fwrx/fwry. */
2582 num_operands -= 1;
2583 nargs = call_expr_nargs (exp);
2584 for (argno = 0; argno < nargs; argno++)
2585 {
2586 tree arg = CALL_EXPR_ARG (exp, argno);
2587 create_input_operand (&ops[opno++], expand_normal (arg),
2588 TYPE_MODE (TREE_TYPE (arg)));
2589 }
2590 if (!maybe_expand_insn (icode, num_operands, ops))
2591 {
2592 error ("invalid argument to built-in function");
2593 return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
2594 }
2595 return has_target_p ? ops[0].value : const0_rtx;
2596 }
2597
2598 /* Nios II has custom instruction built-in functions of the forms:
2599 __builtin_custom_n
2600 __builtin_custom_nX
2601 __builtin_custom_nXX
2602 __builtin_custom_Xn
2603 __builtin_custom_XnX
2604 __builtin_custom_XnXX
2605
2606 where each X could be either 'i' (int), 'f' (float), or 'p' (void*).
2607 Therefore with 0-1 return values, and 0-2 arguments, we have a
2608 total of (3 + 1) * (1 + 3 + 9) == 52 custom builtin functions.
2609 */
2610 #define NUM_CUSTOM_BUILTINS ((3 + 1) * (1 + 3 + 9))
2611 static char custom_builtin_name[NUM_CUSTOM_BUILTINS][5];
2612
2613 static void
2614 nios2_init_custom_builtins (int start_code)
2615 {
2616 tree builtin_ftype, ret_type, fndecl;
2617 char builtin_name[32] = "__builtin_custom_";
2618 int n = strlen ("__builtin_custom_");
2619 int builtin_code = 0;
2620 int lhs, rhs1, rhs2;
2621
2622 struct { tree type; const char *c; } op[4];
2623 /* z */ op[0].c = ""; op[0].type = NULL_TREE;
2624 /* f */ op[1].c = "f"; op[1].type = float_type_node;
2625 /* i */ op[2].c = "i"; op[2].type = integer_type_node;
2626 /* p */ op[3].c = "p"; op[3].type = ptr_type_node;
2627
2628 /* We enumerate through the possible operand types to create all the
2629 __builtin_custom_XnXX function tree types. Note that these may slightly
2630 overlap with the function types created for other fixed builtins. */
2631
2632 for (lhs = 0; lhs < 4; lhs++)
2633 for (rhs1 = 0; rhs1 < 4; rhs1++)
2634 for (rhs2 = 0; rhs2 < 4; rhs2++)
2635 {
2636 if (rhs1 == 0 && rhs2 != 0)
2637 continue;
2638 ret_type = (op[lhs].type ? op[lhs].type : void_type_node);
2639 builtin_ftype
2640 = build_function_type_list (ret_type, integer_type_node,
2641 op[rhs1].type, op[rhs2].type,
2642 NULL_TREE);
2643 snprintf (builtin_name + n, 32 - n, "%sn%s%s",
2644 op[lhs].c, op[rhs1].c, op[rhs2].c);
2645 /* Save copy of parameter string into custom_builtin_name[]. */
2646 strncpy (custom_builtin_name[builtin_code], builtin_name + n, 5);
2647 fndecl =
2648 add_builtin_function (builtin_name, builtin_ftype,
2649 start_code + builtin_code,
2650 BUILT_IN_MD, NULL, NULL_TREE);
2651 nios2_register_builtin_fndecl (start_code + builtin_code, fndecl);
2652 builtin_code += 1;
2653 }
2654 }
2655
2656 /* Helper function for expanding custom builtins. */
2657 static rtx
2658 nios2_expand_custom_builtin (tree exp, unsigned int index, rtx target)
2659 {
2660 bool has_target_p = (TREE_TYPE (exp) != void_type_node);
2661 machine_mode tmode = VOIDmode;
2662 int nargs, argno;
2663 rtx value, insn, unspec_args[3];
2664 tree arg;
2665
2666 /* XnXX form. */
2667 if (has_target_p)
2668 {
2669 tmode = TYPE_MODE (TREE_TYPE (exp));
2670 if (!target || GET_MODE (target) != tmode
2671 || !REG_P (target))
2672 target = gen_reg_rtx (tmode);
2673 }
2674
2675 nargs = call_expr_nargs (exp);
2676 for (argno = 0; argno < nargs; argno++)
2677 {
2678 arg = CALL_EXPR_ARG (exp, argno);
2679 value = expand_normal (arg);
2680 unspec_args[argno] = value;
2681 if (argno == 0)
2682 {
2683 if (!custom_insn_opcode (value, VOIDmode))
2684 error ("custom instruction opcode must be compile time "
2685 "constant in the range 0-255 for __builtin_custom_%s",
2686 custom_builtin_name[index]);
2687 }
2688 else
2689 /* For other arguments, force into a register. */
2690 unspec_args[argno] = force_reg (TYPE_MODE (TREE_TYPE (arg)),
2691 unspec_args[argno]);
2692 }
2693 /* Fill remaining unspec operands with zero. */
2694 for (; argno < 3; argno++)
2695 unspec_args[argno] = const0_rtx;
2696
2697 insn = (has_target_p
2698 ? gen_rtx_SET (target,
2699 gen_rtx_UNSPEC_VOLATILE (tmode,
2700 gen_rtvec_v (3, unspec_args),
2701 UNSPECV_CUSTOM_XNXX))
2702 : gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec_v (3, unspec_args),
2703 UNSPECV_CUSTOM_NXX));
2704 emit_insn (insn);
2705 return has_target_p ? target : const0_rtx;
2706 }
2707
2708
2709 \f
2710
2711 /* Main definition of built-in functions. Nios II has a small number of fixed
2712 builtins, plus a large number of FPU insn builtins, and builtins for
2713 generating custom instructions. */
2714
2715 struct nios2_builtin_desc
2716 {
2717 enum insn_code icode;
2718 enum nios2_ftcode ftype;
2719 const char *name;
2720 };
2721
2722 #define N2_BUILTINS \
2723 N2_BUILTIN_DEF (sync, N2_FTYPE_VOID_VOID) \
2724 N2_BUILTIN_DEF (ldbio, N2_FTYPE_SI_CVPTR) \
2725 N2_BUILTIN_DEF (ldbuio, N2_FTYPE_UI_CVPTR) \
2726 N2_BUILTIN_DEF (ldhio, N2_FTYPE_SI_CVPTR) \
2727 N2_BUILTIN_DEF (ldhuio, N2_FTYPE_UI_CVPTR) \
2728 N2_BUILTIN_DEF (ldwio, N2_FTYPE_SI_CVPTR) \
2729 N2_BUILTIN_DEF (stbio, N2_FTYPE_VOID_VPTR_SI) \
2730 N2_BUILTIN_DEF (sthio, N2_FTYPE_VOID_VPTR_SI) \
2731 N2_BUILTIN_DEF (stwio, N2_FTYPE_VOID_VPTR_SI) \
2732 N2_BUILTIN_DEF (rdctl, N2_FTYPE_SI_SI) \
2733 N2_BUILTIN_DEF (wrctl, N2_FTYPE_VOID_SI_SI)
2734
2735 enum nios2_builtin_code {
2736 #define N2_BUILTIN_DEF(name, ftype) NIOS2_BUILTIN_ ## name,
2737 N2_BUILTINS
2738 #undef N2_BUILTIN_DEF
2739 NUM_FIXED_NIOS2_BUILTINS
2740 };
2741
2742 static const struct nios2_builtin_desc nios2_builtins[] = {
2743 #define N2_BUILTIN_DEF(name, ftype) \
2744 { CODE_FOR_ ## name, ftype, "__builtin_" #name },
2745 N2_BUILTINS
2746 #undef N2_BUILTIN_DEF
2747 };
2748
2749 /* Start/ends of FPU/custom insn builtin index ranges. */
2750 static unsigned int nios2_fpu_builtin_base;
2751 static unsigned int nios2_custom_builtin_base;
2752 static unsigned int nios2_custom_builtin_end;
2753
2754 /* Implement TARGET_INIT_BUILTINS. */
2755 static void
2756 nios2_init_builtins (void)
2757 {
2758 unsigned int i;
2759
2760 /* Initialize fixed builtins. */
2761 for (i = 0; i < ARRAY_SIZE (nios2_builtins); i++)
2762 {
2763 const struct nios2_builtin_desc *d = &nios2_builtins[i];
2764 tree fndecl =
2765 add_builtin_function (d->name, nios2_ftype (d->ftype), i,
2766 BUILT_IN_MD, NULL, NULL);
2767 nios2_register_builtin_fndecl (i, fndecl);
2768 }
2769
2770 /* Initialize FPU builtins. */
2771 nios2_fpu_builtin_base = ARRAY_SIZE (nios2_builtins);
2772 nios2_init_fpu_builtins (nios2_fpu_builtin_base);
2773
2774 /* Initialize custom insn builtins. */
2775 nios2_custom_builtin_base
2776 = nios2_fpu_builtin_base + ARRAY_SIZE (nios2_fpu_insn);
2777 nios2_custom_builtin_end
2778 = nios2_custom_builtin_base + NUM_CUSTOM_BUILTINS;
2779 nios2_init_custom_builtins (nios2_custom_builtin_base);
2780 }
2781
2782 /* Array of fndecls for TARGET_BUILTIN_DECL. */
2783 #define NIOS2_NUM_BUILTINS \
2784 (ARRAY_SIZE (nios2_builtins) + ARRAY_SIZE (nios2_fpu_insn) + NUM_CUSTOM_BUILTINS)
2785 static GTY(()) tree nios2_builtin_decls[NIOS2_NUM_BUILTINS];
2786
2787 static void
2788 nios2_register_builtin_fndecl (unsigned code, tree fndecl)
2789 {
2790 nios2_builtin_decls[code] = fndecl;
2791 }
2792
2793 /* Implement TARGET_BUILTIN_DECL. */
2794 static tree
2795 nios2_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
2796 {
2797 gcc_assert (nios2_custom_builtin_end == ARRAY_SIZE (nios2_builtin_decls));
2798
2799 if (code >= nios2_custom_builtin_end)
2800 return error_mark_node;
2801
2802 if (code >= nios2_fpu_builtin_base
2803 && code < nios2_custom_builtin_base
2804 && ! N2FPU_ENABLED_P (code - nios2_fpu_builtin_base))
2805 return error_mark_node;
2806
2807 return nios2_builtin_decls[code];
2808 }
2809
2810 \f
2811 /* Low-level built-in expand routine. */
2812 static rtx
2813 nios2_expand_builtin_insn (const struct nios2_builtin_desc *d, int n,
2814 struct expand_operand *ops, bool has_target_p)
2815 {
2816 if (maybe_expand_insn (d->icode, n, ops))
2817 return has_target_p ? ops[0].value : const0_rtx;
2818 else
2819 {
2820 error ("invalid argument to built-in function %s", d->name);
2821 return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
2822 }
2823 }
2824
2825 /* Expand ldio/stio form load-store instruction builtins. */
2826 static rtx
2827 nios2_expand_ldstio_builtin (tree exp, rtx target,
2828 const struct nios2_builtin_desc *d)
2829 {
2830 bool has_target_p;
2831 rtx addr, mem, val;
2832 struct expand_operand ops[MAX_RECOG_OPERANDS];
2833 machine_mode mode = insn_data[d->icode].operand[0].mode;
2834
2835 addr = expand_normal (CALL_EXPR_ARG (exp, 0));
2836 mem = gen_rtx_MEM (mode, addr);
2837
2838 if (insn_data[d->icode].operand[0].allows_mem)
2839 {
2840 /* stxio. */
2841 val = expand_normal (CALL_EXPR_ARG (exp, 1));
2842 if (CONST_INT_P (val))
2843 val = force_reg (mode, gen_int_mode (INTVAL (val), mode));
2844 val = simplify_gen_subreg (mode, val, GET_MODE (val), 0);
2845 create_output_operand (&ops[0], mem, mode);
2846 create_input_operand (&ops[1], val, mode);
2847 has_target_p = false;
2848 }
2849 else
2850 {
2851 /* ldxio. */
2852 create_output_operand (&ops[0], target, mode);
2853 create_input_operand (&ops[1], mem, mode);
2854 has_target_p = true;
2855 }
2856 return nios2_expand_builtin_insn (d, 2, ops, has_target_p);
2857 }
2858
2859 /* Expand rdctl/wrctl builtins. */
2860 static rtx
2861 nios2_expand_rdwrctl_builtin (tree exp, rtx target,
2862 const struct nios2_builtin_desc *d)
2863 {
2864 bool has_target_p = (insn_data[d->icode].operand[0].predicate
2865 == register_operand);
2866 rtx ctlcode = expand_normal (CALL_EXPR_ARG (exp, 0));
2867 struct expand_operand ops[MAX_RECOG_OPERANDS];
2868 if (!rdwrctl_operand (ctlcode, VOIDmode))
2869 {
2870 error ("Control register number must be in range 0-31 for %s",
2871 d->name);
2872 return has_target_p ? gen_reg_rtx (SImode) : const0_rtx;
2873 }
2874 if (has_target_p)
2875 {
2876 create_output_operand (&ops[0], target, SImode);
2877 create_integer_operand (&ops[1], INTVAL (ctlcode));
2878 }
2879 else
2880 {
2881 rtx val = expand_normal (CALL_EXPR_ARG (exp, 1));
2882 create_integer_operand (&ops[0], INTVAL (ctlcode));
2883 create_input_operand (&ops[1], val, SImode);
2884 }
2885 return nios2_expand_builtin_insn (d, 2, ops, has_target_p);
2886 }
2887
2888 /* Implement TARGET_EXPAND_BUILTIN. Expand an expression EXP that calls
2889 a built-in function, with result going to TARGET if that's convenient
2890 (and in mode MODE if that's convenient).
2891 SUBTARGET may be used as the target for computing one of EXP's operands.
2892 IGNORE is nonzero if the value is to be ignored. */
2893
2894 static rtx
2895 nios2_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
2896 machine_mode mode ATTRIBUTE_UNUSED,
2897 int ignore ATTRIBUTE_UNUSED)
2898 {
2899 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2900 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
2901
2902 if (fcode < nios2_fpu_builtin_base)
2903 {
2904 const struct nios2_builtin_desc *d = &nios2_builtins[fcode];
2905
2906 switch (fcode)
2907 {
2908 case NIOS2_BUILTIN_sync:
2909 emit_insn (gen_sync ());
2910 return const0_rtx;
2911
2912 case NIOS2_BUILTIN_ldbio:
2913 case NIOS2_BUILTIN_ldbuio:
2914 case NIOS2_BUILTIN_ldhio:
2915 case NIOS2_BUILTIN_ldhuio:
2916 case NIOS2_BUILTIN_ldwio:
2917 case NIOS2_BUILTIN_stbio:
2918 case NIOS2_BUILTIN_sthio:
2919 case NIOS2_BUILTIN_stwio:
2920 return nios2_expand_ldstio_builtin (exp, target, d);
2921
2922 case NIOS2_BUILTIN_rdctl:
2923 case NIOS2_BUILTIN_wrctl:
2924 return nios2_expand_rdwrctl_builtin (exp, target, d);
2925
2926 default:
2927 gcc_unreachable ();
2928 }
2929 }
2930 else if (fcode < nios2_custom_builtin_base)
2931 /* FPU builtin range. */
2932 return nios2_expand_fpu_builtin (exp, fcode - nios2_fpu_builtin_base,
2933 target);
2934 else if (fcode < nios2_custom_builtin_end)
2935 /* Custom insn builtin range. */
2936 return nios2_expand_custom_builtin (exp, fcode - nios2_custom_builtin_base,
2937 target);
2938 else
2939 gcc_unreachable ();
2940 }
2941
2942 /* Implement TARGET_INIT_LIBFUNCS. */
2943 static void
2944 nios2_init_libfuncs (void)
2945 {
2946 /* For Linux, we have access to kernel support for atomic operations. */
2947 if (TARGET_LINUX_ABI)
2948 init_sync_libfuncs (UNITS_PER_WORD);
2949 }
2950
2951 \f
2952
2953 /* Register a custom code use, and signal error if a conflict was found. */
2954 static void
2955 nios2_register_custom_code (unsigned int N, enum nios2_ccs_code status,
2956 int index)
2957 {
2958 gcc_assert (N <= 255);
2959
2960 if (status == CCS_FPU)
2961 {
2962 if (custom_code_status[N] == CCS_FPU && index != custom_code_index[N])
2963 {
2964 custom_code_conflict = true;
2965 error ("switch %<-mcustom-%s%> conflicts with switch %<-mcustom-%s%>",
2966 N2FPU_NAME (custom_code_index[N]), N2FPU_NAME (index));
2967 }
2968 else if (custom_code_status[N] == CCS_BUILTIN_CALL)
2969 {
2970 custom_code_conflict = true;
2971 error ("call to %<__builtin_custom_%s%> conflicts with switch "
2972 "%<-mcustom-%s%>", custom_builtin_name[custom_code_index[N]],
2973 N2FPU_NAME (index));
2974 }
2975 }
2976 else if (status == CCS_BUILTIN_CALL)
2977 {
2978 if (custom_code_status[N] == CCS_FPU)
2979 {
2980 custom_code_conflict = true;
2981 error ("call to %<__builtin_custom_%s%> conflicts with switch "
2982 "%<-mcustom-%s%>", custom_builtin_name[index],
2983 N2FPU_NAME (custom_code_index[N]));
2984 }
2985 else
2986 {
2987 /* Note that code conflicts between different __builtin_custom_xnxx
2988 calls are not checked. */
2989 }
2990 }
2991 else
2992 gcc_unreachable ();
2993
2994 custom_code_status[N] = status;
2995 custom_code_index[N] = index;
2996 }
2997
2998 /* Mark a custom code as not in use. */
2999 static void
3000 nios2_deregister_custom_code (unsigned int N)
3001 {
3002 if (N <= 255)
3003 {
3004 custom_code_status[N] = CCS_UNUSED;
3005 custom_code_index[N] = 0;
3006 }
3007 }
3008
3009 /* Target attributes can affect per-function option state, so we need to
3010 save/restore the custom code tracking info using the
3011 TARGET_OPTION_SAVE/TARGET_OPTION_RESTORE hooks. */
3012
3013 static void
3014 nios2_option_save (struct cl_target_option *ptr,
3015 struct gcc_options *opts ATTRIBUTE_UNUSED)
3016 {
3017 unsigned int i;
3018 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
3019 ptr->saved_fpu_custom_code[i] = N2FPU_N (i);
3020 memcpy (ptr->saved_custom_code_status, custom_code_status,
3021 sizeof (custom_code_status));
3022 memcpy (ptr->saved_custom_code_index, custom_code_index,
3023 sizeof (custom_code_index));
3024 }
3025
3026 static void
3027 nios2_option_restore (struct gcc_options *opts ATTRIBUTE_UNUSED,
3028 struct cl_target_option *ptr)
3029 {
3030 unsigned int i;
3031 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
3032 N2FPU_N (i) = ptr->saved_fpu_custom_code[i];
3033 memcpy (custom_code_status, ptr->saved_custom_code_status,
3034 sizeof (custom_code_status));
3035 memcpy (custom_code_index, ptr->saved_custom_code_index,
3036 sizeof (custom_code_index));
3037 }
3038
3039 /* Inner function to process the attribute((target(...))), take an argument and
3040 set the current options from the argument. If we have a list, recursively
3041 go over the list. */
3042
3043 static bool
3044 nios2_valid_target_attribute_rec (tree args)
3045 {
3046 if (TREE_CODE (args) == TREE_LIST)
3047 {
3048 bool ret = true;
3049 for (; args; args = TREE_CHAIN (args))
3050 if (TREE_VALUE (args)
3051 && !nios2_valid_target_attribute_rec (TREE_VALUE (args)))
3052 ret = false;
3053 return ret;
3054 }
3055 else if (TREE_CODE (args) == STRING_CST)
3056 {
3057 char *argstr = ASTRDUP (TREE_STRING_POINTER (args));
3058 while (argstr && *argstr != '\0')
3059 {
3060 bool no_opt = false, end_p = false;
3061 char *eq = NULL, *p;
3062 while (ISSPACE (*argstr))
3063 argstr++;
3064 p = argstr;
3065 while (*p != '\0' && *p != ',')
3066 {
3067 if (!eq && *p == '=')
3068 eq = p;
3069 ++p;
3070 }
3071 if (*p == '\0')
3072 end_p = true;
3073 else
3074 *p = '\0';
3075 if (eq) *eq = '\0';
3076
3077 if (!strncmp (argstr, "no-", 3))
3078 {
3079 no_opt = true;
3080 argstr += 3;
3081 }
3082 if (!strncmp (argstr, "custom-fpu-cfg", 14))
3083 {
3084 char *end_eq = p;
3085 if (no_opt)
3086 {
3087 error ("custom-fpu-cfg option does not support %<no-%>");
3088 return false;
3089 }
3090 if (!eq)
3091 {
3092 error ("custom-fpu-cfg option requires configuration"
3093 " argument");
3094 return false;
3095 }
3096 /* Increment and skip whitespace. */
3097 while (ISSPACE (*(++eq))) ;
3098 /* Decrement and skip to before any trailing whitespace. */
3099 while (ISSPACE (*(--end_eq))) ;
3100
3101 nios2_handle_custom_fpu_cfg (eq, end_eq + 1, true);
3102 }
3103 else if (!strncmp (argstr, "custom-", 7))
3104 {
3105 int code = -1;
3106 unsigned int i;
3107 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
3108 if (!strncmp (argstr + 7, N2FPU_NAME (i),
3109 strlen (N2FPU_NAME (i))))
3110 {
3111 /* Found insn. */
3112 code = i;
3113 break;
3114 }
3115 if (code >= 0)
3116 {
3117 if (no_opt)
3118 {
3119 if (eq)
3120 {
3121 error ("%<no-custom-%s%> does not accept arguments",
3122 N2FPU_NAME (code));
3123 return false;
3124 }
3125 /* Disable option by setting to -1. */
3126 nios2_deregister_custom_code (N2FPU_N (code));
3127 N2FPU_N (code) = -1;
3128 }
3129 else
3130 {
3131 char *t;
3132 if (eq)
3133 while (ISSPACE (*(++eq))) ;
3134 if (!eq || eq == p)
3135 {
3136 error ("%<custom-%s=%> requires argument",
3137 N2FPU_NAME (code));
3138 return false;
3139 }
3140 for (t = eq; t != p; ++t)
3141 {
3142 if (ISSPACE (*t))
3143 continue;
3144 if (!ISDIGIT (*t))
3145 {
3146 error ("`custom-%s=' argument requires "
3147 "numeric digits", N2FPU_NAME (code));
3148 return false;
3149 }
3150 }
3151 /* Set option to argument. */
3152 N2FPU_N (code) = atoi (eq);
3153 nios2_handle_custom_fpu_insn_option (code);
3154 }
3155 }
3156 else
3157 {
3158 error ("%<custom-%s=%> is not recognised as FPU instruction",
3159 argstr + 7);
3160 return false;
3161 }
3162 }
3163 else
3164 {
3165 error ("%<%s%> is unknown", argstr);
3166 return false;
3167 }
3168
3169 if (end_p)
3170 break;
3171 else
3172 argstr = p + 1;
3173 }
3174 return true;
3175 }
3176 else
3177 gcc_unreachable ();
3178 }
3179
3180 /* Return a TARGET_OPTION_NODE tree of the target options listed or NULL. */
3181
3182 static tree
3183 nios2_valid_target_attribute_tree (tree args)
3184 {
3185 if (!nios2_valid_target_attribute_rec (args))
3186 return NULL_TREE;
3187 nios2_custom_check_insns ();
3188 return build_target_option_node (&global_options);
3189 }
3190
3191 /* Hook to validate attribute((target("string"))). */
3192
3193 static bool
3194 nios2_valid_target_attribute_p (tree fndecl, tree ARG_UNUSED (name),
3195 tree args, int ARG_UNUSED (flags))
3196 {
3197 struct cl_target_option cur_target;
3198 bool ret = true;
3199 tree old_optimize = build_optimization_node (&global_options);
3200 tree new_target, new_optimize;
3201 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
3202
3203 /* If the function changed the optimization levels as well as setting target
3204 options, start with the optimizations specified. */
3205 if (func_optimize && func_optimize != old_optimize)
3206 cl_optimization_restore (&global_options,
3207 TREE_OPTIMIZATION (func_optimize));
3208
3209 /* The target attributes may also change some optimization flags, so update
3210 the optimization options if necessary. */
3211 cl_target_option_save (&cur_target, &global_options);
3212 new_target = nios2_valid_target_attribute_tree (args);
3213 new_optimize = build_optimization_node (&global_options);
3214
3215 if (!new_target)
3216 ret = false;
3217
3218 else if (fndecl)
3219 {
3220 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
3221
3222 if (old_optimize != new_optimize)
3223 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
3224 }
3225
3226 cl_target_option_restore (&global_options, &cur_target);
3227
3228 if (old_optimize != new_optimize)
3229 cl_optimization_restore (&global_options,
3230 TREE_OPTIMIZATION (old_optimize));
3231 return ret;
3232 }
3233
3234 /* Remember the last target of nios2_set_current_function. */
3235 static GTY(()) tree nios2_previous_fndecl;
3236
3237 /* Establish appropriate back-end context for processing the function
3238 FNDECL. The argument might be NULL to indicate processing at top
3239 level, outside of any function scope. */
3240 static void
3241 nios2_set_current_function (tree fndecl)
3242 {
3243 tree old_tree = (nios2_previous_fndecl
3244 ? DECL_FUNCTION_SPECIFIC_TARGET (nios2_previous_fndecl)
3245 : NULL_TREE);
3246
3247 tree new_tree = (fndecl
3248 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
3249 : NULL_TREE);
3250
3251 if (fndecl && fndecl != nios2_previous_fndecl)
3252 {
3253 nios2_previous_fndecl = fndecl;
3254 if (old_tree == new_tree)
3255 ;
3256
3257 else if (new_tree)
3258 {
3259 cl_target_option_restore (&global_options,
3260 TREE_TARGET_OPTION (new_tree));
3261 target_reinit ();
3262 }
3263
3264 else if (old_tree)
3265 {
3266 struct cl_target_option *def
3267 = TREE_TARGET_OPTION (target_option_current_node);
3268
3269 cl_target_option_restore (&global_options, def);
3270 target_reinit ();
3271 }
3272 }
3273 }
3274
3275 /* Hook to validate the current #pragma GCC target and set the FPU custom
3276 code option state. If ARGS is NULL, then POP_TARGET is used to reset
3277 the options. */
3278 static bool
3279 nios2_pragma_target_parse (tree args, tree pop_target)
3280 {
3281 tree cur_tree;
3282 if (! args)
3283 {
3284 cur_tree = ((pop_target)
3285 ? pop_target
3286 : target_option_default_node);
3287 cl_target_option_restore (&global_options,
3288 TREE_TARGET_OPTION (cur_tree));
3289 }
3290 else
3291 {
3292 cur_tree = nios2_valid_target_attribute_tree (args);
3293 if (!cur_tree)
3294 return false;
3295 }
3296
3297 target_option_current_node = cur_tree;
3298 return true;
3299 }
3300
3301 /* Implement TARGET_MERGE_DECL_ATTRIBUTES.
3302 We are just using this hook to add some additional error checking to
3303 the default behavior. GCC does not provide a target hook for merging
3304 the target options, and only correctly handles merging empty vs non-empty
3305 option data; see merge_decls() in c-decl.c.
3306 So here we require either that at least one of the decls has empty
3307 target options, or that the target options/data be identical. */
3308 static tree
3309 nios2_merge_decl_attributes (tree olddecl, tree newdecl)
3310 {
3311 tree oldopts = lookup_attribute ("target", DECL_ATTRIBUTES (olddecl));
3312 tree newopts = lookup_attribute ("target", DECL_ATTRIBUTES (newdecl));
3313 if (newopts && oldopts && newopts != oldopts)
3314 {
3315 tree oldtree = DECL_FUNCTION_SPECIFIC_TARGET (olddecl);
3316 tree newtree = DECL_FUNCTION_SPECIFIC_TARGET (newdecl);
3317 if (oldtree && newtree && oldtree != newtree)
3318 {
3319 struct cl_target_option *olddata = TREE_TARGET_OPTION (oldtree);
3320 struct cl_target_option *newdata = TREE_TARGET_OPTION (newtree);
3321 if (olddata != newdata
3322 && memcmp (olddata, newdata, sizeof (struct cl_target_option)))
3323 error ("%qE redeclared with conflicting %qs attributes",
3324 DECL_NAME (newdecl), "target");
3325 }
3326 }
3327 return merge_attributes (DECL_ATTRIBUTES (olddecl),
3328 DECL_ATTRIBUTES (newdecl));
3329 }
3330
3331 /* Implement TARGET_ASM_OUTPUT_MI_THUNK. */
3332 static void
3333 nios2_asm_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
3334 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
3335 tree function)
3336 {
3337 rtx this_rtx, funexp;
3338 rtx_insn *insn;
3339
3340 /* Pretend to be a post-reload pass while generating rtl. */
3341 reload_completed = 1;
3342
3343 if (flag_pic)
3344 nios2_load_pic_register ();
3345
3346 /* Mark the end of the (empty) prologue. */
3347 emit_note (NOTE_INSN_PROLOGUE_END);
3348
3349 /* Find the "this" pointer. If the function returns a structure,
3350 the structure return pointer is in $5. */
3351 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
3352 this_rtx = gen_rtx_REG (Pmode, FIRST_ARG_REGNO + 1);
3353 else
3354 this_rtx = gen_rtx_REG (Pmode, FIRST_ARG_REGNO);
3355
3356 /* Add DELTA to THIS_RTX. */
3357 nios2_emit_add_constant (this_rtx, delta);
3358
3359 /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX. */
3360 if (vcall_offset)
3361 {
3362 rtx tmp;
3363
3364 tmp = gen_rtx_REG (Pmode, 2);
3365 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
3366 nios2_emit_add_constant (tmp, vcall_offset);
3367 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
3368 emit_insn (gen_add2_insn (this_rtx, tmp));
3369 }
3370
3371 /* Generate a tail call to the target function. */
3372 if (!TREE_USED (function))
3373 {
3374 assemble_external (function);
3375 TREE_USED (function) = 1;
3376 }
3377 funexp = XEXP (DECL_RTL (function), 0);
3378 /* Function address needs to be constructed under PIC,
3379 provide r2 to use here. */
3380 nios2_adjust_call_address (&funexp, gen_rtx_REG (Pmode, 2));
3381 insn = emit_call_insn (gen_sibcall_internal (funexp, const0_rtx));
3382 SIBLING_CALL_P (insn) = 1;
3383
3384 /* Run just enough of rest_of_compilation to get the insns emitted.
3385 There's not really enough bulk here to make other passes such as
3386 instruction scheduling worth while. Note that use_thunk calls
3387 assemble_start_function and assemble_end_function. */
3388 insn = get_insns ();
3389 shorten_branches (insn);
3390 final_start_function (insn, file, 1);
3391 final (insn, file, 1);
3392 final_end_function ();
3393
3394 /* Stop pretending to be a post-reload pass. */
3395 reload_completed = 0;
3396 }
3397
3398 \f
3399 /* Initialize the GCC target structure. */
3400 #undef TARGET_ASM_FUNCTION_PROLOGUE
3401 #define TARGET_ASM_FUNCTION_PROLOGUE nios2_asm_function_prologue
3402
3403 #undef TARGET_IN_SMALL_DATA_P
3404 #define TARGET_IN_SMALL_DATA_P nios2_in_small_data_p
3405
3406 #undef TARGET_SECTION_TYPE_FLAGS
3407 #define TARGET_SECTION_TYPE_FLAGS nios2_section_type_flags
3408
3409 #undef TARGET_INIT_BUILTINS
3410 #define TARGET_INIT_BUILTINS nios2_init_builtins
3411 #undef TARGET_EXPAND_BUILTIN
3412 #define TARGET_EXPAND_BUILTIN nios2_expand_builtin
3413 #undef TARGET_BUILTIN_DECL
3414 #define TARGET_BUILTIN_DECL nios2_builtin_decl
3415
3416 #undef TARGET_INIT_LIBFUNCS
3417 #define TARGET_INIT_LIBFUNCS nios2_init_libfuncs
3418
3419 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
3420 #define TARGET_FUNCTION_OK_FOR_SIBCALL hook_bool_tree_tree_true
3421
3422 #undef TARGET_CAN_ELIMINATE
3423 #define TARGET_CAN_ELIMINATE nios2_can_eliminate
3424
3425 #undef TARGET_FUNCTION_ARG
3426 #define TARGET_FUNCTION_ARG nios2_function_arg
3427
3428 #undef TARGET_FUNCTION_ARG_ADVANCE
3429 #define TARGET_FUNCTION_ARG_ADVANCE nios2_function_arg_advance
3430
3431 #undef TARGET_ARG_PARTIAL_BYTES
3432 #define TARGET_ARG_PARTIAL_BYTES nios2_arg_partial_bytes
3433
3434 #undef TARGET_TRAMPOLINE_INIT
3435 #define TARGET_TRAMPOLINE_INIT nios2_trampoline_init
3436
3437 #undef TARGET_FUNCTION_VALUE
3438 #define TARGET_FUNCTION_VALUE nios2_function_value
3439
3440 #undef TARGET_LIBCALL_VALUE
3441 #define TARGET_LIBCALL_VALUE nios2_libcall_value
3442
3443 #undef TARGET_FUNCTION_VALUE_REGNO_P
3444 #define TARGET_FUNCTION_VALUE_REGNO_P nios2_function_value_regno_p
3445
3446 #undef TARGET_RETURN_IN_MEMORY
3447 #define TARGET_RETURN_IN_MEMORY nios2_return_in_memory
3448
3449 #undef TARGET_PROMOTE_PROTOTYPES
3450 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
3451
3452 #undef TARGET_SETUP_INCOMING_VARARGS
3453 #define TARGET_SETUP_INCOMING_VARARGS nios2_setup_incoming_varargs
3454
3455 #undef TARGET_MUST_PASS_IN_STACK
3456 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
3457
3458 #undef TARGET_LEGITIMATE_CONSTANT_P
3459 #define TARGET_LEGITIMATE_CONSTANT_P nios2_legitimate_constant_p
3460
3461 #undef TARGET_LEGITIMIZE_ADDRESS
3462 #define TARGET_LEGITIMIZE_ADDRESS nios2_legitimize_address
3463
3464 #undef TARGET_DELEGITIMIZE_ADDRESS
3465 #define TARGET_DELEGITIMIZE_ADDRESS nios2_delegitimize_address
3466
3467 #undef TARGET_LEGITIMATE_ADDRESS_P
3468 #define TARGET_LEGITIMATE_ADDRESS_P nios2_legitimate_address_p
3469
3470 #undef TARGET_PREFERRED_RELOAD_CLASS
3471 #define TARGET_PREFERRED_RELOAD_CLASS nios2_preferred_reload_class
3472
3473 #undef TARGET_RTX_COSTS
3474 #define TARGET_RTX_COSTS nios2_rtx_costs
3475
3476 #undef TARGET_HAVE_TLS
3477 #define TARGET_HAVE_TLS TARGET_LINUX_ABI
3478
3479 #undef TARGET_CANNOT_FORCE_CONST_MEM
3480 #define TARGET_CANNOT_FORCE_CONST_MEM nios2_cannot_force_const_mem
3481
3482 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
3483 #define TARGET_ASM_OUTPUT_DWARF_DTPREL nios2_output_dwarf_dtprel
3484
3485 #undef TARGET_PRINT_OPERAND
3486 #define TARGET_PRINT_OPERAND nios2_print_operand
3487
3488 #undef TARGET_PRINT_OPERAND_ADDRESS
3489 #define TARGET_PRINT_OPERAND_ADDRESS nios2_print_operand_address
3490
3491 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
3492 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA nios2_output_addr_const_extra
3493
3494 #undef TARGET_ASM_FILE_END
3495 #define TARGET_ASM_FILE_END nios2_asm_file_end
3496
3497 #undef TARGET_OPTION_OVERRIDE
3498 #define TARGET_OPTION_OVERRIDE nios2_option_override
3499
3500 #undef TARGET_OPTION_SAVE
3501 #define TARGET_OPTION_SAVE nios2_option_save
3502
3503 #undef TARGET_OPTION_RESTORE
3504 #define TARGET_OPTION_RESTORE nios2_option_restore
3505
3506 #undef TARGET_SET_CURRENT_FUNCTION
3507 #define TARGET_SET_CURRENT_FUNCTION nios2_set_current_function
3508
3509 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
3510 #define TARGET_OPTION_VALID_ATTRIBUTE_P nios2_valid_target_attribute_p
3511
3512 #undef TARGET_OPTION_PRAGMA_PARSE
3513 #define TARGET_OPTION_PRAGMA_PARSE nios2_pragma_target_parse
3514
3515 #undef TARGET_MERGE_DECL_ATTRIBUTES
3516 #define TARGET_MERGE_DECL_ATTRIBUTES nios2_merge_decl_attributes
3517
3518 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
3519 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK \
3520 hook_bool_const_tree_hwi_hwi_const_tree_true
3521
3522 #undef TARGET_ASM_OUTPUT_MI_THUNK
3523 #define TARGET_ASM_OUTPUT_MI_THUNK nios2_asm_output_mi_thunk
3524
3525 struct gcc_target targetm = TARGET_INITIALIZER;
3526
3527 #include "gt-nios2.h"