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